                          ============================
                          The Sunsort Reference Manual  
                          ============================

Contents
========

1		Introduction
2		Writing a Sortfile
3		Compiling a SunSort Sortfile
4		SunSort Command Summary
5		SunSort library functions
6		`Nobby' uses SunSort
Appendix A	Other Formats

1 Introduction
==============

The aim of the SunSort package is to provide software to replay event-by-event
data produced during Charissa experiments.

The design goals which were used to frame the evolution of this package were:

    - Provide as `user friendly' a package as possible.
    - Attempt to exploit the benefits of the UNIX programming environment.
    - Modularise the tasks required of the package into several distinct
      objects.
    - Reduce the overheads involved in producing a working sorting process.
    - Incorporate other useful physics programs directly into the
      reduction package eg the fast fitting routine BUFFIT written by
      N.M.Clarke.
    - Maintain backward compatibility with S.J.Bennett's earlier version
      of sunsort.

SunSort in its present incarnation is made up of several cooperative processes
which interact with one another through various UNIX IPCs.

At the heart of the SunSort package is a library of C functions which provides
the user with facilities to access data from one of four possible sources
(disk, exabyte, ethernet or the DEMON DA system) and to decode this data into
a simple array of ADC values. A user provided FORTRAN subroutine is linked to
this library to form the core sort process.  During sorting, the user's
FORTRAN subroutine is called once per event and is passed the array containing
the ADC values. The user, through his/her coding of this subroutine, is
therefore left to decide how to manipulate the experimental data. Within the
FORTRAN subroutine the user can call upon various SunSort library utility
routines in order to, almost other things, increment spectra, perform
windowing operations and filter selected events back to a storage medium.

2 Writing a Sortfile
====================

SunSort sort files are divided up into a number of logical sections by the use
of keywords which are indicated by an asterix. The sortfile is then run
through a preprocessor (makesort) to generate FORTRAN code to define the
spectra and variables and to strip out the user subroutine.  The files which
are produced are then compiled and linked to form an executable load module. A
brief example sortfile is included in Appendix A, and an explanation of the
syntax of each keyword section is given below.

2.1 *trigger section
--------------------

Everything in the sortfile up to this statement is totally ignored by the
preprocessor enabling as many comment lines to be included in the sortfile as
desired by the user. The next line must contain an integer which is greater
than or equal to the highest number of simple adcs ever included in a single
event. At present this number can not exceed 1024. For the sake of efficient
sorting it is recommended that this number is not set higher than the number
of adc you want to process.

NSF format only {
Subsequent lines in this section specify the direct triggers which have been
used, if any. The syntax is a line of integers, separated by one or more
spaces or tab stops. The first integer is the direct trigger number, which is
then followed by the list of adcs associated with that trigger definition. For
example the lines

4	2 4 8 12
10	1 3

defines trigger 4 to contain adcs: 2, 4, 8, and 12, and trigger 10 to contain
adcs: 1, and 3. The ordering of the adcs must match that of the trigger
definition used to write the events.
}

2.2 *oned section
-----------------

Each line in this section specifies a one dimensional spectrum and contains
the three fields below separated by one or more spaces or tab stops:-

specnum     specname     specdim

specnum is an INTEGER spectrum identification number which specifies where the
spectrum is stored in the spectrum array. specnum can vary from 1 to
TAB_SIZE_1D, where TAB_SIZE_1D is a configuable parameter currently set to
800.  Typically specnum can have values 1, 2, 3... etc. but they need not be
continuous or in numerical sequence. specname should be compatable with a
CHARACTER*10 variable and is the spectrum's name. It is used to refer to the
spectrum for display purposes and to generate the file name in which the
spectrum is saved.  specdim gives the INTEGER dimension of the spectrum such
that the spectrum will range from channel 0 up to channel specdim-1.

A shorthand way of defining spectra with similar names is available. For
the spectrum number put a range indicating the first and last spectra in
the range using `..' to separate the first and last, for example, 1..4 means
spectra 1, 2, 3 and 4. If the spectra are not adjacent, then specify the
interval between spectra by adding a `,' and the interval, for example,
1..7,2 means spectra 1, 3, 5 and 7. The spectrum name should end in a number.
This number is incremented by 1 for each spectrum in the set. Some examples
should give a clearer picture:

1..5	adc1	4096

is equivalent to

1	adc1	4096
2	adc2	4096
3	adc3	4096
4	adc4	4096
5	adc5	4096

41..44	spec5	128

is equivalent to

41	spec5	128
42	spec6	128
43	spec7	128
44	spec8	128

and

61..67,2 siga1	4096
62..68,2 sigb1	4096

is equivalent to

61	siga1	4096
62	sigb1	4096
63	siga2	4096
64	sigb2	4096
65	siga3	4096
66	sigb3	4096
67	siga4	4096
68	sigb4	4096

2.3 *twod section
-----------------

Each line in this section specifies a two dimensional spectrum and contains
the three fields below, separated by one or more spaces or tab stops:

specnum     specname     specdim

These are the same as in the *oned section with three exceptions.

1) If a spectrum's name begins with `w' it is deemed to be a two dimensional
   window. These are treated like spectra except that they can be loaded and
   saved via a different menu.

2) All two dimensional spectra must be square and only specdim up to 512
   are supported. Be warned that 512x512 spectra each use 1 MB of memory
   so using more than a few is likely to cause the computer to swap which
   will slow down your code drastically.

3) specnum can vary from 1 to TAB_SIZE_2D, where TAB_SIZE_2D is a currently
   set to 250.

2.4 *variables section
----------------------

Each line in this section specifies a variable with its default value and
contains the three fields below separated by one or more spaces or tab stops:

varnum     varname     varvalue

varnum and varname are the same as their *oned equivalents. varvalue is the
REAL default value of the variable. varnum can vary from 1 to TAB_SIZE_VAR,
where TAB_SIZE_VAR is a currently set to 500.

2.5 *sort section
-----------------

The presence of the *sort command tells the preprocessor to strip out the
following source lines into the file `sunsort_proc.f' or `sunsort_proc.c'with
no further modification. Consequently this part of the sortfile must conform
to the standard accepted by your FORTRAN or C compiler.

For FORTRAN sort codes, this section must at least specify a subroutine
called `init' with 2 entry points called `sortin' and `finish'. For C
sort codes, this section must at least specify 3 subroutines called
`init_', `sortin_' and `finish_'.

2.5.1 Subroutine `init'

`init' is called each time SunSort a new call is made to read more records
from the current input file (see section on SunSort commands).  It is useful
for defining and initialising variables before a sort.  The subroutine should
include the following code segment to allow the user routine to interface with
the body of the sort code

For FORTRAN codes:

      subroutine init
      save
      include '.sunsort_initadc.i'

It's useful to add the statement `implicit none' just before the save line.
You should add a return statement at the end of the initialisation routines
just before the sortin entry.

For C sort codes, you should have the line

#include ".sunsort_initadc.h"

somewhere near the start of your code before the declaration of subroutine
init_, which should be declared as void function with no parameters.

2.5.2 Entry Point `sortin'/subroutine sortin_

`entry sortin' (or subroutine sortin_() in the case of C sort codes) is called
each time SunSort has successfully unpacked an event for processing by the
user code. This code segment passes the following information to the user sort
program (FORTRAN and C names and definitions are given)

integer event
int adcs_.event;
	The current event's number in the current record.

integer	record
int adcs_.record;
	The current record's number in this attempt to read from the input
	file.

logical	wrtevt
int adcs_.wrtevt;
	A logical variable set on an event-by-event basis to control whether
	an event is fed to the output stream. This variable is initially set
	to be false (0), and if set by the user to be true (1) at any point
	between `entry sortin' and `return' the current event is copied to the
	output stream where it is included in records and blocks as
	appropriate.

integer	adc(*)
short adcs_.bitpattern[], adcs_.triggernos, adcs_.adcs[];
	This array is responsible for passing the adc values of the current
	event into the user sort code. The array holds the following
	information. If an adc does not appear in the current event its value
	will be set to -1.

	In FORTRAN adc(1) onwards hold the value of the appropriate adc for
	the current event, in C, adcs_.adcs[0] onwards hold the data. To
	avoid confusion in C, the macro ADC has been defined so that ADC(1)
	holds the value of the first adc.

	For NSF format data, adc(0) is returned with the Daresbury trigger
	number of the current event, ranging from 1 up to 26. adc(-1) to
	adc(-8) hold the values of the hit patterns for indirect trigger
	events. adc(-1) hold the first hit pattern word for adcs 1 to 16,
	adc(-2) holds the second hit pattern word for adcs 17 to 32 etc.
	In C, the trigger is in adcs_.triggernos and the hit patterns are
	in adcs_.bitpattern[0]..adcs_.bitpattern[NOS_BIT_WORDS-1] with the
	highest numbered element corresponding to the FORTRAN adc(-1).

real var(*)
float vars_.var[];
	This array passes the current values of previously defined variables
	to the user's sort program. This allows the sortcode to have access to
	the variables on an event by event basis.

	In FORTRAN, var(1) holds the value of variable for which varnum equals
	1, var(2) the value for which varnum equals 2 etc. In C, vars_.var[0]
	holds the value of the variable for which varnum equals 1. To avoid
	confusion, a macro VAR has been defined so that VAR(1) corresponds
	to FORTRAN var(1).


character*40 filein
char filenm_.filein[filenm_SIZE];
	This holds the file name of the current source of event by
	event data. An event can be uniquely identified by a combination of
	filein, record, and event; for diagnostics.

character*40 fileou
char filenm_.fileou[filenm_SIZE];
	This holds the file name of the current destination of filtered event
	by event data.

The sortcode is entirely up to the user, though a typical sort might
progress as follows: verify the event is good by checking its trigger
number and the combination of adcs present in it using the hit patterns,
increment singles spectra using a loop, calculate new pseudo-parameters
such as the total energy in a detector or the position of an event,
increment such oned and twod spectra as necessary, window on oned or twod
spectra before finally incrementing those spectra of physical interest.
The path of executable statements must finally end up at a `return' for
each event.

2.5.3 Entry Point `finish'

Entry `finish' is called when SunSort has either: finished reading to the end
of the current data file, read as many records as requested by the user, or
been interupted by a control-c. The purpose of this entry point is to allow
the user to report any end of run statistics such as number of each type of
event etc. The entry point should end with a `return' statement and in
FORTRAN sortcodes, as this is the last piece of code in subroutine `init',
it should be followed by an `end'.

2.6 Example sort codes
----------------------

The following sortcodes are very basic to show how sortcodes are structured.
Each code declares 64 spectra called adc1 to adc64, for each event it
increments the spectra of the adcs contained in the event (suppressing
0 readings). The codes also count up how many events were sorted and reports
this figure to the user.

2.6.1 FORTRAN example


*trigger
128
*oned
1..64 adc1 4096
*twod
*vars
*sort
      subroutine init
      implicit none
      save
      include '.sunsort_initadc.i'
      integer events, i

      events = 0
      return

      entry sortin
      events=events+1
      do i=1,64
         if (adc(i).gt.0) call inc1d(i, nint(adc(i)))
      enddo
      return

      entry finish
      print *,events,' events sorted.'
      return
      end

2.6.2 C example

*trigger
128
*oned
1..64 adc1 4096
*twod
*vars
*sort
#include <stdio.h>
#include ".sunsort_initadc.h"

static int events;

void init_(void)
{
    events = 0;
}

void sortin_(void)
{
    int i;

    events++;

    for(i = 1; i <= 64; i++)
	if (ADC(i) > 0)
	    inc1d(i, ADC(i));
}

void finish_(void)
{
    printf("%d events sorted.\n", events);
}

3 Compiling a SunSort Sortfile
==============================

Once a user has produced a suitable sort file it must be processed into a form
which is directly useable by SunSort. This involves passes the file through a
preprocessor call makesort which generates a spectrum definitions file and a
code file. The latter is then compiled and linked by makesort into a binary
execuable file.  See the makesort(1) manual page for information on the
makesort command line options.

When a user invokes makesort the name of a sort file must be supplied and by
default the three files produced will be called:

	sunsort_proc.spec	-	the spectrum definition file
	sunsort_proc.f		-	the code file
	sunsort_proc		-	the executable

A command line option for makesort exists that over-rides this default
behaviour and enables the user to respecify the "sunsort_proc" part of these
names.

4 SunSort Command Summary
=========================

Once Sunsort has been sucessfully started the user may issue commands from
within the launching window in order to manipulate data files etc. See the
sunsort(1) manual page for a detailed explanation of these commands. Any
commands which are not recognized by SunSort are passed on to be interpreted
by the Bourne shell sh(1).

Note that typically one would expect that SunSort would be controlled using
the graphical user interface (GUI) rather than by typing the commands in from
the launching window. However, the commands marked with an asterisk below are
not available on the current GUI.

The following commands are recognized by the sunsort command interpreter
{Arguments in <> must be supplied and those in [] are optional}:

	batch <batch file name>
	clear <spectra> [#specnos1] [#specnos2] .....
	close [data input stream]
	debugsort
	display1d <#specnos1> [#specnos2] [#specnos3] [#specnos4]
	display2d <#spectnos>
	editsort <editor> <sort program name>
	eject [access mode]
*	end 
	exit
*	help [command name]
	killsort
	load <type> <load directory> <format> [#add]
	loadsort [-keep] [sort_prog_name]
	makesort <sort source name> [debug] [[-o sort name] other options...]
	newtape <volume name> <#drive nos>
	open <data source> <sort_file>
	overlay1d <#specnos1> [#specnos2] [#specnos3] [#specnos4]
*	printsenv
	printvars
	refresh <#seconds>
	reset <job>
	save <type> <save directory> <format> [#overwrite]
*	setsenv <variable name> <new value>
	setwin <#window nos> on <#2d spectrum nos>
	showwin <#window nos>
*	sleep <#seconds>
	sort <#skip records> <#records to sort>
*	status
	tapemount <volume_label> <#drive nos> <access mode>
*	tapemove <#nos of files>
	tapeumount <access mode>
*	update
	var <#variable nos> <#new value>
	vars 
	viewwin <#window nos> <region> <#2d spectrum nos>
	wclose <destination>
	wopen <destination> <write_file>

5 SunSort library functions
===========================

These functions reside in the object library libsunsort.a and are linked into
the user's sort program during a makesort.

5.1 FORTRAN callable routines
-----------------------------

5.1.1 Utility functions

Function to logically and short integers, included for backward compatibility
	INTEGER*2 IANDHW
	INTEGER*2 IOP1,IOP2,IOP3
	IOP3 = IANDHW(IOP1,IOP2)

Call to return array IOP2 set to 1 or 0 depending on bits in IOP1
	INTEGER*2 IOP1
	INTEGER   IOP2(16)
	CALL BITAHW(IOP1, IOP2)

Call to return array IOP2 set to 1 or 0 depending on bits in IOP1
	INTEGER  IOP1
	INTEGER  IOP2(32)
	CALL BITAW(IOP1, IOP2)

Function to return whether bit IOP2 is set in IOP1 lsbit = bit number 1 and
msbit = bit number 16
	INTEGER*2 IOP1, 
	INTEGER IOP2, IOP3
	INTEGER*2 IBITSHW
	IOP3 = IBITSHW(IOP1,IOP2)

Function to return whether bit IOP2 is set in IOP1
	INTEGER IOP1,IOP2,IOP3
	INTEGER IBITSHW
	IOP3 = IBITSW(IOP1,IOP2)	

Function to return byte swapped short 
	INTEGER*2 IOP1,IOP2
	INTEGER*2 ISWAPHW
	IOP2 = ISWAPHW(IOP1)	

Function to return byte swapped int 
	INTEGER IOP1,IOP2
	INTEGER ISWAPW
	IOP2 = ISWAPW(IOP1)
	
Function to return number of bits set in IOP1
	INTEGER*2 IOP1
	INTEGER IOP2, NBITHW
	IOP2 = NBITHW(IOP1)

Function to return number of bits set in IOP1
	INTEGER IOP1
	INTEGER IOP2, NBITW
	IOP2 = NBITW(IOP1)
	
5.1.2 Scaling functions

In general, these have the name XscaleY(value, low, high, base)

    if X == i then value is int and function returns int
    if X == r then value is real and function returns real
    if Y == i then low, high and base are int
    if Y == r then low, high and base are real

these functions perform the calculation
	IRESULT = ((VALUE - LOW) * BASE) / (HIGH - LOW)

Function to scale IVALUE
	INTEGER IVALUE, ILOW, IHIGH, IBASE
	INTEGER ISCALE, IRESULT
	IRESULT = ISCALEI(IVALUE, ILOW, IHIGH, IBASE)

Function to scale IVALUE
        INTEGER IVALUE
	REAL LOW, HIGH, BASE
	INTEGER ISCALE, IRESULT
	IRESULT = ISCALER(IVALUE, LOW, HIGH, BASE)

Function to scale IVALUE
	REAL VALUE, LOW, HIGH, BASE
	REAL SCALE, RESULT
	RESULT = RSCALER(VALUE, LOW, HIGH, BASE)

Function to scale IVALUE
        REAL VALUE
	INTEGER ILOW, IHIGH, IBASE
	REAL RSCALEI, RESULT
	RESULT = RSCALEI(VALUE, ILOW, IHIGH, IBASE)

5.1.3 Spectrum manipulation routines

Call to increment channel ICHAN in 1d spectrum ISPEC
	INTEGER ISPEC, ICHAN
	CALL INC1D(ISPEC, ICHAN)

Call to increment channel IXCHAN, IYCHAN in 2d spectrum ISPEC
	INTEGER ISPEC, IXCHAN, IYCHAN
	CALL INC2D(ISPEC, IXCHAN, IYCHAN)

Call to add IVAL to channel ICHAN in 1d spectrum ISPEC
	INTEGER ISPEC, ICHAN, IVAL
	CALL INCV1D(ISPEC, ICHAN, IVAL)

Call to add IVAL to channel IXCHAN, IYCHAN in 2d spectrum ISPEC
	INTEGER ISPEC, IXCHAN, IYCHAN, IVAL
	CALL INCV2D(ISPEC, IXCHAN, IYCHAN, IVAL)

Call to set channel ICHAN in 1d spectrum ISPEC to IVAL
	INTEGER ISPEC, ICHAN, IVAL
	CALL SET1D(ISPEC, ICHAN, IVAL)

Call to set channel IXCHAN, IYCHAN in 2d spectrum ISPEC to IVAL
	INTEGER ISPEC, IXCHAN, IYCHAN, IVAL
	CALL SET2D(ISPEC, IXCHAN, IYCHAN, IVAL)

Function to return value of channel IXCHAN in 1d spectrum ISPEC
	INTEGER ISPEC, ICHAN, IVAL
	IVAL=VAL1D(ISPEC, ICHAN)

Function to return value of channel IXCHAN,IYCHAN in 2d spectrum ISPEC
	INTEGER ISPEC, ICHANX, ICHANY, IVAL
	IVAL=VAL2D(ISPEC, ICHANX, ICHANY)

Call to test whether point (IXCHAN,IYCHAN) lies within the 2D spectrum ISPEC.
Return with IN set to true if it does.
	INTEGER ISPEC, IXCHAN, IYCHAN	
	LOGICAL IN
	CALL WIN2D(ISPEC, IXCHAN, IYCHAN, IN)

There are variants of these commands which expect ICHAN, IXCHAN and IYCHAN
to be INTEGER*2, REAL and DOUBLE PRECISION these routines provide on the
fly conversion and rounding to integer so can save a little typing. The
names of these routines are obtained by prefixing the above names with s,
f and d respectively. For example, lines like:

	CALL INC1D(1, NINT(ADC(1)))
	CALL INC2D(5, NINT(PSI*2-116), NINT(THETA*3+64))

to be simplified to:

	CALL SINC1D(1, ADC(1))
	CALL FINC2D(5, PSI*2-116, THETA*3+64)

if PSI and THETA are real. If they were double precision, DINC2D would have to
be used.

The following deprecated interfaces are also provided for use with really
old sort codes and to ease porting of codes from sort-shell. They should
not be used in new codes.

Call to increment channel ICHAN in 1d spectrum ISPEC
	INTEGER ISPEC, ICHAN
	CALL RINC(ISPEC, ICHAN)


Call to increment channel IXCHAN, IYCHAN in 2d spectrum ISPEC
	INTEGER ISPEC, IXCHAN, IYCHAN
	CALL RINC2D(ISPEC, IXCHAN, IYCHAN)

5.1.4 Eurogam data decoding functions

Call to establish a mapping between adc number and hardware address as given
in the file specified by FILENM. IERROR is set to zero if all goes well,
otherwise it is set non-zero.
	INTEGER IERROR
	CHARACTER* FILENM
	CALL EGINIT(FILENM, IERROR)

Call to place adc data correspond to a Eurogam style group IGROUP event into
an array DATA. ILEN specifies the size of the array DATA.  On return from call
ILEN = group length or -ve if call failed
	INTEGER IGROUP, ILEN
	INTEGER*2 DATA(ILEN)
	CALL EGROUP(IGROUP, DATA, ILEN) 

5.1.5 EbyE filtering function

FORTRAN function to write data in IDATA to filter stream in predefined format.
Not all data formats support writing of arbitrary data.
	INTERGER ISIZE, IERR
	INTEGER*2 IDATA(ISIZE)
	IERR = WRTEVT(ISIZE, IDATA)	

5.2 C callable routines
-----------------------

5.2.1 Spectrum manipulation functions

Increment 1d spectrum
	void inc1d(int spec_nos, int channel);

Increment 2d spectrum
	void inc2d(int spec_nos, int x_ch, int y_ch);

Increment 1d spectrum by value
	void incv1d(int spec_nos, int channel, int value);

Increment 2d spectrum by value
	void incv2d(int spec_nos, int x_ch, int y_ch,int value);

Test 2d window, returns 0 if point not in window, else non-zero
	int win2d(int spec_nos, int x_ch, int y_ch);

Set 1d spectrum to value
	void set1d(int spec_nos, int channel, int value);

Set 2d spectrum to value
	void set2d(int spec_nos, int x_ch, int y_ch,int value);

Find value of 1d spectrum
	int val1d(int spec_nos, int channel);

Find value of 2d spectrum
	int val2d(int spec_nos, int x_ch, int y_ch);

There are also double precision versions of these functions where the channel
numbers are floating point. The names of these can be obtained by prefixing
the normal names with a `d'. The short and float versions provided for FORTRAN
are not needed in C as function prototyping allows the compiler to do the
conversion on-the-fly.

5.2.2 Eurogam functions

Initialise Eurogam channel mapping file, returns 0 on success, non-zero on
failure
	int eginit(char *filename);

Return data for a group
	struct group_data *egroup(int group);

The structure group_data contains at least the following fields:
	int group_len;
	unsigned short *group_ptr;

group_len holds the length of the group, and group_ptr points to an array
of the data (the first data element is at group_ptr[0]).

6 `Nobby' uses SunSort
======================

Let us assume that Nobby wants to sort Charissa NSF format data.  He only
wants to see the spectra corresponding to whatever entered the first 128
adcs. He therefore decides to use the sample sortfile adcs128-f.srt from the
directory test_sort distributed with Sunsort. He copies it to sample.sort.
He decides he'd like to filter the events in which both ADCs 2 and 31 fired,
so adds the line

	if (adc(2).gt.0.and.adc(31).gt.0) wrtevt=.true.

just after the enddo.

Nobby must first make sure that the SunSort binaries are in his shell search
path. For example, if on Nobby's system the SunSort binaries are in
/home/charissa/sunsort, then he might use:

	set path = (/home/charissa/sunsort $path)

in a C shell to prepend the directory /home/charissa/sunsort to the list of
places the shell looks for commands.

Nobby decides that he might need to debug his sort code and so `makes'
sample.sort using makesort and specifying the debug option:
	
	makesort sample.sort debug

He is now ready to run SunSort and so types:
	
	sunsort

and SunSort outputs the following:

	----------------------------------
	Charissa SunSort Version 4.06-beta
	----------------------------------

	Sunsort > read_spec: Reading 'sunsort_proc.spec' file
	read_spec: Done
	sort_spec2d started
	sort_xvgr started

Nobby now wants to read data off an exabyte tape sitting in drive 0, sort it
and write any filtered events back to a disk file called
/stage/nobby/run02f. He knows that when the tape was written the data he is
interested in was placed in a run file called RUN02 on a tape called
BMY001. So Nobby types the following into the command window (Nobby's input is
after the sunsort > prompt):

	sunsort > tapemount BMY001 0 r
	tape BMY001 mounted

	sunsort > open tape run02
	*** tape file run02 open
	tape file run02 open

	sunsort > wopen disk /stage/nobby/run02f 
	write disk file /stage/nobby/run02f open

Nobby is now in the position to sort his data, which he does by typing:

	sunsort > sort 0 999999
	starting sort functions ... server: reading from tape ...

Here the value 0 refers to the number of records on tape he wants to skip
before actually sorting and the 999999, the number of records to
process. (Zero followed by a sufficiently large number ensures that all
records are are sorted)

After a few seconds Nobby realises that he actually does need to modify the
sort slightly and so stops the sorting using control-c.

	^C 
 
	*** sort statistics ***
	43721 trigger 26 events
	 
	read 43721 events in 19 seconds
	Average sort rate = 2301.11 events per second
 
	finished sorting data after reading 483 records
	 
	finished writing after issuing 108 write requests
	representing 43721 events out in NSF format

He edits sample.sort and without leaving SunSort makes a new sort program and
loads it:

	sunsort > makesort sample.sort debug
	sunsort > loadsort
(the output from these commands isn't shown here)

Nobby decides that he will close the read and write files in order to start
from the beginning again:

	sunsort > close
 	dtclose: skipping forward to next tape file
	read file CLOSED

	sunsort > wclose
	write file CLOSED

At this point Nobby was very bored of typing in commands and decided to do the
rest of his sorting using the GUI.

******************************************************************************

Appendix A Other Formats
========================

Sunsort has been rewritten over the last couple of years in an attempt
to enable it to support multiple data formats. 

Format	Source

NSF	Daresbury event manager as used by Charissa before Jan 1997
NSF2	Modified NSF format as used by Charissa outside ANU since Jan 1997.
MEGHA	Modified Eurogam format as used by Charissa at ANU since Jan 1997.
DEMON	Eurogam format as used by DEMON
NSCL	Argonne National Laboratory 
ANU	Australian National University  
FSU	Forida State University (1994)
FSUPC	Florida State University PC based DA system
IN2P3	GANIL
JYFL	Jyvaskla data format used by laser group at Birmingham
NONE	Fixed event lengths and no decoding

******************************************************************************

This manual last updated on the 7th of November 1997 by Steven Singer.
