esrf

Beamline Instrument Software Support
SPEC Macro documentation: [ Macro Index | BCU Home ]

#%TITLE% CPLOTARRAY.MAC
#%NAME% 
#  Macros to work with cplot from within spec using arrays
#%CATEGORY% Scans
#%DESCRIPTION%
#  Plotting and printing in spec have some limitations which can be
#  easily overcome by using the external program %B%cplot%B%. To let users
#  with no knowledge in cplot use some of the common features of cplot
#  this macro package has been written. %BR% 
#  For further functionality users are encouraged to use the cplot package
#  directly. (Or their favourite plotting/graphics package). %BR% 
#  The macros in this package also provide a easy way to make special
#  plots %LINK%cplot.gif (example)%LINK%. 
#  You can plot different plots on one page, mix 3D with one
#  dimensional cuts, plot mca or thermocouple information and much
#  more.
#%OVERVIEW%
#  Basic plots can be done with one or two commands. 
#  %DL%
#  %DT%cpsetup%DD% to set up the parameters (like titles..) for the plot
#  %DT%cplot%DD% to plot a graph from a datafile or the last scan done
#		 on the screen.
#  %DT%pplot%DD% to print a graph from a datafile or the last scan done
#		 on the printer
#  %DT%plot3d,contour,pplot3d,pcontour%DD% to make a 3D or contour
#                plot from a data file.
#  %XDL%
#  
#  If you call the macros mentioned above, a plot will be generated in
#  each case. Macros in this section will only plot immediatly if you
#  did not open the plot before with cp_opengraph(). %BR%
#  %DL%
#  %DT%cp_opengraph(): %DD% Opens a graph
#  %DT%cp_closegraph(): %DD% Closes the graph and makes the plot 
#  %DT%cp_windows(2,3) : %DD% Sets the page up with 2 plots in x and 3 plots in
#                   y direction.
#  %DT%cp_advance():%DD% goes to the next plot
#  %DT%cp_mplot:%DD% plots the data from a certain array 
#  %DT%cp_fplot:%DD% plots the data from a file
#  %DT%cp_cplot(counters):%DD% plots the data for selected counters
#  %DT%cp_cont:%DD% plots a contour plot from data in file
#  %DT%cp_3d:%DD% plots a 3D plot from the data in file
#  %XDL%  
#  The plot will go either to the printer or to the screen. You can
#  select this by typing:
#  %UL%  
#  %LI%cp_setprinter
#  %LI%cp_setx11
#  %XUL%  
#  before the plot. The selected output device will stay active until
#  you change it.%BR%
#
#  and may be less important:
#  %DL%  
#  %DT%cp_newpage:%DD% goes to a new page
#  %DT%cp_title(title):%DD% puts a global title on the page
#  %DT%cp_plottitle(title, xl, yl, xunits, yunits):%DD% puts title , 
#             x-label and y-label on an individual
#            plot. This is done normally by the macros above.
#  %XDL%  
#%EXAMPLE%
#  %B% pplot%B% (plots the current scan on the printer) %BR%
#  %B% pplot 12 %B%
#%END%        


# This is the new cplot macro set
# Internals:
#   First time I try to use variables and constant strings with
#   one macro. If you want to give a string variable just enclose it
#   in double brackets like usual. If you want to give a variable
#   use single quotes double quotes '"testvar"'. You have to escape
#   the single quotes in a macro definition \'"testvar"\'
# This is an example of an cp_defaults file # should be in idxxspecial.mac 

def cp_defaults 'example_cp_defaults'

def example_cp_defaults '
CP_PAR["LINES"] = 2; CP_PAR["COLS"] =2 #No of Windows in X and Y direction
CP_PAR["LMARG"] = 0; CP_PAR["RMARG"] = 0 ; #Left Right Bottom Top Margin
CP_PAR["TMARG"]=0.1 ; CP_PAR["BMARG"] =0.1 #on complete page 1== Maximum
# Point size , Point symbol from 0 to 28,  Line symbol from 0 to 6 (0=full)
CP_PAR["PSIZE"]=4 ; CP_PAR["PSYMBOL"]=1 ; CP_PAR["LSYMBOL"]=0 
# how much should point size grow for smaller plots *(1+growfactor*(1/size-1))
CP_PAR["GROWFACTOR"]=0
# Fontsizes for title, label, annotation, symbols, key and date
CP_PAR["TFONT"]=5 ; CP_PAR["LFONT"]=4.5 ; CP_PAR["NFONT"]=4.5 ;
CP_PAR["SFONT"]=2 ; CP_PAR["KFONT"]=4.5 ; CP_PAR["DFONT"]=3
# Filename will be constructed from file and dir
CP_PAR["FILENAME"]="datos"
CP_PAR["FILE"]="datos"
CP_PAR["DIR"]="/users/d/klora/working/cplot"
CP_PAR["CONFILE"]="firsttests"
CP_PAR["SCANNO"]=-1 #Default scan no
CP_PAR["PRINTER"]="a4dc102"
CP_PAR["PRINTFORMAT"]="%s @lp @-d%s" # Print instr. (Sys. V use"%s @lp @-d%s")
CP_PAR["FILTER"]="x11" # Filter x11 -rotate will be appended automatically
# Plot title, label and units
CP_PAR["PTITLE"]="A very long plottitle"  
CP_PAR["PXLABEL"]="X"  
CP_PAR["PYLABEL"]="Y"  
CP_PAR["PXUNITS"]=""  
CP_PAR["PYUNITS"]=""  
# 3D Viewpoint , No of contour lines
CP_PAR["CONLINES"]=30
CP_PAR["VIEWPX"]=1.3 ; CP_PAR["VIEWPY"]=-2.4 ; CP_PAR["VIEWPZ"]=2
# Manual Key can be constructed with
CP_PAR["NOKEYS"]=1
CP_PAR["KEY1"]=0
CP_PAR["KEYT1"]="Label for key symbol 0"
CP_PAR["YLABELLEN"]=30 # Maximum length for y labels
CP_PAR["PAPERLONG"] = 25.75
CP_PAR["PAPERSHORT"] = 19.125
CP_PAR["PLMARG"] = .19; CP_PAR["PRMARG"] = .1 ; #Margin for each plot 
CP_PAR["PTMARG"] = .1; CP_PAR["PBMARG"] = .1 ;  #window
CP_PAR["COMMARG"] =.2 # Margin for extra FWHM and comment below plot
CP_PAR["COMMENT"] = "\\\CAND AN ADDITIONAL COMMENT"
CP_PAR["GLOBTITLE"] = "Global title"
CP_PAR["USESCANS"]=1 # Use specs scan program
# Default columns 
CP_PAR["XCOLUMN"]=1 ; CP_PAR["YCOLUMN"]=-1 ; CP_PAR["ZCOLUMN"]=2
# Manual scaling min and max for x and y
CP_PAR["MINX"]=0 ; CP_PAR["MAXX"]=1 ; CP_PAR["MINY"]=0 ; CP_PAR["MAXY"]=1
# 0x01 = plot lines, 0x02 = plot points, 0x04 = auto scaling x 
# 0x08 = auto scaling y  0x10 = portrait  0x20 = date 
# 0x40 = wait after each page 
# 0x80 = use title from parameter menu , 0x100 = use x-label from
# parameter menu , 0x200 = use y-label from parameter menu
# 0x400 contour (otherwise 3d) , 0x800 = print KEY
# 0x1000 y axis log 0x2000 x axis log 0x4000 error bar mode
# 0x8000 rescale each plot 0x10000 put FWHM and other res on plot
# 0x20000 put global title on each page 0x40000 put page no on each page
# 0x80000 put global text CP_PAR["COMMENT"] on plot
# 0x100000 take filename from spec
# 0x200000 put filename on page
CP_PAR["FLAGS"]=0x6f
'

# OPEN the graph if not already open
# Parameters : none
# VAR : OPEN/m TMPDATA/i TMPFILE/i 

#%UU%  
#%MDESC%
#    Produces a menu with many options. Because of the number of
#    options the menu is subdivided into groups of questions or flags 
#    - each marked with a number.
#    You will see a page like this:
#
#%PRE%
#           ************** CPLOT OPTION MENU ******************
#01  Draw Lines YES 02 Draw Points YES 03  Error Bars NO  04       Log Y NO  
#05       Log X NO  06    Plot Key YES 07   Plot FWHM NO  08 Plot Commen NO  
#09 X Auto Scal YES 10 Y Auto Scal YES 11     Rescale YES 12    Portrait YES 
#13        Date YES 14  Page Title NO  15     Page No NO  16   File Name NO  
#17   Scan File NO  18   Over plot YES 
#19 FILE Name: datos Dir: /users/d/klora/working/cplot 
#20 DEFAULT Col X: 1 Col Y: -1 Col Z: 2 Scan No: -1 
#21 PRINTER Name: a4dc102 
#22 WINDOWS X: 2 Y: 2 
#23 MANUAL SCALE XMin: 0 XMax: 1 YMin: 0 YMax: 1 
#24 PAPERSIZE Long: 25.75 Short: 19.125 
#25 PAGE MARGIN Left: 0 Right: 0 Top: 0.1 Bottom: 0.1 
#26 PLOT MARGIN Left: 0.19 Right: 0.1 Top: 0.1 Bottom: 0.1 
#27 GLOBAL Title: Global title 
#28 COMMENT Comment: \CAND AN ADDITIONAL COMMENT Com Margin: 0.2 
#29 3D Contour Lines: 30 Viewpoint X: 1.3 Y: -2.4 Z: 2 
#30 CHAR SIZE Title: 5 Label: 4.5 Key: 4.5 Date: 3 
#31 SYMBOLS Point Code: 1 Point Size: 4 Point Grow Factor: 0 Line Code: 0 
#32 PLOT Title: A very long plottitle XLabel: X YLabel: Y XUnit:  YUnits:  
#
#  Draw Lines: Connect the points with lines 
#  Draw Points: Draw points at each data point
#  Error Bars: Draw error bars (sqrt(data)) - not implemented yet
#  Log Y: Use log y-axis. If the data contains 0 or negative numbers
#     a linear axis will be used without error message.
#  Log X: Same as for Y
#  Plot Key: A key which indicates which curve corresponds to which symbol
#     is plotted for each plot.
#  Plot FWHM: Information like FWHM, Center of Mass, Peak position ,...
#     is plotted below each plot. his is only done for the last curve
#     plotted for the moment.
#  Plot Comment: An additional comment is printed below each plot.
#  X-Auto Scale: The X axis is scaled automatically. If you want to use
#     a manual scale this option AND THE RESCALE OPTION has to be switched
#     off and the manual scale entered.
#  Y-Auto Scale: Same as X
#  Rescale: Each curve in the plot is rescaled individually. For the
#     second curve an extra axis will be plotted on the right hand side.
#  Portrait: Changes the paper orientation
#  Date: Put the date on each page
#  Page Title: Put a global title on each page (set with global title)
#  Page No: Put the page number on each page
#  File Name: Put the file name on each page
#  Scan File: Use always the spec DATAFILE and DATA_DIR and not the
#     values from this menu
#  Over plot: Plots the selected scans from a file in one graph
#  FILE NAME and DIR: Filename of the files containing the scans
#  DEFAULT: Default scan number, x, y, and z column if no input is provided
#  PRINTER: The name of your printer
#  WINDOWS: The number of plots on one page in x and y direction
#  MANUAL: The manual scale if automatic scaling and resize is switched off
#  PAPERSIZE: The size of a DINA4 page
#  PAGE MARGIN: The margins on each page, Values go from 0 to 1
#  PLOT MARGIN: Margins for each plot on one page. Values go from 0 to 1
#  GLOBAL: The global title (Header on the page(s))
#  COMMENT: A comment and the extra margin below the plot. If the 
#     comment text starts with \C the following text will be centered.
#  3D : Number of contour lines and view point for 3D plots
#  CHAR SIZE: Font size of Title, labels, keys and the date
#  SYMBOLS: Symbol for points (from 0 to 28, where 9 is a very small dot)
#     Size of these symbols, A number which specifies how much a point
#     should shrink if there are more plots on a page. 0 means shrink
#     like everything else (labels for example) 1 means do not shrink
#     at all. Values in between are allowed. Line Symbol from 0 to 6
#     where 0 is a simple line.
#  PLOT : The title and labels will be normally set to something
#     meaningful. The units given here will be put on the plots.
#%PRE%

def cpsetup '
  global CP_TMPFILE CP_PAR CP_WINDOW CP_VAR[]
  global CP_FILEIDX
  if (CP_PAR["PAPERLONG"] == 0) { cp_defaults }

  if (!$#) {
     while (!cp_menu ())
  }
'

#%IU%  
#%MDESC% Display once the menu and asks the user 
def cp_menu () '{
  global optarr[] option
  clscreen()
  tty_move(0,0," ********** \[md]CPLOT OPTION MENU\[me] ************")
  cp_pflags ("TOP")
  cp_pflags ("Draw Lines", 0x01)
  cp_pflags ("Draw Points", 0x02)
  cp_pflags ("Error Bars", 0x4000)
  cp_pflags ("Log Y", 0x1000)
  cp_pflags ("Log X", 0x2000)
  cp_pflags ("Plot Key", 0x800)
  cp_pflags ("Plot FWHM", 0x10000)
  cp_pflags ("Plot Comment", 0x080000)
  cp_pflags ("X Auto Scale", 0x04)
  cp_pflags ("Y Auto Scale", 0x08)
  cp_pflags ("Rescale", 0x8000)
  cp_pflags ("Portrait", 0x10)
  cp_pflags ("Date", 0x20)
  cp_pflags ("Page Title", 0x020000)
  cp_pflags ("Page No", 0x040000)
  cp_pflags ("File Name", 0x200000)
  cp_pflags ("Scan File", 0x100000)
  cp_pflags ("Over plot", 0x400000)

  cp_ppars  ("FILE", "Name,FILE,Dir,DIR")
  cp_ppars  ("DEFAULT", \
		"Col X,XCOLUMN,Col Y,YCOLUMN,Col Z,ZCOLUMN,Scan No,SCANNO" )
  cp_ppars  ("PRINTER", "Name,PRINTER" )
  cp_ppars  ("WINDOWS", "X,LINES,Y,COLS")
  cp_ppars  ("MANUAL SCALE", "XMin,MINX,XMax,MAXX,YMin,MINY,YMax,MAXY")
  cp_ppars  ("PAPERSIZE", "Long,PAPERLONG,Short,PAPERSHORT")
  cp_ppars  ("PAGE MARGIN", "Left,LMARG,Right,RMARG,Top,TMARG,Bottom,BMARG")
  cp_ppars  ("PLOT MARGIN", \
			"Left,PLMARG,Right,PRMARG,Top,PTMARG,Bottom,PBMARG")
  cp_ppars  ("GLOBAL", "Title,GLOBTITLE" )
  cp_ppars  ("COMMENT", "Comment,COMMENT,Com Margin,COMMARG")
  cp_ppars  ("3D", \
		"Contour Lines,CONLINES,Viewpoint X,VIEWPX,Y,VIEWPY,Z,VIEWPZ")
  cp_ppars  ("CHAR SIZE", "Title,TFONT,Label,LFONT,Key,NFONT,Date,DFONT")
  cp_ppars  ("SYMBOLS", \
 	        "Point Code,PSYMBOL,Pnt Size,PSIZE,Pnt Grow Factor,GROWFACTOR,Line Code,LSYMBOL" )
  cp_ppars  ("PLOT", \
     "Title,PTITLE,XLabel,PXLABEL,YLabel,PYLABEL,XUnit,PXUNITS,YUnits,PYUNITS")
  if (cp_askpar ())
    return(1);
  cp_updatefilename()
  return 0;
}'


#%IU% (Flag explanation string, flag mask)
#%MDESC%
#  Displays the flag explanation string with the flag status (The mask is
#  given, Variable CP_PAR["FLAGS"] is used) and saves this
#  information for later reference in optarr and optflag (1 for flags)
#  uses variable option.

def cp_pflags (text, mask) '{
  if (text == "TOP") {
    CP_VAR["ROW"] = 1 ; CP_VAR["COL"] = 0; 
    option = 0
  } else {  
    tty_cntl("updated?")
    tty_move(CP_VAR["COL"],CP_VAR["ROW"],\
	sprintf("\[md]%02d\[me] %11.11s \[mr]%s\[me]", ++option, text, \
	(CP_PAR["FLAGS"]&mask) ? "YES":"NO "))
  
    if ((CP_VAR["COL"] += 20) > COLS - 20 ) {
      CP_VAR["ROW"] ++;
      CP_VAR["COL"] = 0; 
    }

    optarr[option]["text"] = text
    optarr[option]["mask"] = mask
    optarr[option]["flag"] = 1
  }
}'

#%IU% (title, pars)
#%MDESC%
#  Displays the title and expl. string for each parameter. A parameter
#  is defined as CP_PAR["<parameter name>"]. The information is stored 
#  for later reference.

def cp_ppars (title, pars) '{
  local str i _p[]
  optarr[++option]["text"] = title 
  optarr  [option]["flag"] = 0
  optarr  [option]["pars"] = split (pars, _p, ",") 
  str = title " "

  for (i=0; i < optarr[option]["pars"]; i += 2 ) {
     str = str sprintf("%s \[us]%s\[ue] ", _p[i], CP_PAR[_p[i + 1]])
     optarr  [option][i]      = _p[i] 
     optarr  [option][i+1]    = _p[i+1]
  } 
  tty_move(0, -1001, sprintf("\r\[md]%02d\[me] %s",option, str))
}'

#%IU%
#%MDESC%
# Asks the user to enter a reference number and displays the questions
# stored with cp_ppars or toggles the flag

def  cp_askpar() '{
  local val ii
  if ( (val = getval("\nEnter number to change or 0 to exit",0)) == 0)
    return 1
  if (!(val < 1 || val > option )) {
    if (optarr [val]["flag"] == 1) {
      if (CP_PAR["FLAGS"] & optarr[val]["mask"]) 
        CP_PAR["FLAGS"] &= ~optarr[val]["mask"]
      else
        CP_PAR["FLAGS"] |= optarr[val]["mask"]  
    } else {
      for (ii=0; ii < optarr[val]["pars"] / 2; ii++) {
        CP_PAR[optarr[val][2*ii+1]] = \
		getval(optarr[val][2*ii],CP_PAR[optarr[val][2*ii+1]])
      }
    }
  } 
  return 0;
}'

#%IU% (file)
#%MDESC% Deletes the file.
def cp_removefile(file) '{
  unix (sprintf("rm -f %s",file))
}'

#%IU% (val, default_val)
#%MDESC% If length of val is zero (parameter not present) return default
def cp_defaultpar(val, default) '{
  if (val == 0) 
     return CP_PAR[default];
  else
     return val;
}'

#%UU% 
#%MDESC%
#  Opens a new graph. This command will create a new temporary file
#  to put the cplot commands in and inits a couple of variables.
#  This macro is called from almost all the plot commands if the user
#  did not type in cp_opengraph() explicitely before.

def cp_opengraph() '{
 if (!CP_VAR["OPEN"]) { 
   # Remove temporary data and cplot files
   CP_VAR["TMPDATA"] = sprintf("/tmp/cptmpd_%s%s",USER,SPEC)
   close(CP_VAR["TMPDATA"])
   cp_removefile(CP_VAR["TMPDATA"])
   CP_VAR["TMPFILE"] = sprintf("/tmp/cptmp_%s%s",USER,SPEC)
   close(CP_VAR["TMPFILE"])
   cp_removefile(CP_VAR["TMPFILE"])
 
   # Put page start commands in and remember that we opened the file
   CP_VAR["PAGE"]=1
   cp_startpage()
   cp_fonts()
   CP_VAR["OPEN"]=1
   CP_VAR["WID"]=-1
   if (CP_VAR["WINDOW"]) {
     cp_advance()
     }
 }
} '

#%UU%
#%MDESC%
#  Closes the current page and opens a new one (with cp_startpage)

def cp_newpage '
{
  cp_ongraph()
    printf("zs\n%s",(CP_PAR["FLAGS"]&0x40) ? "w\n" : "")
  cp_offgraph()
  cp_startpage()
}'

#%IU%  
#%MDESC%
#  Opens only a new page and puts the title on the page

def cp_startpage() '{
    local filter

    cp_updatefilename()

    cp_ongraph()

    filter = CP_PAR["FILTER"]

    if (CP_PAR["FLAGS"]&0x10) {
        if (CP_PAR["FILTER"] == "x11") filter="x11 -rotate"
    }

    printf("re\nzi %s\ntu %d\nwi 0\ngd 1\n0 0\n1 1\n^d\nzew\n", \
           filter,(CP_PAR["FLAGS"]&0x10) ? 1 : 0)

    if (CP_PAR["FLAGS"]&0x20) {
        printf ("zd\n")
    }

    cp_offgraph()

    if ((CP_PAR["FLAGS"]&0x40000) || (CP_PAR["FLAGS"]&0x20000) || (CP_PAR["FLAGS"]&0x200000)) {
        local title
        title  = ""

        if (CP_PAR["FLAGS"]&0x20000) {
            title = CP_PAR["GLOBTITLE"]
            if (CP_PAR["FLAGS"]&0x40000) title = sprintf("%s / ",title)
        }

        if (CP_PAR["FLAGS"]&0x40000) {
            title = sprintf("%sPage %d",title,CP_VAR["PAGE"]++)
        }

        cp_updatefilename()

        if (CP_PAR["FLAGS"]&0x200000) {
            title = sprintf("%s File:%s",title,CP_PAR["FILENAME"])
        }

        cp_title (title)
    }
}'

#%UU%
#%MDESC%
#  Closes the graph. This includes calling cplot to execute the script
#  which has been written so far.

def cp_closegraph() '{
  cp_plotdata
  cp_ongraph()
    printf("zs\n%sex\n",(CP_PAR["FLAGS"]&0x40) ? "w\n" : "")
  cp_offgraph()
  close(CP_VAR["TMPFILE"])
  close(CP_VAR["TMPDATA"])
  unix(sprintf("(cplot -s %s ; echo /bin/rm -f %s )",CP_VAR["TMPFILE"],CP_VAR["TMPFILE"]))
  CP_VAR["OPEN"]=0
  CP_VAR["WINDOW"]=0
}'

#%IU%  
#%MDESC%
#  Command will send all the output of the following print commands to
#  the cplot scriptfile.

def cp_ongraph() '{
  on(CP_VAR["TMPFILE"]); offt
}'

#%IU%  
#%MDESC%
#  This command will switch the output back to the terminal

def cp_offgraph() '{
  ont;off(CP_VAR["TMPFILE"])
}'

#%IU%  
#%MDESC%
#  This command will send all the following output to the script file
#  for the current plot. As scaling commands will have to be given
#  before the actual data (to plot 2 or more curves in the same plot)
#  another file then the graph file is used for this purpose. 

def cp_ondata() '{
  on(CP_VAR["TMPDATA"]); offt
}'

#%IU%  
#%MDESC%
#  Switches the output back to the terminal

def cp_offdata() '{
  ont;close(CP_VAR["TMPDATA"])
}'

#%UU% [title string]
#%MDESC%
#  Will put a title command into the script. If no input is given the
#  title is taken from CP_PAR["TITLE"]

def cp_title(title) '{
  cp_ongraph()
  title =cp_defaultpar(title,"TITLE")
  printf("tx\n%s\n\n\n\n\nzt\n",title)
  cp_offgraph()
}
  '

#%UU% (title, xlabel, ylabel, xunits, yunits)
#%MDESC%
#  Puts a individual plot title and axis information into the
#  script file. If a parameter is not given it will take it from
#  CP_PAR["PTITLE"] (or PXLABEL PYLABEL PXUNITS PYUNITS). The y-label
#  length willbe cut to CP_PAR["YLABELLEN"] characters.

def cp_plottitle (pt, pxl, pyl, pxu, pyu) '{
  pt  = cp_defaultpar(pt, "PTITLE")
  pxl = cp_defaultpar(pxl, "PXLABEL")
  pyl = cp_defaultpar(pyl, "PYLABEL")
  pxu = cp_defaultpar(pxu, "PXUNITS")
  pyu = cp_defaultpar(pyu, "PYUNITS")
  pt = sprintf(sprintf("%%.%ds",CP_PAR["YLABELLEN"]),pt)
  if (pt == "") pt="\\"
  if (pxl == "") pxl="\\"
  if (pyl == "") pyl="\\"
  if (pxu == "") pxu="\\"
  if (pyu == "") pyu="\\"
  cp_ongraph()
    printf("tx\n%s\n%s\n%s\n%s\n%s\n",pt,pxl,pxu,pyl,pyu);
  cp_offgraph()
}'

#%UU% [no of columns] [no of lines]
#%MDESC%
#  Will define the general page layout with <no of columns> number of
#  plots in x direction and <no of lines> number of plots in y direction.
#  If a parameter is not given it is taken from CP_PAR["COLS"] or
#  CP_PAR["LINES"]. The CP_VAR["WID"] (for window id) is set to -1, the
#  number of plots per page will be taken as CP_PAR["LINES"]*CP_PAR["COLS"]
#  later. You can create your own special layout by assigning the
#  border information to CP_WINDOW[uu] in the format: %BR%
#  sprintf ("%f %f %f %f",1-y2,x1,1-y1,x2) for portrait and
#  sprintf ("%f %f %f %f",x1,y1,x2,y2) for landscape.
#  The number are relative positions between 0 and 1.

def cp_windows(cols,rows) '{
  local x1 y1 x2 y2 line uu row
  if (cols > 0) CP_PAR["COLS"] = cols
  if (rows > 0) CP_PAR["LINES"] = rows

  CP_VAR["WID"] = -1
  xwidth = (1 - CP_PAR["RMARG"] - CP_PAR["LMARG"]) / CP_PAR["COLS"]
  ywidth = (1 - CP_PAR["TMARG"] - CP_PAR["BMARG"]) / CP_PAR["LINES"]
  for (uu=0,line=0,row=0;uu<CP_PAR["COLS"]*CP_PAR["LINES"];uu++) {
    x1=row*xwidth + CP_PAR["LMARG"]; 
    y1 = 1 - CP_PAR["TMARG"] - (line+1)*ywidth
    x2 = x1 + xwidth; y2 = y1 + ywidth
    if (CP_PAR["FLAGS"]&0x10) {
      CP_WINDOW[uu] = sprintf ("%f %f %f %f",1-y2,x1,1-y1,x2)
    }
    else {
      CP_WINDOW[uu] = sprintf ("%f %f %f %f",x1,y1,x2,y2)
    }
    if (++row >= CP_PAR["COLS"]) {
      line++
      row =0
    } 
  }
  CP_VAR["PLOTTED"]=1
  cp_advance()
  CP_VAR["WINDOW"] =1
}'

#%UU%
#%MDESC%
#  Advances one plot. If you do not enter this command all the plots
#  will be plotted into the same graph.

def cp_advance() '{
  cp_plotdata
  if (CP_VAR["WID"] >= (CP_PAR["COLS"]*CP_PAR["LINES"]-1)) {
    CP_VAR["WID"] = -1;
    cp_newpage
    }  
  cp_indmarg()
  cp_ongraph()
    printf("lo %s\n",CP_WINDOW[++CP_VAR["WID"]])
  cp_offgraph()
  if (CP_PAR["FLAGS"]&0x04) {
    CP_VAR["MINX"]=1E50 ; CP_VAR["MAXX"]=-1E50;
  } else {
    CP_VAR["MINX"]=CP_PAR["MINX"] ; CP_VAR["MAXX"]=CP_PAR["MAXX"];
  }
  if (CP_PAR["FLAGS"]&0x08) {
    CP_VAR["MINY"]=1E50 ; CP_VAR["MAXY"]=-1E50; 
  } else {
    CP_VAR["MINY"]=CP_PAR["MINY"] ; CP_VAR["MAXY"]=CP_PAR["MAXY"];
  }

}'

#%IU%  
#%MDESC%
#  Puts the calculated result (FWHM ..) and a comment from CP_PAR["COMMENT"]
#  in the script.

def cp_restext() '{
  local restext
  restext = ""
  if (CP_PAR["FLAGS"]&0x10000) {
    restext = sprintf("\\\CPeak at %.5g is %.5g.  COM at %.5g",\
        CP_VAR["PEAK"],CP_VAR["MAX"],CP_VAR["COM"])
    restext = sprintf("%s\n\\\CFWHM is %.5g at %.5g.   ",\
        restext,CP_VAR["FWHM"],CP_VAR["CFWHM"])
    if (CP_PAR["FLAGS"]&0x80000) restext = sprintf("%s\n",restext)
  } 
  if (CP_PAR["FLAGS"]&0x80000) {
    restext = sprintf("%s%s",restext,CP_PAR["COMMENT"])
  } 
  cp_text (restext)
}'


#%IU%  
#%MDESC%
#  Calculates the window size, depending on CP_PAR["PLMARG"], ..PRMARG,
#  PBMARG, PTMARG and puts it into the script file.

def cp_indmarg() '{
  local hor ver wid hei soff
  soff=0
  if (CP_PAR["FLAGS"]&0x90000) soff = CP_PAR["COMMARG"]
  if (CP_PAR["FLAGS"]&0x10) {
    hoff = CP_PAR["PAPERSHORT"] * CP_PAR["PLMARG"] 
    voff = CP_PAR["PAPERLONG"] * (CP_PAR["PBMARG"]+soff) 
    wid = CP_PAR["PAPERSHORT"] * (1 - CP_PAR["PRMARG"] - CP_PAR["PLMARG"]) 
    hei = CP_PAR["PAPERLONG"]  * (1-CP_PAR["PTMARG"]-CP_PAR["PBMARG"]-soff)
  } else {
    hoff = CP_PAR["PAPERLONG"] * CP_PAR["PLMARG"] 
    voff = CP_PAR["PAPERSHORT"] * (CP_PAR["PBMARG"]+soff) 
    wid = CP_PAR["PAPERLONG"] *(1 - CP_PAR["PRMARG"] - CP_PAR["PLMARG"])
    hei = CP_PAR["PAPERSHORT"]*(1-CP_PAR["PTMARG"]-CP_PAR["PBMARG"]-soff)
  }
  cp_ongraph()
    printf ("wi %f %f %f %f\n",hoff,voff,wid,hei)
  cp_offgraph()

} '

#%IU%  <text string>
#%MDESC%
#  Puts a text string below a plot. 

def cp_text(text) '{
  local soff
  soff = 0
  if (CP_PAR["FLAGS"]&0x90000) soff = CP_PAR["COMMARG"]
  if (CP_PAR["FLAGS"]&0x10) {
    voff =CP_PAR["PAPERLONG"]*(1-CP_PAR["PBMARG"]-CP_PAR["PTMARG"]-soff) +2.5
    hoff = 0
  } else {
    voff =CP_PAR["PAPERSHORT"]*(1-CP_PAR["PBMARG"]-CP_PAR["PTMARG"]-soff) +2.5 
    hoff = 0
  }
  cp_ongraph()
    printf("zn %f %f\n%s\n^d\n",hoff,voff,text)
  cp_offgraph()
} '

#%IU%  
#%MDESC%
#  Sets the font size for title, labels, keys, date, text and symbols
#  from global parameters.

def cp_fonts() '{
  cp_ongraph()
    printf("cs t %f\n",CP_PAR["TFONT"])
    printf("cs l %f\n",CP_PAR["LFONT"])
    printf("cs n %f\n",CP_PAR["NFONT"])
    printf("cs s %f\n",CP_PAR["SFONT"])
    printf("cs k %f\n",CP_PAR["KFONT"])
    printf("cs d %f\n",CP_PAR["DFONT"])
  cp_offgraph()
}'


#%IU%  <array> <x> <y> <npts> [point symbol] [point size] [line symbol]
#%MDESC%
#  Puts the data points and some scaling and axis information in the 
#  cplot data script. If the three last parameters are not given they will
#  be taken from: CP_PAR["PSYMBOL"], CP_PAR["PSIZE"], CP_PAR["LSYMBOL"], 
#  If the option <Resize every plot> is set, the y-label must be known
#  here. Depending if the label to be drawn is on the left or on the right 
# hand side CP_PAR["KEYT1"] or CP_PAR["KEYT2"] will be used. 

def cp_data '
{
  local g px py pn parr max mix may miy psize psymbol lsymbol reduct sortfile
  local dummyfile awkfile 
  
  parr = "$1"
  # changed by holger on 23/7/2020, the PLOT_MOTS add threw an index in array
  # problem in the array_dump function below.
#  px = $2 ; py = cnt_num($3) + PLOT_MOTS  ; pn = "$4" 
  px = $2 ; py = cnt_num($3) ; pn = "$4" 

  if (index(pn,":") == 0 && index(pn,",") == 0)
    pn = ":" pn

  if ($#>4) { psymbol = $5 } else { psymbol =  CP_PAR["PSYMBOL"] }
  if ($#>5) { psize = $6 } else { psize =  CP_PAR["PSIZE"] }
  if ($#>6) { lsymbol = $7 } else { psize =  CP_PAR["LSYMBOL"] }
  
  CP_VAR["PLOTTED"]=0
  reduct = 1+CP_PAR["GROWFACTOR"]*((CP_PAR["LINES"]+CP_PAR["COLS"])/2-1)
  psize = psize * reduct
  cp_ondata()
    printf("gd 1\n")
  cp_offdata()
  if (CP_PAR["SORT"] == 1 || (CP_PAR["FLAGS"] & 0x1000) ) {
     sortfile = sprintf("/tmp/cptmps_%s%s",USER,SPEC)
     close(sortfile)
     cp_removefile(sortfile)
     on(sortfile) ; offt 
        array_dump(@parr[pn][px,py])
     ont ; close(sortfile)
     if (CP_PAR["SORT"] == 1) {
       if (CP_PAR["FLAGS"] & 0x1000) # log plot 
         unix(sprintf("awk \'{if (\$2 > 0) print \$0} \' %s |sort -n >> %s",\
			sortfile,CP_VAR["TMPDATA"]))	
       else 
         unix(sprintf("sort -n %s >>%s",sortfile,CP_VAR["TMPDATA"]))
     } else if (CP_PAR["FLAGS"] & 0x1000) 
       unix(sprintf("awk \'{ if (\$2 > 0) print \$0 } \' %s >> %s",\
						sortfile,CP_VAR["TMPDATA"]))
     cp_removefile(sortfile)
  } else {
      cp_ondata()
      array_dump(@parr[pn][px,py])
      cp_offdata()
  }
  cp_ondata()
    printf("^d\n")
    if (CP_PAR["FLAGS"] & 0x8000) {
      printf("np\n")
      if (CP_VAR["RIGHTAXIS"] == 0) \
        printf("tx\n\n\n\n%s\n\nty . . +256\nty . . -640\nzal\nty . . -256\n",\
		CP_PAR["KEYT1"])
      if (CP_VAR["RIGHTAXIS"] == 1) {
        printf("tx\n\n\n\n%s\n\nty . . -256\nty . . +640\nzal\nty . . -640\n",\
		CP_PAR["KEYT2"])
        }
      CP_VAR["RIGHTAXIS"]++
      }
    if (CP_PAR["FLAGS"] & 0x01) \
	printf("sy %c\nzp\n",(lsymbol==0)?76:lsymbol+64)
    if (CP_PAR["FLAGS"] & 0x02) {
      printf("cs s %f\nsy %s\nzp\n",psize,psymbol)
      }
  cp_offdata()
  if (CP_PAR["FLAGS"]&0x04) {
    mix=array_op("min",@parr[pn][px]) ; max=array_op("max",@parr[pn][px])
    if (CP_VAR["MINX"]>mix) CP_VAR["MINX"]=mix
    if (CP_VAR["MAXX"]<max) CP_VAR["MAXX"]=max
    CP_VAR["MIX"] = mix   
    CP_VAR["MAX"] = max   
  } else {
    CP_VAR["MIX"] = CP_VAR["MINX"]
    CP_VAR["MAX"] = CP_VAR["MAXX"]   
  } 
  if (CP_PAR["FLAGS"]&0x08) {
    miy=array_op("min",@parr[pn][py]) ; may=array_op("max",@parr[pn][py])
    if (CP_PAR["FLAGS"] & 0x1000) {
      local array atmp[array_op("rows",@parr)] [array_op("cols",@parr)]
      atmp = (@parr[pn][py] <= 0) * may + @parr[pn][py]
      miy=array_op("min",atmp[pn][py])
      if (may <= 0) may = 0
    } 
    if (CP_VAR["MINY"]>miy) CP_VAR["MINY"]=miy
    if (CP_VAR["MAXY"]<may) CP_VAR["MAXY"]=may
    CP_VAR["MIY"] = miy   
    CP_VAR["MAY"] = may   
  } else {
    CP_VAR["MIY"] = CP_VAR["MINY"]
    CP_VAR["MAY"] = CP_VAR["MAXY"]   
  } 
  if (CP_PAR["FLAGS"] &0x10000) {
    CP_VAR["FWHM"]=arr__FWHM($1,px,py,pn)
    CP_VAR["CFWHM"]=arr__CFWHM($1,px,py,pn)
    CP_VAR["COM"]=arr__COM($1,px,py,pn)
    CP_VAR["PEAK"]=arr__xMAX($1,px,py,pn)
    CP_VAR["MAX"]=arr__MAX($1,py,pn)
  }
  
}  
'
#%IU%  
#%MDESC%
#  The script written to the data file will be inserted with some scale 
#  information into the cplot graph script.

def cp_plotdata '
{
  local mix max miy may
  if (CP_PAR["FLAGS"] & 0x8000) {
    mix = CP_VAR["MIX"]  ; max = CP_VAR["MAX"]  
    miy = CP_VAR["MIY"]  ; may = CP_VAR["MAY"]  
  } else {
    mix = CP_VAR["MINX"]  ; max = CP_VAR["MAXX"]  
    miy = CP_VAR["MINY"]  ; may = CP_VAR["MAXY"]  
  } 
  if (!CP_VAR["PLOTTED"]) {
    if (miy >= may) {
      print "Y Min >= Y Max "
    } else {
      if (mix >= max) {
        print "X Min >= X Max " 
      } else {
        cp_ongraph()
           if ( (miy >= 0) && (CP_PAR["FLAGS"]& 0x1000))  { 
             printf("ty . +8 .\n")
           } else {
	     printf("ty . -8 .\n")
           }
           if ( (mix > 0) && (CP_PAR["FLAGS"]& 0x2000))  { 
             printf("ty +8 . .\n")
           } else {
	     printf("ty -8 . .\n")
           }
           printf("eb %d\n",(CP_PAR["FLAGS"] & 0x4000)?1:0)
           if (!(CP_PAR["FLAGS"] & 0x8000)) {
	     printf("ra %g %g %g %g\nza\nztl\n",CP_VAR["MINX"],\
                   CP_VAR["MAXX"],CP_VAR["MINY"],CP_VAR["MAXY"])
           } else {
             printf("zt\n")
           } 
        cp_offgraph()
        close(CP_VAR["TMPFILE"])
        unix (sprintf("cat %s >> %s",CP_VAR["TMPDATA"],CP_VAR["TMPFILE"]))
        if (CP_PAR["FLAGS"] & 0x90000) {
          cp_restext()
        }
        if (CP_VAR["RIGHTAXIS"] == 1) {
          cp_ongraph()
            printf("ty . . -256\nty . . +640\nza\nty . . -640\n")
          cp_offgraph()
        }
      }
    }
    cp_key()    
    cp_removefile(CP_VAR["TMPDATA"])
    CP_VAR["PLOTTED"]=1
    CP_VAR["RIGHTAXIS"] = 0
  }
}  
'
#%IU%  
#%MDESC%
#  If the option <Key> is set, this macro will insert the CP_PAR["NOKEYS"]
##  keys with symbols CP_PAR["KEYxx"] and text CP_PAR["KEYTxx"]

def cp_key () '{
  if (CP_PAR["FLAGS"] & 0x800) {
    cp_ongraph() 	
      printf ("gk\n")
      for (iu=0;iu<CP_PAR["NOKEYS"];iu++) {
        printf ("%s %s\n",CP_PAR[sprintf("KEY%d",iu+1)],\
	  CP_PAR[sprintf("KEYT%d",iu+1)])
      }	
      printf ("^D\nzk\n")
    cp_offgraph()
  }
}'	

#%IU%  [filename]
#%MDESC%
#  Gets information about the scans in a file. If filename is not given
#  CP_PAR["FILENAME"] will be used. The following global variables contain
#  the information: %BR%
#   %B%CP_SCANNO%B% real scanno, %B%CP_SCANTITLE%B% = "ascan ddsd sds d", 
#   %B%CP_SCANAXIS%B% columns separated with two blanks 
#   split(SC_SCANAXIS[uu],tt,"  "),
#   %B%CP_SCANINFO%B% No of scans 


def cp_getfileinfo(filename) '{
  global CP_SCANNO CP_SCANTITLE CP_SCANAXIS CP_SCANINFO
  local line tmpfile uu filename
  cp_updatefilename()
  if (filename == 0 || filename == "") {filename = CP_PAR["FILENAME"]} 
  tmpfile = sprintf("/tmp/cpfi_%s%s",SPEC,USER)
  cp_removefile(tmpfile)
  unix(sprintf("awk \'/#S/ { SN=\$2; ST=substr(\$0,length(\$2)+6); } /#L/ { printf(\"%%d\\t%%s\\t%%s\\n\",SN,ST,substr(\$0,4)) } \' %s >%s",filename,tmpfile))
  if (file_info(tmpfile,"-r")) {
    for (uu=0;(line=getline(tmpfile)) != -1;uu++) {
      sscanf(line,"%[^\t] %[^\t] %[^\n]",CP_SCANNO[uu],CP_SCANTITLE[uu],CP_SCANAXIS[uu])
    }
    CP_SCANINFO = uu
    getline(tmpfile,"close")
    cp_removefile(tmpfile)
    }
  else {
    CP_SCANINFO = 0
  }
}'

#%IU%  [Scan-no] [column-list] [filename]
#%MDESC%
#   Reads the specified columns from scan <Scan-no> and puts them into 
#   group CP_FILEGRP. CP_VAR["PTSINFILE"] will contain the number of points
#   read and CP_VAR["COLSINFILE"] the number of columns.
#   The default values are taken from CP_PAR["SCANNO"] and CP_PAR[FILENAME"]
#   If CP_PAR["USESCANS"] is set the program scans is used and not awk
#   if the number of columns is less than 4.

def cp_getfiledata_awk (scanno, select, filename) '{
  local line tmpfile uu tmpstr filename ii
  global CP_FILEIDX
  cp_updatefilename()
  if (scanno == 0) { scanno = CP_PAR["SCANNO"] }
  if (select != 0) { cp_analpars (select,scanno) } 
  if (filename == 0 || filename == "") { filename = CP_PAR["FILENAME"] }
  tmpfile = sprintf("/tmp/cpfd_%s%s",SPEC,USER)
  cp_removefile(tmpfile)
  tmpstr = sprintf("awk \'/#S/ { SPRINT=0 } \
      /#S %d / { SPRINT=1 } /^[^#]/ { if (SPRINT) printf(\" ",scanno)
  for (ii=0;ii<CP_SELNO;ii++) {
    tmpstr = sprintf("%s%%12g ",tmpstr)
  }
  tmpstr = sprintf("%s\\n\" ",tmpstr)

  for (ii=0;ii<CP_SELNO;ii++) {
    tmpstr = sprintf("%s,\$%d",tmpstr,CP_SELECTED[ii])
    CP_FILEIDX[ii]=CP_SELECTED[ii]
  }
  tmpstr = sprintf("%s) } \' %s >%s",tmpstr,filename,tmpfile)
  unix(tmpstr)
  CP_VAR["PTSINFILE"] = 0
  CP_VAR["COLSINFILE"] = 0
  if (file_info(tmpfile,"-r")) {
    local str
    unix (sprintf("wc %s",tmpfile), str)
    sscanf (str, "%d", maxn)
    if (maxn > 0) {
      array CP_FILED[maxn][CP_SELNO]
      CP_VAR["PTSINFILE"] = array_read (tmpfile,CP_FILED)
      CP_VAR["COLSINFILE"] = CP_SELNO
    } else 
      print "No data points found from \"",tmpstr,"\""
    cp_removefile(tmpfile)
  }
}'

def cp_getfiledata (scanno, select, filename) '{
  local line tmpfile uu tmpstr ii
  global CP_FILEIDX
  cp_updatefilename()
  scanno = cp_defaultpar(scanno,"SCANNO")
  if (select != 0) { cp_analpars (select,scanno) } 
  filename = cp_defaultpar(filename,"FILENAME")
  tmpfile = sprintf("/tmp/cpfd_%s%s",SPEC,USER)
  cp_removefile(tmpfile)
  if ((CP_SELNO > 3) || !(CP_PAR["USESCANS"])) {
    tmpstr = sprintf("awk \'/#S/ { SPRINT=0 } \
        /#S %d / { SPRINT=1 } /^[^#]/ { if (SPRINT) printf(\" ",scanno)
    for (ii=0;ii<CP_SELNO;ii++) {
      tmpstr = sprintf("%s%%12g ",tmpstr)
    }
    tmpstr = sprintf("%s\\n\" ",tmpstr)
    for (ii=0;ii<CP_SELNO;ii++) {
      tmpstr = sprintf("%s,\$%d",tmpstr,CP_SELECTED[ii])
      CP_FILEIDX[ii]=CP_SELECTED[ii]
    }
    tmpstr = sprintf("%s) } \' %s >%s",tmpstr,filename,tmpfile)
  } else {
     if (CP_SELNO == 3) {
        # Option s is sort & merge (merge will add both counts) 
        tmpstr=sprintf("scans -f %s +Sv -sedrnIq x=%d y=%d z=%d %d >%s 2>/dev/null",\
        filename,CP_SELECTED[0],CP_SELECTED[1],CP_SELECTED[2],scanno,tmpfile) 
     } else {
        tmpstr=sprintf("scans -f %s +Sv -sedrnIq x=%d y=%d %d >%s 2>/dev/null",\
        filename,CP_SELECTED[0],CP_SELECTED[1],scanno,tmpfile) 
     }

     for (ii=0; ii < CP_SELNO; ii++) {
        CP_FILEIDX[ii]=CP_SELECTED[ii]
     }

  }
  unix(tmpstr)
  CP_VAR["PTSINFILE"] = 0
  CP_VAR["COLSINFILE"] = 0
  if (file_info(tmpfile,"-r")) {
    local str
    unix (sprintf("wc %s",tmpfile), str)
    sscanf (str, "%d", maxn)
    if (maxn > 0) {
      array CP_FILED[maxn][CP_SELNO]
      CP_VAR["PTSINFILE"] = array_read (tmpfile,CP_FILED)
      CP_VAR["COLSINFILE"] = CP_SELNO
    } else 
      print "No data points found from \"",tmpstr,"\""
    cp_removefile(tmpfile)
  }
}'

#%UU% [array] [x] [y-list] [no-pts] [plot-title] [x-label] [y-label]
#%MDESC%
#   This macro plots data from a specified group.
#   The default values for group x and y are 0 0 1. The default values
#   for the title, x and y labels are taken from CP_PAR["PTITLE"] , "PXLABEL",
#   "PYLABEL". The graph is opened and closed if it is not already open.

def cp_mplot '
{
  global CP_SELECTED CP_SELNO CP_MAXSEL
  local opened windowed ii _cp_x _cp_y
  local _mxtitle _mxlabel _mylabel
  
  if (!CP_VAR["OPEN"]) {
     cp_opengraph()
     opened = 1 
     }
  if (!CP_VAR["WINDOW"]) {
     cp_windows() 
     windowed =1
     }
     
  cp_memdefaults $# $1 $2 \'$3\' \'$4\' \'$5\' \'$6\' \'$7\'
  cp_plottitle (_mtitle, _mxlabel, _mylabel)
  for (ii=0;ii<CP_SELNO;ii++) {
    local sym lsym size
    size = CP_PAR["PSIZE"]
    if (CP_PAR["FLAGS"]&0x02) {
      sym = (ii+CP_PAR["PSYMBOL"]) 
      lsym = CP_PAR["LSYMBOL"] 
    } else {
      sym = CP_PAR["PSYMBOL"] 
      lsym = (ii+CP_PAR["LSYMBOL"]) 
    }
    cp_data $1 _cp_x CP_SELECTED[ii] \'"_cp_n"\' sym size lsym 
  }
  if (opened) {
     cp_closegraph()
  }
     
} '  

#%UU% [scanno-list] [x-col] [y-col-list] [title] [x-label] [y-label]
#%MDESC%
#   Plots data from a file. The default values for scanno-list, x-col, and
#   y-col-list are taken from CP_PAR["SCANNO"]. 
#   The default title is "SCAN <SCANNO>: <SCANTITLE>". The default x-label
#   is taken from the file column header. The y-label is contructed from
#   all the file column headers if there is only one label. The keys are
#   taken in any case from the file column headers. The graph is opened and
#   closed if it is not already open. The plotwindow is advanced after 
#   each scan.

def cp_fplot '
{
  global CP_SELECTED CP_SELNO CP_MAXSEL
  local opened windowed ii _cp_sn _cp_scan _cp_x _cp_y _cp_lastpt
  local temp i1
  global labels
  if (!CP_VAR["OPEN"]) {
     cp_opengraph()
     opened = 1 
     }
  if (!CP_VAR["WINDOW"]) {
     cp_windows() 
     }

  cp_updatefilename()
  ifile = CP_PAR["FILENAME"]
  cp_getfileinfo (ifile)
  CP_MAXSEL = CP_SCANNO[0] 
  minscanno = CP_SCANNO[0] 
  for (ii=1;ii< CP_SCANINFO ; ii++ ) {
    if ((CP_SCANNO[ii]+0) > CP_MAXSEL) CP_MAXSEL = CP_SCANNO[ii]+0
    if ((CP_SCANNO[ii]+0) < minscanno) minscanno = CP_SCANNO[ii]+0
    }
  maxscanno = CP_MAXSEL 
  cp_filedefaults $# \'$1\' \'$2\' \'$3\'
  # Prepare selectionlist in group elements (user supplied columns)
  collist = sprintf("%s,%s",_cp_x,_cp_y)
  for (j1=0;j1<_cp_sn;j1++) {
    if ( (_cp_scan[j1] > maxscanno ) || (_cp_scan[j1] < minscanno)) {
      printf("Scanno %d is not in [%d,%d]",_cp_scan[j1],minscanno,maxscanno)
      continue
    }
    # find scanno
    for (uu=0;uu<CP_SCANINFO;uu++) {
      if (CP_SCANNO[uu] == _cp_scan[j1]) {
        idx = uu
        }
      }  
    CP_MAXSEL = split(CP_SCANAXIS[idx],labels,"  ")
# SPLIT changed in 4.04.01 and there is a problem in the scans with 4 blanks
    if (index(CP_SCANAXIS[idx],"    "))
	CP_MAXSEL -= split("1    4",temp,"  ") - 2
    cp_getfiledata (_cp_scan[j1],collist)
    cp_ftitle $# \'$4\' \'$5\' \'$6\' \'$7\'
    for (ii=0;ii<CP_VAR["COLSINFILE"];ii++) {
      if (CP_FILEIDX[ii] == _cp_x) _xcol = ii
    }
    for (i1=0;i1<CP_VAR["COLSINFILE"];i1++) {
      if (i1 != _xcol) {
        local sym lsym size
        size = CP_PAR["PSIZE"]
        if (CP_PAR["FLAGS"]&0x02) {
          sym = (i1 - 1 +CP_PAR["PSYMBOL"]) 
          lsym = CP_PAR["LSYMBOL"] 
        } else {
          sym = CP_PAR["PSYMBOL"] 
          lsym = (i1 -1 +CP_PAR["LSYMBOL"]) 
        }
        _cp_lastpt = CP_VAR["PTSINFILE"]-1  
        cp_data CP_FILED _xcol i1 \'"_cp_lastpt"\' sym size lsym
      }
    }
    if ((j1 != (_cp_sn-1))&&!(CP_PAR["FLAGS"]&0x400000)) { cp_advance() }
  }
  if (opened) {
     cp_closegraph()
  }
} '  

#%IU%  
#%MDESC%
#   Used internally. Will update CP_PAR["FILENAME"] from spec's DATAFILE
#   or value given by the user.

def cp_updatefilename() '{
  if (CP_PAR["FLAGS"]&0x100000) {
    if (DATAFILE != "/dev/null") CP_PAR["FILE"]=DATAFILE
    CP_PAR["DIR"]=DATA_DIR
  } else {
    if ( (CP_VAR["OLDFILE"] != 0) && (CP_PAR["FILE"]==DATAFILE)) 
      CP_PAR["FILE"] = CP_VAR["OLDFILE"]
    CP_VAR["OLDFILE"]=CP_PAR["FILE"]
    if ( (CP_VAR["OLDDIR"] != 0) && (CP_PAR["DIR"]==DATA_DIR)) 
      CP_PAR["DIR"] = CP_VAR["OLDDIR"]
    CP_VAR["OLDDIR"]=CP_PAR["DIR"]
  }
  if (!index(CP_PAR["FILE"], "/") && file_info(CP_PAR["DIR"],"-d") )
    CP_PAR["FILENAME"] = sprintf("%s/%s",CP_PAR["DIR"],CP_PAR["FILE"])
  else
    CP_PAR["FILENAME"] = CP_PAR["FILE"]
  CP_PAR["CONFILE"]=CP_PAR["FILENAME"]
}'

#%IU%  [title] [x-label] [y-label]
#%MDESC%
#   Used in cp_fplot to create and plot the title and the labels.

def cp_ftitle '
{
  if ($1 >3) { 
    _ftitle = "$2"
  } else {
    _ftitle = sprintf("Scan %d : %s",CP_SCANNO[idx],CP_SCANTITLE[idx])
  }
  
  if ($1 >4) {
    _fxlabel = "$3"
  } else {
    if (_cp_x + 0 > 0) 
      _fxlabel = labels[_cp_x+0-1]
    else
      _fxlabel = _cp_x
  }

  if ($1> 5) {
    _fylabel = "$4"
  } else {
      for (_fylabel="",u1=0;u1<CP_SELNO;u1++) {
        if (CP_SELECTED[u1] != (_cp_x+0)) {
          _fylabel = sprintf("%s %s",_fylabel,labels[CP_SELECTED[u1]-1])
        }
      }
  }  

  if (CP_PAR["FLAGS"] & 0x8800) {
    for (u1=0,u2=0;u1<CP_SELNO;u1++) {
      if (CP_SELECTED[u1] != (_cp_x+0)) {
        if (CP_PAR["FLAGS"]&0x02) {
          CP_PAR[sprintf("KEY%d",u2+1)] = u2+CP_PAR["PSYMBOL"]
        } else {
          CP_PAR[sprintf("KEY%d",u2+1)] = sprintf("%c",\
		(u2+CP_PAR["LSYMBOL"] ==0)?76:u2+CP_PAR["LSYMBOL"]+64)
        }  
        CP_PAR[sprintf("KEYT%d",u2+1)] = labels[CP_SELECTED[u1]-1]
        u2++
      }
    }
    CP_PAR["NOKEYS"] = u2  
  } 

  cp_plottitle (_ftitle,_fxlabel,_fylabel) 
} '
#%IU%  <no-of-pars> <array> <x> <y-list> <npts> <title> <xlabel> <ylabel>
#%MDESC%
#   Used in cp_mplot to get defaults

def cp_memdefaults '
  if ($1>1) {_cp_x = $3} else {_cp_x = 0}
  if ($1<=2) {
    CP_SELECTED[0]=1 ; CP_SELNO = 1
  } else {
    local inp ; inp = "$4"
    CP_MAXSEL = COUNTERS
    cp_analpars (inp)
  }
  if ($1>3) { _cp_n = "$5" } else {_cp_n = ":"}
  if ($1>4) { _mtitle = "$6" } else { _mtitle = CP_PAR["PTITLE"] } 
  if ($1>5) { _mxlabel = "$7" } else { _mxlabel = CP_PAR["PXLABEL"] } 
  if ($1>6) { _mylabel = "$8" } else { _mylabel = CP_PAR["PYLABEL"] } 

  if (index(_cp_n,":") == 0 && index (_cp_n,",") == 0) 
    _cp_n = ":" _cp_n
'

#%IU%  <n-of-pars> <scanno-list> <x-col> <ycol-list> <title>  <xlabel> <ylabel>
#%MDESC%
# Used in cp_fplot to get defaults
#
# parameter can be given as single number, region (a:b), negative
# number (from the end) and comma separated lists of this
# Example: -5:-1,2,4-6
#
def cp_filedefaults '
  # Get default parameters
  if ($1>0) { 
    local inp ; inp = _deref("$2")
    cp_analpars (inp)
    for (ii = 0; ii< CP_SELNO; ii++ ) {
      _cp_scan[ii] = CP_SELECTED[ii]
    }
    _cp_sn = CP_SELNO
  } else {
    _cp_scan[0] = CP_PAR["SCANNO"] ; _cp_sn = 1
  }
  
  if ($1 <= 1) {_cp_x = CP_PAR["XCOLUMN"] ; _cp_y = CP_PAR["YCOLUMN"] }
  else if ($1 == 2) {_cp_x = CP_PAR["XCOLUMN"] ; _cp_y = "$3"} 
  else if ($1 == 3) {_cp_x = "$3" ; _cp_y = "$4" } 
'

#%IU%  [list]
#%MDESC%
#  [list] is parsed to get a list of selected elements. CP_MAXSEL must
#  be the highest possible number for an element. This is used to interpret
#  -1. [list] can be given as single number, region (a:b), negative
#  number (from the end) and comma separated lists of this
#  Example: -5:-1,2,4-6
#  The result is returned in the global array CP_SELECTED. The number of
#  selected elements is in CP_SELNO. 
def cp_analpars(inp, scanno) '{
  global CP_SELECTED CP_SELNO CP_MAXSEL
  local swap nolist ii jj
  sno =0 ;
  if (length(scanno))
    inp = cp_replacefilemnes(inp, scanno)
  nolist = split(inp,list,",")
  for (ii=0; ii < nolist; ii++) {
    if (index(list[ii],":")) {
      split(list[ii],region,":")
      if (region[0] < 0) 
        region[0] = CP_MAXSEL + 1 + region[0]
      if (region[1] < 0) 
        region[1] = CP_MAXSEL + 1 + region[1]
      if (region[1] < region[0]) { 
	swap = region[1] ; region[1] = region[0] ; region[0] = swap
      } 
      for (jj = region[0]; jj <= region[1]; jj ++)
        selected[sno++] = jj
    } else {
      if (list[ii] < 0)
        list[ii] = CP_MAXSEL + 1 + list[ii]
      selected[sno++] = list[ii]
    }
  }
  
  # Sort it
  for (ii=0;ii<sno-1;ii++) {
    for (jj=ii+1;jj<sno;jj++) {
      if (selected[ii] > selected[jj]) {
         swap = selected[ii]
         selected[ii]= selected[jj]
         selected[jj]= swap
      }
    }
  }

  # Delete double elements
  CP_SELECTED[0]=selected[0]
  if (sno > 0) {
    for (ii=1,jj=0;ii<sno;ii++) {
      if (selected[ii] != selected[ii-1]) jj++
      CP_SELECTED[jj]=selected[ii]
    }
    CP_SELNO = jj+1
  } else {
    CP_SELNO = 0
  }

# LOOK INTO THAT  
  _cp_x=selected[0]

}'


def cp_replacefilemnes (str, scanno) '{
  local names no tmp pos ccol[] mcol[]

  if (CP_SCANNO[scanno] == scanno)
    cntstr = CP_SCANAXIS[scanno]
  else {
    for (uu = 0; uu < CP_SCANINFO ;uu++) {
      if (CP_SCANNO[uu] == scanno) {
        cntstr = CP_SCANAXIS[uu]
        break;
      }
    }
  }

  # Delete carriage return and multiple blanks
  if (pos = index(cntstr,"\n"))
    cntstr = substr (cntstr, 1, pos - 1)
  while (pos = index(cntstr,"   ")) {
    cntstr = substr(cntstr, 1 , pos - 1)  substr(cntstr, pos + 1)
  }
  no = split(cntstr,names,"  ")

  for (j = 0; j < COUNTERS; j++) { 
    ccol[j] = -1
    if (index(sprintf("%s  ",cntstr),sprintf("%s  ",cnt_name(j)))) {
      for (i = 0; i < no; i++ )
        if (cnt_name(j) == names[i])
          break
      if (i != no) 
        ccol[j] = i+1
    }
  }

  for (j = 0; j < MOTORS; j++) {
    mcol[j] = -1
    if (index(sprintf("%s  ",cntstr),sprintf("%s  ",motor_name(j)))) {
      for (i = 0; i < no; i++ )
        if (motor_name(j) == names[i])
          break
      if (i != no) 
        mcol[j] = i+1
    }
  }

  # correcting the string concatenation as function argument feature 
  local tmpstr1; tmpstr1 = str ","
  local tmpstr2; tmpstr2 = cnt_mne(i) ","
  for (i = 0 ; i < COUNTERS; i++ )
    if ( ccol[i] != -1 && (start = index(tmpstr1, tmpstr2)) ) 
       str = sprintf("%s%d%s", substr (str, 1 , start - 1) , ccol[i], \
            substr (str, start + length(cnt_mne(i))))  

  local tmpstr2; tmpstr2 = motor_mne(i) ","
  for (i = 0 ; i < MOTORS; i++ )
    if ( mcol[i] != -1 && (start = index(tmpstr1, tmpstr2)) )
       str = sprintf("%s%d%s", substr (str, 1 , start - 1) , mcol[i], \
            substr (str, start + length(motor_mne(i))))  
  return str
}
'

#%UU% <counter list>
#%MDESC%
#  Plot slected counters.
def cp_cplot (cntlist) '{
  local cindexes ylabel i firsthit spl_arr spl_no yind i cursel

  if (length(cntlist) == 0) {
      cntlist = PLOT_SEL[0]
      for (i = 1; i < PLOT_NUM; i++){
          cntlist = cntlist "," PLOT_SEL[i]
      }
  }

  yind = _cp_plot_replacemne (cntlist)
  spl_no = split(yind,spl_arr,",")

  if (!(CP_PAR["FLAGS"] & 0x8800)) {
      for (i2=0,ylabel=""; i2<spl_no; i2++) {
          ylabel = sprintf("%s %s",ylabel,cnt_name(spl_arr[i2]-1))
      }
  }
  else {
      ylabel = "Counters"

      for (u1=0;u1<spl_no;u1++) {
          if (CP_PAR["FLAGS"]&0x02) {
              CP_PAR[sprintf("KEY%d",u1+1)] = u1+CP_PAR["PSYMBOL"]
          }
          else {
              CP_PAR[sprintf("KEY%d",u1+1)] = sprintf("%c",     \
                                (u1+CP_PAR["LSYMBOL"] ==0)?76:u1+CP_PAR["LSYMBOL"]+64)
          }
          CP_PAR[sprintf("KEYT%d",u1+1)] = cnt_name(spl_arr[u1]-1)
      }
      CP_PAR["NOKEYS"] = spl_no
  }

  cp_mplot SCAN_D 0 \'"yind"\' \'"LDT"\' \'"T_L"\' \'"X_L"\' \'"ylabel"\'

}'

#%IU% (str)
#%MDESC% _plot_replacemne taken from old plotarray.mac
def _cp_plot_replacemne(str) '{
         local i, j, n, m, s[], r

         if (index(str, ","))
                 m = split(str, s, ",")
         else
                 m = split(str, s)
         n = array_op("cols", @pl_a)
         r = ""
         for (j=0; j<m; j++) {
           for (i=0; i<n; i++)
             if (s[j] == PLOT_MNE[i])
                 s[j] = i
           r = r s[j]  (j!=m-1)?",":""
         }
         return r
}'

#%IU%  [scanno-list] [x-col] [y-col] [z-col] [title] [xlabel] [ylabel]
#%MDESC%
#  Plot a contour plot or a 3D plot (can be selected with ["CP_FLAGS"])
#  of the selected scans. The default values for 
#  [scanno-list] [x-col] [y-col] [z-col] are taken from CP_PAR["SCANNO"],
#  "XCOLUMN", "YCOLUMN", "ZCOLUMN". Title, x and y labels are constructed
#  as in cp_fplot. Open the graph if not already open.

def cp_contourdata '
{
  cp_updatefilename()
  cp_ongraph()
    printf("np\n");
    printf("fn scans.4 +d -f %s x=%d y=%d z=%d %d\n",CP_PAR["CONFILE"],$2,$3,$4,$1)
    printf("np\n");
    if (!(CP_PAR["FLAGS"]&0x400)) {
      printf("fn contour.4 +gs -vr %d\n",CP_PAR["CONLINES"])
      printf("sy L\nza\nztlp\n")
    } else {
      printf("3d\n");
      printf("vi %f %f %f\n",CP_PAR["VIEWPX"],CP_PAR["VIEWPY"],\
		CP_PAR["VIEWPZ"])
      if (CP_PAR["FLAGS"] & 0x01) printf ("sy L\n")
      printf("za\nztlp\n2d\n") 
    }
  cp_offgraph()
  CP_VAR["PLOTTED"]=1
} '

#%UU% [scanno-list] [x-col] [y-col] [z-col] [title] [xlabel] [ylabel]
#%MDESC%
#  Calls cp_contour to make a 3D plot

def cp_3d '
  CP_PAR["FLAGS"] |= (0x400)
  cp_contour $*
  '

#%UU% [scanno-list] [x-col] [y-col] [z-col] [title] [xlabel] [ylabel]
#%MDESC%  Calls cp_contour to make a contour plot

def cp_cont '
  CP_PAR["FLAGS"] &= 0xfbff
  cp_contour $*
  '

#%UU% [scanno-list] [x-col] [y-col] [z-col] [title] [xlabel] [ylabel]
#%MDESC%   
#  Plot a contour plot or a 3D plot (can be selected with ["CP_FLAGS"])
#  of the selected scans. The default values for 
#  [scanno-list] [x-col] [y-col] [z-col] are taken from CP_PAR["SCANNO"],
#  "XCOLUMN", "YCOLUMN", "ZCOLUMN". Title, x and y labels are constructed
#  as in cp_fplot. Open the graph if not already open.

def cp_contour '
{
  global CP_SELECTED CP_SELNO CP_MAXSEL
  local opened windowed ii _cp_sn _cp_scan _cp_x _cp_y _cp_z 
  global labels

  if (!CP_VAR["OPEN"]) {
     cp_opengraph()
     opened = 1 
     }
  if (!CP_VAR["WINDOW"]) {
     cp_windows() 
     windowed =1
     }
  cp_updatefilename()
  ifile = CP_PAR["CONFILE"] ; 
  cp_getfileinfo (ifile)
  CP_MAXSEL = CP_SCANNO[0] 
  minscanno = CP_SCANNO[0] 
  for (ii=1;ii< CP_SCANINFO ; ii++ ) {
    if ((CP_SCANNO[ii]+0) > CP_MAXSEL) CP_MAXSEL = CP_SCANNO[ii]+0
    if ((CP_SCANNO[ii]+0) < minscanno) minscanno = CP_SCANNO[ii]+0
    }
  maxscanno = CP_MAXSEL 

  cp_contourdefaults $# \'$1\' $2 $3 $4

  for (j1=0;j1<_cp_sn;j1++) {
    if ( (_cp_scan[j1] > maxscanno ) || (_cp_scan[j1] < minscanno)) continue
    # find scanno
    for (uu=0;uu<CP_SCANINFO;uu++) {
      if (CP_SCANNO[uu] == _cp_scan[j1]) {
        idx = uu
        }
      }  
    split(CP_SCANAXIS[idx],labels,"  ")
    cp_fconttitle $# \'$5\' \'$6\' \'$7\' \'$8\'
    cp_contourdata _cp_scan[j1] _cp_x _cp_y _cp_z
    if (j1 != (_cp_sn-1)) { cp_advance() }
  }
  if (opened) {
     cp_closegraph()
  }
} '  

#%IU%  <no of pars> <scan-list> <x-col> <y-col> <z-col>
#%MDESC%
#  used in cp_contour to get default values for contour or 3D plots.

def cp_contourdefaults '
  # Get default parameters
  if ($1>0) { 
    local inp ; inp = "$2"
    cp_analpars (inp)
    for (ii = 0; ii< CP_SELNO; ii++ ) {
      _cp_scan[ii] = CP_SELECTED[ii]
    }
    _cp_sn = CP_SELNO
  } else {
    _cp_scan[0] = CP_PAR["SCANNO"] ; _cp_sn = 1
  }

  if ($1>1) {_cp_x = $3} else {_cp_x = CP_PAR["XCOLUMN"]}
  
  if ($1>2) {_cp_y = $4 } else {_cp_y = CP_PAR["YCOLUMN"]}

  if ($1>3) {_cp_z = $5} else {_cp_z = CP_PAR["ZCOLUMN"]}
  
'
#%IU% <no-of-pars> <title> <x-label> <y-label>
#%MDESC% 
#used in cp_contour to plot title and labels.

def cp_fconttitle '
{
  if ($1 >4) { 
    _ftitle = "$2"
  } else {
    _ftitle = sprintf("Scan %d : %s",CP_SCANNO[idx],CP_SCANTITLE[idx])
  }
  
  if ($1 >5) {
    _fxlabel = "$3"
  } else {
    _fxlabel = labels[_cp_x+0-1]
  }

  if ($1 >6) {
    _fylabel = "$4"
  } else {
    _fylabel = labels[_cp_y+0-1]
  }

  cp_plottitle (_ftitle, _fxlabel, _fylabel)
} '
##Old type functions 

#%UU%
#%MDESC% 
#  sets the filter to print on the printer

def cp_setprinter '
  CP_PAR["FILTER"]=sprintf(CP_PAR["PRINTFORMAT"],"psfilter",CP_PAR["PRINTER"])
  CP_PAR["FLAGS"]&=(~0x40)
'

#%UU%
#%MDESC% 
#  sets the filter to print on the screen

def cp_setx11 '
  CP_PAR["FILTER"]="x11"
  CP_PAR["FLAGS"]|=(0x40)
'

def pplot '{
  cp_setprinter
  cp_guessplot $*
}'

#%UU% <scan-list> [xcolumn] [ycolumn-list] or [detector-mnemonic] [detector-mnemonic] ...
#%MDESC%
#    The first form of the command with the parameters command will plot for 
#    the scans given in %B%scan-list%B% the columns given in %B%ycolumn-list%B%
#    against the column given as %B%xcolumn%B%. Default values for %B%xcolumn%B%
#    is 1, for %B%ycolumn-list%B% the detector column.   
#    A list consists of comma separated numbers, mnemonics or regions. 
#    A region is
#    two numbers or mnemonics (start and end) separated with a colon (:).
#    Negative numbers are counted from the highest possible number,
#    where -1 represents the last scan or the last column.
#    No spaces are allowed (e.g. %B% cplot -1:2,3,4:5 %B%: plots from the 
#    last scan
#    to the one before the last plus the third plus the fourth to the fifth scan,
#    so in total 5 scans). %BR%
#    
#    The second form with the parameters %B% [detector-mnemonic] [detector-mnemonic] %B%  
#    plots for the last scan the given counters. If no argument is given
#    the counters selected with plotselect are plotted.

def cplot '
{
  cp_setx11
  cp_guessplot $*
}'

#%IU%  <input parameters from pplot or cplot>
#%MDESC%
#  Tries to guess (from the first parameter) if user wants to plot
#  from memory or from a file and calls cp_mplot or cp_fplot
def cp_guessplot '{
  local found first rstr pos ii

  cp_opengraph()

  if ($# == 1) {
      for (rstr = "$1" ; pos = index(rstr, ",");){
          rstr = substr (rstr, 0, pos -1) " " substr (rstr, pos + 1)
      }
  }
  else {
      rstr = "$*"
  }
  sscanf (rstr,"%s",first)

  for (ii=0,found=0;($#) && (ii<COUNTERS);ii++) {
      if (cnt_mne(ii) == first) {
          found = 1
          break
      }
  }

  if (($# == 0)|| found) {
      # Plots list of counters rstr. (calls cp_mplot).
      cp_cplot (rstr)
  }
  else {
      # Plots from a file.
      cp_fplot $*
  }

  cp_closegraph()
}'

def cp_contr '
{
  cp_opengraph()
  cp_cont $*
  cp_closegraph()
} '

def cp_plot3d '
{
  cp_opengraph()
  cp_3d $*
  cp_closegraph()
} '

def pplot3d '
{
  cp_setprinter
  cp_plot3d $*
}'

#%UU% <scan-list> [xcolumn] [ycolumn] [z-column]
#%MDESC%
# This command will print the 3D representation of z-column against
# x and y.

def plot3d '
{
  cp_setx11
  cp_plot3d $*
}'

def contour '
{
  cp_setx11
  cp_contr $*
}'

def pcontour '
{
  cp_setprinter
  cp_contr $*
}'

##
# Examples
##
def cplot_test '
{
local plottitle
        cp_opengraph()
#       cp_title ("mytitle")
        cp_windows( 2, 2)
	cp_plottitle ("Plot1", "X-Label", "Y-Label")
        cp_data SCAN_D 1 0 LDT 0 6
        cp_data SCAN_D 0 1 LDT 1 6
        cp_advance()
	cp_plottitle ()
        cp_data SCAN_D 1 0 LDT 2
        cp_advance()
        cp_data SCAN_D 1 0 LDT
        cp_advance()
        cp_data SCAN_D 0 1 LDT 
        cp_advance()
        cp_data SCAN_D 1 0 LDT
        cp_closegraph()        
}
'


def cplot_test2 '
{
local plottitle
	CP_PAR["TMARG"] = 0 ; CP_PAR["BMARG"] = 0 ; 
        cp_opengraph()
        cp_windows( 1, 1)
	cp_plottitle ("Plot1", "X-Label", "Y-Label")
	cp_data SCAN_D 0 1 LDT
        cp_closegraph()        
}
'

def cplot_test3 '{
    cp_opengraph()
    cp_windows( 2, 2)
    CP_PAR["FLAGS"] = 0x6e
    cp_3d 47 1 2 5
    CP_PAR["FLAGS"] = 0x6f
    cp_advance()
    cp_cont 47 1 2 5
    cp_advance()
    cp_mplot 0 0 1 "title"
    cp_advance()
    cp_fplot 143 1 7,8
    cp_closegraph()
}'

def cp_test4 '{
    CP_PAR["FLAGS"] |=0x10000
    CP_PAR["FLAGS"] |=0x800
    #CP_PAR["FLAGS"] |=0x8000
    array test_data [4096][2]
    test_data[][0] = SCAN_D[][0]
    test_data[][1] = SCAN_D[][2] * SCAN_D[][3]
    cp_opengraph()
    cp_windows( 1, 1)
    cp_cplot ("mon")
    cp_mplot test_data 0 1 "" "" "Det*Mon"
    cp_closegraph()
}'

#%MACROS%

#%IMACROS%

#%SETUP%
#  %UL%
#  %LI% cplot must be installed for you, that means:
#  %UL%%LI% setenv CPLOTHOME xxxx  where xxxx is the home directory of cplot
#               (normally something like ${BLISSADM}/spec/${BLOS}/cplot)
#  %LI% The cplot binary directory (${BLISSADM}/spec/${BLOS}/cplot/bin)  
#       must be in your path.
#  %XUL%
#  %LI% Your printer must be set up correctly
#  %LI% A cp_defaults macro has to be written - see ATTENTION
#  %XUL%

#%INTERNALS%
#  First time I try to use variables and constant strings with
#  one macro. If you want to give a string variable just enclose it
#  in double brackets like usual. If you want to give a variable
#  use single quotes double quotes '"testvar"'. You have to escape
#  the single quotes in a macro definition \'"testvar"\'

#%ATTENTION% 
# A macro has to be written to set the default values. 
# This is an example of an cp_defaults file (should be in idxxspecial.mac) 
# This example is included in the macro set. It can be copied and
# modified. The name has to be changed to cp_defaults.

#%DEPENDENCIES%
# The file cplot.mac has to be read in            !done by: startup script

#%AUTHOR% Jorg Klora , 3.94  Version: 0.600
#%TOC%