Writing a Daphne UH (User-Histogram) Routine                        Page 1
    Introduction                                                    6 May 1997


      1  Introduction

      There is no way to anticipate all the needs users have  to  manipulate
      histograms, either arithmetically or graphically.  It is not enough to
      compute projections in the X and  Y  directions:   eventually  someone
      will  want  to  compute  a  projection at an oblique angle.  It is not
      enough to write a routine to fit a Gaussian  to  a  peak:   eventually
      someone will want to fit two Gaussians to overlapping peaks.

      The Daphne UH program provides a method for  users  to  extend  Daphne
      capabilities  with Fortran subroutines that can access existing Daphne
      histograms and  existing  Daphne  graphics  routines.   The  interface
      between  Daphne  and  the user-written routine has been designed to be
      relatively simple for Fortran programmers, and yet  allow  experts  to
      write very general routines, if they wish to invest some extra effort.

      Enough of generalities.  Here is an example of a simple UH routine  to
      compute the sum of an INTEGER*4 1D histogram:

          +--------------------------------------------------+ 
          |         subroutine userhist (nChan,array)        | 
          |         implicit none                            | 
          | c                                                | 
          | c  array is a histogram of "nChan" channels      | 
          | c    numbered from 0 to (nChan-1)                | 
          | c                                                | 
          |         integer*4 nChan                          | 
          |         integer*4 array (0:nChan-1)              | 
          | c                                                | 
          |         integer*4 i                              | 
          |         integer*4 sum                            | 
          | c                                                | 
          |         sum=0                                    | 
          |         do i=0,nChan-1                           | 
          |           sum=sum+array(i)                       | 
          |         end do                                   | 
          | c                                                | 
          |         write (6,*) 'The sum is: ',sum           | 
          |         return                                   | 
          |         end                                      | 
          | cccccccccccccccccccccccccccccccccccccccccccccccc | 
          |         subroutine userHistInit                  | 
          |         implicit none                            | 
          | c                                                | 
          | c  tell Daphne that argument to userHist must be | 
          | c    a single INTEGER*4 1D histogram             | 
          | c                                                | 
      ->  |         call uh_1d_init                          | 
          |         return                                   | 
          |         end                                      | 
          | cccccccccccccccccccccccccccccccccccccccccccccccc | 
          |         subroutine printHelp                     | 
          |         write (6,1) 'This is an example'         | 
          | 1       format (1x,a)                            | 
          |         return                                   | 
          |         end                                      | 
          +--------------------------------------------------+ 
    Writing a Daphne UH (User-Histogram) Routine                        Page 2
    Introduction                                                    6 May 1997


      To compile, link, and run the user routine to sum 1D histograms  named
      "HIST1" and "HIST2" use the following procedure:

          +--------------------------------------------------+ 
          | $ FORTRAN UHEXAMPLE                              | 
          | $ @DAPEXE:DAPUH.LNK UHEXAMPLE                    | 
          | $ UH UHEXAMPLE HIST1                             | 
          | $ UH UHEXAMPLE HIST2                             | 
          +--------------------------------------------------+ 

      The most mysterious part is the call to the statement  highlighted  by
      the arrow in the left margin.  This call forces the linker to select a
      routine named "UH_1D" from  the  Daphne  user-function  library.   The
      routine  "UH_1D"  is  one  of several "policy" routines written by the
      Daphne developers for standard cases.  The UH_1D routine  checks  that
      the  argument  given  on  the UH command line is a single 1D INTEGER*4
      histogram, as required by this particular example.  If the argument is
      a  1D  INTEGER*2  histogram,  or  a 2D histogram, or the user puts two
      arguments on the command line instead of one, the user will receive an
      appropriate  error  message  and the userhist subroutine will never be
      called.

      The "standard" policy routines are discussed in section 4.
    Writing a Daphne UH (User-Histogram) Routine                        Page 3
    Introduction                                                    6 May 1997


      Suppose you want to compute the sum of a 2D  histogram.   The  program
      would then look something like this:

          +--------------------------------------------------+ 
          |         subroutine userhist (xChan,yChan,array)  | 
          |         implicit none                            | 
          | c                                                | 
          | c  array is a histogram xChan by yChan           | 
          | c                                                | 
          |         integer*4 xChan                          | 
          |         integer*4 yChan                          | 
          |         integer*2 array (0:xChan-1,0:yChan-1)    | 
          | c                                                | 
          |         integer*4 i                              | 
          |         integer*4 j                              | 
          |         integer*4 sum                            | 
          | c                                                | 
          |         sum=0                                    | 
          |         do j=0,yChan-1                           | 
          |           do i=0,xChan-1                         | 
          |             sum=sum+array(i,j)                   | 
          |           end do                                 | 
          |         end do                                   | 
          | c                                                | 
          |         write (6,*) 'The sum is: ',sum           | 
          |         return                                   | 
          |         end                                      | 
          | cccccccccccccccccccccccccccccccccccccccccccccccc | 
          |         subroutine userHistInit                  | 
          |         implicit none                            | 
          | c                                                | 
          | c  tell Daphne that argument to userHist must be | 
          | c    a single INTEGER*2 2D histogram             | 
          | c                                                | 
      ->  |         call uh_2d_init                          | 
          |         return                                   | 
          |         end                                      | 
          | cccccccccccccccccccccccccccccccccccccccccccccccc | 
          |         subroutine printHelp                     | 
          |         write (6,1) 'This is a 2D example'       | 
          | 1       format (1x,a)                            | 
          |         return                                   | 
          |         end                                      | 
          +--------------------------------------------------+ 

      It would be linked  with  exactly  the  same  commands  as  the  first
      example.
    Writing a Daphne UH (User-Histogram) Routine                        Page 4
    UH Command Line                                                 6 May 1997


      2  UH Command Line

      Assume there is a UH routine SUM1D which prints out the sum of  counts
      in all channels of a histogram.

      Assume there is a UH routine named ADD1D which adds  together  two  1D
      histogram  to  create  a  third histogram, and then displays the third
      histogram on the selected display device.

      Here are some examples of command lines:

              $ UH  SUM1D  HIST1 
                      ^      ^ 
                      |      +-- A 1D histogram 
                      | 
                      +-- File SUM1D.EXE contains the user routine 
        
              $ UH  ADD1D  HIST1,HIST2  TEMP 
                      ^ 
                      | 
                      +-- Add histograms HIST1 and HIST2 and store 
                            result in TEMP 
        
              $ UH  SUM1D  0 
                           ^ 
                           +-- The histogram currently displayed on the 
                                 primary display device. 
        
              $ UH /SECOND  SUM1D  0 
                                   ^ 
                                   +-- The histogram currently displayed 
                                         on the secondary display device. 
                                       If only the primary display device is 
                                         active the /SECOND qualifier is ignored 
        
              $ UH  ADD1D  -1,-2  TOTAL 
        
                          Add the histogram on the primary display device 
                            to that displayed on the secondary device and 
                            put the result in TOTAL. 
                          The result is displayed on the primary display device. 
        
              $ UH /SECOND ADD1D  -1,-2  TOTAL 
        
                              Same as above, except that the result is displayed 
                                on the secondary device. 
        
              $ UH /DEBUG GAUSSFIT TEST_HIST 
                      ^ 
                      +-- Start the UH program with the VAX/VMS 
                            symbolic debugger 
        
              $ UH  ADD1D /HELP 
                            ^ 
                            +----- Call the user-written printHelp routine 
                                     the ADD operation is not performed. 
                                   All other command line arguments are ignored. 
    Writing a Daphne UH (User-Histogram) Routine                        Page 5
    UH Command Line                                                 6 May 1997


      2.1  Qualifiers

      2.1.1  Qualifier /SECOND

      This qualifier specifies the default display device.  This argument is
      ignored if only one display device is active.

      When this qualifier is present, any graphics subroutine calls (such as
      uhReadCursor)  will  use  the  second  display  device rather than the
      primary display device.

      When this qualifier is present, a reference to  histogram  0  will  be
      interpreted as a reference to the histogram currently displayed on the
      secondary display device.  A user can still explicitly  refer  to  the
      currently  displayed  histogram  on  the  primary or secondary display
      device by using histogram numbers "-1" (primary) or "-2" (secondary).



      2.1.2  Qualifier /HELP

      When this qualifier is present on the command  line,  the  UH  program
      will  call  a  user-supplied  routine  named "printHelp".  If the user
      neglected to write a printHelp routine, the message

                      No HELP available 

      will be printed.


                                       NOTE

              No histogram manipulation will  take  place  when  the
              HELP qualifier is present.




      2.1.3  Qualifier /DEBUG

      When this qualifier is present a special version  of  the  UH  program
      which  has  been  linked  with  the  VAX/VMS symbolic debugger is run,
      rather than the standard version of UH.  This allows the  use  of  the
      debugger on the user-histogram routine.  See section 6 for information
      on how to use the VAX/VMS symbolic debugger to  debug  your  histogram
      routine.
    Writing a Daphne UH (User-Histogram) Routine                        Page 6
    UH Command Line                                                 6 May 1997


      2.1.4  Qualifier /INPUT=file-name

      This qualifier causes Fortran Unit 5, the standard input unit,  to  be
      assigned to the specified file rather than the keyboard.



      2.1.5  Qualifier /OUTPUT=file-name

      This qualifier causes Fortran Unit 6, the standard output unit, to  be
      assigned  to  the  specified  file  rather  than  the command terminal
      screen.



      2.1.6  Qualifier /APPEND

      When this qualifier is present with the /OUTPUT  qualifier  output  to
      Fortran  Unit  6  is appended to the specified file.  If a file of the
      proper name does not exist then one is created.



      2.1.7  Qualifier /LOG=file-name

      When a user codes this qualifier he is requesting that a log  file  of
      some kind be created by the user-routine.  By default the log file has
      the extension ".LOG" and is placed in the current directory.   If  the
      name  is  not  specified,  it  is  derived  from  the name of the file
      containing the user-routine.  Thus

                      $ UH BGO$ANALYSIS:GAGA3 1/1D /LOG 

      will create a log file in the current directory named "GAGA3.LOG".



      2.1.8  Qualifier /[NO]HEADER

      When a user codes /NOHEADER he is requesting that the output file  (or
      log  file)  be  formatted  in  such  a  way as to be easy to read with
      another computer program.  Output should  normally  be  formatted  for
      ease of reading by a human being.



      2.1.9  Qualifier /USERDATA=arbitrary-string

      This qualifier allows a user to  pass  arbitrary  information  to  the
      user-routine  on  the  command line.  This can be used for passing the
      name of files containing calibration  data  or  specifying  additional
      user options.  One can use quotation marks to include arbitrary text:

                      $ UH XYZ 1/1D /USER="RUN-5 14.1 33.0 12.0" 
    Writing a Daphne UH (User-Histogram) Routine                        Page 7
    UH Command Line                                                 6 May 1997


      2.1.10  Qualifier /PARM=(list-of-values)

      Not implemented.
    Writing a Daphne UH (User-Histogram) Routine                        Page 8
    UH Command Line                                                 6 May 1997


      2.2  Histogram Lists

      The UH command allows for two lists of histogram, although,  for  many
      user  written  routines,  this  is  far  too  general.   There  is  no
      restriction on which histograms can appear in each list, or on  mixing
      1D  and 2D histograms in lists.  It was envisioned that the first list
      would normally be an "input" list and the  second  list  would  be  an
      "output" list.  The choice of direction was based on the convention of
      VMS commands, such as $COPY.  It is a  convention,  not  a  rule,  and
      there is nothing to prevent one from using the first list as an output
      list and the second list as an input list, or mixing input and  output
      histograms in each list.

      A histogram can be specified by name, or number, or you can refer to a
      histogram  currently  displayed on a graphic device by using histogram
      numbers of "0", "-1", and "-2".  When using the 0/-1/-2 convention  to
      specify  a  histogram,  the  histogram  must  be  the  only  histogram
      displayed on the graphics device.  The $UH program is like $BLW, $SUM,
      and  $W2  in  this  way.   It  is not necessary to specify whether the
      displayed histogram is 1D or 2D since the $UH program can figure  this
      out.

      The following list summarizes the ways to refer to a histogram:


       -  "0"       The histogram displayed on the currently selected
                      graphics device.
                    Depends on whether /SECOND qualifier present.

       -  "-1"      The histogram displayed on the primary graphics device

       -  "-2"      The histogram displayed on the secondary graphics device

       -  name      The name of the histogram must not be ambiguous.  There
                      must not be both a 1D and 2D histogram with this name.

       -  name/1D   Use when the name alone is ambiguous

       -  name/2D   Use when the name alone is ambiguous

       -  number    Histogram number ambiguous unless there are only 1D or
                      only 2D histogram defined

       -  number/1D Never ambiguous

       -  number/2D Never ambiguous


    Writing a Daphne UH (User-Histogram) Routine                        Page 9
    UH Command Line                                                 6 May 1997


      Some examples:

          $ UH SUM 0 
        
              The currently displayed histogram 
        
          $ UH ADD EHEX1,EHEX2  TOTAL 
          $ UH ADD 14/1D,15/1D  TOTAL 
        
              Names usually aren't ambiguous as far as 
                whether they refer to a 1D or 2D histogram 
              Numbers usually are, thus the "/1D" qualifier 
        
          $ UH SQRT_ERR SIGNAL SIGNAL_ERR 
          $ UH SQRT_ERR BACKGROUND BACKGROUND_ERR 
          $ UH SUB_ERR SIGNAL,SIGNAL_ERR,BACKGROUND,BACKGROUND_ERR - 
                  DIFFERENCE,DIFFERENCE_ERR 
        
              The user wants to subtract background from a signal. 
              He first computes an "error" spectrum with value proportional 
                to the square-root of the value in each channel. 
              This is for both the signal and the background histograms. 
              To compute the error of the differences: 
        
                   err(i)=square-root 
                            (signal_err(i)**2 + background_err(i)**2) 
        
              The SUB_ERR user routine is a little bit unusual because 
                it has four input arguments (actually two pairs) and 
                two output arguments (actually one pair). 
        
          $ UH ADD_MANY HEX1,HEX2,HEX3,HEX4,HEX5,HEX6 ALL_HEX 
        
              A user can write a routine which accepts an indefinite 
                number of histograms in a list. 
              At the moment, the program is limited to 25 histograms 
                in the input list and 25 histograms in the output list. 
    Writing a Daphne UH (User-Histogram) Routine                       Page 10
    Daphne Service Routines                                         6 May 1997


      3  Daphne Service Routines

      The Daphne developers have written a number of subroutines to help the
      user  extract  information  about  the  histogram  from  Daphne and to
      interact with the Daphne display programs.

      In all the routines  described  below,  "array"  represents  an  array
      passed to the userHist routine.



      3.1  General Purpose Service Routines


       -  subroutine uhHistName (array,name)

          "name" is output/character string

          The routine returns the name of the histogram, truncated or padded
          with blanks, as necessary.  Histogram names in Daphne may be up to
          12 characters long.  If the histogram was created without a  name,
          the routine returns a string of the form "H1#xxx" (or "H2#xxx" for
          a 2D histogram) where xxx is the histogram number.  For  instance,
          "H1#9".   If  the array cannot be identified, a string filled with
          asterisks ("*") is returned to the caller.

       -  subroutine uhHistNumber (array,number,rank)

          "number" is output/integer*4
          "rank" is output/integer*4

          The routine returns the Daphne histogram number and the "rank"  of
          the histogram corresponding to the array.

          For a 1D histogram the rank is 1, for a 2D histogram the  rank  is
          2.

       -  subroutine uhGetDisplayNumber (displayNumber)

          "displayNumber" is output/integer*4

          The routine returns 0 if no display  is  active,  1  if  the  user
          selected the primary output device, and 2 if the user selected the
          secondary display device.

       -  subroutine uhGetDisplayType (displayType)

          "displayType" is output/character string

          The routine returns the  Daphne  code  for  the  selected  display
          device.   If  no  display  device is active it returns a string of
          spaces.  At the moment all supported devices begin with  the  code
          "TEK"  followed  by  the  model  number:   TEK4010 TEK4014 TEK4105
          TEK4107 TEK4111 TEK4114 TEK4115 TEK4205 TEK4207.

    Writing a Daphne UH (User-Histogram) Routine                       Page 11
    Daphne Service Routines                                         6 May 1997


      3.2  Command Line Related Service Subroutines


       -  subroutine uhGetLogFileName (fileName)

          "fileName" is output/character string

          The routine returns the fully expanded name of the log  file.   If
          if the /LOG qualifier was not present the string is set to blanks.

       -  subroutine uhGetUserData (string)

          "string" is output/character string

          The routine  returns  the  string  specified  with  the  /USERDATA
          qualifier  of  the command line.  If the qualifier was not present
          the string is set to blanks.

       -  subroutine uhOutputHeaders (yesNo)

          "yesNo" is output/logical

          The routine returns  the  logical  value  ".false."  if  the  user
          specified  /NOHEADERS  on  the  command line, otherwise it returns
          ".true.".




      3.3  Display Related Service Subroutines

      3.3.1  Histogram Coordinate System

      Many of the routines described in this section use an  X/Y  coordinate
      system  for  locating  points  on  the  screen of the graphics device.
      Unless stated otherwise, all  coordinates  are  in  "histogram  space"
      rather than the device's coordinate space.

      For instance, if one is displaying channels 500 through 700 of a  8192
      channel  1D  histogram,  the  X  values  returned  by uhReadCursor are
      constrained to be between 500 and 700.  If the histogram is  displayed
      with  logarithmic  scaling,  then  Y  values of 10, 100, and 1000 will
      appear to be equal distances apart on the screen.

      At the moment, there are NO routines that use device coordinates.
    Writing a Daphne UH (User-Histogram) Routine                       Page 12
    Daphne Service Routines                                         6 May 1997


      3.3.2  Clipping

      At the moment, Daphne uses a very simple method of clipping  lines  at
      the  border of the display.  The diagrams below depicts a histogram of
      which only a portion is visible on the display display.

             Correct Clipping               Clipping by Daphne 
       +---------------------------+    +---------------------------+ 
       |       \                   |    |       |                   | 
       |        \                  |    |       |                   | 
       |         \                 |    |       |                   | 
       |          \                |    |       |                   | 
       |           \               |    |       |                   | 
       |      +-----\\-------+     |    |      +-\\-----------+     | 
       |      |      \\      |     |    |      |   \\         |     | 
       |      |       \\     |     |    |      |     \\       |     | 
       |      |        \\    |     |    |      |       \\     |     | 
       |      | Display \\   |     |    |      | Display \\   |     | 
       |      |          \\  |     |    |      |           \\ |     | 
       |      |           \\ |     |    |      |             \\     | 
       |      +------------\\+     |    |      +--------------+ |   | 
       |                    \      |    |                       |   | 
       |  Entire Histogram   \     |    |  Entire Histogram     |   | 
       |                      \    |    |                       |   | 
       |                       \   |    |                       |   | 
       +---------------------------+    +---------------------------+ 

      As one can see from the above diagrams, a line clipped by Daphne  will
      not  intersect  the  borders at the same point as a "properly" clipped
      line.



      3.3.3  Default Display (Graphics) Device

      As mentioned above, the default display device is  determined  by  the
      presence  (or  absence)  of  the  /SECOND qualifier on the $UH command
      line.
    Writing a Daphne UH (User-Histogram) Routine                       Page 13
    Daphne Service Routines                                         6 May 1997


      3.4  Colors and Patterns

      Sometimes objects can be displayed with  color  or  with  a  patterned
      line.   For  instance,  one can request that a dotted line be drawn by
      executing  "call  uhSetDrawPattern  ('DOTTED')"  before  "call  uhDraw
      (x,y)".    Lines   will   continue   to   be  drawn  with  dots  until
      uhSetDrawPattern is called with  a  different  argument,  or  the  $UH
      program exits.

      When using a monochrome device, such as a Tektronix 4014,  colors  are
      interpreted  as  one  of  the  possible  patterns.  When using a color
      device (in color mode) such as a Tektronix  4107,  both  patterns  and
      colors  will  usually be implemented, but you cannot specify a colored
      pattern.

      One specifies the color or line pattern (but not both) by using one of
      the following character strings:

       -  GREEN     (Abbreviation:  GRE)
       -  BLUE      (Abbreviation:  BLU)
       -  YELLOW    (Abbreviation:  YEL)
       -  RED       
       -  WHITE     (Abbreviation:  WHI)
       -  SOLID
       -  DOTTED    (Abbreviation:  DOT)
       -  DASH
       -  DOTDASH


      The default pattern for lines is 'SOLID'.  The default color for lines
      is usually 'WHITE'.
    Writing a Daphne UH (User-Histogram) Routine                       Page 14
    Daphne Service Routines                                         6 May 1997


      3.4.1  Service Routine Descriptions

       -  logical function uhIsDisplayed (array)

          Returns "true"  if  the  array  is  the  one  and  only  histogram
          displayed  on the default graphics device.  If there is no display
          device, or it is displaying a scatterplot, or it is clear,  or  it
          has more than one histogram displayed, or a different histogram is
          displayed:  the result will be "false".

       -  subroutine uhClearDisplay

          Clears the graphics display.

       -  subroutine uhD1H (array)

          Displays the 1D histogram corresponding to the array.  Same action
          as the $D1H command.

       -  subroutine uhD2H (array)

          Displays the 2D histogram corresponding to the array.  Same action
          as the $D2H command.

       -  subroutine uhDO1H (array,color_or_pattern_string)

          "color_or_pattern_string" is input/character string

          Displays the 1D histogram, corresponding to the array, on  top  of
          the  already  displayed  1D  histogram.   If  no  1D  histogram is
          currently  displayed,  it  acts  like  $D1H   (or   uhD1H).    The
          interpretation of the color/pattern string is described in section
          3.4.

          Same action as the $DO1H command.
    Writing a Daphne UH (User-Histogram) Routine                       Page 15
    Daphne Service Routines                                         6 May 1997


       -  subroutine uhDraw (x,y)

          "x" is input/real*4
          "y" is input/real*4

          Moves the graphics cursor  to  the  specified  coordinate  of  the
          histogram,  while  drawing  a  solid  line from the current cursor
          position.  The color/pattern is controlled by uhSetDrawPattern.

       -  subroutine uhGetDrawPattern (color_or_pattern_string)
       -  subroutine uhSetDrawPattern (color_or_pattern_string)

          "color_or_pattern_string" is a character string

          Change (or determine) the color  or  pattern  of  lines  drawn  by
          uhDraw.    The  interpretation  of  the  color/pattern  string  is
          described in section 3.4.

       -  subroutine uhMove (x,y)

          "x" is input/real*4
          "y" is input/real*4

          This is like the uhDraw subroutine but no line is drawn  when  the
          cursor is moved.

    Writing a Daphne UH (User-Histogram) Routine                       Page 16
    Daphne Service Routines                                         6 May 1997


       -  subroutine uhReadCursor (x,y,c)

          "x" is output/real*4
          "y" is output/real*4
          "c" is output/character*(*)

          Returns to the user the position of the graphics  cursor  and  the
          keyboard  character  (or mouse button) the user the user struck to
          terminate the cursor input  sequence.   The  character  is  always
          translated to uppercase.

          If the display device supports a mouse (and the argument "c" is at
          least  3  characters  long)  then  uhGetCursor  will return "MB1",
          "MB2", or "MB3" when one of the  mouse  buttons  is  pressed.   If
          argument  "c" is less than 3 characters long then uhGetCursor will
          return the single character "1", "2", or "3" when one of the mouse
          buttons is pressed.

          The  UIS  display  program   (VWS   workstations   or   DECwindows
          workstations  with  UISX  emulation  software)will  return the SMG
          (Screen Management Routines) name of special  function  keys  when
          they are pressed.  The SMG names are:

               Program   Keypad    Keypad    Arrow   Function   Other 
               Function  Numbers   Special 
               --------  -------   -------   -----   --------   -------- 
                 PF1       KP0      ENTER     UP        F1      HELP 
                 PF2       KP1      MINUS     DOWN      F2      DO 
                 PF3       KP2      COMMA     LEFT      F3      FIND 
                 PF4       KP3      PERIOD    RIGHT     F4      INSERT_HERE 
                           KP4                          F5      REMOVE 
                           KP5                          F6      PREV_SCREEN 
                           KP6                          F7      NEXT_SCREEN 
                           KP7                          F8 
                           KP8                          F9 
                           KP9                          F10 
                                                        F11 
                                                        F12 
                                                        F13 
                                                        F14 
                                                        F15 
                                                        F16 
                                                        F17 
                                                        F18 
                                                        F19 
                                                        F20 

          If the output argument "c" is too short to contain  the  key  name
          the string "?" is returned to the caller.
    Writing a Daphne UH (User-Histogram) Routine                       Page 17
    Daphne Service Routines                                         6 May 1997


       -  subroutine uhAnnotate (x,y,angle,string)

          "x" is input/real*4
          "y" is input/real*4
          "angle" is input/real*4
          "string" is input/character*(*)

          Displays up  to  80  characters  from  "string"  at  the  position
          specified  by  the  X/Y  coordinates.  The string is written at an
          angle given by "angle" (in degrees).

       -  subroutine uhGetAnnotatePattern (color_or_pattern_string)
       -  subroutine uhSetAnnotatePattern (color_or_pattern_string)

          "color_or_pattern_string" is character string

          Change (or determine) the color  used  by  uhAnnotate  in  drawing
          characters.   Characters  can  be  drawn with colors, but patterns
          will be ignored.  The interpretation of the  color/pattern  string
          is described in section 3.4.

       -  subroutine uhGetAnnotateSize (relative_size)
       -  subroutine uhSetAnnotateSize (relative_size)

          "relative_size" is real*4

          Change (or determine) the  size  of  the  text  displayed  by  the
          uhAnnotate  subroutine.   A value of 1.0 is the default text size.
          A value of 2.0 is twice normal size.  The "relative_size" must  be
          between 0.1 and 10.0

       -  subroutine uhSymbol (x,y,symbol)

          "x" is input/real*4
          "y" is input/real*4
          "symbol" is input/integer*4

          Displays a graphics symbol (such  as  a  vertical  cross)  at  the
          coordinate  given  by the X and Y coordinates.  The interpretation
          of the symbols depends on the graphics device:

          Symbol      D4100             Both                 DSPDP 
          Number   Display Program   D4100 and DSPDP      Display Program 
            
            0                         vertical cross 
            1                         diagonal cross 
            2                         diamond 
            3                         square 
            4                         fancy diamond 
            5                         fancy square 
            6     double dagger                           fancy vertical cross 
            7     vertical cross                          fancy diagonal cross 
            8     cross inside square                     starburst 
            9                         octagon 

    Writing a Daphne UH (User-Histogram) Routine                       Page 18
    Daphne Service Routines                                         6 May 1997


       -  subroutine uhVertLine (x)

          "x" is input/real*4

          Draws a vertical line from the bottom to the top of the  histogram
          at the specified X coordinate.

       -  subroutine uhInvocation (string)

          "string" is output/character string

          This subroutine allows a UH routine to tell whether  it  is  being
          called  by  a UH command or by a CUH (callable UH) program.  If it
          is called via a  UH  command  it  will  return  the  string  "CLI"
          (command  language interpreter).  If it is called by a CUH program
          it will return the string "SUB" (subroutine).   CUH  programs  are
          described in a separate document:  DAPHLP:CUH.MEM.

    Writing a Daphne UH (User-Histogram) Routine                       Page 19
    Daphne Service Routines                                         6 May 1997


      3.4.2  Getting the Definition of a Daphne 1D Window

      If you have defined a 1D window in Daphne (using the $W1 command), you
      can retrieve the upper and lower limits for use in your user-histogram
      routine.


       -  subroutine uhGetW1Limits (windowName,Low,High)

          windowName is input/character string

          The windowName is the name (or number)  of  the  window  the  user
          wants  to  use.  The name can be in upper or lowercase letters and
          may be padded with blanks.  If no such window exists then it is  a
          fatal error, and the uhGetW1Limits does NOT return to the caller.

          Low,High are output/integer*4

          These output arguments describe the lower and upper range  of  the
          window.   The lower and upper limits are inclusive.  For instance,
          if a 1D window is defined from 100 to 200 then values of  100  and
          200 are "inside".

    Writing a Daphne UH (User-Histogram) Routine                       Page 20
    Daphne Service Routines                                         6 May 1997


      3.4.3  Testing for Points Inside Daphne  2D  Windows  (and  Drawing  a
             Window)

      If you have defined a 2D window in Daphne (using the $W2 command), you
      can test for a point inside the window in your user-histogram routine.

      For instance, to compute the sum of the points of a histogram inside a
      2D window one could use the following UH routine:

        +---------------------------------------------------------------+ 
        |         subroutine userhist (nx,ny,a)                         | 
        |         implicit integer*4 (a-z)                              | 
        | c                                                             | 
        |         logical*4       uhInsideW2                            | 
        |         character*12    windowName                            | 
        | c                                                             | 
        |         write (6,*) 'Enter name of Daphne 2D window'          | 
        |         read (5,1005) windowName                              | 
        |  1005   format (a)                                            | 
        | c                                                             | 
        | c  select the window by its name (or number) and get          | 
        | c    coordinates of rectangular region enclosing the window   | 
        | c  one can later use the rectangle as do loop indices and     | 
        | c    limits sometimes                                         | 
        | c                                                             | 
        |         call uhSelectW2 (windowName,loX,hiX,loY,hiY)          | 
        |         sum=0                                                 | 
        | c                                                             | 
        |         do j=loy,hiy                                          | 
        |           do i=lox,hix                                        | 
        | c                                                             | 
        | c  logical function "uhInsideWindow (i,j)" tests for point    | 
        | c     with X=i and Y=j inside the selected 2D window          | 
        | c                                                             | 
        |             if (uhInsideW2 (i,j)) then                        | 
        | c                                                             | 
        | c  if inside the window then add value in this channel to sum | 
        | c                                                             | 
        |               sum=sum+a(i,j)                                  | 
        |             end if                                            | 
        |           end do                                              | 
        |         end do                                                | 
        | c                                                             | 
        |         write (6,*) 'Sum within window ',windowName,': ',sum  | 
        |         return                                                | 
        |         end                                                   | 
        | c                                                             | 
        | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc | 
        | c                                                             | 
        |         subroutine userhistinit                               | 
        |         call uhi4_2d_init                                     | 
        |         return                                                | 
        |         end                                                   | 
        +---------------------------------------------------------------+ 

    Writing a Daphne UH (User-Histogram) Routine                       Page 21
    Daphne Service Routines                                         6 May 1997


       -  subroutine uhSelectW2 (windowName,xLow,xHigh,yLow,yHigh)

          windowName is input/character string

          The windowName is the name (or number)  of  the  window  the  user
          wants  to  use.   The name can be in upper or lowercase and may be
          padded with blanks.  If no such window exists then it is  a  fatal
          error, and the uhSelectW2 routine does NOT return to the caller.

          xLow,xHigh,yLow,yHigh are output/integer*4

          These  output  arguments  describe  a  rectangular  region   which
          encloses the window.

       -  logical function uhInsideW2 (ix,iy)

          ix is input/integer*4
          iy is input/integer*4

          If the point X=ix and  Y=iy  is  inside  the  window  selected  by
          uhSelectW2 then the function returns the value ".true.", otherwise
          it returns the value ".false.".

       -  subroutine uhCornerOfW2 (cornerNumber,ix,iy)

          cornerNumber is input/integer*4
          ix is output/integer*4
          iy is output/integer*4

          This routine returns the X and Y coordinates of the corners  of  a
          2D  window.   If the corner number is not between 1 and the number
          of corners in the window then ix and iy will be set to (-1).

          The purpose of this routine is to allow a UH routine to draw a  2D
          window  on a display.  This would be helpful if the user wanted to
          see the area that has been selected by the function uhInsideW2.

    Writing a Daphne UH (User-Histogram) Routine                       Page 22
    Daphne Service Routines                                         6 May 1997


      3.5  Routines to Change FIX and FLT Variables

      These routine allow one to inquire about or change  the  FIX  and  FLT
      variables  used  by user-functions during acquisition and replay.  For
      more information  on  how  to  use  FIX  and  FLT  variables  see  the
      Experimenter's Guide (Sections 22 of EG and 24.11 of EG).

      Routines which change FIX and FLT variables  may  take  some  time  to
      execute.   During acquisition the sort process must send new values to
      each of the event processors.  During replay the sort  process  checks
      for  new  FIX  and  FLT variables only when it has finished sorting an
      entire block of data.

      Calling these routines with an undefined FIX or FLT name, a  subscript
      which  is  out of bounds, a subscript where none is appropriate, or no
      subscript where one is required will cause  the  UH  program  to  exit
      immediately.

      If the subroutine has the suffix "Element" it is used with subscripted
      FIX  and FLT variables.  If it lacks this suffix it is used for scaler
      FIX and FLT variables.

       -  subroutine uhGetFix (name,value)

          name is input/character string
          value is output/integer*4

       -  subroutine uhSetFix (name,value)

          name is input/character string
          value is input/integer*4

       -  subroutine uhSetFixElement (name,subscript,value)

          name is input/character string
          subscript is input/integer*4
          value is input/integer*4

       -  subroutine uhGetFixElement (name,subscript,value)

          name is input/character string
          subscript is input/integer*4
          value is output/integer*4
    Writing a Daphne UH (User-Histogram) Routine                       Page 23
    Daphne Service Routines                                         6 May 1997


       -  subroutine uhGetFlt (name,value)

          name is input/character string
          value is output/real*4

       -  subroutine uhSetFlt (name,value)

          name is input/character string
          value is input/real*4

       -  subroutine uhSetFltElement (name,subscript,value)

          name is input/character string
          subscript is input/integer*4
          value is input/real*4

       -  subroutine uhGetFltElement (name,subscript,value)

          name is input/character string
          subscript is input/integer*4
          value is output/real*4

    Writing a Daphne UH (User-Histogram) Routine                       Page 24
    Daphne Service Routines                                         6 May 1997


      3.6  Routines to Change Histogram Display Attributes

      These routines allow one  to  inquire  about  or  change  the  display
      attributes of 1D and 2D histograms.



      3.6.1  Display Mode

       -  subroutine uhGetMode (array,display_mode_string)
       -  subroutine uhSetMode (array,display_mode_string)

          For 1D histograms valid display modes are:  "LOG" or "LIN".
          For 2D histograms valid display modes  are:   "LOG"  or  "LIN"  or
          "SQRT".




      3.6.2  Scale

      The "scale" value overrides the  automatic  scaling  of  data  by  the
      display  programs.  Normally, the maximum Y value, most intense color,
      or greatest dot density, is chosen with a "peak value" in  mind.   The
      peak  value is the largest value found in the section of the histogram
      actually displayed.

      The value supplied by the user for "scale" replaces the  one  computed
      by the display program for scaling the display.

      Setting the "scale" to 0 causes a reversion to automatic scaling.

       -  subroutine uhGetScale (array,integer*4_value)
       -  subroutine uhSetScale (array,integer*4_value)

    Writing a Daphne UH (User-Histogram) Routine                       Page 25
    Daphne Service Routines                                         6 May 1997


      3.6.3  High and Low Display Limits

      The user can control what range  of  a  1D  histogram  or  rectangular
      region of a 2D histogram will be displayed in response to a subroutine
      call to uhD1H or uhD2H.

      A new value for the lower display limit must  be  between  0  and  the
      upper display limit.

      A new value for the upper display limit  must  be  between  the  lower
      display limit and the last channel of the histogram.  The last channel
      of a histogram is  one  less  than  the  number  of  channels  in  the
      histogram, because the channels are numbered from zero rather than 1.

      The number of channels  in  a  histogram  is  usually  passed  to  the
      userHist subroutine as a calling argument.

      The following routines are for 1D histograms:

       -  subroutine uhGetHI (array,integer*4_value)
       -  subroutine uhSetHI (array,integer*4_value)

       -  subroutine uhGetLO (array,integer*4_value)
       -  subroutine uhSetLO (array,integer*4_value)


      The following routines are for 2D histograms:

       -  subroutine uhGetXHI (array,integer*4_value)
       -  subroutine uhSetXHI (array,integer*4_value)

       -  subroutine uhGetXLO (array,integer*4_value)
       -  subroutine uhSetXLO (array,integer*4_value)

       -  subroutine uhGetYHI (array,integer*4_value)
       -  subroutine uhSetYHI (array,integer*4_value)

       -  subroutine uhGetYLO (array,integer*4_value)
       -  subroutine uhSetYLO (array,integer*4_value)

    Writing a Daphne UH (User-Histogram) Routine                       Page 26
    Daphne Service Routines                                         6 May 1997


      3.7  Routines for Camac

      3.7.1  Branches and Crates

      Daphne supports up to nine branches, numbered 0 to 8.  Each branch may
      have  one or more crates on it.  A branch may not contain a mixture of
      controller types.

      Daphne supports two models of Camac crate controllers:


       -  Kinetic Systems 3989 RS232 Crate Controller (KS3989)

          A maximum of  three  to  five  KS3989  crate  controllers  may  be
          daisy-chained to a single RS232 controller, depending on the RS232
          controller.  The crate numbers on  each  branch  are  independent.
          Thus branches 0, 1, and 2 may all have a crate number 1.


                                         NOTE

                  Do not configure a KS3989 as crate number 3


          More information on using and configuring KS3989 crate controllers
          may be found in the Experimenter's Guide.

       -  Hytec Electronics 1365 Ethernet Crate Controller (ECC)

          In theory, as many as 255 ECC may be located on a single ethernet.
          In  practice,  Daphne  software  limits  the  user  to nine crates
          (numbered 0 to 8).  All ECC must be on a single branch.


      In order to  use  the  Daphne  Camac  routines  you  must  define  the
      addresses  and  types of the Camac units using the Daphne $CDV command
      or the subroutine "initCamac".  A program may use more than one  Camac
      branch simultaneously.

      To indicate that branch 0 has one or more Hytec 1365 controllers:

                      $ CDV HY1365     

      To indicate that branch 0 has one or more KS3989 on  RS232  controller
      TXA3:

                      $ CDV TXA3 

    Writing a Daphne UH (User-Histogram) Routine                       Page 27
    Daphne Service Routines                                         6 May 1997


      If you are using KS3989 controllers on RS232  controllers  TXA3:   and
      TXA4:

                      $ CDV @BRANCHLIST.BRA 

                      where BRANCHLIST.BRA contains: 

                              +-------------+ 
                              | TXA3:       | branch 0 
                              | TXA4:       | branch 1 
                              +-------------+ 

      You may use a combination of ECC and KS3989 branches:

                      $ CDV @BRANCHLIST.BRA 

                      where BRANCHLIST.BRA contains: 

                              +-------------+ 
                              | TXA3:       | branch 0 
                              | TXA4:       | branch 1 
                              | HY1365      | branch 2 
                              +-------------+ 

      Crate numbers usually start at 1, while branch numbers start at 0.




      3.7.2  Routine Descriptions

      In the following descriptions:

       -  branch   - branch number between 0 and 8 (input/integer*4)

          If the user specifies branch=0  then  (crate-number/100)  supplies
          the  real branch number and the (crate-number modulo 100) supplies
          the real crate number.   Thus  a  call  to  bcnaf  (0,102,...)  is
          equivalent to bcnaf (1,2,...).

       -  crate    - crate number between 0 and 8 (input/integer*4)

       -  slot     - slot number between 1 and 24 (or 30) (input/integer*4)

       -  address  - sub-address between 0 and 15 (input/integer*4)

       -  function - function code between 0 and 31 (input/integer*4)

       -  value    - may be input or output depending on function code

          read function code (0 to 7) then "value" is output/integer*4
          write function code (16 to 23) then "value" is input/integer*4
          control function code (8 to 15 and 24 to 31) then "value" ignored
    Writing a Daphne UH (User-Histogram) Routine                       Page 28
    Daphne Service Routines                                         6 May 1997


       -  Q - Q response from the module (output/integer*4)

       -  inhibitState - input/integer*4

          0 means turn crate inhibit off
          1 means turn crate inihibit on


       -  call initCamacWithCDVinfo()

          Allows one to use whatever branches have been defined via the $CDV
          command.

       -  call initCamac (branchDescription)

          The argument to  the  initCamac  routine  is  a  string  which  is
          interpreted  in  the  same was as the command line argument of the
          $CDV command.  It can consist of a description of a single  branch
          ("TXA3:"  or  ("HY1365")  or  the name of a file containing a list
          ("@BRANCHLIST.BRA").  Please note the use of an at-sign  ("@")  to
          indicate an indirect reference.

       -  call closeCamac ()

          This releases all resources and closes all I/O channels related to
          Camac I/O.

       -  call bcnaf (branch,crate,slot,address,function,value)

       -  call cnaf (crate,slot,address,function,value)

          Identical to bcnaf when branch is 0

       -  call bcnafQ (branch,crate,slot,address,function,value,Q)

       -  call cnafQ (crate,slot,address,function,value,Q)

          Identical to bcnafQ when branch is 0

       -  call setInhibit (branch,crate,inhibitState)

          Controller independent method to enable or disable  inhibit.   The
          ECC does NOT use N=30 operations to enable or disable inhibit.



                                       NOTE

              When using the Camac  routines  with  a  "stand-alone"
              program  it  is  necessary  to  link  the  program  as
              outlined in the Experimenter's Guide page 245  section
              43.2.3.   When  using  Camac  routines  with  UH it is
              important to NOT link as  described  in  that  section
              because  the Camac routines are already included among
              the UH service routines.  Linking your UH  routine  as
              described  in that section will lead to messages about
              multiple definitions of symbols  and  will  result  in
              erroneous behavior.
    Writing a Daphne UH (User-Histogram) Routine                       Page 29
    Standard Policy Routines                                        6 May 1997


      4  Standard Policy Routines

      Standard  policy  routines  assume  that  all  1D  histogram  will  be
      INTEGER*4.    If  you  wish  to  process  INTEGER*1  or  INTEGER*2  1D
      histograms you should modify the source code for one of  the  existing
      policy routines.  This should be relatively straightforward.

      Standard routines assume that most 2D histograms will be INTEGER*2 and
      that the remainder will be INTEGER*4.

      New policy routines will be added as demand requires.

      The following notation is used to indicate the argument list  for  the
      userhist routines:

           a, b, c 
                      first, second, and third histogram in UH argument list 
        
           xa, xb, xc 
                      number of X channels in histograms a, b, and c 
        
           ya, yb, yc 
                      number of Y channels in 2D histograms a, b, and c 
        
           na, nb, nc 
                      number of channels in 1D histograms a, b, and c 

      To incorporate the  policy  routine  in  your  user-histogram  program
      include  a  call  to  the  policy  initialization  routine in your own
      initialization routine.  Usually the initialization routine will  look
      like the following:

          +--------------------------------------------------+ 
          |         subroutine userHistInit                  | 
          |         implicit none                            | 
          | c                                                | 
          | c  tell Daphne that argument to userHist must be | 
          | c    a single INTEGER*4 1D histogram             | 
          | c                                                | 
      ->  |         call uh_1d_init                          | 
          |         return                                   | 
          |         end                                      | 
          +--------------------------------------------------+ 
    Writing a Daphne UH (User-Histogram) Routine                       Page 30
    Standard Policy Routines                                        6 May 1997


                                       NOTE

              Remember  that  a  histogram  with  "N"  channels  has
              channels numbered from 0 to "N-1".


      Name                                Description    Description 
                                            Input          Output 
        
      UH_1D_INIT                          One 1D I*4 
      subroutine userhist (na,a) 
        
      UH_2D_INIT                          One 2D I*2 
      subroutine userhist (xa,ya,a) 
        
      UHI4_2D_INIT                        One 2D I*4 
      subroutine userhist (xa,ya,a) 
        
      UH_1D_1D_INIT                       One 1D I*4     One 1D I*4 
      subroutine userhist (na,a,nb,b) 
        
      UH_2D_2D_INIT                       One 2D I*2     One 2D I*2 
      subroutine userhist (xa,ya,a,xb,yb,b) 
        
      UHI4_2D_2D_INIT                     One 2D I*4     One 2D I*4 
      subroutine userhist (xa,ya,a,xb,yb,b) 
        
      UH_1D1D_1D_INIT                     Two 1D I*4     One 1D I*4 
      subroutine userhist (na,a,nb,b,nc,c) 
        
      UH_2D2D_1D_INIT                     Two 2D I*2     One 1D I*2 
      subroutine userhist (xa,ya,a,xb,yb,b,nc,c) 
        
      UH_2D2D_2D_INIT                     Two 2D I*2     One 2D I*2 
      subroutine userhist (xa,ya,a,xb,yb,b,xc,yc,c) 
        
      UHI4_2D2D_2D_INIT                   Two 2D I*4     One 2D I*4 
      subroutine userhist (xa,ya,a,xb,yb,b,xc,yc,c) 
        
      UH_2D_1D_INIT                       One 2D I*2     One 1D I*4 
      subroutine userhist (xa,ya,a,nb,b) 
        
      UH_2DI4_1D_INIT                     One 2D I*4     One 1D I*4 
      subroutine userhist (xa,ya,a,nb,b) 
    Writing a Daphne UH (User-Histogram) Routine                       Page 31
    Standard Policy Routines                                        6 May 1997


      The following policy routines accept more than  histogram  type.   For
      instance,  the CUR routine will accept a 1D INTEGER*4, a 2D INTEGER*2,
      or a 2D INTEGER*4 histogram as an argument.

      single operand          UH_ANY1OF_1D_2D_2DI4_INIT 
        
              All of the following must be present: 
                  for 1D I*4 subroutine userhist_1D (na,a) 
                  for 2D I*2 subroutine userhist_2D (xa,ya,a) 
                  for 2D I*4 subroutine userhist_2DI4 (xa,ya,a) 
        
      two operands            UH_ANYPAIROF_1D_2D_2DI4_INIT 
        
              one histogram in input list 
              one histogram in output list 
              output histogram must have same rank as input histogram 
        
              All of the following must be present: 
                  for 1D I*4 subroutine userhist_1D (na,a,nb,b) 
                  for 2D I*2 subroutine userhist_2D (xa,ya,a,xb,yb,b) 
                  for 2D I*4 subroutine userhist_2DI4 (xa,ya,a,xb,yb,b) 
        
      two operands            UH_1D_1D_OR_2DXX_2DXX_INIT 
        
              one histogram in input list 
              one histogram in output list 
              a) both input and output may be 1D INTEGER*4 
              b) input and output may be any combination of 
                 2D INTEGER*2 and 2D INTEGER*4 
        
              All of the following must be present: 
                  for 1D I*4 subroutine userhist_1D (na,a,nb,b) 
                  for 2D I*2 subroutine userhist_2D (xa,ya,a,xb,yb,b) 
                  for 2D I*4 subroutine userhist_2DI4 (xa,ya,a,xb,yb,b) 
        
      three operands          UH_ANY3OF_1D_2D_2DI4_INIT 
        
              two histograms in input list 
              one histogram in output list 
              input histograms must have identical shape 
              output histogram must have same rank as input histograms 
        
              All of the following must be present: 
                  for 1D I*4 subroutine userhist_1D (nab,a,b,nc,c) 
                  for 2D I*2 subroutine userhist_2D (xab,yab,a,b,xc,yc,c) 
                  for 2D I*4 subroutine userhist_2DI4 (xab,yab,a,b,xc,yc,c) 
    Writing a Daphne UH (User-Histogram) Routine                       Page 32
    Standard Policy Routines                                        6 May 1997


      The following routines differ from those above in  that  they  require
      that  all  histogram arguments have the same number of channels, hence
      the appearance of the letters "SNC" in their names.  Thus in the  case
      of  UH_SNC_2D_2D  there  are  two 2D histogram arguments and they must
      have identical values for the  number  of  X  channels  and  identical
      values for the number of Y channels.

      Name                                    Description    Description 
                                                Input          Output 
        
      UH_SNC_1D_1D_INIT                       One 1D I*4     One 1D I*4 
      subroutine userhist (nab,a,b) 
        
      UH_SNC_2D_2D_INIT                       One 2D I*2     One 2D I*2 
      subroutine userhist (xab,yab,a,b) 
        
      UHI4_SNC_2D_2D_INIT                     One 2D I*4     One 2D I*4 
      subroutine userhist (xab,yab,a,b) 
        
      UH_SNC_1D1D_1D_INIT                     Two 1D I*4     One 1D I*4 
      subroutine userhist (nabc,a,b,c) 
        
      UH_SNC_2D2D_2D_INIT                     Two 2D I*2     One 2D I*2 
      subroutine userhist (xabc,yabc,a,b,c) 
        
      UHI4_SNC_2D2D_2D_INIT                   Two 2D I*4     One 2D I*4 
      subroutine userhist (xabc,yabc,a,b,c) 
    Writing a Daphne UH (User-Histogram) Routine                       Page 33
    Use $@DAPEXE:DAPUH.LNK to Link User-Histogram Function          6 May 1997


      5  Use $@DAPEXE:DAPUH.LNK to Link User-Histogram Function

      The procedure for linking a user-histogram  function  is  sufficiently
      complicated that it has been placed in a command file.



      5.1  DAPUH.LNK Command Procedure

      The simplest case is the linking of a single file containing your user
      defined  histogram  function,  no  common  block  definitions,  and no
      special linker options.  For example to link a user-histogram function
      named MYUSER the command reduces to:

                      $ @DAPEXE:DAPUH.LNK MYUSER 

      The command procedure parameter has three parts:

       -  Object Files

          The name of the file (or files) containing object  code  for  your
          user-histogram function.

       -  Linker Options File (When using common blocks)

          Because of an unfortunate choice of common block attributes by the
          Fortran   compiler   it  is  necessary  to  create  a  file  which
          "overrides" the default attributes of each common block.

          For example, suppose  your  user-histogram  function  uses  common
          blocks  /GAGACOM/,  /FIT/, and /CALIBRATION/.  You should create a
          file with the extension ".OPT" (for example COMMONBLOCKS.OPT) with
          the following statements:

                      +---------------------------------------+ 
                      | PSECT_ATTR=GAGACOM,NOSHR              | 
                      | PSECT_ATTR=FIT,NOSHR                  | 
                      | PSECT_ATTR=CALIBRATION,NOSHR          | 
                      +---------------------------------------+ 

          The link options file should appear after  all  object  files  and
          should  be followed with the qualifier "/OPTION" as in the example
          below.

       -  Link Qualifiers

          For example /DEBUG or /MAP

      A complex example of the command procedure:

          +-------------------------------------------------------------+ 
          | $ @DAPEXE:DAPUH.LNK  ANALYZE,GAUSSSFIT,SPLINES,PEAKSEARCH,- | 
          |         DATATABLES,COMMONBLOCKS/OPTION -                    | 
          |         /DEBUG/MAP/EXE=NEW_ANALYZE                          | 
          +-------------------------------------------------------------+ 

    Writing a Daphne UH (User-Histogram) Routine                       Page 34
    Use $@DAPEXE:DAPUH.LNK to Link User-Histogram Function          6 May 1997


      5.2  Pre-Declared Common Blocks

      For convenience the following common blocks have  been  "pre-declared"
      in  the  standard  link  options file:  /A/, /B/, and /C/.  No options
      file is needed if you are using only common blocks with these names.



      5.3  Hints

      You might want to create a single options file which you can use  with
      all  your  user  routines.   In  it you can put the common blocks that
      appear in any of your user-histogram functions:  the linker  does  NOT
      consider  it  to  be an error if you over-ride the psect attributes of
      common blocks which are not defined.

      If you have a very large user-histogram function it may  be  difficult
      to  determine  the  names  of all your common blocks.  One trick is to
      link your function with the /MAP  qualifier.   Then  use  the  $SEARCH
      program  to  look  for all psects that have the attributes SHR (rather
      than NOSHR) and WRT (rather than NOWRT).

              $ @DAPEXE:DAPUH.LNK ANALYSIS,SPLINES,FITSUBS,GAUSS/MAP 
              $ SEARCH RMASS.MAP " SHR"," WRT" /MATCH=AND 
                                  ^      ^ 
                                  |      | 
                                space  space 



      5.4  VMS Error Messages From $UH


       -  %SYSTEM-F-NOTINSTALL, writable shareable images must be installed

          This message appears when the user  has  forgotten  to  declare  a
          common  block  in  the  options  file  (Section 5.1).  Only common
          blocks /A/, /B/, and /C/ are "pre-declared".

          If you can't identify a common block which is causing the  problem
          use the procedure described in Section 5.3.

          When a common block or other  psect  has  both  the  SHR  and  WRT
          attributes it must appear with the PSECT_ATTR link option in order
          to turn off the SHR attribute.

       -  %RMS-E-FNF, file not found

          This usually means that the system was unable to locate  the  file
          you  specified in your $UH command.  Check that the file exists by
          doing a $DIRECTORY command.

          A second possibility is that the system was unable to find UH.EXE,
          UI.EXE,  or  UIDEBUG.EXE.   In  this  case consult a member of the
          computer staff.
    Writing a Daphne UH (User-Histogram) Routine                       Page 35
    Use $@DAPEXE:DAPUH.LNK to Link User-Histogram Function          6 May 1997


       -  %SYSTEM-F-SHRIDMISMAT, ident mismatch with shareable image

          This usually means that you are trying  to  use  a  user-histogram
          function which was linked with an older or incompatible version of
          UH.

          The message could also appear if you  linked  your  user  function
          without using the DAPEXE:DAPUH.LNK command procedure (Section 5).

          Relink your user function using DAPEXE:DAPUH.LNK

    Writing a Daphne UH (User-Histogram) Routine                       Page 36
    Debugging UH Subroutines with the VAX/VMS Symbolic Debugger     6 May 1997


      6  Debugging UH Subroutines with the VAX/VMS Symbolic Debugger

      The following  log  demonstrates  how  to  use  the  VAX/VMS  symbolic
      debugger  with user written UH routines.  It is not a lesson on how to
      use the debugger.  There is a deliberate error in the program:  it  is
      written  to  access a histogram starting from channel 1 when the array
      starts at channel 0.  When the program gets to the  last  row  of  the
      histogram it runs off the end of the memory allocated to the histogram
      and receives a hardware detected access violation.
    Writing a Daphne UH (User-Histogram) Routine                       Page 37
    Debugging UH Subroutines with the VAX/VMS Symbolic Debugger     6 May 1997


      +----------------------------------------------------------------------+ 
      | $ fortran/nooptimize/debug accvio                                    | 
      |     (Compile with the /NOOPTIMIZE and /DEBUG)                        | 
      | $ @dapexe:dapuh.lnk accvio /debug                                    | 
      |     (Link with the /DEBUG qualifier)                                 | 
      | $ h2 64 64 /name=test                                                | 
      |     (Create a histogram which ends on a page boundary as described   | 
      |     (  in the "Hints and Notes" section)                             | 
      | $ uh accvio test /debug                                              | 
      | Expanded file name is SYS$SYSDEVICE:[MOOG]ACCVIO.EXE;3               | 
      |                                                                      | 
      |          VAX DEBUG Version V4.6-9                                    | 
      |                                                                      | 
      | %DEBUG-I-INITIAL, language is FORTRAN, module set to UH_PART2        | 
      | DBG> set image dapuhsub                                              | 
      | DBG> set module userhist                                             | 
      | DBG> set break userhist                                              | 
      |     (The three statements above are necessary in order to set        | 
      |     (  a breakpoint at the beginning of userHist)                    | 
      | DBG> go                                                              | 
      | %DEBUG-I-DYNMODSET, setting module UHTRANSFER                        | 
      | break at routine USERHISTINIT                                        | 
      | DBG> go                                                              | 
      | break at routine USERHIST                                            | 
      |      8:         integer*2       hist (0:xChan-1,0:yChan-1)           | 
      | DBG> step                                                            | 
      | stepped to USERHIST\%LINE 14                                         | 
      |     14:         sum=0.0                                              | 
      | DBG> exam xchan,ychan                                                | 
      | USERHIST\XCHAN: 64                                                   | 
      | USERHIST\YCHAN: 64                                                   | 
      | DBG> step                                                            | 
      | stepped to USERHIST\%LINE 15                                         | 
      |     15:         do j=1,yChan                                         | 
      | DBG> go                                                              | 
      | %SYSTEM-F-ACCVIO, access violation, reason mask=01,                  | 
      |      virtual address=0019FC00,PC=00012C52, PSL=03C00020              | 
      |                                                                      | 
      | DBG> show calls                                                      | 
      |  module name     routine name       line     rel PC    abs PC        | 
      | *USERHIST        USERHIST           17      00000052  00012C52       | 
      |  UH_2D           USERHISTINIT       ^       00000804  0001301C       | 
      |  POLICY          USERHISTINIT       |       000005FF  00012E17       | 
      |  SHARE$UIDEBUG                      |       00000000  0000B344       | 
      |                                     |                                | 
      | DBG> type 17 -----------------------+                                | 
      | module USERHIST                                                      | 
      |     17:             sum=sum+hist(i,j)                                | 
      | DBG> exam i,j                                                        | 
      | USERHIST\I:     64                                                   | 
      | USERHIST\J:     63                                                   | 
      | DBG> exit                                                            | 
      +----------------------------------------------------------------------+ 
    Writing a Daphne UH (User-Histogram) Routine                       Page 38
    Hints and Notes                                                 6 May 1997


      7  Hints and Notes

      7.1  Processing 2D Histograms

      It is particularly important when  processing  moderate  to  large  2D
      histograms,  to  access  the  histogram  in the correct way, if at all
      possible.  The VAX memory is organized so that it is very efficient to
      vary  the  first subscript (the X subscript) first and vary the second
      subscript  (the  Y  subscript)  more  slowly.   It   is   particularly
      inefficient to process the histogram in the other order.  To emphasize
      this point, a program which computed a projection of a 2,000 by  2,000
      histogram  was  stopped  after  it  had  been running for 6 hours.  By
      rewriting the program to access the histogram in the proper order, the
      running time was reduced to less than 3 minutes.

                     Good                       VERY BAD ! 
        
               +-----------------+            +---------------+ 
              7|---------------->|            | ^ ^ ^ ^ ^ ^ ^ | 
              6|---------------->|            | | | | | | | | | 
              5|---------------->|            | | | | | | | | | 
              4|---------------->|            | | | | | | | | | 
              3|---------------->|            | | | | | | | | | 
              2|---------------->|            | | | | | | | | | 
              1|---------------->|            | | | | | | | | | 
               +-----------------+            +---------------+ 
                                                1 2 3 4 5 6 7 8 
        
                do j=1,ny                     do i=1,nx 
                  do i=1,nx                     do j=1,ny 
                    sum=sum+hist(i,j)             sum=sum+hist(i,j) 
                  end do                        end do 
                end do                        end do 
        
                Good                          VERY BAD ! 

      Of course it sometimes happens that the nature of the algorithm  makes
      it  absolutely  necessary to do things the "wrong" way, but you should
      try to avoid it because the performance penalties can be severe.  Some
      users  have  resorted to keeping two copies of their matrices, one the
      transpose of the other, because the performance penalty is worse  than
      the waste of disk storage.
    Writing a Daphne UH (User-Histogram) Routine                       Page 39
    Hints and Notes                                                 6 May 1997


      7.2  Zero Extending INTEGER*2 Values

      When converting from an  INTEGER*2  to  an  INTEGER*4  value  one  can
      control whether the value is zero extended or sign extended.

      The default in VAX Fortran is  sign  extension,  which  will  yield  a
      negative value when the most significant bit is set.  By using the VAX
      Fortran ZEXT function one can get zero extension.  Using ZEXT for zero
      extension  is  no  more  expensive,  in  terms  of CPU time, then sign
      extension.

      Hexadecimal  Sign Extension    Zero Extension 
         Value    i4value=i2value  i4value=zext(i2value) 
        
       0                   0                  0 
      '7fff'X         32,767             32,767 
      '8000'X        -32,768             32,768 
      '8001'X        -32,767             32,769 
      'FFFF'X             -1             65,535 




      7.3  Channel and a Half

      Daphne programs, such as $BLW and $SUM, draw vertical lines  or  place
      markers to indicate selected channels of a histogram.  Daphne programs
      place the vertical line or marker at the center of the channel, not at
      the border.  Thus, a user performing a $SUM between channels 10 and 15
      will see vertical lines drawn at 10.5 and 15.5 of the X axis.

      The rule followed  by  these  programs,  is  to  truncate  the  cursor
      position  reported  by the display program to the next lowest integer,
      but to display the line or marker at the channel number plus one-half.
      For  instance, if the cursor is at X=10.9, then channel 10 is selected
      and a vertical line is drawn at X=10.5
    Writing a Daphne UH (User-Histogram) Routine                       Page 40
    Hints and Notes                                                 6 May 1997


      7.4  Suggestion for Debugging

      A common error in many programs is to process one extra channel  of  a
      1D  histogram  or one extra row or column of a 2D histogram.  Although
      there is no easy, sure-fire way of checking  for  this  problem  in  a
      program,  there  is  a  technique  which  often  shows up this kind of
      problem.

      This technique is based on the VAX's memory management system which is
      able  to  detect  a reference to non-existent memory.  The VAX manages
      memory in units of pages, which are 512 bytes long,  and  begin  on  a
      boundary which is a multiple of 512 bytes.

      Histograms are preceded by headers which are 256  bytes  long  for  1D
      histograms and 512 bytes long for 2D histograms.

      All Daphne histograms begin on page boundaries.  By making  sure  your
      2D  histogram  has  a  multiple  of 512 bytes, the last channel of the
      histogram will fall at the end of a page, and a reference to the  next
      page, if it doesn't exist, will cause an access violation.

      To create a 2D histogram which is a multiple of 512 bytes simply  make
      sure that the number of X channels times the number of Y channels is a
      multiple of 512.  The smallest square matrix satisfying this condition
      would be one which is 32 by 32 channels.

      By making your 1D histogram an ODD multiple  of  256  bytes  long  the
      histogram will end up with the last channel at a page boundary.  Since
      almost all users create INTEGER*4 1D  histograms,  one  needs  an  odd
      multiple of 64 channels:

                                       256 bytes 
                      64 channels = ----------------- 
                                     4 bytes/channel 

      Thus you  should  choose  histograms  which  have  64,  192,  or  1088
      (1024+64) channels.
    Writing a Daphne UH (User-Histogram) Routine                       Page 41
    Hints and Notes                                                 6 May 1997


      7.5  Different Size Histograms

      When writing a  UH  routine  you  should  consider  whether  to  allow
      histograms of different sizes as operands.  If you allow histograms of
      different sizes you must make a decision about  how  to  handle  extra
      channels.

      You should warn the user by means of the printHelp routine about  your
      choice.

      My  personal  rule  depends  on  whether  the  "output"  histogram  is
      "updated"  or "replaced" by the computation.  For example, if adding A
      to B giving B, then this is an "update" of B and if A is smaller  than
      B  then  the  remaining  part of B should not be altered.  However, if
      adding A to B giving C, then when A and  B  are  shorter  than  C  the
      remainder  of  C  should  be  set  to zero.  For this last example, my
      routines require that A and B have identical shape.



      8  Writing a Policy Routine

      For the moment, one must learn by example.  Start with the  relatively
      simple     routine     "DAPUH:UH_1D.FOR",     then     progress     to
      "DAPUH:UH_1D_1D.FOR".   For  a  fairly  complicated  routine  look  at
      "DAPUH:UH_ANY1OF_1D_2D_2DI4.FOR"   which   allows  a  user  to  supply
      different routines, depending on whether the single input histogram is
      1D INTEGER*4, 2D INTEGER*2, or 2D INTEGER*4.



      8.1  Flags Computed by $UH

      The UH flags are defined in "DAPDIR:UH.INC".  When  using  the  flags,
      one  should  remember  that  it  isn't  necessarily meaningful to make
      assertions about ALL or ANY elements of a null set.  In  other  words,
      the value of the flag "all_h2d_i4" ("all 2D histograms are INTEGER*4")
      is meaningless unless there is at least one 2D histogram.   Similarly,
      the  flag "all_out_h2d_same_nx_and_ny" ("all 2D output histograms have
      the same number of X channels and the same number of Y  channels")  is
      meaningless unless there is at least one output histogram which is 2D.
    Writing a Daphne UH (User-Histogram) Routine                       Page 42
    Examples                                                        6 May 1997


      9  Examples

      9.1  Histogram Value Related to the Observed Value

      The observed  values  are  proportional  to  the  square-root  of  the
      quantity of interest.  The following user function was used to rescale
      the data:  DAPUH:TOMASS.FOR



      9.2  Computing Error Bars

      The user wanted to compute error bars for his data.   Subtracting  the
      background  required  additional computations.  See DAPUH:SQRT.FOR and
      DAPUH:PYTHAG.FOR



      9.3  Display Symbol at Specified Coordinates

      For  an  example  of  uhSymbol,  uhReadCursor,  and  uhD1H/uhD2H   see
      DAPUH:CUR.FOR



      9.4  Read in Histogram Data in Non-Daphne Format

      A UH routine is the perfect method for reading  or  writing  histogram
      data in a non-Daphne format.



      9.5  Annotating Histogram

      For   an   example   of   uhAnnotate   see    DAPUH:ANNOTATE.FOR    or
      DAPUH:ANNOTATE90.FOR



      9.6  Copy

      See DAPUH:COPY.FOR for an  example  of  how  to  all  combinations  of
      INTEGER*2 and INTEGER*4 2D histograms.