1. What are the compile/link commands for various platforms?

    Assuming, for example, that funtools is installed in /soft/saord and that gcc is the compiler being used:

    1. Linux:
      gcc -g -I/soft/saord/include -c -o foo.o foo.c
      gcc -g foo.o -o foo -L/soft/saord/lib -lfuntools -ldl -lm
      
    2. Apple OS X:
      gcc -g -no-cpp-precomp -fno-common -I/soft/saord/include -c -o foo.o foo.c
      gcc -g foo.o -o foo -L/soft/saord/lib -lfuntools -lm
      
    3. Sun Solaris:
      gcc -g -no-cpp-precomp -fno-common -I/soft/saord/include -c -o foo.o foo.c
      gcc -g foo.o -o foo -L/soft/saord/lib -lfuntools -lsocket -lnsl -ldl -lm
      
  2. What is the simplest possible program?

    #include <stdlib.h>
    #include <funtools.h>
    
    int main(int argc, char **argv)
    {
      Fun fun;
    
      /* sanity check */
      if( argc < 2 ) return 1;
      /* open file for reading */
      if( !(fun=FunOpen(argv[1], "r", NULL)) ){
        fprintf(stderr, "ERROR: can't open funtools file: %s\n", argv[1]);
        return 1;
      }
      /* close file */
      FunClose(fun);
      return 0;
    }
    
  3. How do I read and display events?

    #
    #include <stdlib.h>
    #include <funtools.h>
    
    typedef struct evstruct{
      double x, y;
      int pi, pha;
    } *Ev, EvRec;
    
    int main(int argc, char **argv)
    {
      int i, got;
      int maxrow=1024;
      Ev ev, ebuf=NULL;
      Fun fun;
    
      /* sanity check */
      if( argc < 2 ) return 1;
      /* open file for reading */
      if( !(fun=FunOpen(argv[1], "r", NULL)) ){
        fprintf(stderr, "ERROR: can't open funtools file: %s\n", argv[1]);
        return 1;
      }
      /* select columns to read (and data types to convert to) */
      got = FunColumnSelect(fun, sizeof(EvRec), NULL,
    			"x",       "D", "r", FUN_OFFSET(Ev, x),
    			"y",       "D", "r", FUN_OFFSET(Ev, y),
    			"pha",     "J", "r", FUN_OFFSET(Ev, pha),
    			"pi",      "J", "r", FUN_OFFSET(Ev, pi),
    			NULL);
      /* read and process events */
      while( (ebuf=(void *)FunTableRowGet(fun, NULL, maxrow, NULL, &got)) && got ){
        for(i=0; i<got; i++){
          ev = (Ev)ebuf+i;
          fprintf(stdout, "%.1f %.1f %d %d\n", ev->x, ev->y, ev->pha, ev->pi);
        }
        if( ebuf) free(ebuf);
      }
      /* close file */
      FunClose(fun);
      return 0;
    }
    
  4. How do I change the value of a single column in all events?

    #include <stdlib.h>
    #include <funtools.h>
    
    typedef struct evstruct{
      int pi;
    } *Ev, EvRec;
    
    int main(int argc, char **argv)
    {
      int i, got;
      int maxrow=1024;
      Ev ev, ebuf=NULL;
      Fun fun, ofun;
    
      /* sanity check */
      if( argc < 3 ) return 1;
      /* open file for reading */
      if( !(fun=FunOpen(argv[1], "r", NULL)) ){
        fprintf(stderr, "ERROR: can't open input funtools file: %s\n", argv[1]);
        return 1;
      }
      /* open output file and inherit header params, columns, etc. from input */
      if( !(ofun=FunOpen(argv[2], "w", fun)) ){
        fprintf(stderr, "ERROR: can't open output funtools file: %s\n", argv[2]);
        return 1;
      }
      /* select columns to read (and data types to convert to) */
      /* use "merge=update" to change value while keeping original data type */
      /* use "merge=replace" to change boh the value and data type */
      got = FunColumnSelect(fun, sizeof(EvRec), "merge=update",
    			"pi",     "J", "rw", FUN_OFFSET(Ev, pi),
    			NULL);
      /* read and process events */
      while( (ebuf=(void *)FunTableRowGet(fun, NULL, maxrow, NULL, &got)) && got ){
        for(i=0; i<got; i++){
          ev = (Ev)ebuf+i;
          ev->pi = ev->pi + 1;
        }
        /* write rows to output file */
        if( FunTableRowPut(ofun, ebuf, got, 0, NULL) != got ){
          fprintf(stderr, "ERROR: writing to funtools file: %s\n", argv[2]);
          return 1;
        }
        if( ebuf) free(ebuf);
      }
      /* close files */
      FunClose(ofun);
      FunClose(fun);
      return 0;
    }
    
  5. How do I process events based on the region each is in?

    #include <stdlib.h>
    #include <funtools.h>
    
    typedef struct evstruct{
      int x, y;
      int pi, pha;
      int region;
    } *Ev, EvRec;
    
    int main(int argc, char **argv)
    {
      int i, got;
      int maxrow=1024;
      Ev ev, ebuf=NULL;
      Fun fun;
    
      /* sanity check */
      if( argc < 2 ) return 1;
      /* open file for reading */
      if( !(fun=FunOpen(argv[1], "r", NULL)) ){
        fprintf(stderr, "ERROR: can't open funtools file: %s\n", argv[1]);
        return 1;
      }
      /* select columns to read (and data types to convert to) */
      /* specifying $REGION will retrieve the one-indexed region number */
      /* events passing the filter but not in a region will have value -1 */
      got = FunColumnSelect(fun, sizeof(EvRec), NULL,
    			"x",       "J", "r", FUN_OFFSET(Ev, x),
    			"y",       "J", "r", FUN_OFFSET(Ev, y),
    			"pha",     "J", "r", FUN_OFFSET(Ev, pha),
    			"pi",      "J", "r", FUN_OFFSET(Ev, pi),
    			"$REGION", "J", "r", FUN_OFFSET(Ev, region),
    			NULL);
      /* read and process events */
      while( (ebuf=(void *)FunTableRowGet(fun, NULL, maxrow, NULL, &got)) && got ){
        for(i=0; i<got; i++){
          ev = (Ev)ebuf+i;
          fprintf(stdout, "%4d %4d %3d %3d %4d\n", 
    	      ev->x, ev->y, ev->pha, ev->pi, ev->region);
        }
        if( ebuf) free(ebuf);
      }
      /* close file */
      FunClose(fun);
      return 0;
    }
    
  6. How do I make a FITS event file from a non-FITS source (and add my own params)?

    #include <stdlib.h>
    #include <funtools.h>
    
    typedef struct evstruct{
      int x, y;
      int pha;
      float pi;
    } *Ev, EvRec;
    
    int main(int argc, char **argv)
    {
      int i, nev;
      int pmod=16, put=1;
      double pinc=0.1234;
      char xbuf[32], ybuf[32];
      Ev ev;
      Fun ofun;
    
      /* sanity check */
      if( argc < 3 ) return 1;
      /* open new file for writing */
      if( !(ofun=FunOpen(argv[1], "w", NULL)) ){
        fprintf(stderr, "ERROR: can't open funtools file: %s\n", argv[1]);
        return 1;
      }
      if( (nev = atoi(argv[2])) <=0 ) return 1;
      ev = (Ev)calloc(1, sizeof(EvRec));
      /* The pair of numeric values specify the data value range, used to bin
         x, y into an image. They are permitted but not needed for pi and pha */
      sprintf(xbuf, "J:1:%d", nev);
      sprintf(ybuf, "J:1:%d", nev);
      /* select columns to write */
      FunColumnSelect(ofun, sizeof(EvRec), NULL,
    		  "x",   xbuf,      "w", FUN_OFFSET(Ev, x),
    		  "y",   ybuf,      "w", FUN_OFFSET(Ev, y),
    		  "pha", "J:1:16",  "w", FUN_OFFSET(Ev, pha),
    		  "pi",  "E",       "w", FUN_OFFSET(Ev, pi),
    		  NULL);
      /* write params to header; generally added before first event is written */
      FunParamPuti(ofun, "PMOD",  0, pmod,  "modulus for pha generation", 1);
      FunParamPutd(ofun, "PINC",  0, pinc,  7, "increment for pi generation", 1);
      /* make up events */
      for(i=1; i<=nev; i++){
        ev->x = i; ev->y = nev-i+1; ev->pha = i % pmod; ev->pi = ev->pha + pinc;
        /* write rows to output file -- this can be done in batches, of course */
        if( FunTableRowPut(ofun, ev, put, 0, NULL) != put ){
          fprintf(stderr, "ERROR: writing to funtools file: %s\n", argv[1]);
          return 1;
        }
      }
      if( ev) free(ev);
      /* close file */
      FunClose(ofun);
      return 0;
    }
    
  7. How do I process an image in double float format?

    #include <stdlib.h>
    #include <funtools.h>
    
    int main(int argc, char **argv)
    {
      int i, j, dim1, dim2;
      double *buf;
      Fun fun;
    
      /* sanity check */
      if( argc < 2 ) return 1;
      /* open file for reading */
      if( !(fun=FunOpen(argv[1], "r", NULL)) ){
        fprintf(stderr, "ERROR: can't open funtools file: %s\n", argv[1]);
        return 1;
      }
      /* extract (and bin, if necessary) data into a double prec. image buffer */
      if( !(buf = FunImageGet(fun, NULL, "bitpix=-64")) ){
        fprintf(stderr, "ERROR: can't get image: %s\n", argv[1]);
        return 1;
      }
      /* get image dimensions after FunImageGet, in case an image section
         was specified on the command line, which changes image dimensions */
      FunInfoGet(fun, FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, 0);
      /* loop through image */
      for(i=0; i<dim2; i++){
        for(j=0; j<dim1; j++){
          fprintf(stdout, "%.1f ", buf[i*dim1+j]);
        }
        fprintf(stdout, "\n");
      }
      /* close file */
      FunClose(fun);
      return 0;
    }
    
  8. How do I process an image in its native format?
    #include <funtools.h>
    
    int main(int argc, char **argv)
    {
      int i, j, bitpix, dim1, dim2;
      double *buf;
      unsigned char *cbuf;
      short *sbuf;
      int *ibuf;
      float *fbuf;
      double *dbuf;
      Fun fun;
    
      /* sanity check */
      if( argc < 2 ) return 1;
      /* open file for reading */
      if( !(fun=FunOpen(argv[1], "r", NULL)) ){
        fprintf(stderr, "ERROR: can't open funtools file: %s\n", argv[1]);
        return 1;
      }
      /* extract (and bin, if necessary) data into a buffer whose
         data type is not specified and therefore is that of the file */
      if( !(buf = FunImageGet(fun, NULL, NULL)) ){
        fprintf(stderr, "ERROR: can't get image: %s\n", argv[1]);
        return 1;
      }
      /* get image dimensions after FunImageGet, in case an image section
         was specified on the command line, which changes image dimensions */
      FunInfoGet(fun, FUN_SECT_BITPIX, &bitpix, 
    	     FUN_SECT_DIM1, &dim1, FUN_SECT_DIM2, &dim2, 0);
      /* set appropriate data type buffer to point to image buffer */
      switch(bitpix){
        case 8:   cbuf = (unsigned char *)buf; break;
        case 16:  sbuf = (short *)buf;         break;
        case 32:  ibuf = (int *)buf;           break;
        case -32: fbuf = (float *)buf;         break;
        case -64: dbuf = (double *)buf;        break;
      }
      /* loop through image */
      for(i=0; i<dim2; i++){
        for(j=0; j<dim1; j++){
          switch(bitpix){
            case 8:   fprintf(stdout, "%4d ",  cbuf[i*dim1+j]);  break;
            case 16:  fprintf(stdout, "%6d ",  sbuf[i*dim1+j]);  break;
            case 32:  fprintf(stdout, "%9d ",  ibuf[i*dim1+j]);  break;
            case -32: fprintf(stdout, "%.2f ", fbuf[i*dim1+j]);  break;
            case -64: fprintf(stdout, "%.6f ", dbuf[i*dim1+j]);  break;
          }
        }
        fprintf(stdout, "\n");
      }
      /* close file */
      FunClose(fun);
      return 0;
    }