diff options
Diffstat (limited to 'funtools/funtable.c')
-rw-r--r-- | funtools/funtable.c | 609 |
1 files changed, 0 insertions, 609 deletions
diff --git a/funtools/funtable.c b/funtools/funtable.c deleted file mode 100644 index 2418241..0000000 --- a/funtools/funtable.c +++ /dev/null @@ -1,609 +0,0 @@ -/* - * Copyright (c) 1999-2003 Smithsonian Astrophysical Observatory - */ - -#include <funtoolsP.h> -#include <find.h> -#include <zprocess.h> -#include <chandra.h> - -#define MAXROW 8192 -static int maxrow=MAXROW; -static char macrobuf[SZ_LINE]; - -#define SORTPROG "_funsort" - -typedef struct rowstruct{ - int x, y; - double value; - int region; - int n; -} *Row, RowRec; - -extern char *optarg; -extern int optind; - -#ifdef ANSI_FUNC -static char * -_funtableCB(char *name, void *client_data) -#else -static char *_funtableCB(name, client_data) - char *name; - void *client_data; -#endif -{ - int n=*(int *)client_data; - if( !strcasecmp(name, "n") ){ - snprintf(macrobuf, SZ_LINE-1, "%d", n); - return(macrobuf); - } - else{ - return NULL; - } -} - -#ifdef ANSI_FUNC -static void -usage (char *fname) -#else -static void usage(fname) - char *fname; -#endif -{ - fprintf(stderr, - "usage: %s [-a] [-i|-z] [-m] [-s cols] iname oname [columns]\n", - fname); - fprintf(stderr, "optional switches:\n"); - fprintf(stderr, " -a # append to existing output file as a table extension\n"); - fprintf(stderr, " -i # for image data, only generate X and Y columns\n"); - fprintf(stderr, " -m # for tables, write a separate file for each region\n"); - fprintf(stderr, " -s 'col1 ...' # columns on which to sort\n"); - fprintf(stderr, " -z # for image data, output zero-valued pixels\n"); - fprintf(stderr, "\n(version: %s)\n", FUN_VERSION); - exit(1); -} - -#ifdef ANSI_FUNC -int -main (int argc, char **argv) -#else -int -main(argc, argv) - int argc; - char **argv; -#endif -{ - int c; - int i, j, k, n; - int args; - int nfile; - int got, put; - int type, isize; - int dim1, dim2, dims; - int ichan, ochan, pid, status; - int rtype, rmode, roffset; - int r=0; - int rval=0; - int ncol=0; - int ip=0; - int doindiv=0, dozero=0, dosort=0, domulti=0; - int dtype, doffset, dmode, dn; - int plen, elen, flen; - int epad, ppad; - int rlen; - double dval; - char *iname=NULL; - char *oname=NULL; - char *mode=NULL; - char *sortcols=NULL; - char *actcols=NULL; - char *prog=NULL; - char *path=NULL; - char *ebuf=NULL; - char *eptr=NULL; - char *omode="w"; - char *s=NULL; - char *t=NULL; - char *u=NULL; - char *fits=NULL; - char *extn=NULL; - char col[SZ_LINE]; - char tbuf[SZ_LINE]; - char cmd[SZ_LINE]; - double *dbuf=NULL; - FILE *ifile; - Fun fun, tfun=NULL; - Fun *funs=NULL; - Filter filt=NULL; - FITSCard card; - Row rowbuf, row; - - /* exit on gio errors */ - if( !getenv("GERROR") ) - setgerror(2); - - /* we want the args in the same order in which they arrived, and - gnu getopt sometimes changes things without this */ - putenv("POSIXLY_CORRECT=true"); - - /* process switch arguments */ - while ((c = getopt(argc, argv, "aims:z")) != -1){ - switch(c){ - case 'a': - omode = "A"; - case 'i': - doindiv = 1; - break; - case 'm': - domulti=1; - break; - case 's': - dosort = 1; - sortcols=xstrdup(optarg); - break; - case 'z': - dozero = 1; - break; - } - } - - /* get maxrow,if user-specified */ - if( (s=getenv("FUN_MAXROW")) != NULL ) - maxrow = atoi(s); - - /* check for required arguments */ - args = argc - optind; - if( args < 2 ) usage(argv[0]); - iname = argv[optind+0]; - oname = xstrdup(argv[optind+1]); - - if( !(fun = FunOpen(iname, "rc", NULL)) ) - gerror(stderr, "can't FunOpen input file (or find extension): %s\n", - iname); - - /* for multiple outputs, we need a file for each region and one extra */ - if( domulti ){ - if( fun->filter ) - tfun = fun; - else{ - /* for non-disk files, we should punt, but we'll open a fake - Chandra/ACIS FITS file and hope for the best */ - if( !strncasecmp(iname, "stdin", 5) || !strncmp(iname, "-", 1) || - !strncasecmp(iname, "pipe:", 5) ){ - extn = FileExtension(iname); - plen = strlen(_prim); - if( (ppad = FT_BLOCK - (plen % FT_BLOCK)) == FT_BLOCK ) ppad = 0; - elen = strlen(_extn); - if( (epad = FT_BLOCK - (elen % FT_BLOCK)) == FT_BLOCK ) epad = 0; - flen = plen + ppad + elen + epad; - fits = (char *)calloc(flen+1, sizeof(char)); - memset(fits, (int)' ', flen); - memcpy(fits, _prim, plen); - memcpy(fits+plen+ppad, _extn, elen); - snprintf(tbuf, SZ_LINE-1, - "buf:%#lx:%d%s", (long)fits, flen, extn?extn:""); - tfun = FunOpen(tbuf, "r", NULL); - } - /* otherwise we can open the input file once again */ - else - tfun = FunOpen(iname, "r", NULL); - } - FunInfoGet(tfun, FUN_TYPE, &type, 0); - if( (type == FUN_IMAGE) || (type == FUN_ARRAY) ) - gerror(stderr, "can't output to multiple image files\n"); - strcpy(tbuf, "lexonly=true"); - if( tfun->bincols ){ - strcat(tbuf, ","); - strcat(tbuf, tfun->bincols); - } - filt = FilterOpen(tfun->header, tfun->filter, tbuf); - nfile = FilterRegionCount(TOK_IREG)+1; - FilterClose(filt); - if( tfun != fun ) - FunClose(tfun); - } - /* output a single file */ - else{ - nfile = 1; - /* current fun handle is always first */ - r = 0; - } - /* should work for multi and single file output */ - if( !(funs = (Fun *)xcalloc(nfile, sizeof(Fun))) ) - gerror(stderr, "can't allocate space for multiple fun handles\n"); - /* make up output file names and open files */ - if( domulti ){ - /* open the input FITS file */ - if( !(u=strchr(oname, '$')) ){ - s = calloc(SZ_LINE, sizeof(char)); - if( (t=strchr(oname, '.')) ){ - *t='\0'; - t++; - } - } - for(i=0; i<nfile; i++){ - /* put ivalue exactly where the user asked for it */ - if( u ) - s = ExpandMacro(oname, NULL, NULL, 0, _funtableCB, (void *)&i); - /* put ivalue before first '.' */ - else if( t ) - snprintf(s, SZ_LINE-1, "%s%d.%s", oname, i, t); - /* no hint about what to do -- prepend the ivalue */ - else - snprintf(s, SZ_LINE-1, "%s%d", oname, i); - /* last one triggers open of input file and possible copy */ - if( i == (nfile-1) ) - strncpy(tbuf, omode, SZ_LINE-1); - /* otherwise, just add output fd to list of output file */ - else - snprintf(tbuf, SZ_LINE-1, "%sd", omode); - /* open the output FITS table, preparing to copy input params. - must be done before accessing the input file to allow for ext copy */ - if( !(funs[i] = FunOpen(s, tbuf, fun)) ) - gerror(stderr, "can't FunOpen output file #%d: %s\n", i, s); - if( u && s ) xfree(s); - } - if( !u && s ) xfree(s); - } - else{ - if( !(funs[r] = FunOpen(oname, omode, fun)) ) - gerror(stderr, "can't FunOpen output file: %s\n", oname); - } - - /* get type of input data */ - FunInfoGet(fun, FUN_TYPE, &type, 0); - - /* process data by type */ - switch(type){ - case FUN_TABLE: - case FUN_EVENTS: - /* uness we are sorting, only read $region & $n into user space so we - can override their values (by merging with raw data) */ - if( !dosort ){ - FunColumnSelect(fun, sizeof(RowRec), "merge=replace", - "$REGION", "J", "rw", FUN_OFFSET(Row, region), - "$N", "J", "rw", FUN_OFFSET(Row, n), - NULL); - FunColumnActivate(fun, "-$REGION -$N", NULL); - } - - /* set activate specified output columns */ - if( args >= 3 ) actcols = argv[optind+2]; - FunColumnActivate(fun, actcols, NULL); - - /* if region was not activiated by the user, activate now for read only */ - if( domulti ){ - if( !FunColumnLookup(fun, COL_REGION_NAME, - 0, NULL, &rtype, &rmode, &roffset, NULL, NULL) || - !(rmode&COL_ACTIVE)) - FunColumnActivate(fun, "+$REGION", "mode=r"); - } - /* if we specified columns, we also can specify "mask=transparent" - and get all events, with the regionid (assuming we specified - the region column to display as well) */ - if( args >= 4 ) mode = argv[optind+3]; - - /* set up sorting, if necessary */ - if( dosort ){ - /* look for sort program */ - path = (char *)getenv("PATH"); - if( !(prog=Find(SORTPROG, "x", NULL, path)) ) - gerror(stderr, "can't locate sort program: %s\n", SORTPROG); - /* allow commas as delims */ - newdtable(","); - /* get the size of the input record */ - FunInfoGet(fun, FUN_ROWSIZE, &isize, 0); - /* construct argument list for sort program */ - snprintf(cmd, SZ_LINE-1, "%s -B%d", prog, isize); - rlen = SZ_LINE - strlen(cmd) - 1; - for(ncol=0; word(sortcols, col, &ip); ncol++ ){ - if( !FunColumnLookup(fun, col, 0, NULL, &dtype, &dmode, &doffset, &dn, - NULL) ){ - gerror(stderr, "can't find sort column '%s'\n", col); - } - if( !(dmode & COL_ACTIVE) ){ - gerror(stderr, "sort column '%s' must be active\n", col); - } - switch(dtype){ - case 'A': - snprintf(tbuf, SZ_LINE-1, "+t%d.%d", doffset, dn); - break; - case 'B': - snprintf(tbuf, SZ_LINE-1, "+B%d", doffset); - break; - case 'I': - snprintf(tbuf, SZ_LINE-1, "+s%d", doffset); - break; - case 'U': - snprintf(tbuf, SZ_LINE-1, "+S%d", doffset); - break; - case 'J': - snprintf(tbuf, SZ_LINE-1, "+i%d", doffset); - break; - case 'K': - snprintf(tbuf, SZ_LINE-1, "+l%d", doffset); - break; - case 'V': - snprintf(tbuf, SZ_LINE-1, "+I%d", doffset); - break; - case 'E': - snprintf(tbuf, SZ_LINE-1, "+f%d", doffset); - break; - case 'D': - snprintf(tbuf, SZ_LINE-1, "+d%d", doffset); - break; - default: - gerror(stderr, "unsupported sort data type for column %s\n", tbuf); - } - strncat(cmd, " ", rlen); - rlen--; - strncat(cmd, tbuf, rlen); - rlen -= strlen(tbuf); - if( rlen <=0 ){ - gerror(stderr, "too many arguments for sort\n"); - exit(1); - } - } - freedtable(); - /* start the sort program */ - if( !ProcessOpen(cmd, &ichan, &ochan, &pid) ){ - gerror(stderr, "ERROR: can't start sort program: %s\n", prog); - } - } - /* extract events */ - while( (ebuf = FunTableRowGet(fun, NULL, maxrow, mode, &got)) ){ - /* sort: write unsorted events to sort program */ - if( dosort ){ - write(ochan, ebuf, got*isize); - } - /* no sort: copy directly to output */ - else{ - /* multiple files -- one for each region id */ - if( domulti ){ - for(n=0; n<got; n++){ - row = (Row)ebuf+n; - r = MAX(0,row->region); - if( (put=FunTableRowPut(funs[r], row, 1, n, NULL)) != 1 ){ - gerror(stderr, "expected to write %d rows; only wrote %d\n", - 1, put); - } - } - } - /* single file output */ - else{ - if( (put=FunTableRowPut(funs[r], ebuf, got, 0, NULL)) != got ){ - gerror(stderr, "expected to write %d rows; only wrote %d\n", - got, put); - } - } - } - xfree(ebuf); - } - /* finish up sorting, if necessary */ - if( dosort ){ - /* signal EOF to sort program */ - close(ochan); - if( maxrow * isize > fun->maxbufsize ){ - if( isize > fun->maxbufsize ) - maxrow = 1; - else - maxrow = fun->maxbufsize / isize; - } - if( maxrow <= 0 ) maxrow = 1; - ebuf = xmalloc(maxrow*isize); - /* use stdio to avoid returning partial records */ - if( !(ifile = fdopen(ichan, "r")) ){ - gerror(stderr, "can't retrieve sorted records\n"); - } - while( (got=fread(ebuf, isize, maxrow, ifile)) ){ - /* multiple files -- one for each region id */ - if( domulti ){ - for(n=0; n<got; n++){ - /* point at next event */ - eptr = ebuf + (n*isize); - /* get region id */ - switch(rtype){ - case 'B': - rval = (int)*(unsigned char *)(eptr+roffset); - break; - case 'I': - rval = (int)*(short *)(eptr+roffset); - break; - case 'U': - rval = (int)*(unsigned short *)(eptr+roffset); - break; - case 'J': - rval = *(int *)(eptr+roffset); - break; - case 'K': -#if HAVE_LONG_LONG == 0 - gerror(stderr, - "64-bit data support not built (long long not available)\n"); -#endif - rval = *(longlong *)(eptr+roffset); - break; - case 'V': - rval = (int)*(unsigned int *)(eptr+roffset); - break; - case 'E': - rval = (int)*(float *)(eptr+roffset); - break; - case 'D': - rval = (int)*(double *)(eptr+roffset); - break; - } - /* offset is region id (but not less than 0) */ - r = MAX(0, rval); - /* output event to appropriate file */ - if( (put=FunTableRowPut(funs[r], eptr, 1, n, NULL)) != 1 ){ - gerror(stderr, "expected to write %d rows; only wrote %d\n", - 1, put); - } - } - } - /* single file output */ - else{ - /* output all events in this buffer to single file */ - if( (put=FunTableRowPut(funs[r], ebuf, got, 0, NULL)) != got ){ - gerror(stderr, "expected to write %d rows; only wrote %d\n", - got, put); - } - } - } - /* done with sorting process */ - ProcessClose(pid, &status); - fclose(ifile); - if( sortcols ) xfree(sortcols); - if( ebuf ) xfree(ebuf); - } - /* write out heap space, if it exists -- this quick hack needs cleanup! */ - if( fun->header && (ft_pcount(fun->header) > 0) ){ - int got; - int hlen; - char *heap; - hlen=ft_pcount(fun->header); - if( (heap = xmalloc(hlen)) ){ - /* read heap data */ - got = gread (fun->gio, heap, sizeof(char), hlen); - fun->bytes += got; - /* write heap data to each output file */ - for(n=0; n<nfile; n++){ - got = gwrite (funs[n]->gio, heap, sizeof(char), got); - funs[n]->bytes += got; - } - xfree(heap); - } - } - break; - case FUN_IMAGE: - case FUN_ARRAY: - if( dosort ) gerror(stderr, "can't sort image data\n"); - if( domulti ) gerror(stderr, "can't output to multiple image files\n"); - /* get image section information */ - FunInfoGet(fun, - FUN_SECT_DIM1, &dim1, - FUN_SECT_DIM2, &dim2, - FUN_SECT_DIMS, &dims, 0); - /* make a standard extension name for the new binary table */ - FunParamPuts(funs[r], "EXTNAME", 0, "EVENTS", NULL, 1); - if( dims >= 2 ){ - /* add tlmin/tlmax values for the x,y columns */ - FunParamPuti(funs[r], "TLMIN1", 0, 1, NULL, 1); - FunParamPuti(funs[r], "TLMAX1", 0, dim1, NULL, 1); - FunParamPuti(funs[r], "TLMIN2", 0, 1, NULL, 1); - FunParamPuti(funs[r], "TLMAX2", 0, dim2, NULL, 1); - /* transform WCS cards from image to binary table */ - for(i=1; i<=2; i++){ - if( (s=ft_headgets(fun->header, "CTYPE", i, NULL, &card)) && card ){ - FunParamPuts(funs[r], "TCTYP", i, s, NULL, 1); - xfree(s); - } - if((dval=ft_headgetr(fun->header, "CRVAL", i, 0.0, &card)) && card){ - FunParamPutd(funs[r], "TCRVL", i, dval, 7, NULL, 1); - } - if((dval=ft_headgetr(fun->header, "CDELT", i, 0.0, &card)) && card){ - FunParamPutd(funs[r], "TCDLT", i, dval, 7, NULL, 1); - } - if((dval=ft_headgetr(fun->header, "CROTA", i, 0.0, &card)) && card){ - FunParamPutd(funs[r], "TCROT", i, dval, 7, NULL, 1); - } - if((dval=ft_headgetr(fun->header, "CRPIX", i, 0.0, &card)) && card){ - FunParamPutd(funs[r], "TCRPX", i, dval, 7, NULL, 1); - } - } - /* select columns */ - if( doindiv ){ - FunColumnSelect(funs[r], sizeof(RowRec), NULL, - "X", "J", "w", FUN_OFFSET(Row, x), - "Y", "J", "w", FUN_OFFSET(Row, y), - NULL); - } - else{ - FunColumnSelect(funs[r], sizeof(RowRec), NULL, - "X", "J", "w", FUN_OFFSET(Row, x), - "Y", "J", "w", FUN_OFFSET(Row, y), - "VALUE", "D", "rw", FUN_OFFSET(Row, value), - NULL); - } - } - else{ - /* set dim2 to 1 for 1D image */ - dim2 = 1; - /* select columns */ - if( doindiv ){ - FunColumnSelect(funs[r], sizeof(RowRec), NULL, - "X", "J", "w", FUN_OFFSET(Row, x), - NULL); - } - else{ - FunColumnSelect(funs[r], sizeof(RowRec), NULL, - "X", "J", "w", FUN_OFFSET(Row, x), - "VALUE", "D", "rw", FUN_OFFSET(Row, value), - NULL); - } - } - /* we will make event row(s) for each x,y pixel */ - rowbuf = xcalloc(dim1, sizeof(RowRec)); - /* process each image row */ - for(j=1; j<=dim2; j++){ - /* extract image data and make event rows */ - if( !(dbuf = FunImageRowGet(fun, dbuf, j, j, "bitpix=-64")) ) - gerror(stderr, "can't FunImageRowGet: %s\n", iname); - if( doindiv ){ - /* generate an event for this pixel */ - for(i=0; i<dim1; i++){ - /* replicate individual row according to the value of the pixel. - don't replicate pixels values less than zero; round fp values */ - if( dbuf[i] >0 ){ - rowbuf[i].x = i+1; - rowbuf[i].y = j; - for(k=0; k<(int)(dbuf[i]+0.5); k++){ - /* write replicated row */ - if( FunTableRowPut(funs[r], &rowbuf[i], 1, 0, NULL) != 1 ) - gerror(stderr, "can't FunTableRowPut: %s\n", oname); - } - } - } - } - else{ - /* generate one event per pixel, with an accompanying value column */ - for(i=0; i<dim1; i++){ - /* don't write zero rows unless asked */ - if( dozero || (dbuf[i] > 0) ){ - rowbuf[i].x = i+1; - rowbuf[i].y = j; - rowbuf[i].value = dbuf[i]; - /* write row */ - if( FunTableRowPut(funs[r], &rowbuf[i], 1, 0, NULL) != 1 ) - gerror(stderr, "can't FunTableRowPut: %s\n", oname); - } - } - } - } - if( rowbuf ) xfree(rowbuf); - if( dbuf ) xfree(dbuf); - break; - default: - gerror(stderr, "unknown Funtools data type: %d\n", type); - exit(1); - } - - /* for multiple outputs, flush the input extension to all files at once */ - if( domulti ){ - FunFlush(fun, "copy=ref"); - } - - /* if we close output before input, all flushing is done automatically */ - /* free up space from multiple fun handles */ - for(i=0; i<nfile; i++){ - if( funs[i] ){ - FunClose(funs[i]); - } - } - xfree(funs); - if( oname ) xfree(oname); - if( fits ) xfree(fits); - if( extn ) xfree(extn); - FunClose(fun); - return(0); -} |