19804 Maycrest Way
Germantown MD 20876 USA
301 806-0867
delaglio@nmrscience.com
NMRPipe Processing Functions
MACRO: Slice-Processing Macro.
|
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 imaginary 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 imaginaries 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 -ovAs the examples above imply, the macro language has many similarities to the C programming language. Some of these include:
VARIABLES
In the current implementation, the macro language supports three types of variables:
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 writing, 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 necessary 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"
specnum
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.
NULL_DIM
Used to define dimCode for getParm/setParm below (=0).
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).
CUR_ADIM
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 might 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 finished.
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
The MAC language supports these C-style assignmemnt 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 exponentiation operator '^':
var = expr + expr; /* Addition. */ var = expr - expr; /* Subtraction. */ var = expr * expr; /* Multiplication. */ var = expr / expr; /* Division. */ var = expr % expr; /* Modulus. */ var = expr ^ expr; /* Exponentiation. */ var = -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.
angleNear( x1, x2, d );
Returns 1 if the absolute difference between angles
x1 and x2 is less than the absolute value of d.
The angles are expressed in degrees.
LOOP STATEMENTS
Loop statements in the macro language must have their
body enclosed in '{' and '}' curly braces. Only two types of loop.
for
and while
loops, are availble:
The general form of the loops is the same as in C, but with the requirement that statement list in the loop body is always enclosed in curly braces:
while( condition ) { statementList; } for( initExpr; condition; incrExpr ) { statementList; }
CONDITIONAL STATEMENTS
Conditional statements in the macro language differ from the usual C syntax in two ways:
if
statement
must be enclosed by '{' and '}' curly braces.if
statement 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
The MAC language provides several "scalar" math functions, which in many cases invoke the C functions of the same name. Angular functions use values in radians:
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 nthArg() Extract the Nth string from the command-line. debug() Set debug mode getByteSwap() Return current data current byte swap status. setByteSwap() Set current byte swap status. getAutoSwap() Return current auto byte-swap status. setAutoSwap() Set current auto byte-swap status.SELECTED VECTOR AND FUNCTION CALLS
printf( string );
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 accordingly.
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 accordingly.
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:
Character UNIX open() Flag 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
dClose( fileID );
Closes the given file.
dSeek( fileID, byteLoc );
Positions the given file; this cannot be used for pipeline data.
vvCopy( destArray, srcArray, length );
Copy contents of srcArray to destArray.
vvCopyOff( destArray, srcArray, length, destOffset, srcOffset );
Copy srcArray[srcOffset...] to destArray[destOffset...]
dReadB( fileID, array, byteCount );
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.
dReadHdr( fileID, array, byteCount );
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( rdata, idata, length, p0, p1 );
Apply a phase correction.
fft( rdata, idata, length );
Apply a forward Fourier transform.
ift( rdata, idata, length );
Apply an inverse Fourier transform.
vSim1D( rdata, idata, tSize, fSize, x0, xfw, hi );
vSim1D( rdata, idata, tSize, fSize, x0, xfw, hi, p0, p1 );
Add a simulated 1D time-domain data to the given real/imaginary array.
Arguments tSize and fSize are the time-domain size and anticipated frequency-domain size in points. Argument x0 is the position of the signal in the
corresponding frequency-domain, in points. Argument xfw is the
full-width in points in the corresponding frequency-domain. Argument hi
is the time-domain amplitude, and optional arguments p0 and p1 are
the desired phase for the signal in degrees.
COMMAND-LINE 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 indicated
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 executed.
EXAMPLES
Various examples can be found the the nmrtxt
directory
of the NMRPipe installation ($NMRTXT/*.M).
This example shows a custom window function which expects parameters settings from the command line (in this case, the variables called LB and GB) , and exracts the sweep width from the current data in order to interpret the requested window function parameters. This function will be called repeatedly, once for every 1D vector in the data.
The macro uses the following pre-defined variables:
fdata[] Parameter Header from the Current Spectrum rdata[] Array of real values for the currect vector. idata[] Array of imaginary vectors for the current vector. size Number of points in the current vector. CUR_XDIM A pre-defined constant for referring to the X-Axis. PI The pre-defined constant pi.The contents of the macro can also be found in the file $NMRTXT/gmb.M:
/* Bruker's GM function; requires LB and GB from command-line: */ /* | nmrPipe -fn MAC -macro gmb.M -var LB 2 GB 8 \ */ NDSW = 1003; sw = getParm( fdata, NDSW, CUR_XDIM ); aq = size/sw; a = PI*LB; b = -a/(2.0*GB*aq); (void) printf( "sw: %f\n", sw ); for( i = 0; i < size; i++ ) { t = i/sw; g = exp( -a*t - b*t*t ); rdata[i] *= g; idata[i] *= g; }For other examples, see the NMRPipe macros in the $NMRTXT directory:
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.