In the first installment of this thrilling saga, I talked about how to name your AIPS scripts and load them into AIPS. Now, we're going to get into the nitty gritty details of how to write your own AIPS scripts.
 
In AIPS scripts, you have access to all the usual AIPS commands and tasks like listr,  calib, and imagr. You also have access to some basic programming tools. To see exactly what you have in your toolbox, type help popsym (POPS is the name of the AIPS scripting language). I've replicated the contents of the popsym help files below for your enjoyment:
Help on POPSYM in AIPS version 31DEC04
POPSYM
Type:  Symbols used in the POPS interpretive language
 
    VERB      USE        COMMENTS
 
                   ----Arithmetic expressions
 
     +       A + B       Add the expression A to B
     -       A - B       Subtract the expression B from A
     *       A * B       Multiply the expression A with B
     /       A / B       Divide the expression A by B
     **      A ** B      Calculate A to the power B
     ( )     (A+B)*C     Grouping expressions as desired
     =       A = B       Store the value of B into A
     ,       A = 3,5,4   Separator of elements in an array
     ~       A(i) ~ 1,2,3  Store values in A(i),A(i+1)...
                         (change only as many as on RHS)
     :       TO          Equivalent to the verb TO
     ;                   Separator between AIPS statements
 
                   ----Logical expressions
 
     >       A > B       A greater than B
     <       A < B       A less than B
     =       A = B       A equal B (numeric or string)
     >=      A >= B      A equal to or greater than B
     <=      A <= B      A equal to or less than B
     <>      A <> B      A not equal to B (numeric or string)
     !       A ! B       A or B
     &       A & B       A and B
     ^       ^ A         not A
 
                   ----String expressions
 
  !!       A !! B        string = string A followed by string B
  SUBSTR   SUBSTR(A,i,j) string = chars i through j of string A
  LENGTH   LENGTH(A)     position last non-blank in A
  CHAR     CHAR(A)       convert number A to string
  VALUE    VALUE(A)      convert string A to number
 
 
                   ----Looping constructions
 
  (FOR-TO-BY-END)        FOR I=1 TO 7 BY 2
                         
                         END
 
  (WHILE-END)            WHILE 
                         
                         END
 
  (IF-THEN-ELSE-END)     IF 
                         THEN 
                         ELSE 
                         END
 
                   ----Built-in functions
 
  ATAN          Arctangent (one argument)
  ATAN2         Arctangent (two arguments)
  COS           Cosine (degrees)
  SIN           Sine (degrees)
  TAN           Tangent (degrees)
  EXP           Exponential
  LN            Log base e
  LOG           Log base 10
  SQRT          Square-root
  MAX           Maximum i.e. X = MAX (A, B)
  MIN           Minimum i.e. X = MIN (A, B)
  MODULUS       Root-square sum of two arguments
  MOD(A,B)      A - (A/B) * B  i.e. remainder of A/B
  CEIL(A)       Lowest integer >= A
  FLOOR(A)      Highest integer <= A
 
                   ----Procedure building verbs
 
  PROC      PV  Begin building a procedure
  PROCEDUR  PV  Begin building a procedure
  LIST      pV  List a procedure
  EDIT      PV  Edit a procedure
  ENDEDIT   PV  End editing a procedure
  ERASE     PV  Delete line(s) of a procedure
  MODIFY    PV  Modify a line in a procedure
  RETURN    V   Last statement in a procedure
  FINISH    PV  End procedure building
 
                   ----Variable declarations
 
  SCALAR    pV  Declare scalars
  ARRAY     pV  Declare arrays
  STRING    pV  Declare strings
 
                   ----Input/Output functions
 
  PRINT     V   Print the following keyword value(s)
  TYPE      V   Print the following keyword value(s)
  READ      V   Read value(s) from terminal after # prompt
 
                   ----Other information
 
  CORE      pV  Amount of core left in POPS
  COMPRESS  PV  Compress the core area, recovering lost space
                and acquiring any new vocabulary
  CLRTEMP   V   Clear the temp data array
  DEBUG     pV  Debug: turns on compiler debug information
  DUMP      V   Dump K array on terminal screen
  SCRATCH   PV  Remove procedures in POPS
  $         PV  Makes rest of input line a comment
As you can see, you have most of the basic programming tools like if/then statements, for loops, mathematical functions, and comparison operators. The only non-useful bits are in the "Procedure building verbs" section. Some of the verbs in this section (list, edit, endedit, erase, and modify) are left-over from the bad old days and were used for writing procedures using AIPS built-in line editor. Trust me, you don't want to use this editor. Just write your scripts outside AIPS in your favorite text editor and load them into AIPS. 
Now that you know what tools you have to work with, let's move on to how AIPS scripts are actually structured. In general, an AIPS script has two parts. The first part declares all the variables one is going to use in a script, while the second part is the actual script itself. Note that you can have more than one script (declaration plus code) inside the file you created in part 1. The convention is to group scripts that work together in one file. For example, my custom calibration routines contain a declaration section, a calibration script, and a script to nuke the current calibration.  Start each section with proc scriptname, substituting the name of your script for scriptname and end each section with return; finish. 
Looking at the pops language commands, you only three options for variables. (No advanced data structures for you!) Scalars are just numbers, while strings are just letters. Arrays can either be a collection of numbers or letters. To declare a scalar, you just say scalar anumber. Strings need to have their length declared (just like Fortran): string*8 aname. This creates an eight character string. Now declaring an array is slightly tricky. First, you decide what sort of array you want, then you append a number telling AIPS how big to make the array. To create an array of 15 strings, you say string*8 obj_name(15). Variable names are limited to about nine characters, so choose them wisely!
Now to remember what you were thinking when you wrote a script originally you can put an asterisk (*) at the beginning of any line to indicate that the entire line is a comment. You can also put a dollar sign ($) anywhere in a line to indicate that the rest of the line is a comment.
Note that AIPS does NOT pay attention to the first line of a script file, so always start your files with a comment (put a * on the first line).  In addition, AIPS gets cranky if you have any tab characters in your script. (This may just be an issue relating to how my editor of choice, emacs, stores files.) If everything looks fine in your script and AIPS still won't read it in, look for tabs. Usually if you move the cursors over the line of code with your arrow keys you can see where the tabs are because the arrow keys move the cursor more than one space.
Well, that's enough for now. Next time, I'll go through a simple example demonstrating everything I talked about in this entry.
Monday, April 23, 2007
Teaching the Monkey to Dance: Scripting AIPS #2
Subscribe to:
Post Comments (Atom)
If you have a question about AIPS that CANNOT be answered by reading the 
6 comments:
Thanks Amanda! Very handy tips. :)
Anybody know how to do nested procedures in AIPS? It is suggested in the AIPS helpfile for RETURN. Example of desired usage (quasi-pseudocode):
proc test1
scalar z
z=1
CALL test2
z=2
CALL test2
return
proc test2
type z
return
Scratch that. I figured it out. You just have to be careful in your order of procedure declaration in the runfile. For example, test2 should have been declared before test1 in my previous post. This would work:
proc test1
scalar z
type z
return; finish
proc test2
scalar z
z=1
test1
z=2
test1
return; finish
This scripting stuff is very useful, but I can't find scripting AIPS #3 and etc. Is it out there?
I have lots of files to input, run sdgrid on, then write out. I have no idea how I could go about making sure stuff gets in the right slot to work for any given task.
Thanks,
-Bruce
I had a question for you guys:
I was writing a script to run imstat on several hundred images, matching the central RA value in the images (from the header) to a value in an array I defined elsewhere. This required me to round the header RA to 3 decimals by the following:
FLOOR(HEADERRA*1000)/1000
So for a number (say 321.504335) i should get 321.504. However I noticed that AIPS stores this value as 321.5039978. This, for obvious reasons, is causing problems.
Is there any way get AIPS to store this value correctly?
Hi Anonymous,
This looks like a potential bug in AIPS (or in your installation). You should probably contact the AIPS help desk using my.nrao.edu.
Amanda
Post a Comment