/******************************************************************************/ /* */ /* ---- NIH NMR Software System ---- */ /* Copyright 1992 and 1993 */ /* Frank Delaglio */ /* NIH Laboratory of Chemical Physics */ /* */ /* This software is not for distribution without */ /* the written permission of the author. */ /* */ /******************************************************************************/ /***/ /* nmrAux: utility modules for nmrPipe and other programs which use the /* nmrPipe processing function library. /***/ #include #include #include #include #include #ifdef USE_IMSL_C #include #endif #include "cmndargs.h" #include "version.h" #include "memory.h" #include "dataio.h" #include "fdatap.h" #include "nmrserver.h" #include "token.h" #include "prec.h" #include "atof.h" #include "rand.h" #include "nmrpipe.h" #include "nmrtime.h" #define FPR (void) fprintf #define ARGC dataInfo->argc #define ARGV dataInfo->argv #define HDR dataInfo->fdata #define DI dataInfo static struct ProcFuncInfo *funcInfoList = (struct ProcFuncInfo *) NULL; static struct ProcFuncInfo *glbFuncInfoPtr = (struct ProcFuncInfo *) NULL; static struct ProcDataInfo *glbDataInfoPtr = (struct ProcDataInfo *) NULL; static char *sigProgName = (char *)NULL; static int (*shutDownProc)() = NULL; static int userSignal = 0; /***/ /* initNMRAux: must be called first to use the modules here. /***/ int initNMRAux( argc, argv, funcInfo, dataInfo, shutDownFn ) struct ProcFuncInfo *funcInfo; struct ProcDataInfo *dataInfo; int (*shutDownFn)(); int argc; char **argv; { static int firstTime = 1; if (firstTime) (void) initDataIO(); glbFuncInfoPtr = funcInfo; glbDataInfoPtr = dataInfo; shutDownProc = shutDownFn; firstTime = 0; return( 0 ); } /***/ /* initNMRSizes: establish data sizes, quad states, etc. /***/ int initNMRSizes( fdata, dataInfo ) struct ProcDataInfo *dataInfo; float fdata[FDATASIZE]; { int nDim; /***/ /* Extract sizes: /***/ nDim = getParm( fdata, FDDIMCOUNT, 0 ); dataInfo->size = nDim < 1 ? 1 : getParm( fdata, NDSIZE, CUR_XDIM ); dataInfo->specnum = nDim < 2 ? 1 : getParm( fdata, NDSIZE, CUR_YDIM ); dataInfo->zSize = nDim < 3 ? 1 : getParm( fdata, NDSIZE, CUR_ZDIM ); dataInfo->aSize = nDim < 4 ? 1 : getParm( fdata, NDSIZE, CUR_ADIM ); dataInfo->firstPlane = getParm( fdata, FDFIRSTPLANE, 0 ); dataInfo->lastPlane = getParm( fdata, FDLASTPLANE, 0 ); dataInfo->dimCount = nDim; /***/ /* Extract recorded slice count parameter FDSLICECOUNT. /* /* Slice Count of -1: /* Indicates variable slice count processing. /* /* In server mode: /* FDPARTITION records count of 1D slices to process. /* /* In pipe mode with no first/last plane limits: /* Product of Y Z and A axis sizes gives count of 1D slices to process. /* In pipe mode with first/last plane limits: /* FDSLICECOUNT gives count of 1D slices to process. /* /* Otherwise: /* 1D Slice count is simply the Y size. /***/ dataInfo->sliceCount = getParm( fdata, FDSLICECOUNT, 0 ); if (dataInfo->sliceCount == -1) { dataInfo->varCountFlag = 1; } if (dataInfo->serverMode == SMODE_SERVER) { dataInfo->sliceCount = getParm( fdata, FDPARTITION, 0 ); } else if (NULL_DIM != (int)getParm( fdata, FDPIPEFLAG, 0 )) { if (!dataInfo->firstPlane && !dataInfo->lastPlane) { dataInfo->sliceCount = dataInfo->specnum*dataInfo->zSize*dataInfo->aSize; } } else { dataInfo->sliceCount = dataInfo->specnum; } if (!dataInfo->firstPlane && !dataInfo->lastPlane) { dataInfo->firstPlane = 1; dataInfo->lastPlane = dataInfo->zSize*dataInfo->aSize; } /***/ /* Set other parameters relating to data: /***/ dataInfo->slicesLeft = dataInfo->sliceCount; dataInfo->timeSize = getParm( fdata, NDAPOD, CUR_XDIM ); dataInfo->ftFlag = getParm( fdata, NDFTFLAG, CUR_XDIM ); dataInfo->transposed = getParm( fdata, FDTRANSPOSED, 0 ); dataInfo->quadState = getQuad( fdata, FDQUADFLAG, 0 ); dataInfo->maxSize = dataInfo->size; dataInfo->outSize = dataInfo->size; dataInfo->outQuadState = dataInfo->quadState; dataInfo->locList[XLOC] = 0; dataInfo->locList[YLOC] = 0; dataInfo->locList[ZLOC] = dataInfo->firstPlane; dataInfo->locList[ALOC] = 1; if (dataInfo->timeSize < 1) dataInfo->timeSize = dataInfo->size; return( 0 ); } /***/ /* updateHeader: adjust header to indicated post-processing state; /* also finds client/server partitions if needed. /* also parses for User-specified "-fdata" parameters. /* also checks final argument usage if requested. /***/ int updateHeader( funcInfo, dataInfo ) struct ProcFuncInfo *funcInfo; struct ProcDataInfo *dataInfo; { int i, sliceCount, loc1, loc2, itemp, xQuadState, yQuadState, aqMode2D, argCheckFlag, error; float pOld, pNew, totalSpeed; char *sPtr1, *sPtr2; /***/ /* Initialize: /***/ error = 0; sPtr1 = (char *)NULL; sPtr2 = (char *)NULL; argCheckFlag = 1; /***/ /* Remove references to file footer: /***/ (void) setParm( dataInfo->fdata, FDSCALEFLAG, (float)0.0, 0 ); (void) setParm( dataInfo->fdata, FDLASTBLOCK, (float)0.0, 0 ); (void) setParm( dataInfo->fdata, FDCONTBLOCK, (float)0.0, 0 ); (void) setParm( dataInfo->fdata, FDBASEBLOCK, (float)0.0, 0 ); (void) setParm( dataInfo->fdata, FDPEAKBLOCK, (float)0.0, 0 ); (void) setParm( dataInfo->fdata, FDBMAPBLOCK, (float)0.0, 0 ); (void) setParm( dataInfo->fdata, FDHISTBLOCK, (float)0.0, 0 ); (void) setParm( dataInfo->fdata, FD1DBLOCK, (float)0.0, 0 ); /***/ /* Increment processing function count for explicit functions: /***/ if (dataInfo->inName) { (void) setParm( dataInfo->fdata, FDPIPECOUNT, (float)0, 0 ); if (flagLoc( dataInfo->argc, dataInfo->argv, "-fn" )) { (void) setParm( dataInfo->fdata, FDPIPECOUNT, (float)1, 0 ); } } else { itemp = getParm( dataInfo->fdata, FDPIPECOUNT, 0 ); (void) setParm( dataInfo->fdata, FDPIPECOUNT, (float)itemp+1, 0 ); } /***/ /* Find coords of the selected processing region if needed: /***/ if (loc1 = flagLoc( dataInfo->argc, dataInfo->argv, "-select" )) { loc2 = nextFlag( dataInfo->argc, dataInfo->argv, loc1 ); if ((loc2 <= loc1) || !((loc2 - loc1) % 2)) { (void) fprintf( stderr, "NMRPipe Warning: bad arguments" ); (void) fprintf( stderr, " for -select option.\n" ); dataInfo->selectMode = SELECT_ALL; loc1 = 0; loc2 = 0; } i = YLOC; while( loc1 < loc2 - 1 ) { if (i > dataInfo->dimCount - 1) { (void) fprintf( stderr, "NMRPipe Warning: too many arguments" ); (void) fprintf( stderr, " for -select option.\n" ); dataInfo->selectMode = SELECT_ALL; break; } sPtr1 = getNthArg( ARGC, ARGV, loc1 + 1 ); sPtr2 = getNthArg( ARGC, ARGV, loc1 + 2 ); dataInfo->selX1[i] = spec2iPnt( HDR, i+1, sPtr1 ); dataInfo->selXN[i] = spec2iPnt( HDR, i+1, sPtr2 ); if (dataInfo->selX1[i] < 1) dataInfo->selX1[i] = 1; if (dataInfo->selXN[i] < 1) dataInfo->selXN[i] = 1; if (dataInfo->selX1[i] > dataInfo->selXN[i]) { itemp = dataInfo->selX1[i]; dataInfo->selX1[i] = dataInfo->selXN[i]; dataInfo->selXN[i] = itemp; } loc1 += 2; i++; } } /***/ /* Allow processing function to initialize and adjust header if needed. /* Update maximum vector size as a defensive measure. /***/ dataInfo->sliceCode = FN_INIT; if (funcInfo->func) { dataInfo->sliceCode = FN_INIT; if (error = (*funcInfo->func)( dataInfo )) return( error ); } else { return( 1 ); } if (dataInfo->maxSize < dataInfo->outSize) { dataInfo->maxSize = dataInfo->outSize; } if (dataInfo->maxSize < dataInfo->size) { dataInfo->maxSize = dataInfo->size; } /***/ /* Reset processing function count if needed: /***/ if (dataInfo->outName) { (void) setParm( dataInfo->fdata, FDPIPECOUNT, (float)0, 0 ); } /***/ /* Delete Imaginaries: /* Choose either only DT or XI mode if DI mode is selected. /* Adjust for DT mode if needed (delete hypercomplex imags). /* Adjust for XI mode if needed (delete complex imags). /* /* Nota Bene: FDSLICECOUNT is only updated when data is not /* variable slice count; variable slice count data /* must always have this value as -1. /***/ xQuadState = getQuad( HDR, NDQUADFLAG, CUR_XDIM ); yQuadState = getQuad( HDR, NDQUADFLAG, CUR_YDIM ); aqMode2D = getParm( HDR, FD2DPHASE, 0 ); if (dataInfo->typeFlags[DIFLAG]) { if (xQuadState == 2 && yQuadState == 2) { dataInfo->typeFlags[DTFLAG] = 1; dataInfo->typeFlags[XIFLAG] = 0; } else { dataInfo->typeFlags[DTFLAG] = 0; dataInfo->typeFlags[XIFLAG] = 1; } } if (dataInfo->typeFlags[DTFLAG]) { if (xQuadState == 1 && yQuadState == 1) { (void) fprintf( stderr, "NMRPipe Warning: -dt On Real Data." ); (void) fprintf( stderr, " Consider -xi or -di instead.\n" ); } else if (xQuadState != 2 || yQuadState != 2) { (void) fprintf( stderr, "NMRPipe Warning: -dt On Complex Data." ); (void) fprintf( stderr, " Consider -xi or -di instead.\n" ); } if (!dataInfo->varCountFlag) { (void) setParm( HDR, FDSLICECOUNT, (float)DI->sliceCount/2, 0 ); } (void) setParm( HDR, NDSIZE, (float)DI->specnum/2, CUR_YDIM ); (void) setParm( HDR, NDQUADFLAG, (float)1.0, CUR_XDIM ); dataInfo->outQuadState = 1; } if (dataInfo->typeFlags[XIFLAG]) { if (xQuadState == 2 && yQuadState == 2 && (aqMode2D == FD_STATES || aqMode2D == FD_IMAGE)) { (void) fprintf( stderr, "NMRPipe Warning:" ); (void) fprintf( stderr, " -xi on Hypercomplex Data." ); (void) fprintf( stderr, " Consider -dt or -di instead.\n" ); } (void) setParm( HDR, FDQUADFLAG, (float)1.0, 0 ); (void) setParm( HDR, NDQUADFLAG, (float)1.0, CUR_XDIM ); dataInfo->outQuadState = 1; } /***/ /* Add imaginaries: /* Choose either only AD or AI mode if AC mode is selected. /* Adjust for AD mode if needed (add hypercomplex imags). /* Adjust for AI mode if needed (add complex imags). /* /* Nota Bene: FDSLICECOUNT is only updated when data is not /* variable slice count; variable slice count data /* must always have this value as -1. /***/ if (dataInfo->typeFlags[ACFLAG]) { if (xQuadState == 2 && yQuadState == 2) { dataInfo->typeFlags[ADFLAG] = 0; dataInfo->typeFlags[AIFLAG] = 0; } else if (xQuadState == 1 && yQuadState == 1) { dataInfo->typeFlags[ADFLAG] = 0; dataInfo->typeFlags[AIFLAG] = 1; } else { dataInfo->typeFlags[ADFLAG] = 1; dataInfo->typeFlags[AIFLAG] = 0; } } if (dataInfo->typeFlags[ADFLAG]) { if (xQuadState == 2 && yQuadState == 2) { (void) fprintf( stderr, "NMRPipe Warning:" ); (void) fprintf( stderr, " -ad on Hypercomplex Data." ); (void) fprintf( stderr, " Consider -ai or -ac instead.\n" ); } else if (xQuadState == 1 && yQuadState == 1) { (void) fprintf( stderr, "NMRPipe Warning: -ad on Real Data.\n" ); (void) fprintf( stderr, " Consider -ai or -ac instead.\n" ); } (void) setParm( HDR, FDQUADFLAG, (float)0.0, 0 ); (void) setParm( HDR, NDQUADFLAG, (float)0.0, CUR_XDIM ); (void) setParm( HDR, NDQUADFLAG, (float)0.0, CUR_YDIM ); (void) setParm( HDR, NDSIZE, (float)DI->specnum*2, CUR_YDIM ); if (!dataInfo->varCountFlag) { (void) setParm( HDR, FDSLICECOUNT, (float)DI->sliceCount*2, 0 ); } dataInfo->outQuadState = 2; } if (dataInfo->typeFlags[AIFLAG]) { (void) setParm( HDR, FDQUADFLAG, (float)0.0, 0 ); (void) setParm( HDR, NDQUADFLAG, (float)0.0, CUR_XDIM ); dataInfo->outQuadState = 2; } /***/ /* Adjust output quad state if both dimensions seem to be real. /***/ if ((1 == getQuad( dataInfo->fdata, NDQUADFLAG, CUR_XDIM )) && (1 == getQuad( dataInfo->fdata, NDQUADFLAG, CUR_YDIM ))) { (void) setParm( dataInfo->fdata, FDQUADFLAG, (float)1.0, 0 ); } /***/ /* If this is a parallel processing client: /* Partition total slice counts between servers according to server speed. /* Adjust counts so that total exactly matches number of slices to process. /***/ if (dataInfo->serverMode == SMODE_CLIENT) { sliceCount = 0; totalSpeed = 0.0; for( i = 0; i < dataInfo->serverCount; i++ ) { totalSpeed += dataInfo->server[i].speed; } for( i = 0; i < dataInfo->serverCount; i++ ) { dataInfo->server[i].partition = (float)dataInfo->sliceCount*dataInfo->server[i].speed/totalSpeed; sliceCount += dataInfo->server[i].partition; } if (sliceCount > dataInfo->sliceCount) { dataInfo->server[0].partition -= sliceCount - dataInfo->sliceCount; if (dataInfo->server[0].partition < 0) { (void) fprintf( stderr, "NMRPipe Error adjusting partitions.\n" ); return( 1 ); } } else if (sliceCount < dataInfo->sliceCount) { dataInfo->server[0].partition += dataInfo->sliceCount - sliceCount; } } /***/ /* Parse for user-specified header parameters: /***/ if (loc1 = flagLoc( ARGC, ARGV, "-fdata" )) { loc2 = nextFlag( ARGC, ARGV, loc1 ); while( loc1 < loc2 - 1 ) { itemp = atoi( getNthArg( ARGC, ARGV, loc1 + 1) ) - 1; pNew = ATOF( getNthArg( ARGC, ARGV, loc1 + 2) ); pOld = getParm( HDR, itemp, 0 ); if (dataInfo->verbose) { (void) fprintf( stderr, "FDATA[%d] %f --> %f\n", itemp+1, pOld, pNew ); } (void) setParm( dataInfo->fdata, itemp, pNew, 0 ); loc1 += 2; } } /***/ /* Check final argument usage: /***/ if (flagLoc( ARGC, ARGV, "-checkArgs" )) argCheckFlag = 1; if (flagLoc( ARGC, ARGV, "-nocheckArgs" )) argCheckFlag = 0; if (argCheckFlag) (void) checkArgs( dataInfo->argc, dataInfo->argv ); return( 0 ); } /***/ /* initSignal: start signal handler. /***/ int initSignal( mode, argc, argv, pName ) char **argv, *pName; int argc, mode; { int sig; #ifdef USE_IMSL_C void nmrMathErr(); #endif /***/ /* Initialize application signal testing: /***/ sigProgName = pName; (void) setUserSignal( 0 ); /***/ /* Redirect math library error output: /***/ #ifdef USE_IMSL_C (void) imsl_error_options( IMSL_SET_STOP, IMSL_NOTE, 0, IMSL_SET_STOP, IMSL_ALERT, 0, IMSL_SET_STOP, IMSL_WARNING, 0, IMSL_SET_STOP, IMSL_FATAL, 0, IMSL_SET_STOP, IMSL_TERMINAL, 0, IMSL_ERROR_PRINT_PROC, nmrMathErr, 0 ); #endif /***/ /* Suppress signal catching if needed: /***/ if (flagLoc( argc, argv, "-noSig" )) return( 0 ); (void) alarm( 0 ); /***/ /* Set signal catching: let OS take care of ^Z and fg/bg. /***/ for( sig = 1; sig < 32; sig++ ) { if (sig != SIGKILL && #ifndef WINNT sig != SIGSTOP && sig != SIGTSTP && sig != SIGCONT && #endif sig != SIGWINCH) { (void) signal( sig, getSignal ); } } return( 0 ); } /***/ /* nmrMathErr: called by math library to display an error. /***/ #ifdef USE_IMSL_C void nmrMathErr( eType, eCode, eProc, eMess ) Imsl_error eType; long eCode; char *eProc, *eMess; { if (glbDataInfoPtr->debug) { (void) fprintf( stderr, "\n\n" ); (void) fprintf( stderr, "*** Math Library Error: %s\n", eProc ); (void) fprintf( stderr, "%s\n", eMess ); } } #endif /***/ /* getSignal: called by OS to handle a signal. /***/ void getSignal( sig, code, scp, addr ) int sig, code; struct sigcontext *scp; char *addr; { char ctemp[NAMELEN+1]; switch( sig ) { case SIGINT: if (glbDataInfoPtr) glbDataInfoPtr->silentExit = 1; (void) shutDownProc( 1 ); break; case SIGUSR1: (void) signal( sig, getSignal ); (void) fprintf( stderr, "%s: User Signal 1.\n", sigProgName ); userSignal = 1; break; case SIGUSR2: (void) signal( sig, getSignal ); (void) fprintf( stderr, "%s: User Signal 2.\n", sigProgName ); userSignal = 2; break; case SIGHUP: case SIGQUIT: case SIGILL: case SIGABRT: case SIGFPE: case SIGBUS: case SIGSEGV: case SIGTERM: #ifndef LINUX case SIGSYS: #endif (void) fprintf( stderr, "%s Abort Signal: %d %d\n", sigProgName, sig, code ); (void) sprintf( ctemp, "%s System Message", sigProgName ); (void) perror( ctemp ); (void) sprintf( ctemp, "%s Signal Message", sigProgName ); (void) psignal( (unsigned)sig, ctemp ); (void) shutDownProc( 1 ); break; default: if (glbDataInfoPtr && glbDataInfoPtr->debug) { (void) fprintf( stderr, "%s Signal: %d %d\n", sigProgName, sig, code ); (void) sprintf( ctemp, "%s Signal Message", sigProgName ); (void) psignal( (unsigned)sig, ctemp ); } break; } } /***/ /* getUserSignal: get current value of the user signal variable; /* used by processing functions which test for /* special interrupt requests from the user. /***/ int getUserSignal() { return( userSignal ); } /***/ /* setUserSignal: set current value of the user signal variable; /* used by processing functions which test for /* special interrupt requests from the user; /* returns previous user signal value. /***/ int setUserSignal( newSignal ) int newSignal; { int oldSignal; oldSignal = userSignal; userSignal = newSignal; return( oldSignal ); } /***/ /* initInfo: initialize data and function pointers, etc to NULL. /***/ int initInfo( argc, argv, fdata, funcInfo, dataInfo ) struct ProcFuncInfo *funcInfo; struct ProcDataInfo *dataInfo; float fdata[FDATASIZE]; char **argv; int argc; { static char msgBuff[NAMELEN+1]; int i; struct ProcFuncInfo *getFuncList(); int uNULL(); SRANDINIT( 54321 ); if (!(funcInfoList = getFuncList())) { (void) fprintf( stderr, "NMRPipe Error extracting function list.\n" ); return( 1 ); } funcInfo->func = uNULL; funcInfo->name = (char *) NULL; funcInfo->descrip = (char *) NULL; funcInfo->args = (char *) NULL; dataInfo->rdata = (float *) NULL; dataInfo->idata = (float *) NULL; dataInfo->fdataOrig = (float *) NULL; dataInfo->fdata = fdata; dataInfo->inBuff = (float *) NULL; dataInfo->outBuff = (float *) NULL; dataInfo->inBuffPtr = (float *) NULL; dataInfo->outBuffPtr = (float *) NULL; dataInfo->debug = 0; dataInfo->verbose = 0; dataInfo->verbInc = 16; dataInfo->silentExit = 0; dataInfo->x11Flag = 0; dataInfo->message = msgBuff; dataInfo->rdFlag = 1; dataInfo->wrFlag = 1; dataInfo->vecFlag = 1; dataInfo->inSwapFlag = 0; dataInfo->outSwapFlag = 0; dataInfo->inCapacity = 0; dataInfo->outCapacity = 0; dataInfo->buffCountIn = 0; dataInfo->buffCountOut = 0; dataInfo->serverID = 0; dataInfo->serverCount = 0; dataInfo->serverSock = -1; dataInfo->inSock = -1; dataInfo->outSock = -1; dataInfo->serverMsgSock = -1; dataInfo->serverMaxTries = -1; dataInfo->serverTimeOut = getDefTimeout(); dataInfo->serverMode = SMODE_NONE; for( i = 0; i < MAXSOCK; i++ ) { (void) nullServer( &dataInfo->server[i] ); } dataInfo->quadState = 1; dataInfo->size = 0; dataInfo->specnum = 0; dataInfo->zSize = 0; dataInfo->aSize = 0; dataInfo->dimCount = 0; dataInfo->sliceCount = 0; dataInfo->transposed = 0; dataInfo->varCountFlag = 0; dataInfo->selectMode = SELECT_ALL; for( i = 0; i < MAXTYPE; i++ ) { dataInfo->typeFlags[i] = 0; } for( i = 0; i < MAXDIM; i++ ) { dataInfo->locList[i] = 0; dataInfo->selX1[i] = 0; dataInfo->selXN[i] = 0; } dataInfo->maxSize = 0; dataInfo->outSize = 0; dataInfo->timeSize = 0; dataInfo->outQuadState = 1; dataInfo->argc = argc; dataInfo->argv = argv; dataInfo->inName = (char *) NULL; dataInfo->outName = (char *) NULL; dataInfo->inHdrName = (char *) NULL; dataInfo->outHdrName = (char *) NULL; dataInfo->fnName = "NULL"; dataInfo->inUnit = FB_STDIN; dataInfo->outUnit = FB_STDOUT; dataInfo->maxTries = -1; dataInfo->timeOut = getDefTimeout(); dataInfo->finalDelay = 0; dataInfo->ovFlag = 0; dataInfo->inPlace = 0; dataInfo->sliceCode = FN_PARAMS; dataInfo->slicesLeft = 0; dataInfo->max = -LARGENUM; dataInfo->min = LARGENUM; dataInfo->scaleFlag = 0; return( 0 ); } /***/ /* allocSlice: allocate real and imaginary 1D slice memory. /***/ int allocSlice( dataInfo ) struct ProcDataInfo *dataInfo; { int size; /***/ /* Expand buffer sizes for in=place processing. /* Allocate slice buffers. /* Allocate input buffer. /* Allocate output buffer. /***/ if (dataInfo->inPlace) { if (dataInfo->inName) dataInfo->inCapacity = dataInfo->specnum; else dataInfo->outCapacity = dataInfo->specnum; } if (!(dataInfo->rdata = fltAlloc( "nmr", dataInfo->maxSize ))) return( 1 ); if (!(dataInfo->idata = fltAlloc( "nmr", dataInfo->maxSize ))) return( 1 ); if (dataInfo->inCapacity) { size = dataInfo->size*dataInfo->quadState*dataInfo->inCapacity; if (!(dataInfo->inBuff = fltAlloc( "nmr", size ))) return( 1 ); dataInfo->inBuffPtr = dataInfo->inBuff; } if (dataInfo->outCapacity) { size = dataInfo->outSize*dataInfo->outQuadState*dataInfo->outCapacity; if (!(dataInfo->outBuff = fltAlloc( "nmr", size ))) return( 1 ); dataInfo->outBuffPtr = dataInfo->outBuff; } return( 0 ); } /***/ /* freeSlice: de-allocate real and imaginary 1D slice memory, etc; /* also closes files and calls process function shutdown. /***/ int freeSlice( funcInfo, dataInfo ) struct ProcFuncInfo *funcInfo; struct ProcDataInfo *dataInfo; { int size, error; (void) deAlloc( "nmr", dataInfo->rdata, sizeof(float)*dataInfo->maxSize ); (void) deAlloc( "nmr", dataInfo->idata, sizeof(float)*dataInfo->maxSize ); size = dataInfo->size*dataInfo->quadState*dataInfo->inCapacity; (void) deAlloc( "nmr", dataInfo->inBuff, sizeof(float)*size ); size = dataInfo->outSize*dataInfo->outQuadState*dataInfo->outCapacity; (void) deAlloc( "nmr", dataInfo->outBuff, sizeof(float)*size ); if (dataInfo->fdataOrig) { (void) deAlloc( "nmr", dataInfo->fdataOrig, sizeof(float)*FDATASIZE ); } if (funcInfo->func) { dataInfo->sliceCode = FN_SHUTDOWN; if (error = (*funcInfo->func)( dataInfo )) return( error ); } else { return( 1 ); } if (dataInfo->inName || dataInfo->inSock != -1) { (void) dataClose( dataInfo->inUnit ); } if (dataInfo->outName || dataInfo->outSock != -1) { if (dataInfo->inUnit != dataInfo->outUnit) { (void) dataClose( dataInfo->outUnit ); } } dataInfo->inUnit = (UNIT) NULL; dataInfo->outUnit = (UNIT) NULL; return( 0 ); } /***/ /* showSlice: display status of process. /***/ int showSlice( funcInfo, dataInfo ) struct ProcFuncInfo *funcInfo; struct ProcDataInfo *dataInfo; { static int firstTime = 1; if (dataInfo->verbose) { TIMER_ON( msgTime ); if (dataInfo->verbose == 1 && firstTime) { (void) fprintf( stderr, "\n" ); if (dataInfo->varCountFlag) { (void) fprintf( stderr, "%-6s %dx%d Variable Count \n", dataInfo->fnName, dataInfo->size, dataInfo->quadState ); } else { (void) fprintf( stderr, "%-6s %dx%dx%d \n", dataInfo->fnName, dataInfo->size, dataInfo->sliceCount, dataInfo->quadState ); } (void) fflush( stderr ); firstTime = 0; } if (dataInfo->verbose > 1 && ((dataInfo->sliceCode == 1) || !(dataInfo->sliceCode % dataInfo->verbInc) || (dataInfo->sliceCode == dataInfo->sliceCount))) { if (dataInfo->varCountFlag) { (void) fprintf( stderr, "%-6s %6d \015", dataInfo->fnName, dataInfo->sliceCode ); } else { (void) fprintf( stderr, "%-6s %6d of %d \015", dataInfo->fnName, dataInfo->sliceCode, dataInfo->sliceCount ); } (void) fflush( stderr ); } if (dataInfo->verbose > 1 && dataInfo->sliceCode == dataInfo->sliceCount) { (void) fprintf( stderr, "\n" ); (void) fflush( stderr ); firstTime = 1; } (void) fflush( stderr ); TIMER_OFF( msgTime ); } return( 0 ); } /***/ /* showInfo: display a special one-time-only message in dataInfo->message. /***/ int showInfo( dataInfo ) struct ProcDataInfo *dataInfo; { char ctemp[NAMELEN+1]; int error; if (dataInfo->x11Flag) { (void) sprintf( ctemp, "xNotify -label %s %s &", dataInfo->fnName, dataInfo->message ); error = sysCmnd( ctemp ); } else { (void) fprintf( stderr, "%s: %s\n", dataInfo->fnName, dataInfo->message ); } return( error ); } /***/ /* showPluginInfo: display Plugin Function Help Info. /***/ int showPluginInfo() { char *fnPtr, *infoPtr, thisFn[NAMELEN+1], thisInfo[NAMELEN+1]; int nFn, nInfo, i; #ifndef USE_NMR_PLUGIN return( 0 ); #endif infoPtr = (char *)NULL; fnPtr = (char *)NULL; nInfo = 0; nFn = 0; if (!(fnPtr = getenv( "NMR_PLUGIN_FN" ))) return( 0 ); nFn = cntTokenC( fnPtr, ":" ); if (!nFn) return( 0 ); if (infoPtr = getenv( "NMR_PLUGIN_INFO" )) { nInfo = cntTokenC( infoPtr, ":" ); } (void) fprintf( stderr, "Available Plugin Functions:\n" ); for( i = 1; i <= nFn; i++ ) { thisFn[0] = '\0'; thisInfo[0] = '\0'; (void) strcpy( thisFn, getTokenC( i, fnPtr, ":" )); if (i <= nInfo) (void) strcpy( thisInfo, getTokenC( i, infoPtr, ":" )); (void) fprintf( stderr, " -fn %-8s %s\n", thisFn, thisInfo ); } return( 0 ); } /***/ /* getparams: extract command arguments for NMRPipe. /***/ int getparams( argc, argv, funcInfo, dataInfo, pathName, portName, serverListName, checkFlag, ttyOk ) struct ProcFuncInfo *funcInfo; struct ProcDataInfo *dataInfo; char **argv, *pathName, *portName, *serverListName; int argc, *checkFlag, *ttyOk; { struct ProcFuncInfo *infoPtr; static char inName[NAMELEN+1], outName[NAMELEN+1]; int i, count, fnFound, loc, allHelpFlag, error; char *sPtr, fnString[NAMELEN+1]; static char fnName[NAMELEN+1]; #ifndef LINT_CHECK #ifdef LINUX char *getcwd(); #else char *getwd(); #endif #endif /***/ /* Install defaults: /***/ (void) strcpy( fnString, "NULL" ); *checkFlag = 1; *ttyOk = 0; *pathName = '\0'; *portName = '\0'; *serverListName = '\0'; allHelpFlag = 0; /***/ /* Extract help mode. /* Print a banner. /***/ if (flagLoc( argc, argv, "-allHelp" )) allHelpFlag = 1; if (flagLoc( argc, argv, "-help" )) dataInfo->silentExit = 1; else allHelpFlag = 0; (void) lnType( argc, argv, "-help", "-help", "-TEST", "-QUIET" ); if (flagLoc( argc, argv, "-help" ) && !flagLoc( argc, argv, "-fn" )) { FPR_VERSION; FPR( stderr, "\n" ); FPR( stderr, "NMR Stream Processing:\n" ); FPR( stderr, "%s -fn fnName [fnArgs]", argv[0] ); FPR( stderr, " < inFile > outFile\n" ); FPR( stderr, "Optional Flags:\n" ); FPR( stderr, " -in inName NMRPipe Format Input File Name.\n" ); FPR( stderr, " -out outName NMRPipe Format Output File Name.\n" ); FPR( stderr, " -ov Force Overwrite of Existing Data.\n"); FPR( stderr, " -nofs Suppress File Size Check.\n" ); FPR( stderr, " -tty Suppress Check for I/O to TTY.\n" ); FPR( stderr, " -inPlace Allows in-place processing.\n" ); FPR( stderr, "Data Type Adjustment; Select Only One:\n" ); FPR( stderr, "Deleting Imaginary Data:\n" ); FPR( stderr, " -xi Delete Imaginaries;\n" ); FPR( stderr, " Complex Data Only.\n" ); FPR( stderr, " -dt Delete Imaginaries;\n" ); FPR( stderr, " Hypercomplex (Double Block) Only.\n" ); FPR( stderr, " -di Delete Current Imaginaries;\n" ); FPR( stderr, " Hypercomplex or Complex Data.\n" ); FPR( stderr, "Creating Empty Imaginary Data:\n" ); FPR( stderr, " -ai Create Imaginaries;\n" ); FPR( stderr, " Real Data Only.\n" ); FPR( stderr, " -ad Create Hypercomplex Imaginaries;\n" ); FPR( stderr, " Complex Data Only.\n" ); FPR( stderr, " -ac Create Current Imaginaries;\n" ); FPR( stderr, " Real or Complex Data.\n" ); FPR( stderr, "Processing or Pass-Through of a Selected Region:\n" ); FPR( stderr, " -select Y1 YN ... Specification of Region Limits.\n" ); FPR( stderr, " -outside Process vectors outside region.\n" ); FPR( stderr, " -inside Process vectors inside region;\n" ); FPR( stderr, " (Default).\n" ); FPR( stderr, "Report Modes:\n" ); FPR( stderr, " -verb verboseLevel [2]\n" ); FPR( stderr, " -inc verboseIncrement [16]\n" ); FPR( stderr, " -dbg debugReportLevel [0]\n" ); FPR( stderr, " -noSig Suppress Signal Catching.\n" ); FPR( stderr, " -X11 X11 is available for reports.\n" ); FPR( stderr, " -checkArgs Check for Unused Arguments (Default).\n" ); FPR( stderr, " -nocheckArgs No Checking for Unused Arguments.\n" ); FPR( stderr, "Help Text:\n" ); FPR( stderr, " -help Prints help text; use the\n" ); FPR( stderr, " -fn fnName switch for more.\n" ); FPR( stderr, " -allHelp Prints help text for all\n" ); FPR( stderr, " functions (requires -help).\n" ); FPR( stderr, "Parallel Processing:\n" ); FPR( stderr, " -client serverListName\n" ); FPR( stderr, " -server portFileName\n" ); FPR( stderr, " -sID serverID\n" ); FPR( stderr, " -inSock inSocketPort\n" ); FPR( stderr, " -outSock outSocketPort\n" ); FPR( stderr, " -path pathName [$cwd]\n" ); FPR( stderr, " -smt serverMaxTries [-1]\n" ); FPR( stderr, " -sto serveruSecTimeOut [%d]\n", getDefTimeout() ); FPR( stderr, "Header Control:\n" ); FPR( stderr, " -inHdr inHdrName Use Name or !cmnd.\n" ); FPR( stderr, " -outHdr outHdrName Use Name, !cmnd, or 'none'.\n" ); FPR( stderr, " -inSwap Byte Swap of Input ON.\n" ); FPR( stderr, " -outSwap Byte Swap of Output ON.\n" ); FPR( stderr, " -fdata loc1 parm1... Parameter/Value List.\n" ); FPR( stderr, "I/O Control:\n" ); FPR( stderr, " -buff ioBuffCount [0]\n" ); FPR( stderr, " -ibuff inputBuffCount [0]\n" ); FPR( stderr, " -obuff outputBuffCount [0]\n" ); FPR( stderr, " -mt maxTries [-1]\n" ); FPR( stderr, " -to uSecTimeOut [%d]\n", getDefTimeout() ); FPR( stderr, " -noRd Suppress Reading of Input.\n" ); FPR( stderr, " -noWr Suppress Writing of Output.\n" ); FPR( stderr, "\n" ); FPR( stderr, "Processing Functions:\n" ); for( infoPtr = funcInfoList; infoPtr->name; infoPtr++ ) { if (allHelpFlag) { (void) fprintf( stderr, "--------------------------" ); (void) fprintf( stderr, "--------------------------\n" ); (void) fprintf( stderr, "%s: %s.\n", infoPtr->name, infoPtr->descrip ); (void) fprintf( stderr, "Arguments: %s\n", infoPtr->args[0] ? infoPtr->args : "None." ); if (infoPtr->args[0]) { (void) fprintf( stderr, "Outline:\n\n" ); (void) (*infoPtr->func)( dataInfo ); } (void) fprintf( stderr, "\n" ); } else { count = cntToken( infoPtr->name ); for( i = 1; i <= count; i++ ) { (void) strcpy( fnName, getToken( i, infoPtr->name )); (void) fprintf( stderr, " %3s %-8s %-40s %-s\n", i == 1 ? "-fn" : " ", fnName, infoPtr->args, infoPtr->descrip ); } } } (void) showPluginInfo(); } /***/ /* Extract verbose mode level and increment. /* Extract overwrite mode and in-place mode. /* Extract input and output files, if any. /* Extract File Size Check mode. /* Abort if input and output file names match. /***/ if (loc = flagLoc( argc, argv, "-verb" )) { if (loc + 1 == nextFlag( argc, argv, loc )) dataInfo->verbose = 2; else (void) intArgD( argc, argv, "-verb", &dataInfo->verbose ); } if (flagLoc( argc, argv, "-noverb" )) dataInfo->verbose = 0; (void) intArgD( argc, argv, "-dbg", &dataInfo->debug ); (void) intArgD( argc, argv, "-inc", &dataInfo->verbInc ); if (flagLoc( argc, argv, "-select" )) { dataInfo->selectMode = SELECT_INSIDE; if (flagLoc( argc, argv, "-outside" )) DI->selectMode = SELECT_OUTSIDE; if (flagLoc( argc, argv, "-inside" )) DI->selectMode = SELECT_INSIDE; } if (flagLoc( argc, argv, "-inPlace" )) dataInfo->inPlace = 1; if (flagLoc( argc, argv, "-X11" )) dataInfo->x11Flag = 1; if (flagLoc( argc, argv, "-ov" )) dataInfo->ovFlag = 1; if (flagLoc( argc, argv, "-nofs" )) *checkFlag = 0; if (flagLoc( argc, argv, "-tty" )) *ttyOk = 1; if (dataInfo->inPlace) dataInfo->ovFlag = 1; if (flagLoc( argc, argv, "-in" )) { (void) strcpy( inName, strArg( argc, argv, "-in" )); dataInfo->inName = inName; } if (flagLoc( argc, argv, "-out" )) { (void) strcpy( outName, strArg( argc, argv, "-out" )); dataInfo->outName = outName; } if (dataInfo->inName && dataInfo->outName) { if (!strcmp( inName, outName )) dataInfo->inPlace = 1; } if (flagLoc( argc, argv, "-inHdr" )) { dataInfo->inHdrName = ptrArg( argc, argv, "-inHdr" ); } if (flagLoc( argc, argv, "-outHdr" )) { dataInfo->outHdrName = ptrArg( argc, argv, "-outHdr" ); } /***/ /* Data Type Adjustment: /* Extract XI (delete complex imags on output) mode. /* Extract DT (delete hypercomplex imags on output) mode. /* Extract DI (delete current imags, complex or hypercomplex) mode. /* Extract AI (add imags to real on output) mode. /* Extract AD (add imags to complex on output) mode. /* Extract AC (add imags to current on output) mode. /* /* Check for exclusive choices. /***/ count = 0; if (flagLoc( argc, argv, "-xi" )) count += dataInfo->typeFlags[XIFLAG] = 1; if (flagLoc( argc, argv, "-dt" )) count += dataInfo->typeFlags[DTFLAG] = 1; if (flagLoc( argc, argv, "-di" )) count += dataInfo->typeFlags[DIFLAG] = 1; if (flagLoc( argc, argv, "-ai" )) count += dataInfo->typeFlags[AIFLAG] = 1; if (flagLoc( argc, argv, "-ad" )) count += dataInfo->typeFlags[ADFLAG] = 1; if (flagLoc( argc, argv, "-ac" )) count += dataInfo->typeFlags[ACFLAG] = 1; if (count > 1) { (void) fprintf( stderr, "NMRPipe Error: Flags are exclusive:\n" ); (void) fprintf( stderr, " -xi -dt -di -ai -ad -ac\n" ); return( 1 ); } /***/ /* Extract Blocking and Buffered I/O parameters and format conversions: /***/ (void) intArgD( argc, argv, "-mt", &dataInfo->maxTries ); (void) intArgD( argc, argv, "-to", &dataInfo->timeOut ); (void) intArgD( argc, argv, "-delay", &dataInfo->finalDelay ); (void) intArgD( argc, argv, "-smt", &dataInfo->serverMaxTries ); (void) intArgD( argc, argv, "-sto", &dataInfo->serverTimeOut ); (void) intArgD( argc, argv, "-buff", &dataInfo->inCapacity ); (void) intArgD( argc, argv, "-buff", &dataInfo->outCapacity ); (void) intArgD( argc, argv, "-ibuff", &dataInfo->inCapacity ); (void) intArgD( argc, argv, "-obuff", &dataInfo->outCapacity ); (void) logArgD( argc, argv, "-inSwap", &dataInfo->inSwapFlag ); (void) logArgD( argc, argv, "-outSwap", &dataInfo->outSwapFlag ); if (flagLoc( argc, argv, "-noWr" )) dataInfo->wrFlag = 0; if (flagLoc( argc, argv, "-noRd" )) dataInfo->rdFlag = 0; /***/ /* Extract the function name. /* Find the function name in the function table. /***/ (void) strArgD( argc, argv, "-fn", fnString ); (void) strcpy( fnName, getToken( 1, fnString )); (void) raiseStr( fnName ); fnFound = 0; for( infoPtr = funcInfoList; infoPtr->name; infoPtr++ ) { count = cntToken( infoPtr->name ); while( count-- ) { if (!strcmp( fnName, getToken( count + 1, infoPtr->name ))) { dataInfo->fnName = fnName; *funcInfo = *infoPtr; fnFound = 1; } } } if (!fnFound) { (void) sprintf( dataInfo->message, "NMRPipe Error, unknown function %s.", fnName ); (void) showInfo( dataInfo ); return( 1 ); } /***/ /* Extract parallel processing client/server parameters: /* /* Nota Bene: Input and output buffers must be non-zero and equal. /* Server verbose level is normally suppressed. /***/ #ifdef LINUX sPtr = getcwd( pathName, NAMELEN ); #else sPtr = getwd( pathName ); #endif if (!sPtr) { (void) fprintf( stderr, "NMRPipe Error extracting working dir.\n" ); return( 1 ); } (void) strArgD( argc, argv, "-path", pathName ); if (flagLoc( argc, argv, "-inSock" )) { (void) intArgD( argc, argv, "-inSock", &dataInfo->inSock ); dataInfo->serverMode = SMODE_SOCKIO; dataInfo->inCapacity = 0; dataInfo->outCapacity = 0; } if (flagLoc( argc, argv, "-outSock" )) { (void) intArgD( argc, argv, "-outSock", &dataInfo->outSock ); dataInfo->serverMode = SMODE_SOCKIO; dataInfo->inCapacity = 0; dataInfo->outCapacity = 0; } if (flagLoc( argc, argv, "-client" )) { (void) strArgD( argc, argv, "-client", serverListName ); dataInfo->serverMode = SMODE_CLIENT; if (dataInfo->inCapacity < 1) dataInfo->inCapacity = 1; if (dataInfo->outCapacity < 1) dataInfo->outCapacity = 1; if (dataInfo->inCapacity > dataInfo->outCapacity) dataInfo->outCapacity = dataInfo->inCapacity; else dataInfo->inCapacity = dataInfo->outCapacity; } if (flagLoc( argc, argv, "-server" )) { (void) intArgD( argc, argv, "-sID", &dataInfo->serverID ); (void) strArgD( argc, argv, "-server", portName ); dataInfo->serverMode = SMODE_SERVER; if (dataInfo->inCapacity < 1) dataInfo->inCapacity = 1; if (dataInfo->outCapacity < 1) dataInfo->outCapacity = 1; if (dataInfo->inCapacity > dataInfo->outCapacity) dataInfo->outCapacity = dataInfo->inCapacity; else dataInfo->inCapacity = dataInfo->outCapacity; dataInfo->verbose = dataInfo->debug; } /***/ /* Call the processing function to extract its own arguments: /***/ if (funcInfo->func) { dataInfo->sliceCode = FN_PARAMS; if (error = (*funcInfo->func)( dataInfo )) return( error ); } else { return( 1 ); } return( 0 ); } /***/ /* Bottom. /***/