GOOSY legacies
| GSI | Biophysics | SATAN long write-up |

GOOSY legacies

This section describes how to move from the VMS GOOSY environment to SATAN on UNIX. Since SATAN is prepared to read GOOSY data, only analysis programs have to be adapted.

Recycling old analysis programs

Unfortunately there's no way to reuse old analysis programs directly without modifications. The main reason is that GOOSY uses PL/I as base language, whereas SATAN on UNIX uses C. You will rarely find PL/I compilers on UNIX computers, although there's an IBM product for AIX, but probably not for other UNIXes. As far as the author's knowledge is concerned, there is no PL/I->C converter software available (please leave me a note if I'm wrong). So you have to do the hard work by hand. The following table gives the correspondence of some often used PL/I and C constructs.
PL/I                                              C

DCL ( i_e(4), I_PosXL(3) ) BIN FIXED(15);         short i_e[4], I_PosXL[3];
DCL (ENERGY init(0E0), Q_CAL(3)) BIN FLOAT(24);   float ENERGY=0E0, Q_CAL[3]; 
DCL ( ABS, SQRT, CHAR ) BUILTIN:                  #include <math.h>
                                                  (in program header)
DCL (i,j,k,l,m) BIN FIXED(31);                    long i,j,k,l,m;

DCL (B_Pos_X(3)) BIT(1) ALIGNED;                  int B_POS_X[3]; 
B_Pos_X(i) = '0'B;                                B_Pos_X[i-1] = 0;

DO i = 1 TO 3;                                    for( i=1; i<=3; i++ ) { 
...                                               ...
END;                                              }

IF I_Posxl ^= 0 THEN ...;                         if ( I_posxl != 0 ) ...; 

IF II ^= 0 & JJ < 4090 THEN DO;                   if ( (II!=0) && (JJ<4090) ) { 
...                                               ...   
END;                                              } 

FLOOR(xx);                                        floor(xx); 
FLOAT(ii,24)                                      (float) ii

DCL 1 PATTERN_WORD UNION,                         
      2 PATTERN_BIT(32) BIT(1), 
      2 B_PATTERN BIT(32),
      2 I_PATTERN BIN FIXED(31);                  unsigned long I_PATTERN;
IF ( PATTERN_BIT(I) ) ...                         if ( I_PATTERN & (1L<<(I-1)) ) ...

                                                  #define PI M_PI                                         
                                                  #define SIND(phi) sin((phi)*PI/180E0)
                                                  #define COSD(phi) cos((phi)*PI/180E0) 
SIND(phi)                                         SIND(phi)
COSD(phi)                                         COSD(phi)

Note that, except macros , C must be coded in lower case characters and variable names are case sensitive, that is i_Energy and I_ENERGY are different variables. You might use a case-insensitive text editor (e.g.nedit) to change variables to common spelling.

The most nasty difference, however, is the different handling of arrays, which in C always start with index '0'. Either you diminish all array indices by 1, or you declare the C array with an additional element:

PL/I                                        C

DCL Array(3) DEC FLOAT(16);                 double Array[3];
Array(1) = ...;                             Array[0] = ...;
Array(2) = ...;                             Array[1] = ...;
Array(3) = ...;                             Array[2] = ...; 

DCL Array(3) DEC FLOAT(16);                 double Array[4];
Array(1) = ...;                             Array[1] = ...;
Array(2) = ...;                             Array[2] = ...;
Array(3) = ...;                             Array[3] = ...; 

The second method may be preferred if you have full control over the array length, you must use the first one if the array is 'inherited' from some other program. Arrays of analyzers and global parameters are corrected for automatically.

Access to GOOSY internal information

Naturally the GOOSY innards are very much different from that of SATAN on UNIX. For instance, there's no such thing as a database, spectra are kept in memory, and, unless they are dumped to the data element library, are lost on exit of session. Likewise, global parameters are defined during a session only, but may be kept on external text files and can be changed interactively via commands.
Another difference is that conditions in SATAN are always linked to an analyzer, that is, they are checked automatically whenever an analyzer is addressed with the $ANAL() macro, the result can be accessed with the $AC() macro.
When such internal information is to be accessed by an analysis program, the access methods have to be changed too. Here are some GOOSY analysis constructs and their SATAN counterparts. There's no 1:1 relationship, only functionally equivalent code sections.
GOOSY                                                       SATAN on UNIX


global parameters with e.g.
PAR.R.Q_CAL(3)                                              $PARDCL( Q_CAL(3) ) TYPE(3); 
... = PAR.R.Q_CAL(I);                                       ... = $GLOPAR( Q_CAL(i) )); 
                                                            struct SIOGOOSYEVT10 *psE10;
                                                            struct SIOGOOSYEVT101SUB *psE101S;
                                                            struct SIOGOOSYEVT101DATA *psE101D;
@ON_ANY_W(U_CLEANUP);                                       $ANTRY; 
STS$VALUE=1;                                                $EVENT(p(8192));
P_SA$VE10_1=P_EVENT;                                        psE10 = (struct SIOGOOSYEVT10 *) p_pars;
P_SA$VES10_1=ADDR(IA$VE10_1(1));                            psE101S = (struct SIOGOOSYEVT101SUB *) (psE10+1);
                                                            psE101D = (struct SIOGOOSYEVT101DATA *) (psE101S+1);

                                                            $AGEN( ADC_E(8) ) NCND(1) LIMITS(1,4096); 
DCL (ADC_E(8)) BIN FIXED(15);                               short iADCE[8];
do I=1 to 8;                                                for( ii=0; ii<8; ii++ ) {                                    
   ADC_E(I) = IA$VES10_1(i*2);                                 iADCE[ii] = psE101D[ii].iValue; 
   $accu1(L,DB,$SPECTRUM,ADC,I,1,1,ADC_E(I));                  $ANAL( ADC_E(ii+1), iADCE[ii] ); 
end;                                                        }  

U$RANDOM(1.0)                                               _prn()

$accu(L,DB,$SPECTRUM,qsum_e,L_INCR,1,SUM_E/3);              $ANAL( QSUM_E, iSumE/3 )  incr(L_INCR);                       
if B_SUM_E then ...                                         if ( $AC( QSUM_E, 1 ) ) ...                                        

@RET(STS$value);                                            $ENDEVT;

$XANAL:ENTRY RETURNS(BIN FIXED(31));                        N/A, corresponds to initialization section
@INCLUDE $MACRO($SECDEF);                                   of analysis program    

A complete real-world example of an GOOSY analysis program is available, with the original PL/I version and the SATAN version.

| GSI | Biophysics | SATAN long write-up |

Valid HTML 3.2!

Last updated:, 3-Aug-1999