view tools/gate.c @ 0:5242703e91d3 tip

Initial checkin for AIM92 aimR8.2 (last updated May 1997).
author tomwalters
date Fri, 20 May 2011 15:19:45 +0100
parents
children
line wrap: on
line source
/*
  gate.c      gate numbers from input stream
  ------
    Read and write numbers of a given type.
    All numbers within the given gate ranges are replaced by the
    given gate <value>, (a real ie. float number).
    Gate ranges are: xrange (a time range, with optional time units)
    and:             yrange (an amplitude range, in real ie. float numbers).
    If the gate is not a <value>, but is an <operation>, then the numbers
    within the gate ranges are operated on as appropriate.
    Abbreviated forms of the operation names are allowed.

	<operation>     comment
	-----------     -----------------------------
	exclude         exclude numbers from output
	negate          negate numbers
	count           print a count of the numbers found in the gate range
			on the stderr.

Examples:

1. Replace all numbers <=0 by value 0  (ie. half-wave rectification).

gate yrange=min-0 val=0  file

2. Replace all numbers <=0 by their inverse (ie. full-wave rectification).

gate yrange=min-0 val=neg  file

3. Gate the onset of a signal: replace the first 20ms with zeroes.

gate xrange=0-20ms yrange=min-max val=0 file

4. Exclude all numbers <=0

gate yrange=min-0  val=exclude file

5. Exclude all numbers >0

gate yrange=1-max val=exclude file

6. Delete lines 4 to 8 inclusive from ascii input (lines numbered 0,1,2,...)

gate type=ASCII xrange=4-8 yrange=min-max val=exclude  file

7. Replace all numbers in the yrange -1 to +1 inclusive by 0

gate yrange=-1-1 val=0  file

8. Replace all instances of number 10 by -10

gate yrange=10 val=-10  file

9. Print a count of all numbers = 0

gate yrange=0 val=count file

10. Print a count of all numbers < 0

gate yrange=min--1  val=count file

*/


#include <stdio.h>
#include <math.h>
#include "options.h"
#include "units.h"
#include "strmatch.h"

char applic[] = "gate specific numbers in input stream using given value." ;

static char *helpstr, *debugstr, *sampstr, *xrstr, *yrstr, *gstr, *typestr ;

static Options option[] = {
    {   "help"      ,   "off"       ,  &helpstr     ,   "help"                      , DEBUG   },
    {   "debug"     ,   "off"       ,  &debugstr    ,   "debugging switch"          , DEBUG   },
    {   "samplerate",   "20kHz"     ,  &sampstr     ,   "samplerate "               , VAL     },
    {   "xrange"    ,   "min-max"   ,  &xrstr       ,   "time range"                , VAL     },
    {   "yrange"    ,   "min-0"     ,  &yrstr       ,   "amplitude range"           , VAL     },
    {   "value"     ,   "0"         ,  &gstr        ,   "replacement value or <operation>", VAL     },
    {   "type"      ,   "short"     ,  &typestr     ,   "datatype"                  , VAL     },
   ( char * ) 0 } ;


int    samplerate  ;
int    type        ;    /* datatype index */

main(argc, argv)
int    argc;
char **argv;
{
    FILE   *fp ;
    int     i, n=0, ax, bx, real_range(), helpoperations() ;
    float   ay, by, x, val ;

    fp = openopts( option, argc, argv ) ;
    if ( !isoff( helpstr ) )
	helpopts1( helpstr, argv[0], applic, option, helpoperations ) ;

    samplerate = to_Hz( sampstr, 0 ) ;

    if ( ( type = typeindex( typestr ) ) < 0 ) {
	fprintf( stderr, "gate: bad type [%s]\n", typestr ) ;
	exit( 1 ) ;
    }

    if ( range( xrstr, &ax, &bx, samplerate ) == 0 ) {
	fprintf(stderr,"gate: bad xrange [%s]\n", xrstr ) ;
	exit( 1 ) ;
    }

    if ( real_range( yrstr, &ay, &by ) == 0 ) {
	fprintf(stderr,"gate: bad yrange [%s]\n", yrstr ) ;
	exit( 1 ) ;
    }

    if ( iststr( gstr, "count" ) ) {            /* gate=count */

	for ( i = 0 ; readitem( &x, type, 1, fp ) ; i++ )
	    if ( i >= ax && ( i <= bx || bx == (-1) ) )
		if ( x >= ay && x <= by )
		    n++ ;
	fprintf(stderr,"%d numbers in gate\n", n);
    }


    else if ( iststr( gstr, "exclude" ) ) {     /* gate=exclude */

	for ( i = 0 ; readitem( &x, type, 1, fp ) ; i++ ) {
	    if ( i < ax || ( i > bx && bx != (-1) ) )
		writeitem( &x, type, 1, stdout ) ;
	    else if ( x < ay || x > by )
		writeitem( &x, type, 1, stdout ) ;
	}
    }

    else if ( iststr( gstr, "negate" ) ) {      /* gate=negate  */

	for ( i = 0 ; readitem( &x, type, 1, fp ) ; i++ ) {
	    if ( i < ax || ( i > bx && bx != (-1) ) )
		writeitem( &x, type, 1, stdout ) ;
	    else if ( x < ay || x > by )
		writeitem( &x, type, 1, stdout ) ;
	    else {
		x = ( -x ) ;
		writeitem( &x, type, 1, stdout ) ;
	    }
	}
    }

    else {                                      /* gate=<value> */
	val = atof( gstr ) ;
	for ( i = 0 ; readitem( &x, type, 1, fp ) ; i++ ) {
	    if ( i < ax || ( i > bx && bx != (-1) ) )
		writeitem( &x, type, 1, stdout ) ;
	    else if ( x < ay || x > by )
		writeitem( &x, type, 1, stdout ) ;
	    else
		writeitem( &val, type, 1, stdout ) ;
	}
    }

    fclose(fp);
}


/*
Parse a range specifier into real numbers representing amplitude.
*/

int real_range( s, a, b )
char  *s ;
float *a, *b ;
{
    char *val1, *val2 ;

    if ( getvals( s, &val1, &val2, "-" ) == (-3) )
	return ( 0 ) ;
    if      ( ismin( val1 ) ) *a = (-1e10) ;    /* minimum         */
    else if ( ismax( val1 ) ) *a =   1e10  ;    /* maximum         */
    else *a = atof( val1 ) ;

    if ( isempty( val2 ) )    *b = *a ;          /* single object        */
    else if ( ismin( val2 ) ) *b = (-1e10) ;
    else if ( ismax( val2 ) ) *b =   1e10  ;
    else *b = atof( val2 ) ;

    if ( *a > *b ) return 0 ;
    return 1 ;
}


helpoperations()
{
    fprintf(stderr,"\n<operation>:          \n");
    fprintf(stderr,"            exclude     exclude numbers in gate range from output \n");
    fprintf(stderr,"            negate      negate numbers in gate range              \n");
    fprintf(stderr,"            count       print count of numbers in gate range      \n");
    exit( 1 ) ;
}