Documentation on ASCII gls (.ags) Level Scheme Files for RadWare


This documentation is for .ags file format version 1.0
D.C. Radford, August 1996
HTML version: April 1998
Updated for C code July 2002

  1. Introduction.
  2. Format of the .ags files.
  3. Example of a short .ags file.
  4. Listing of the gls include file, gls.h
  5. Listings of the subroutines to read and write the .ags files.

1. Introduction.

Since the original LEVELS file format (.lvl) is no longer heavily supported in RadWare, there is a need for a new type of ASCII file format so that level schemes can be copied between different computer systems without the need for file conversion, e-mailed to collaborators, etc. This need is now met by the .ags file format, standing for Ascii Graphical level Scheme. It is essentially a formatted version of the more usual (unformatted) .gls file. The .ags files can contain all the same information as .gls files, and can be read and written by all of the standard GLS programs (e.g. gls, escl8r_gls, xmlev, gls_conv, etc...). They can also be converted to/from .gls files using the gls_conv program.

The .ags files contain only standard ASCII text, and all lines are less than 80 characters long. The data fields within the files are strictly formatted, that is, unlike the .lvl files, the format of the fields is specified and use of any other format will generally make the file illegible by RadWare programs.

C source code that could be used to write and read the .ags files is given in listings towards the end of this file. The actual C code for the relevant parts of radware can be found in the src/libs/gls directory, in glsa.c. The data fields written to the .ags and .gls files are declared in gls.h, which is also listed here.

A version of this file for FORTRAN programmers can be found here.

Here is a table listing the ASCII character codes.

2. Format of the .ags files.

An example of a short .ags file is given below.

The first five lines of a .ags file are reserved for a header comment; their contents are simply echoed to the output terminal of the reading program.

The sixth line specifies the format version to allow for future extensions, and must be set to:

ASCII GLS file format version 1.0
Lines 7 through 12 specify fields such as the atomic number, numbers of levels, bands, gammas and text labels, default character sizes etc. Lines 7, 9 and 11 are simply comments that identify the fields contained in each of the following lines. In the C source code for radware, this section is written with
      fprintf(file,
              "**  Z Nlevels Ngammas  Nbands Nlabels CharSizeX CharSizeY ArrowWidFact\n"
              "%5i %7i %7i %7i %7i %9.2f %9.2f %9.2f\n"
              "**  MaxArrowTan MaxArrowDX DefBandWid DefBandSep ArrowWidth ArrowLength\n"
              "%15.6f %10.2f %10.2f %10.2f %10.2f %10.2f\n"
              "** ArrowBreak LevelBreak   LevCSX   LevCSY LevEnCSX LevEnCSY   GamCSX   GamCSY\n"
              "%12.2f %11.2f %8.2f %8.2f %8.2f %8.2f %8.2f %8.2f\n",
              glsgd.atomic_no, glsgd.nlevels, glsgd.ngammas, glsgd.nbands, glsgd.ntlabels,
              glsgd.csx, glsgd.csy, glsgd.aspect_ratio, glsgd.max_tangent, glsgd.max_dist,
              glsgd.default_width, glsgd.default_sep, glsgd.arrow_width, glsgd.arrow_length,
              glsgd.arrow_break, glsgd.level_break, glsgd.lsl_csx, glsgd.lsl_csy,
              glsgd.lel_csx, glsgd.lel_csy, glsgd.gel_csx, glsgd.gel_csy);
Lines 13 and 14 are comments to specify the data fields for each level. They are followed by one or two lines of data for each level in the scheme. These contain, for example, the energy, spin, parity, number of the band to which the level belongs, etc. Optional fields, to do with modified positions of spin-parity and level energy labels, and altered left/right ends of the level drawn with respect to the boundaries of the band, are given in the second line. This second line is to be present if and only if the first line ends in the characters ' &', placed immediately after the last data field, i.e. in characters 76 and 77. If this is not the case, default values are used for the optional data fields.

Three integer flags at the end of the first level data line deserve special mention. In the file, these are called LevelFlag, LabelFlag and EnLabFlag; in gls.h they are declared as:

  int   flg;          /* flag for tentative level */
  int   slflg;        /* flag for level spin label */
  int   elflg;        /* flag for level energy label */
in the typedef struct {} levdat structure declaration.

These flags define the appearance of the level and its spin-parity and energy labels, as follows:

   LevelFlag = 0 for normal level
               1 for broken (tentative) level
               2 for thick (e.g. isomeric) level
   LabelFlag = 0 for spin label =  Jpi
               1 for spin label = (J)pi
               2 for spin label = J(pi)
               3 for spin label = (Jpi)
               4 for spin label =   J
               5 for spin label =  (J)
               6 for no spin label
   EnLabelFlag = 0 for no energy label
                 1 for energy label as nearest integer  e.g.   123
                 2 for tentative nearest integer        e.g.  (123)
                 3 for one decimal place                e.g.  123.4
                 4 for tentative, one decimal place     e.g. (123.4)
Following the level data, there is a single comment line followed by a line of data for each band defined in the level scheme. The data for each band include the band name, position and width of the band in the drawing, and optional fields to do with level spin-parity/energy label positions.

Next come three comment lines, identifying the gamma-ray data fields. Each gamma then has one, two or three lines of data. The second and third lines are optional; as for the level data lines, the second line must be present if and only if the first line ends in ' &' (in characters 63 and 64), and the third line must be present if and only if the second line is present and ends in ' &' (in characters 72 and 73).

The first gamma data line contains the energy and relative intensity, multipolarity, and initial and final level index numbers.

The optional second gamma data line contains the Conversion coefficient, branching ratio and mixing ratio. If it is not present, default values are taken for the conversion coefficient (from Hager-Seltzer ICC tables) and the mixing ratio (zero). The branching ratio is ignored in RadWare programs, since it is generally taken directly from the intensities of the transitions. It is provided only for compatibility with other types of level scheme data files.

The optional third gamma data line contains position information for the gamma ray and its energy label, if they are not to be drawn at their default positions.

Two integer flags at the end of the third gamma data line deserve special mention. In the file, these are called GammaFlag and LabelFlag; in gls.h they are declared as:

  int   flg;          /* flag for tentative gammas */
  int   elflg;        /* flag for gamma energy lebels */
in the typedef struct {} gamdat structure declaration.

These flags define the appearance of the gamma and its energy label, as follows:

    GammaFlag = 0 for normal gamma
                1 for broken (tentative) gamma
    LabelFlag = 0 for label as nearest integer      e.g.   123
                1 for tentative nearest integer     e.g.  (123)
                2 for no label
                3 for one decimal place             e.g.  123.4
                4 for tentative, one decimal place  e.g. (123.4)
Last in the file are the data on any text labels used in the level scheme. After an initial two-line comment, there are two lines of data for each label, containing the text, number of characters, character sizes, and label position.


3. Sample .ags file.

Here is an example of a short .ags file.
The atomic number is 67 (Ho). It contains 18 levels in 4 bands, 36 gammas and 2 text labels.

** ASCII Graphical Level Scheme file.
** First five lines are reserved for comments.
** This file created 22-AUG-96 11:50:48  
** Program GLS,  author D.C. Radford
**
 ASCII GLS file format version 1.0
**  Z Nlevels Ngammas  Nbands Nlabels CharSizeX CharSizeY ArrowWidFact
   67      18      36       4       2     40.00     45.00      3.00
**  MaxArrowTan MaxArrowDX DefBandWid DefBandSep ArrowWidth ArrowLength
       0.267900     999.00     350.00     100.00      30.00      60.00
** ArrowBreak LevelBreak   LevCSX   LevCSY LevEnCSX LevEnCSY   GamCSX   GamCSY
       30.00       40.00    40.00    45.00    40.00    45.00    40.00    45.00
** Level   Energy +/- err     Jpi     K Band# LevelFlag LabelFlag EnLabFlag
++   LabelDX   LabelDY EnLabelDX EnLabelDY  LevelDX1  LevelDX2
     1      0.000   0.000    7/2-     0     1         0         0         0 &
++      0.00      0.00      0.00      0.00      0.00      0.00
     2    210.033   0.040   11/2-     0     1         0         0         0 &
++      0.00      0.00      0.00      0.00      0.00      0.00
     3    345.281   0.047   13/2-     0     2         0         0         0 &
++      0.00      0.00      0.00      0.00      0.00      0.00
     4    499.616   0.049   15/2-     0     1         0         0         0 &
++      0.00      0.00      0.00      0.00      0.00      0.00
     5    673.233   0.052   17/2-     0     2         0         0         0 &
++      0.00      0.00      0.00      0.00      0.00      0.00
     6    863.705   0.055   19/2-     0     1         0         0         0 &
++      0.00      0.00      0.00      0.00      0.00      0.00
     7     94.820   0.044    9/2-     0     2         0         0         0 &
++      0.00      0.00      0.00      0.00      0.00      0.00
     8   1072.905   0.058   21/2-     0     2         0         0         0 &
++      0.00      0.00      0.00      0.00      0.00      0.00
     9   1295.300   0.060   23/2-     0     1         0         0         0 &
++      0.00      0.00      0.00      0.00      0.00      0.00
    10   1786.367   0.067   27/2-     0     1         0         0         0 &
++      0.00      0.00      0.00      0.00      0.00      0.00
    11   1536.811   0.063   25/2-     0     2         0         0         0 &
++      0.00      0.00      0.00      0.00      0.00      0.00
    12   1136.881   0.337   17/2-     0     3         0         0         0 &
++      0.00      0.00      0.00      0.00      0.00      0.00
    13   1321.684   0.337   19/2-     0     4         0         0         0 &
++      0.00      0.00      0.00      0.00      0.00      0.00
    14   1523.316   0.337   21/2-     0     3         0         0         0 &
++      0.00      0.00      0.00      0.00      0.00      0.00
    15   1740.689   0.338   23/2-     0     4         0         0         0 &
++      0.00      0.00      0.00      0.00      0.00      0.00
    16    969.378   0.337   15/2-     0     4         0         0         0 &
++      0.00      0.00      0.00      0.00      0.00      0.00
    17    819.377   0.584   13/2-     0     3         0         0         0 &
++      0.00      0.00      0.00      0.00      0.00      0.00
    18    688.717   0.640   11/2-     0     4         0         0         0 &
++      0.00      0.00      0.00      0.00      0.00      0.00
** Band   Name        X0        NX   LabelDX   LabelDY EnLabelDX EnLabelDY
    1   ho165a  27916.40    450.00     72.92      0.00      0.00      0.00
    2   ho165b  28435.57    450.00    -71.66      0.00      0.00      0.00
    3   Ho165c  29432.87    350.00     39.95      0.00      0.00      0.00
    4   Ho165b  29832.90    350.00    -35.50      0.00      0.00      0.00
** Gamma   Energy +/- err  Mult  ILev  FLev  Intensity +/- err
++     ConvCoef +/- error      BrRatio +/- error     MixRatio +/- error
++   GammaX1  GammaX2  LabelDX  LabelDY GammaFlag LabelFlag
     1    209.996   0.034   E 2     2     1     4.0450  0.1492 &
++  0.20876E+00 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++      0.00  56282.80      0.00      0.00         0         0
     2    135.130   0.030   M 1     3     2    26.8236  0.8285 &
++  0.11301E+01 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++      0.00  56834.91      0.00      0.00         0         0
     3    154.294   0.030   M 1     4     3    28.6106  0.8686 &
++  0.77778E+00 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++      0.00  56774.15      0.00      0.00         0         0
     4    173.556   0.030   M 1     5     4    26.2193  0.7928 &
++  0.55987E+00 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++      0.00  56824.63      0.00      0.00         0         0
     5    190.425   0.030   M 1     6     5    22.3524  0.6751 &
++  0.43284E+00 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++      0.00  56783.83      0.00      0.00         0         0
     6    115.046   0.030   M 1     2     7    20.3988  0.7097 &
++  0.17879E+01 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++      0.00  56763.67      0.00      0.00         0         0
     7     94.634   0.030   M 1     7     1    20.0000  0.0100 &
++  0.31197E+01 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++      0.00  56845.74      0.00      0.00         0         0
     8    209.158   0.030   M 1     8     6    16.7276  0.5067 &
++  0.33412E+00 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++      0.00  56815.10      0.00      0.00         0         0
     9    222.365   0.030   M 1     9     8    12.7343  0.3858 &
++  0.28224E+00 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++      0.00  56792.38      0.00      0.00         0         0
    10    289.654   0.031   E 2     4     2    12.4140  0.3852 &
++  0.74864E-01 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++      0.00  56282.80      0.00      0.00         0         0
    11    364.139   0.030   E 2     6     4    16.1308  0.4902 &
++  0.37817E-01 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++      0.00  56282.80      0.00      0.00         0         0
    12    328.034   0.030   E 2     5     3    15.1664  0.4625 &
++  0.51333E-01 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++      0.00  57321.14      0.00      0.00         0         0
    13    250.452   0.031   E 2     3     7     9.3656  0.2972 &
++  0.11773E+00 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++      0.00  57321.14      0.00      0.00         0         0
    14    431.692   0.030   E 2     9     6    13.1524  0.3998 &
++  0.23493E-01 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++      0.00  56282.80      0.00      0.00         0         0
    15    399.775   0.030   E 2     8     5    14.8525  0.4512 &
++  0.29033E-01 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++      0.00  57321.14      0.00      0.00         0         0
    16    491.108   0.031   E 2    10     9     7.0650  0.2173 &
++  0.16640E-01 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++      0.00  56282.80      0.00      0.00         0         0
    17    463.970   0.031   E 2    11     8     9.8935  0.3020 &
++  0.19339E-01 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++      0.00  57321.14      0.00      0.00         0         0
    18    241.540   0.031   M 1    11     9     8.8071  0.2683 &
++  0.22506E+00 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++      0.00  56806.44      0.00      0.00         0         0
    19    249.386   0.032   M 1    10    11     5.1498  0.1600 &
++  0.20577E+00 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++      0.00  56799.66      0.00      0.00         0         0
    20    184.930   0.033   M 1    13    12     2.0907  0.0822 &
++  0.46903E+00 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++      0.00  59616.29      0.00      0.00         0         0
    21    201.531   0.034   M 1    14    13     1.9312  0.0746 &
++  0.36893E+00 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++      0.00  59615.77      0.00      0.00         0         0
    22    217.310   0.034   M 1    15    14     1.9424  0.0742 &
++  0.30012E+00 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++      0.00  59615.77      0.00      0.00         0         0
    23    386.379   0.039   E 2    14    12     1.5752  0.0724 &
++  0.31951E-01 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++      0.00  59215.74      0.00      0.00         0         0
    24    418.702   0.043   E 2    15    13     1.3541  0.0655 &
++  0.25469E-01 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++      0.00  60015.80      0.00      0.00         0         0
    25    352.525   0.043   E 2    13    16     1.2000  0.0552 &
++  0.41334E-01 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++      0.00  60015.80      0.00      0.00         0         0
    26    167.518   0.033   M 1    12    16     1.6000  0.0637 &
++  0.61698E+00 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++      0.00  59610.61      0.00      0.00         0         0
    27    317.059   0.049   E 2    12    17     0.6000  0.0303 &
++  0.56107E-01 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++      0.00  59215.74      0.00      0.00         0         0
    28    149.391   0.036   M 1    16    17     0.8000  0.0373 &
++  0.85138E+00 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++      0.00  59625.62      0.00      0.00         0         0
    29    280.294   0.123   E 2    16    18     0.1500  0.0172 &
++  0.82240E-01 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++      0.00  60015.80      0.00      0.00         0         0
    30    130.601   0.055   M 1    17    18     0.2100  0.0186 &
++  0.12653E+01 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++      0.00  59600.74      0.00      0.00         0         0
    31    759.235   0.049   E 2    16     2     1.0000  0.0590 &
++  0.58373E-02 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++  29335.57  29132.20      0.00      0.00         0         0
    32    724.915   0.046   E 2    17     7     1.0000  0.0786 &
++  0.64794E-02 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++  29610.32  29416.31      0.00      0.00         0         0
    33    791.657   0.053   E 2    12     3     0.8766  0.0522 &
++  0.53150E-02 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++  29241.61  29029.38      0.00      0.00         0         0
    34    689.002   0.066   E 2    18     1     0.3500161.3821 &
++  0.72799E-02 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++  30004.93  29820.61      0.00      0.00         0         0
    35    609.773   0.061   M 1    17     2     0.5500  0.0480 &
++  0.20021E-01 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++      0.00  58702.50      0.00      0.00         0         0
    36    594.500   1.000   M 1    18     7     0.1100  0.3084 &
++  0.21392E-01 0.000E+00  0.00000E+00 0.000E+00  0.00000E+00 0.000E+00 &
++      0.00  59506.70      0.00      0.00         0         0
** Label                                   text  NChars
++     SizeX     SizeY PositionX PositionY
    1  K=11/2 {gg}-vib                               15 &
++     60.00     65.00  29776.43   1956.54
    2  7/2{u-}[523]                                  12 &
++     60.00     65.00  28377.07   2021.91

End of .ags file example.

4. Listing of file gls.h

Here is the gls include file, gls.h, where the fields to be written to the .gls or .ags files are declared.

Note that not all variables declared in gls.h are written to the .ags file. Many are calculated based on defaults or other data.

A version of this file for FORTRAN programmers can be found here.


#define MAXLEV  1000    /* max number of levels in scheme */
#define MAXGAM  1500    /* max number of gammas in scheme */
#define MAXBAND 200     /* max number of bands in scheme */
#define MAXTXT  100     /* max number of text labels in scheme */
#define MAXEMIT 30      /* max number of gammas allowed from each level */
#define MAXFIT  500     /* max number of fitted free pars, must be even */

/* global data */
/* level definition ---------------------- */
typedef struct {      /* DO NOT CHANGE SIZE OR ORDER OF ELEMENTS! */
  float e, de;        /* level energy and energy uncertainty */
  float j, pi;        /* level spin and parity */
  float k;            /* K (projection of spin onto symmetry axis */
  int   band;         /* number of band to which level belongs */
  int   flg;          /* flag for tentative level */
  int   slflg;        /* flag for level spin label */
  int   elflg;        /* flag for level energy label */
  float dxl, dxr;     /* horizontal offsets for stretching/shrinking levels */
                      /* allows level to have different x-edges than those of its band */
  float sldx, sldy;   /* spin label offsets (from default position) in x, y */
  float eldx, eldy;   /* energy label offsets (from default position) in x, y */

  char  name[12];
  float x[4];         /* x-edges for drawing levels */
  char  sl[16];       /* level spin label */
  int   slnc;         /* no. of chars used in sl */
  float slx, sly;     /* level spin label position */
  char  el[16];       /* level energy label */
  int   elnc;         /* no. of chars used in el */
  float elx, ely;     /* level energy label position */
} levdat;

/* gamma definition ---------------------- */
typedef struct {      /* DO NOT CHANGE SIZE OR ORDER OF ELEMENTS! */
  int   li, lf;       /* id numbers of initial, final levels for this gamma */
  char  em;           /* E or M part of multipolarity (Electric/Magnetic) */
  float e, de;        /* gamma energy and energy uncertainty */
  float i, di;        /* gamma intensity and intensity uncertainty */
  float br;           /* branching ratio (not used yet) */
  float a;            /* conversion coefficient */
  float d;            /* mixing ratio */
  float da;           /* conversion coefficient uncertainty */
  float dd;           /* mixing ratio uncertainty */
  float dbr;          /* branching ratio uncertainty (not used yet) */
  float n;            /* lamba = numeric part of multipolarity */
  float x1, x2;       /* x-position of top and bottom of gamma in figure */
  int   flg;          /* flag for tentative gammas */
  int   elflg;        /* flag for gamma energy lebels */
  float eldx, eldy;   /* energy label offsets (from default position) in x, y */

  float x[10], y[10]; /* x, y points for drawing gammas */
  int   np;           /* number of x, y points to use for drawing this gamma */
  char  el[16];       /* gamma energy label */
  int   elnc;         /* no. of chars used in el */
  float elx, ely;     /* gamma energy label position */
} gamdat;

/* band definition ----------------------- */
typedef struct {      /* DO NOT CHANGE SIZE OR ORDER OF ELEMENTS! */
  char  name[8];      /* band name */
  float x0, nx;       /* position and length in x */
  float sldx, sldy;   /* spin label offsets (from default position) in x, y */
  float eldx, eldy;   /* energy label offsets (from default position) in x, y */
  int   sl_onleft;
} bnddat;

/* text label  definition ---------------- */
typedef struct {      /* DO NOT CHANGE SIZE OR ORDER OF ELEMENTS! */
  char  l[40];        /* general-purpose text label */
  int   nc;           /* no. of chars */
  float csx, csy;     /* character size (width, height) in keV units */
  float x, y;         /* label position */
} txtdat;

struct {
  levdat lev[MAXLEV];
  gamdat gam[MAXGAM];
  bnddat bnd[MAXBAND+2];
  txtdat txt[MAXTXT];
  char  gls_file_name[80];
  int   atomic_no, nlevels, ngammas, nbands, ntlabels;
  float csx, csy;                    /* general default character sizes */
  float aspect_ratio, max_tangent, max_dist;   /* parameters for drawing gammas */
  float default_width, default_sep;  /* band width and distance between bands */
  float arrow_width, arrow_length;   /* shape of gamma arrowheads */
  float arrow_break, level_break;    /* break distance in kev for tentative gammas, levels */
  /* character sizes for level spin labels, level energy labels, gamma energy labels: */
  float lsl_csx, lsl_csy, lel_csx, lel_csy, gel_csx, gel_csy;
  float x0,  hix,  y0,  hiy;
  float tx0, thix, ty0, thiy;
  float x00, dx,   y00, dy;
} glsgd;

struct {
  int n[MAXLEV];
  int l[MAXLEV][MAXEMIT];
} levemit;

#define MAXSAVESIZE 4096000
struct {
  int  lastmode, filepos, lastpos, eof;
  FILE *file;
} glsundo;

/* ==== routines defined in gls.a ==== */
int add_gamma(void);
int add_gls(void);
/* MORE DECLARATIONS REMOVED FOR BREVITY */
int undo_gls(int step);

********* End of gls.h listing

5. Subroutines to read and write .ags files.

Here are listings of two subroutines from the gls programs, to read and write the ASCII gls (.ags) files.
The two subroutines listed here are read_ascii_gls and part of read_write_gls, taken from src/libs/gls/glsa.c. The code segments deleted for the sake of brevity from this listing of read_write_gls concern reading and writing the binary .gls files.

A version of this file for FORTRAN programmers can be found here.


/* ======================================================================= */
int read_ascii_gls(FILE *file)
{
  int  j, j1;
  char eol, jpi[16], kay[16], line[120], lamda;

  /* read comments (first five lines of file)  */
  printf("Level Scheme File header:\n");
  for (j = 0; j < 5; ++j) {
    fgets(line, 120, file);
    printf("%s", line);
  }
  fgets(line, 120, file);
  if (strncmp(line, " ASCII GLS file format version 1.0", 34)) goto ERR;
  fgets(line, 120, file);
  fgets(line, 120, file);
  /* read data */
  if (sscanf(line, "%i%i%i%i%i%f%f%f",
             &glsgd.atomic_no,
             &glsgd.nlevels, &glsgd.ngammas, &glsgd.nbands, &glsgd.ntlabels,
             &glsgd.csx, &glsgd.csy, &glsgd.aspect_ratio) != 8) goto ERR;
  fgets(line, 120, file);
  fgets(line, 120, file);
  if (sscanf(line, "%f%f%f%f%f%f",
             &glsgd.max_tangent, &glsgd.max_dist,
             &glsgd.default_width, &glsgd.default_sep,
             &glsgd.arrow_width, &glsgd.arrow_length) != 6) goto ERR;
  fgets(line, 120, file);
  fgets(line, 120, file);
  if (sscanf(line, "%f%f%f%f%f%f%f%f",
             &glsgd.arrow_break, &glsgd.level_break,
             &glsgd.lsl_csx, &glsgd.lsl_csy,
             &glsgd.lel_csx, &glsgd.lel_csy,
             &glsgd.gel_csx, &glsgd.gel_csy) != 8) goto ERR;
  fgets(line, 120, file);
  fgets(line, 120, file);
  for (j = 0; j < glsgd.nlevels; ++j) {
    fgets(line, 120, file);
    if (sscanf(line, "%*6c%f%f%8c%6c%i%i%i%i %c",
               &glsgd.lev[j].e, &glsgd.lev[j].de, jpi, kay,
               &glsgd.lev[j].band, &glsgd.lev[j].flg,
               &glsgd.lev[j].slflg, &glsgd.lev[j].elflg, &eol) != 9) goto ERR;
    glsgd.lev[j].band--;
    if (eol == '&') {
      fgets(line, 120, file);
      if (sscanf(line, "%*2c%f%f%f%f%f%f",
                 &glsgd.lev[j].sldx, &glsgd.lev[j].sldy,
                 &glsgd.lev[j].eldx, &glsgd.lev[j].eldy,
                 &glsgd.lev[j].dxl, &glsgd.lev[j].dxr) != 6) goto ERR;
    } else {
      glsgd.lev[j].sldx = glsgd.lev[j].sldy = 0.f;
      glsgd.lev[j].eldx = glsgd.lev[j].eldy = 0.f;
      glsgd.lev[j].dxl  = glsgd.lev[j].dxr  = 0.f;
    }
    sscanf(jpi, "%i", &j1);
    if (!strncmp(jpi + 5, "/2", 2)) {
      glsgd.lev[j].j = (float) j1 / 2.f;
    } else {
      glsgd.lev[j].j = (float) j1;
    }
    if (jpi[7] == '-') glsgd.lev[j].pi = -1.f;
    else               glsgd.lev[j].pi = 1.f;
    sscanf(kay, "%i", &j1);
    if (!strncmp(kay + 4, "/2", 2)) {
      glsgd.lev[j].k = (float) j1 / 2.f;
    } else {
      glsgd.lev[j].k = (float) j1;
    }
  }
  fgets(line, 120, file);
  for (j = 0; j < glsgd.nbands; ++j) {
    fgets(line, 120, file);
    if (sscanf(line, "%*6c%8c%f%f%f%f%f%f",
               glsgd.bnd[j].name, &glsgd.bnd[j].x0, &glsgd.bnd[j].nx,
               &glsgd.bnd[j].sldx, &glsgd.bnd[j].sldy,
               &glsgd.bnd[j].eldx, &glsgd.bnd[j].eldy) != 7) goto ERR;
  }
  fgets(line, 120, file);
  fgets(line, 120, file);
  fgets(line, 120, file);
  for (j = 0; j < glsgd.ngammas; ++j) {
    fgets(line, 120, file);
    eol = '&';
    glsgd.gam[j].i = glsgd.gam[j].di = 0.0f;
    if (sscanf(line, "%*6c%f%f%*3c%c%*c%c%i%i%f%f %c",
	       &glsgd.gam[j].e, &glsgd.gam[j].de, &glsgd.gam[j].em, &lamda,
	       &glsgd.gam[j].li, &glsgd.gam[j].lf,
	       &glsgd.gam[j].i, &glsgd.gam[j].di, &eol) < 6) goto ERR;
    if (lamda == ' ') lamda = '0';
    glsgd.gam[j].n = (float) (lamda - '0');
    glsgd.gam[j].li--;
    glsgd.gam[j].lf--;
    if (eol == '&') {
      fgets(line, 120, file);
      if (sscanf(line, "%*2c%f%f%f%f%f%f %c",
                 &glsgd.gam[j].a, &glsgd.gam[j].da,
                 &glsgd.gam[j].br, &glsgd.gam[j].dbr,
                 &glsgd.gam[j].d, &glsgd.gam[j].dd, &eol) != 7) goto ERR;
    } else {
      glsgd.gam[j].a  = glsgd.gam[j].da  = 0.0f;
      glsgd.gam[j].br = glsgd.gam[j].dbr = 0.0f;
      glsgd.gam[j].d  = glsgd.gam[j].dd  = 0.0f;
      calc_alpha(j);
    }
    if (eol == '&') {
      fgets(line, 120, file);
      if (sscanf(line, "%*2c%f%f%f%f%i%i",
                 &glsgd.gam[j].x1, &glsgd.gam[j].x2,
                 &glsgd.gam[j].eldx, &glsgd.gam[j].eldy,
                 &glsgd.gam[j].flg, &glsgd.gam[j].elflg) != 6) goto ERR;
    } else {
      glsgd.gam[j].x1 = glsgd.gam[j].x2 = 0.f;
      glsgd.gam[j].eldx = glsgd.gam[j].eldy = 0.f;
      glsgd.gam[j].flg = glsgd.gam[j].elflg = 0;
    }
  }
  if (glsgd.ntlabels > 0) {
  fgets(line, 120, file);
  fgets(line, 120, file);
    for (j = 0; j < glsgd.ntlabels; ++j) {
      fgets(line, 120, file);
      if (sscanf(line, "%*7c%40c%i",
                glsgd.txt[j].l, &glsgd.txt[j].nc) != 2) goto ERR;
      fgets(line, 120, file);
      if (sscanf(line, "%*2c%f%f%f%f",
                 &glsgd.txt[j].csx, &glsgd.txt[j].csy,
                 &glsgd.txt[j].x, &glsgd.txt[j].y) != 4) goto ERR;
    }
  }
  fclose(file);
  return 0;

 ERR:
  printf("ERROR - cannot read ASCII gls file.\n");
  return 0;
} /* read_ascii_gls */

/* ======================================================================= */
int read_write_gls(char *command)
{
  int   i2, jext, j, j1, j2, rlen, rl = 0;
#define BUFSIZE (24*MAXLEV + 61*MAXGAM + 16*MAXBAND + 60*MAXTXT)
  char  buf[BUFSIZE];
  char  filnam[80], dattim[20], jpi[8], kay[8], q[512], ext[8];
  FILE  *file;

  file = NULL;
  if (!strcmp(command, "WRITE") ||
      !strcmp(command, "WRITE_AGS")) {

    /* ask for and open level scheme file */
    if (!strcmp(command, "WRITE_AGS")) strcpy(ext, ".ags");
    else strcpy(ext, ".gls");

    if (*glsgd.gls_file_name != ' ' &&
	*glsgd.gls_file_name != '\0') {
      jext = setext(glsgd.gls_file_name, ext, 80);
      strcpy(glsgd.gls_file_name + jext, ext);
      sprintf(q, "Name for new GLS level scheme file = ?\n"
	         "   (Type q to quit without saving,\n"
                 "    default .ext = %s, rtn for %s)", ext, glsgd.gls_file_name);
      if (!cask(q, filnam, 80)) strcpy(filnam, glsgd.gls_file_name);
    } else {
      sprintf(q, "Name for new GLS level scheme file = ?\n"
	         "   (Type q to quit without saving,\n"
                 "               default .ext = %s)", ext);
      while (!cask(q, filnam, 80));
    }
    if (!strcmp(filnam, "Q") || !strcmp(filnam, "q")) return 0;

    jext = setext(filnam, ext, 80);
    if (!strcmp(command, "WRITE_AGS") ||
	!strcmp(filnam + jext, ".AGS") ||
	!strcmp(filnam + jext, ".ags")) {
      /* write out ascii version of gls file (.ags file). */
      file = open_pr_file(filnam);
      datetime(dattim);
      fprintf(file,
              "** ASCII Graphical Level Scheme file.\n"
              "** First five lines are reserved for comments.\n"
              "** This file created %.18s\n"
              "** Program GLS,  author D.C. Radford\n"
              "**\n"
              " ASCII GLS file format version 1.0\n", dattim);
      fprintf(file,
              "**  Z Nlevels Ngammas  Nbands Nlabels CharSizeX CharSizeY ArrowWidFact\n"
              "%5i %7i %7i %7i %7i %9.2f %9.2f %9.2f\n"
              "**  MaxArrowTan MaxArrowDX DefBandWid DefBandSep ArrowWidth ArrowLength\n"
              "%15.6f %10.2f %10.2f %10.2f %10.2f %10.2f\n"
              "** ArrowBreak LevelBreak   LevCSX   LevCSY LevEnCSX LevEnCSY   GamCSX   GamCSY\n"
              "%12.2f %11.2f %8.2f %8.2f %8.2f %8.2f %8.2f %8.2f\n"
              "** Level   Energy +/- err     Jpi     K Band# LevelFlag LabelFlag EnLabFlag\n"
              "++   LabelDX   LabelDY EnLabelDX EnLabelDY  LevelDX1  LevelDX2\n",
              glsgd.atomic_no, glsgd.nlevels, glsgd.ngammas, glsgd.nbands, glsgd.ntlabels,
              glsgd.csx, glsgd.csy, glsgd.aspect_ratio, glsgd.max_tangent, glsgd.max_dist,
              glsgd.default_width, glsgd.default_sep, glsgd.arrow_width, glsgd.arrow_length,
              glsgd.arrow_break, glsgd.level_break, glsgd.lsl_csx, glsgd.lsl_csy,
              glsgd.lel_csx, glsgd.lel_csy, glsgd.gel_csx, glsgd.gel_csy);
      for (j = 0; j < glsgd.nlevels; ++j) {
	j2 = (int)(glsgd.lev[j].j * 2.f + 0.5f);
	if (glsgd.lev[j].j < 0.0f) j2 = (int)(glsgd.lev[j].j * 2.f - 0.5f);
	j1 = j2 / 2;
	if (j2 == j1 << 1) {
	  sprintf(jpi, "%7i", j1);
	} else {
	  sprintf(jpi, "%5i/2", j2);
	}
	if (glsgd.lev[j].pi < 0.f) {
	  jpi[7] = '-';
	} else {
	  jpi[7] = '+';
	}
	j2 = (int)(glsgd.lev[j].k * 2.f + 0.5f);
	j1 = j2 / 2;
	if (j2 == j1 << 1) {
	  sprintf(kay, "%6i", j1);
	} else {
	  sprintf(kay, "%4i/2", j2);
	}
      fprintf(file,
              "%6i %10.3f %7.3f%.8s%.6s %5i %9i %9i %9i &\n"
              "++ %9.2f %9.2f %9.2f %9.2f %9.2f %9.2f\n",
              j+1, glsgd.lev[j].e, glsgd.lev[j].de, jpi, kay, glsgd.lev[j].band+1,
              glsgd.lev[j].flg, glsgd.lev[j].slflg, glsgd.lev[j].elflg,
              glsgd.lev[j].sldx, glsgd.lev[j].sldy, glsgd.lev[j].eldx, glsgd.lev[j].eldy,
              glsgd.lev[j].dxl, glsgd.lev[j].dxr);
      }
      fprintf(file,
              "** Band   Name        X0        NX   LabelDX   LabelDY EnLabelDX EnLabelDY\n");
      for (j = 0; j < glsgd.nbands; ++j) {
        fprintf(file,
                "%5i %.8s %9.2f %9.2f %9.2f %9.2f %9.2f %9.2f\n",
                j+1, glsgd.bnd[j].name, glsgd.bnd[j].x0, glsgd.bnd[j].nx,
                glsgd.bnd[j].sldx, glsgd.bnd[j].sldy, glsgd.bnd[j].eldx, glsgd.bnd[j].eldy);
      }
      fprintf(file,
              "** Gamma   Energy +/- err  Mult  ILev  FLev  Intensity +/- err\n"
              "++     ConvCoef +/- error      BrRatio +/- error     MixRatio +/- error\n"
              "++   GammaX1  GammaX2  LabelDX  LabelDY GammaFlag LabelFlag\n");
      for (j = 0; j < glsgd.ngammas; ++j) {
	i2 = (int) (glsgd.gam[j].n + 0.5f);
        fprintf(file,
                "%6i %10.3f %7.3f   %c%2i %5i %5i %10.4f %7.4f &\n"
                "++ %12.5E %9.3E %12.5E %9.3E %12.5E %9.3E &\n"
                "++ %9.2f %9.2f %9.2f %9.2f %9i %9i\n",
                j+1, glsgd.gam[j].e, glsgd.gam[j].de, glsgd.gam[j].em, i2,
                glsgd.gam[j].li+1, glsgd.gam[j].lf+1, glsgd.gam[j].i, glsgd.gam[j].di,
                glsgd.gam[j].a, glsgd.gam[j].da, glsgd.gam[j].br, glsgd.gam[j].dbr,
                glsgd.gam[j].d, glsgd.gam[j].dd, glsgd.gam[j].x1, glsgd.gam[j].x2,
                glsgd.gam[j].eldx, glsgd.gam[j].eldy, glsgd.gam[j].flg, glsgd.gam[j].elflg);
      }
      fprintf(file,
              "** Label                                   text  NChars\n"
              "++     SizeX     SizeY PositionX PositionY\n");
      for (j = 0; j < glsgd.ntlabels; ++j) {
        fprintf(file,
                "%5i  %-40.40s %7i &\n"
                "++ %9.2f %9.2f %9.2f %9.2f\n",
                j+1, glsgd.txt[j].l, glsgd.txt[j].nc,
                glsgd.txt[j].csx, glsgd.txt[j].csy, glsgd.txt[j].x, glsgd.txt[j].y);
      }
    } else {
      /* write out standard unformatted version of gls file. */
      /* CODE DELETED FOR BREVITY */
    }
    strcpy(glsgd.gls_file_name, filnam);

  } else if (!strcmp(command, "OPEN_READ")||
	     !strcmp(command, "READ")) {
    if (!strcmp(command, "OPEN_READ")) {
      /* ask for and open level scheme file */
      while (!file) {
	if (!cask("Name of GLS level scheme file = ?\n"
		  " (default .ext = .gls, rtn to abort)", filnam, 80))
	  return 1;
	jext = setext(filnam, ".gls", 80);
	file = open_readonly(filnam);
      }
      strcpy(glsgd.gls_file_name, filnam);
    } else {
      /* open open level scheme file; name in glsgd.gls_file_name */
      jext = setext(glsgd.gls_file_name, ".gls", 80);
      if (!(file = open_readonly(glsgd.gls_file_name))) return 1;
    }
    if (!strcmp(glsgd.gls_file_name + jext, ".AGS") ||
	!strcmp(glsgd.gls_file_name + jext, ".ags")) {
      read_ascii_gls(file);
      return 0;
    }
    /* FURTHER CODE DELETED FOR BREVITY */
  }
  fclose(file);
  return 0;
} /* read_write_gls */

********* End of GLS read/write subroutines