New features added in Sunsort 4.07
==================================

External spectrum interface
---------------------------

An interface has been provided to allow any program to use sunsort's
1d and 2d spectrum viewers. This means that users have access to all
the standard sunsort peak fitting and projection codes in whatever
programs they write. The interface works for both C and FORTRAN.

The interface routines are:

C:       int start1d();
FORTRAN: call start1d

Starts the 1d viewer (sort_xvgr). The C interface returns the process ID
of the program if successful, or 0 if it couldn't be started.

C:       int start2d();
FORTRAN: call start2d

Starts the 2d viewer (sort_spec2d), same syntax as for the 1d viewer.

C:       void write1d(char *com, char *name, int more, int channels,
             int *data);
FORTRAN: call write1d(com,name,more,channels,data)
         character*(*) com,name
         integer more,channels,data(0:channels)

Display a 1d spectrum. Parameters are as follows:

com holds the sunsort internal command which should be "DISPLAY 1" to display
a spectrum, and "OVERLAY 1" to overlay the spectrum on top of the already
displayed one.

name holds the name of the spectrum.

more holds a flag indicating whether there are more spectra to follow to
make up a montage. If you want the 1d viewer to display several spectra
then you call write1d with more = 1 for all the calls except the last one.
See the FORTRAN example program to see how this works.

channels holds the number of channels to display. This may be less than
the declared length of the array.

data is the array holding the data.

C:       void write2d(char *com, char *name, int more, int channels,
             int arraysize, int *data);
FORTRAN: call write2d(com,name,more,channels,arraysize,data)
         character*(*) com,name
         integer more,channels,arraysize,data(0:arraysize,0:channels)

Displays a square 2d spectrum of size channels*channels. Parameters are
as follows:

com must hold "DISPLAY 2", that's the only supported command at the moment.

name holds the name of the spectrum.

more must hold 0, multiple displays aren't supported.

arraysize holds the declared length of the most rapidly changing index
of the array, ie. Y (in C that's the second index, in FORTRAN it's the
first).

channels holds the number of channels to display.

data is the array holding the data.

In C spectra are held as data[x][y], in FORTRAN they are held as data(y,x).

To use these routines, C programs must include the header file interface.h from
the interface subdirectory of sunsort. Both C and FORTRAN programs need
to be linked with libinterface.a in the same directory.

Sample programs are provided in test_sort/interface along with a Makefile
to show how linking works. To use the Makefile anywhere other than its
current location, alter the variable INTERFACEHOME to point to the
interface subdirectory of Sunsort.

If you want to use the projection routines in the 2d viewer, then the 1d
viewer must have been started even if you are not using it yourself.

Keyboard input to sort codes
----------------------------

Keyboard reding commands in sort codes, such as a FORTRAN read from unit
5, or a C scanf should now work as expected. While a sortcode is running
any text typed Sunsort's text window (the terminal window sunsort was run
from) will be passed to the sort code. As soon as sorting is finished,
commands will pe processed by sunsort as normal.

Should you need to send a command to sunsort while the sort code is running,
then either use the graphical interface as normal, or, if you must type the
command, prefix the command with a $ to let sunsort know to process the
command itself. The most likely command to use this with is killsort if
the sort process gets stuck in an infinite loop.

If you prefix a command with $ when sunsort doesn't expect it, that is,
when the sort code is not running, then sunsort just ignores the $ and
processes the command as normal.

Sending commands to sort codes from batch files is not possible in the same
way. Instead, use the command wrsort to queue a small number of messages
up for the sort code *before* you give the sort command. So the sequence of
commands at in the text window:

sort 0 1000
calib.dat

would become the following in a batch file:

wrsort calib.dat
sort 0 1000

Reading compressed spectra
--------------------------

If you have rarely used spectra on disk and you compress them with gzip or
compress to save disk space, then sunsort can now read the compressed spectra
without you having to decompress them first. Naturally, it's a little slower
than reading the raw spectra as sunsort has to do the deccompression on the
fly, but for rarely used spectra this shouldn't be a problem.

The space savings obtained by compressing sunsort spectra can be huge.  It's
not uncommon to reduce the disk space usage by a factor of 10.

Returning errors from user functions
------------------------------------

The init, sortin and finish routines can now return an error condition to
indicate that a fatal problem has occurred and sorting should be aborted.  A
common use of this could be to signal that an input file is missing.

In C, to signal an error return a non-zero value from the routine. In FORTRAN,
call the routine usererror with a non-zero parameter and then return as
normal.

C example:

int init()
{
    FILE *fp;

    if ((fp = fopen("matchsticks.dat", "r")) == NULL)
    {
        perror("matchsticks.dat");
	return 1;
    }

    ... rest of init routine ...

    return 0;
}

FORTRAN example:

      subroutine init
      implicit none
      save
      include '.sunsort_initadc.i'
      integer ierror
      
      open(unit=8,name='matchsticks.dat',status='old',iostat=ierror)
      if (ierror.ne.0) then
         print *,'Unable to open matchsticks.dat'
         call usererror(1)
         return
      endif

      ... rest of init routine ...

      return

Also, see the example sort codes egam-c.srt and egam-f.srt.

Automatic matchstick and peakfinding
------------------------------------

On the spectrum control panel there's a new control which will come up set to
display. By setting this to different values, you can get sunsort to
automatically perform a matchsticks routine or a peakfinding routine on the
spectrum as soon as it's displayed. The routines will use whatever values you
entered on the control frames for those routines before.

Typically, you will display the first of a set of spectra normally and run,
for example, the matchsticks routine on it. When you are happy with the
settings, you can then hit the Next 1d button in the spectrum control window
and it will automatically move on to the next spectrum and run the matchsticks
routine on it. You can then copy the contents of the log window from the 1d
viewer into a text file and edit out the lines you need.

Note that these routines will only work if you have only 1 spectrum selected
in the control window. If you select more than one you get unexpected results.

Peak fitting on transformed spectra
-----------------------------------

If you transform a spectrum with evaluate expression, then you can now perform
peak fitting on the transformed spectrum provided the X spacing of points is
linear. This means that simple transformations like x = x - 100, or x = x / 5
will work.

The peak centroids and widths will be quoted in X coordinates, but the peak
areas will be the total number of counts in the peak, not number of counts
times x-spacing. For example, if you fit a raw spectrum and get a centroid at
268.13 +/- 0.01 with an area of 86064.79 +/- 325.88 and a fwhm of 6.55 +/-
0.02, then you perform the transformation x = x * 10 and refit with the scaled
limits, you would find a peak at 2681.32 +/- 0.11 with an area of 86064.79 +/-
325.88, and a fwhm of 65.51 +/- 0.23

I've set it up this way as I felt that the area reading is most useful as a
measure of the number of counts in a peak, regardless of how spread out they
are.

Adclist array
-------------

C:		short adclist_.adclist[]
FORTRAN:	integer*2 adclist(*)

The variable listed above is available to sort code in a global area and
common block. The declaration of it is handled automatically when you include
.sunsort_initadc.h or .sunsort_initadc.i. On entry to the sortin routine, the
array holds a list of which ADCs fired terminated by a -1.

This array can allow some sortin routines to run much quicker. In particular
code that just plots a 1d spectrum for every adc is much faster. See the
example sort code adcs768-c.srt for a demonstration.

Custom event generation
-----------------------

Selecting the event format 'user' allows you to specify your own event
generation routines. Instead of getting data of tape, you can provide a set of
routines which generate data for your sort code.

The entry points are analogous to the init, sortin and finish entry points for
sort codes. Each entry point is called before the equivalent entry point in
the sort code.

init entry point:

C:		int rdtape_user_init(void);
FORTRAN:	subroutine rdtapeuserinit

This entry point is called before the init entry point of the sort code. It
allows the user to perform any initialisation the event generation routines
need.

The C code should return 0 if the initialisation succeeded, or non-zero to
indicate failure. The FORTRAN routines should call usererror with a non-zero
value before returning to indicate failure.

sortin entry point:

C:		int rdtape_user_sortin(void);
FORTRAN:	subroutine rdtapeusersortin


This routine is called once for each record the user requests to be sorted.
It should set up everything to do with the event before returning. The data
should be passed to the sort code either through the adc and adclist array, or
through another global or common area.

The C code should return zero to indicate success, a positive number to
indicate that no event is available, but that sunsort should call the code
again to try to get another event, or a negative number to indicate a fatal
error and that sunsort should immediately abort sorting. FORTRAN code should
call usererror with a positive or negative number to indicate soft or hard
errors.

finish entry point:

C:		int rdtape_user_finish(void);
FORTRAN:	subroutine rdtapeuserfinish

This entry point is called at the end of sorting, just before the sort code's
finish entry.

The C code should return 0 if the initialisation succeeded, or non-zero to
indicate failure. The FORTRAN routines should call usererror with a non-zero
value before returning to indicate failure. Failure at this point is pretty
meaningless as sunsort is about to stop sorting regardless.

Note that the FORTRAN routines can be joined into one subroutine with
several entry points as is the case for sort code. This allows sharing of
data. For example:

      subroutine rdtapeuserinit
      implicit none
      save
      include '.sunsort_initadc.i'
      common/mydata/e1,e2,px1,py1,pz1,px2,py2,pz2
      double precision e1,e2,px1,py1,pz1,px2,py2,pz2

      print *,'Event generation code initialised.'

      return

      entry rdtapeusersortin

      adc(5)= ...
      e1= ...

      ... etc ...

      if (event has missed detectors) then
         call usererror(1)
         return
      endif

      ... etc ...

      return

      entry rdtapeuserfinish

      print *,'Event generation code finished.'

      return
      end

The advantage of passing the data through a separate common block is that
you can avoid the overhead of calibration etc. On the other hand, if you
wanted to test your calibration routines, you might want to pass the data
in the adc array so you can see how your routines behave.

At the moment, it's not possible for these routines to read a data file,
so before running them, you should select sort media: disk and sort file:
/dev/zero. The number of records you specify will give the number of
times the event generation sortin routine will be called, the sort code
sortin routine may be called less often if the event generation routine
returns non-zero values.

Run number available for in2p3 data files
-----------------------------------------

C:		int filenm_.runnumber
FORTRAN:	integer runnumber

The variable listed above is available to sort code in a global area and
common block. The declaration of it is handled automatically when you include
.sunsort_initadc.h or .sunsort_initadc.i. On entry to the sortin routine, the
variable holds the run number recorded in in2p3 data files if known.

In2p3 data files store the run number internally near the start of the data
file. When susnort starts sorting in2p3 data files it initially sets this
variable to -1. If it comes across a run number record, it sets this variable
to the run number found in the record. Since the run number record comes
before all data in a run, if you start sorting a tape file from its start,
this variable will be set for all events. If you start a tape file partway
through, or if you are sorting a disk file, the variable will not be set.

Since in2p3 data tapes are not ANSI format, they do not have a concept of file
names. This run number variable is the only way of identifying which run a
file is for. Once data is filtered to disk, then the user will have specified
a file name which may be used for identification instead of the run number.

Comments in spectrum and variable declarations
----------------------------------------------

You can now include comments in the spectrum and variable declaration
section of sort codes. On any line, anything after a # is ignored so
you can do things like:

*oned
# Raw spectra
1..128 adc1 4096
# E and P plots
129..159,2 e1 4096
130..160,2 p1 4096
# Miscellaneous
161 esum 512		# e1 + e2
162 prec 512		# momentum of recoil
163 erec 512		# energy of recoil
164 etot 512		# no prizes for guessing
