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.