Funtools FAQ: Programming

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;
   >     }

   > `