NAME MAC - NMRPipe Macro Interpreter SYNOPSIS nmrPipe -fn MAC -macro macFile] [-var vList] [-str sList] [-all] M [macFileList] [-var vList] [-str sList] [-quit] SPECIAL NOTE The nmrPipe MAC function, and the corresponding macro language M are both under active development. Their features may change substantially, and macros created for the current versions may not always be forward-compatible. This manual page is also still under development. DESCRIPTION MAC is a macro interpreter which executes the contents of the given macro file once for each 1D vector in the data stream. It is used to create custom processing functions and data shuffling schemes. The macro language, which is called M, is based on a subset of the C programming language, augmented by a collection of vector processing functions. In addition to use as a processing function of nmrPipe, the macro language R". also be used interactively via the stand-alone program "M When a macro is invoked via the nmrPipe MAC function, the arrays rdata[] and idata[] will contain the real and ima- ginary parts of the current 1D vector. After the macro is executed, the contents of arrays rdata[] and idata[] will be written to the output stream automatically by nmrPipe. The macro language allows data to be manipulated directly on a point-by-point basis, or by use of vector functions. For example, this 6-line macro would swap the reals and ima- ginaries on a point-by-point basis: for( i = 0; i < size; i++ ) { temp = rdata[i]; rdata[i] = idata[i]; idata[i] = temp; } whereas this one-line macro would perform the same task more quickly using a built-in vector function: (void) vvSwap( rdata, idata, size ); The macro language includes special pre-defined variables, overall data and the current data vector. Other variables are created automatically when used, such as variables "i" and "temp" in the example above. Once a macro is entered into a text file, it can be used to process data in the same way as other nmrPipe processing functions. For example, if either macro above is entered into the text file "swap.M", a scheme like the following could be used to exchange real and imaginary data before a Fourier transform: nmrPipe -in test.fid \ | nmrPipe -fn MAC -macro swap.M \ | nmrPipe -fn FT \ -out test.ft1 -verb -ov As the examples above imply, the macro language has many similarities to the C programming language. Some of these include: Variable names are case-sensitive. Statements are terminated by the ';' character. Array subscripts are enclosed by '[' and ']'. Statement lists are enclosed by '{' and '}'. More details are given below. In the outlines that follow var is scalar variable or a subscripted array variable, and expr is a mathematical expression. VARIABLES In the current implementation, the macro language supports three types of variables: 1. Scalar variables, as double-precision floats. 2. One-dimensional arrays, as single-precision floats. 3. Character arrays. Array index values start at zero, as in C. Array variables of a specific length can be created using a "float" statement, such as: float gReal[size*4], gImag[size*4]; char outName[256]; Scalar variables are created automatically when used. The value of an uninitialized variable is undefined. READING AND WRITING DATA Some macro applications may require the option of reading or 1D vector at a time. In these cases, the automatic read/write performed by nmrPipe can be suppressed by use of the arguments -noRd and -noWr. In these cases, the macro will be responsible for performing its own reading and writ- ing, via functions such as dReadB() and dWrite() described below. HEADER VALUES The pre-defined array fdata[512] contains the file header information from the current data. The functions getParm() and setParm() can be used to get or set values in the header. For example, some macro applications may alter the size of the output data. In these cases it will be neces- sary to adjust the output file header accordingly before processing to indicate the new size. When the -all flag is used, the macro will be invoked twice before any processing is required, to provide an opportunity to perform initialization such as updating the header if needed. If the -all flag is used, the macro will also be invoked once after all processing is finished. The action to perform at any given invocation will be indicated by variable "sliceCode" (see below). If the -all flag is not used, the macro will only be called to process data, never to perform initialization or exit procedures. PREDEFINED VARIABLES rdata[size] Real part of current 1D vector. idata[size] Imaginary part of current 1D vector, if any. fdata[512] Header array from current data. xSize Size of current X-Axis, complex points. ySize Size of current Y-Axis, total points for hypercomplex data, complex points otherwise. zSize Size of current Z-Axis, total points. aSize Size of current A-Axis, total points. size Same as "xSize" Same as "ySize" quadState If this value is 1, the current dimension is being read as real-only data, and therefore the idata[size] array has no imaginary contents. If this value is 2, the current dimension is being treated as complex, and the array idata[size] contains the imaginary data. sliceCode 1D Vector number or code number (see below). A value greater than zero indicates that a 1D vector should be processed. A value less than zero indicates that an initialization or shutdown step should be performed. sliceCount Total 1D slices to process. yLoc Location of current 1D slice in Y-Axis. zLoc Location of current 1D slice in Z-Axis. aLoc Location of current 1D slice in A-Axis. inUnit File ID for current 1D input data. outUnit File ID for current output data. SPECIAL CONSTANTS BUFLEN Default array length (1024). wordLen Number of bytes per word (4). PI The constant pi. E The constant e. CUR_XDIM Used to define dimCode for getParm/setParm below (=1). CUR_YDIM Used to define dimCode for getParm/setParm below (=2). CUR_ZDIM Used to define dimCode for getParm/setParm below (=3). Used to define dimCode for getParm/setParm below (=4). NDSIZE Code for SIZE parameter in header, as taken from "fdatap.h"; used as a parmCode for getParm/setParm below. Other predefined parameter codes will be added in future implementations; in the mean time, parameter codes can be defined "manually" in a macro using values listing in "fdatap.h" or in the fdatap manual page. VALUES FOR SLICECODE The following codes will only be used when the -all option is specified: CODE_ARGS When sliceCode == CODE_ARGS, the macro is being invoked to extract any command line arguments required. At this stage, the data arrays (rdata[size] and idata[size) and the header array (fdata[512]) cannot be accessed. CODE_INIT When sliceCode == CODE_INIT, the macro is being invoked to perform any initialization required for processing. At this time, the header should be updated by the macro if needed. CODE_DONE When sliceCode == CODE_DONE, the processing is fin- ished. The macro should perform any exit procedures (final summary, etc.) needed. At this stage, the data arrays (rdata[size] and idata[size) cannot be accessed. ASSIGNMENT OPERATORS var = expr; Assignment var += expr; Increment var by expr. var -= expr; Decrement var by expr. var *= expr; Multiple var by expr. var /= expr; Divide var by expr. MATH OPERATORS Note that unlike C, this implementation defines an exponen- tiation operator '^': expr + expr Addition expr - expr Subtraction expr * expr Multiplication expr / expr Division expr % expr Modulus -expr Negative ++var Increment var, return new value. var++ Increment var, return original value. --var Decrement var, return new value. var-- Decrement var, return original value. LOGICAL OPERATORS In the current implementation, both sides of binary logical operators are always evaluated, unlike C, where only the left-side argument may be evaluated. expr > expr Greater than expr >= expr Greater than or equal to expr < expr Less than expr <= expr Less than or equal to expr == expr Equal to expr != expr Not equal to expr && expr Logical AND expr || expr Logical OR !expr Logical NOT SPECIAL ITEMS (void) Ignore (don't print) function return value. If this prefix is not used before a function call, the function's return value will be printed. exit( expr ); Exit the macro with the given status. print printList; Print the given list of data; printList is a list of comma-separated variables or string constants. float arrayList; Define and allocate the given arrays; arrayList is a list of comma-separated arrays with subscripts defining their sizes. near( x1, x2, d ); Returns 1 if the absolute difference between x1 and x2 is less than the absolute value of d. LOOP STATEMENTS Loop statements in the macro language must have their while( condition ) { statementList } for( initExpr; condition; incrExpr ) { statementList } CONDITIONAL STATEMENTS Conditional statements in the macro language differ from C in two ways; first, the statement bodies in the "if" state- ment must be enclosed by '{' and '}'; second, the if state- ment must be terminated by a ';' character: if (condition) { statementList; }; if (condition) { statementList; } else { statementList; }; if (condition1) { statementList; } else if (condition2) { statementList; } else { statementList; }; SCALAR FUNCTIONS sin() Sine cos() Cosine tan() Tangent acos() Inverse Cosine atan() Inverse Tangent log() Log Base-e log10() Log Base-10 exp() Exponential erf() Error function sqrt() Square root integer() Truncate to integer abs() Absolute value randX() Uniform random number gRandX() Gaussian random number rseed() Sets random number seed readV() Read a variable debug() Set debug mode SELECTED VECTOR AND FUNCTION CALLS printf( string ); Print the given string, as with the C version of printf(). printf( formatString, argList ); Print the given data, as with the C version of printf(); Note Well: in the current implementation, all variables are treated by this printf as C type "float", so fomat statements must be specified accordingly. fprintf( fileID, string ); Print the given string to a file, as with the C version of fprintf(). The fileID should be a value returned by dOpen(). fprintf( fileID, formatString, argList ); Print the given data, as with the C version of fprintf(); Note Well: in the current implementation, all variables are treated by this printf as C type "float", so fomat statements must be specified accord- ingly. The fileID should be a value returned by dOpen(). sprintf( charArray, string ); Print the given string into the given character array, as with the C version of sprintf(). The character array should be created using the "char" statement. sprintf( charArray, formatString, argList ); Print the given data, as with the C version of sprintf(); Note Well: in the current implementation, all variables are treated by this printf as C type "float", so fomat statements must be specified accord- ingly. The character array should be created using the "char" statement. strcpy( charArray, string ); Copy the string to the given character array, as with be created using the "char" statement. strcat( charArray, string ); Catenate the string to the given character array, as with the C version of strcat(). The character array should be created using the "char" statement. strcmp( string1, string2 ); Compare the given strings, as with the C version of strcmp(). The value returned is either negative, zero, or positive depending on whether string1 is lexically less than, equal to, or greater than string2. strcasecmp( string1, string2 ); Compare the given strings, in case-insensitive mode, as with the C version of strcasecmp(). The value returned is either negative, zero, or positive depending on whether string1 is lexically less than, equal to, or greater than string2. strexpr( string, regexpr ); Return 1 if the given string matches the given regular expression "regexpr". The usual rules of regular expression matching apply. strcpy( charArray, string ); Copy the string to the given character array, as with the C version of strcpy(). The character array should be created using the "char" statement. argTest( string ); True if string was found in argv[] command line list. argVal( string ); Returns the value following string in argv[] command line list. getParm( fdata, parmCode, dimCode ); Gets a parameter from the given file header array fdata according to its parameter code and dimension code. Values of parmCode are listed in the file fdatap.h; values of dimCode are listed above. setParm( fdata, parmCode, value, dimCode ); Sets a parameter in the header array fdata according to its parameter code and dimension code. Values of parmCode are listed in the file fdatap.h; values of dimCode are listed above. pnt2spec( fdata, dimCode, pntVal, unitString ); Returns a location in spectral units corresponding to varies from 1 to N, where N is the number of points in the given dimension (dimCode). The spectral units (unitString) are specified as "ppm", "hz", "pts", or "%". spec2pnt( fdata, dimCode, specString ); Returns a location in points corresponding to the given spectral location. The spectral location is specified as a string (specString) which contains a position with a spectral units label, such as "7.4ppm". dOpen( fileName, modeString ); Opens the give file, and returns a file ID for reading or writing, using the open() UNIX system call. If mode is "r", the file will be opened read-only. If mode is "w", the file will be created if needed, truncated to zero length, and opened for writing. If mode is "rw", the file will be opened for both reading and writing. Alternatively, the mode string can contain combinations of the following characters to use as flags for the open() UNIX system call: ooooooooo oooooooooooooooo Character UNIX open() Flag ooooooooo oooooooooooooooo r O_RDONLY w O_WRONLY d O_NDELAY y O_NOCTTY s O_SYNC a O_APPEND c O_CREAT t O_TRUNC e O_EXCL ooooooooo oooooooooooooooo dClose( fileID ); Closes the given file. dSeek( fileID, byteLoc ); Positions the given file; this cannot be used for pipe- line data. vvCopy( destArray, srcArray, length ); Copy contents of srcArray to destArray. vvCopyOff( destArray, srcArray, length, destOffset, srcOffset ); Copy srcArray[srcOffset...] to destArray[destOffset...] Read given byte count from the given file. dWrite( fileID, array, byteCount ); Write given byte count from the given file. dReadB( fileID, array, byteCount ); Read given byte count from the given file (blocking version, which waits until all data have been read). Use this function to read data from a pipeline. dWriteB( fileID, array, byteCount ); Write given byte count from the given file (blocking version, which waits until all data have been written). vvAdd( array1, array2, length ); array1 = array1 + array2 vvSub( array1, array2, length ); array1 = array1 - array2 vvMult( array1, array2, length ); array1 = array1 * array2 vvDiv( array1, array2, length ); array1 = array1 / array2 vvSwap( array1, array2, length ); Swap contents of array1 and array2 vsAdd( array, length, val ); array = array + val vsMult( array, length, val ); array = array * val vsSet( array, length, val ); array = val lShift( array, length, lsVal ); Left-shift array by lsVal points. rShift( array, length, rsVal ); Right-shift array by lsVal points. vShow( array, length ); Print contents of array. vNeg( array, length ); Negate contents of array. reverse( array, length ); phase( realArray, imaginaryArray, length, p0, p1 ); Apply a phase correction. OPTIONS -macro macroFile Specifies the macro file to execute, relative to the current directory. This is a required argument. -var vList Specifies a space-separated list of variable/value pairs, which allows variables to be initialized at the command line before the macro is executed. -str sList Specifies a space-separated list of variable/string pairs, which allows character arrays to be created and initialized at the command line before the macro is executed. -all (nmrPipe only) If this flag is used, the macro will be invoked to perform initialization and exist steps, as well as processing steps. If the -all is not used, the macro will only be invoked for processing steps. The action that the macro is expected to perform is indi- cated by the variable "sliceCode", explained above. -quit (M stand-alone interpreter only). If this flag is included, the stand-alone program M will exit after all macro files on the command line have been executed. If the flag is not included, the program will enter an interactive mode after all macro files have been exe- cuted. EXAMPLES For examples, see the following nmrPipe macros: skew.M Applies a custom window function. ranceY.M Rance-Kay mode 2D gradient shuffling. ranceZ.M Rance-Kay mode 3D gradient shuffling. shuf3D.M Adjust non-standard 3D acquisition order. rrii.M Adjust non-standard Chemagnetics data. as well as the following stand-alone M macros: xz.M Extract XZ 2D Plane from 3D/4D data. xa.M Extract XA 2D Plane from 4D data.