Ejemplo n.º 1
0
int fitstable_add_fits_columns_as_struct3(const fitstable_t* intab,
					  fitstable_t* outtab,
					  const sl* colnames,
					  int c_offset) {
	int i, NC;
	int noc = ncols(outtab);
	NC = sl_size(colnames);
	for (i=0; i<NC; i++) {
		const qfits_col* qcol;
		fitscol_t* col;
		const char* name = sl_get_const(colnames, i);
		int j = fits_find_column(intab->table, name);
		int off;
		if (j == -1) {
			ERROR("Failed to find FITS column \"%s\"", name);
			return -1;
		}
		qcol = qfits_table_get_col(intab->table, j);
		// We give the offset of the column in the *input* table, so that
		// the resulting "outtab" can handle raw data from the "intab".
		off = fits_offset_of_column(intab->table, j);
		fitstable_add_read_column_struct(outtab, qcol->atom_type, qcol->atom_nb,
						 c_offset + off, qcol->atom_type, qcol->tlabel, TRUE);
		// set the FITS column number.
		col = getcol(outtab, ncols(outtab)-1);
		col->col = noc + i;
	}
	return 0;
}
Ejemplo n.º 2
0
int fitstable_get_type(fitstable_t* tab, const char* name) {
    qfits_col* qcol;
    int colnum;
    colnum = fits_find_column(tab->table, name);
    if (colnum == -1)
        return -1;
    qcol = tab->table->col + colnum;
    return qcol->atom_type;
}
Ejemplo n.º 3
0
int main(int argc, char *argv[]) {
    int argchar;

	char* infn = NULL;
	char* outfn = NULL;
	FILE* fin = NULL;
	FILE* fout = NULL;
	pl* cols;
	char* progname = argv[0];
	int nextens;
	int ext;
	int NC;
	int start, size;
    anqfits_t* anq = NULL;

	qfits_table* outtable;
	unsigned char* buffer;

	cols = pl_new(16);

    while ((argchar = getopt (argc, argv, OPTIONS)) != -1)
        switch (argchar) {
        case 'c':
			pl_append(cols, optarg);
            break;
        case 'i':
			infn = optarg;
			break;
        case 'o':
			outfn = optarg;
			break;
        case '?':
        case 'h':
			printHelp(progname);
            return 0;
        default:
            return -1;
        }

	if (!infn || !outfn || !pl_size(cols)) {
		printHelp(progname);
		exit(-1);
	}

    fin = fopen(infn, "rb");
    if (!fin) {
        ERROR("Failed to open input file %s: %s\n", infn, strerror(errno));
        exit(-1);
    }

    fout = fopen(outfn, "wb");
    if (!fout) {
        ERROR("Failed to open output file %s: %s\n", outfn, strerror(errno));
        exit(-1);
    }

	// copy the main header exactly.
    anq = anqfits_open(infn);
    if (!anq) {
        ERROR("Failed to read \"%s\"", infn);
        exit(-1);
    }
    start = anqfits_header_start(anq, 0);
    size  = anqfits_header_size (anq, 0);
    if (pipe_file_offset(fin, start, size, fout)) {
        ERROR("Failed to copy primary header.\n");
        exit(-1);
    }

	NC = pl_size(cols);
	nextens = anqfits_n_ext(anq);
	printf("Translating %i extensions.\n", nextens);
	buffer = NULL;
	for (ext=1; ext<nextens; ext++) {
		int c2, c;
		int columns[NC];
		int sizes[NC];
		int offsets[NC];
		int offset = 0;
		int off, n;
		int totalsize = 0;
		const int BLOCK=1000;
		qfits_table* table;
		qfits_header* header;
		qfits_header* tablehdr;

		if (ext%100 == 0) {
			printf("Extension %i.\n", ext);
			fflush(stdout);
		}

		if (!anqfits_is_table(anq, ext)) {
			ERROR("extention %i isn't a table.\n", ext);
			// HACK - just copy it.
			return -1;
		}
		table = anqfits_get_table(anq, ext);
		if (!table) {
			ERROR("failed to open table: file %s, extension %i.\n", infn, ext);
			return -1;
		}
        header = anqfits_get_header(anq, ext);
		if (!header) {
			ERROR("failed to read header: extension %i\n", ext);
			exit(-1);
		}

		outtable = qfits_table_new(outfn, QFITS_BINTABLE, 0, NC, table->nr);
		outtable->tab_w = 0;
		
		for (c=0; c<pl_size(cols); c++) {
			columns[c] = -1;
		}
		for (c=0; c<pl_size(cols); c++) {
			char* colname = pl_get(cols, c);
			qfits_col* col;
			c2 = fits_find_column(table, colname);
			if (c2 == -1) {
				ERROR("Extension %i: failed to find column named %s\n",
						ext, colname);
				exit(-1);
			}
			col = table->col + c2;
			columns[c] = c2;
			sizes[c] = col->atom_nb * col->atom_size;
			offsets[c] = offset;
			offset += sizes[c];

			qfits_col_fill(outtable->col + c,
						   col->atom_nb, col->atom_dec_nb,
						   col->atom_size, col->atom_type,
						   col->tlabel, col->tunit,
						   col->nullval, col->tdisp,
						   col->zero_present,
						   col->zero,
						   col->scale_present,
						   col->scale,
						   outtable->tab_w);
			outtable->tab_w += sizes[c];
		}
		totalsize = offset;

		tablehdr = qfits_table_ext_header_default(outtable);
		// add any headers from the original table that aren't part of the BINTABLE extension.
        fits_copy_non_table_headers(tablehdr, header);
		qfits_header_dump(tablehdr, fout);
		qfits_header_destroy(tablehdr);
		
		buffer = realloc(buffer, totalsize * BLOCK);

		for (off=0; off<table->nr; off+=n) {
			if (off + BLOCK > table->nr)
				n = table->nr - off;
			else
				n = BLOCK;
			for (c=0; c<pl_size(cols); c++)
				qfits_query_column_seq_to_array_no_endian_swap
					(table, columns[c], off, n, buffer + offsets[c], totalsize);
			if (fwrite(buffer, totalsize, n, fout) != n) {
				ERROR("Error writing a block of data: ext %i: %s\n", ext, strerror(errno));
				exit(-1);
			}
		}

		qfits_table_close(outtable);
		fits_pad_file(fout);
		qfits_header_destroy(header);
		qfits_table_close(table);
	}
	free(buffer);

	if (fclose(fout)) {
		ERROR("Error closing output file: %s\n", strerror(errno));
	}
	fclose(fin);

    anqfits_close(anq);

	pl_free(cols);
	return 0;
}
Ejemplo n.º 4
0
/**
 If "inds" is non-NULL, it's a list of indices to read.
 */
static void* read_array_into(const fitstable_t* tab,
							 const char* colname, tfits_type ctype,
							 anbool array_ok,
							 int offset, const int* inds, int Nread,
							 void* dest, int deststride,
							 int desired_arraysize,
							 int* p_arraysize) {
    int colnum;
    qfits_col* col;
    int fitssize;
    int csize;
    int fitstype;
    int arraysize;

	char* tempdata = NULL;
    char* cdata;
	char* fitsdata;
	int cstride;
	int fitsstride;
    int N;

    colnum = fits_find_column(tab->table, colname);
    if (colnum == -1) {
        ERROR("Column \"%s\" not found in FITS table %s", colname, tab->fn);
        return NULL;
    }
    col = tab->table->col + colnum;
    if (!array_ok && (col->atom_nb != 1)) {
        ERROR("Column \"%s\" in FITS table %s is an array of size %i, not a scalar",
              colname, tab->fn, col->atom_nb);
        return NULL;
    }

    arraysize = col->atom_nb;
	if (p_arraysize)
		*p_arraysize = arraysize;
	if (desired_arraysize && arraysize != desired_arraysize) {
		ERROR("Column \"%s\" has array size %i but you wanted %i", colname, arraysize, desired_arraysize);
		return NULL;
	}
    fitstype = col->atom_type;
    fitssize = fits_get_atom_size(fitstype);
    csize = fits_get_atom_size(ctype);
    N = tab->table->nr;
    if (Nread == -1)
        Nread = N;
    if (offset == -1)
        offset = 0;

	if (dest)
		cdata = dest;
	else
		cdata = calloc(Nread * arraysize, csize);

	if (dest && deststride > 0)
		cstride = deststride;
	else
		cstride = csize * arraysize;

	fitsstride = fitssize * arraysize;
	if (csize < fitssize) {
		// Need to allocate a bigger temp array and down-convert the data.
		// HACK - could set data=tempdata and realloc after (if 'dest' is NULL)
		tempdata = calloc(Nread * arraysize, fitssize);
		fitsdata = tempdata;
	} else {
		// We'll read the data into the first fraction of the output array.
		fitsdata = cdata;
	}

	if (in_memory(tab)) {
		int i;
		int off;
		int sz;
		if (!tab->rows) {
			ERROR("No data has been written to this fitstable");
			return NULL;
		}
		if (offset + Nread > bl_size(tab->rows)) {
			ERROR("Number of data items requested exceeds number of rows: offset %i, n %i, nrows %zu", offset, Nread, bl_size(tab->rows));
			return NULL;
		}
		off = fits_offset_of_column(tab->table, colnum);
		sz = fitsstride;
		if (inds) {
			for (i=0; i<Nread; i++)
				memcpy(fitsdata + i * fitsstride,
					   ((char*)bl_access(tab->rows, inds[i])) + off,
					   sz);
		} else {
			for (i=0; i<Nread; i++)
				memcpy(fitsdata + i * fitsstride,
					   ((char*)bl_access(tab->rows, offset+i)) + off,
					   sz);
		}
	} else {
		int res;
		if (inds) {
			res = qfits_query_column_seq_to_array_inds(tab->table, colnum, inds, Nread,
													   (unsigned char*)fitsdata, fitsstride);
		} else {
			res = qfits_query_column_seq_to_array(tab->table, colnum, offset, Nread,
												  (unsigned char*)fitsdata, fitsstride);
		}
		if (res) {
			ERROR("Failed to read column from FITS file");
			// MEMLEAK!
			return NULL;
		}
	}

	if (fitstype != ctype) {
		if (csize <= fitssize) {
			// work forward
			fits_convert_data(cdata, cstride, ctype,
							  fitsdata, fitsstride, fitstype,
							  arraysize, Nread);
		} else {
			// work backward from the end of the array
            fits_convert_data(cdata + (((off_t)Nread*(off_t)arraysize)-1) * (off_t)csize,
							  -csize, ctype,
							  fitsdata + (((off_t)Nread*(off_t)arraysize)-1) * (off_t)fitssize,
							  -fitssize, fitstype,
							  1, Nread * arraysize);
		}
	}

	free(tempdata);
	return cdata;
}
Ejemplo n.º 5
0
int fitstable_read_extension(fitstable_t* tab, int ext) {
    int i;
    int ok = 1;

	if (fitstable_open_extension(tab, ext))
		return -1;

	if (tab->readfid) {
		// close FID so that table->end_table_offset gets refreshed.
		fclose(tab->readfid);
		tab->readfid = NULL;
	}

    for (i=0; i<ncols(tab); i++) {
        fitscol_t* col = getcol(tab, i);
        qfits_col* qcol;

        // FIXME? set this here?
        col->csize = fits_get_atom_size(col->ctype);

        // Column found?
        col->col = fits_find_column(tab->table, col->colname);
        if (col->col == -1)
            continue;
        qcol = tab->table->col + col->col;

        // Type & array size correct?
        if (col->fitstype != fitscolumn_any_type() &&
            col->fitstype != qcol->atom_type) {
            col->col = -1;
            continue;
        }
        col->fitstype = qcol->atom_type;
        col->fitssize = fits_get_atom_size(col->fitstype);

        if (col->arraysize) {
            if (col->arraysize != qcol->atom_nb) {
                col->col = -1;
                continue;
            }
        }
		/*  This was causing problems with copying startree tag-along data (Tycho2 test case: FLAGS column)

		 if (col->fitstype == TFITS_BIN_TYPE_X) {
		 // ??? really??
		 col->arraysize = 8 * qcol->atom_nb;
		 } else {
		 col->arraysize = qcol->atom_nb;
		 }
		 */
		col->arraysize = qcol->atom_nb;
    }

    if (tab->br) {
        buffered_read_reset(tab->br);
        tab->br->ntotal = tab->table->nr;
    }

    for (i=0; i<ncols(tab); i++) {
        fitscol_t* col = getcol(tab, i);
        if (col->col == -1 && col->required) {
            ok = 0;
            break;
        }
    }
	if (ok) return 0;
	return -1;
}
Ejemplo n.º 6
0
int tabsort(const char* infn, const char* outfn, const char* colname,
            int descending) {
	FILE* fin;
	FILE* fout;
	int ext, nextens;
	off_t start, size;
    void* data = NULL;
    int* perm = NULL;
    unsigned char* map = NULL;
    size_t mapsize = 0;
    anqfits_t* anq = NULL;

    fin = fopen(infn, "rb");
    if (!fin) {
        SYSERROR("Failed to open input file %s", infn);
        return -1;
    }

    fout = fopen(outfn, "wb");
    if (!fout) {
        SYSERROR("Failed to open output file %s", outfn);
        goto bailout;
    }

	// copy the main header exactly.
    anq = anqfits_open(infn);
    if (!anq) {
        ERROR("Failed to open \"%s\"", infn);
        goto bailout;
    }
    start = anqfits_header_start(anq, 0);
    size  = anqfits_header_size (anq, 0);
    if (pipe_file_offset(fin, start, size, fout)) {
        ERROR("Failed to copy primary FITS header.");
        goto bailout;
    }

	nextens = anqfits_n_ext(anq);
    //logverb("Sorting %i extensions.\n", nextens);
	for (ext=1; ext<nextens; ext++) {
		int c;
		qfits_table* table;
		qfits_col* col;
		int mgap;
		off_t mstart;
		size_t msize;
		int atomsize;
		int (*sort_func)(const void*, const void*);
		unsigned char* tabledata;
		unsigned char* tablehdr;
		off_t hdrstart, hdrsize, datsize, datstart;
		int i;

        hdrstart = anqfits_header_start(anq, ext);
        hdrsize  = anqfits_header_size (anq, ext);
        datstart = anqfits_data_start  (anq, ext);
        datsize  = anqfits_data_size   (anq, ext);
		if (!anqfits_is_table(anq, ext)) {
            ERROR("Extension %i isn't a table. Skipping.\n", ext);
			continue;
		}
		table = anqfits_get_table(anq, ext);
		if (!table) {
			ERROR("Failed to open table: file %s, extension %i. Skipping.", infn, ext);
			continue;
		}
		c = fits_find_column(table, colname);
		if (c == -1) {
			ERROR("Couldn't find column named \"%s\" in extension %i.  Skipping.", colname, ext);
			continue;
		}
		col = table->col + c;
		switch (col->atom_type) {
		case TFITS_BIN_TYPE_D:
			data = realloc(data, table->nr * sizeof(double));
			if (descending)
				sort_func = compare_doubles_desc;
			else
				sort_func = compare_doubles_asc;
			break;
		case TFITS_BIN_TYPE_E:
			data = realloc(data, table->nr * sizeof(float));
			if (descending)
				sort_func = compare_floats_desc;
			else
				sort_func = compare_floats_asc;
			break;
        case TFITS_BIN_TYPE_K:
            data = realloc(data, table->nr * sizeof(int64_t));
			if (descending)
				sort_func = compare_int64_desc;
			else
				sort_func = compare_int64_asc;
			break;

		default:
			ERROR("Column %s is neither FITS type D, E, nor K.  Skipping.", colname);
			continue;
		}

        // Grab the sort column.
		atomsize = fits_get_atom_size(col->atom_type);
        printf("Reading sort column \"%s\"\n", colname);
		qfits_query_column_seq_to_array(table, c, 0, table->nr, data, atomsize);
        // Sort it.
        printf("Sorting sort column\n");
		perm = permuted_sort(data, atomsize, sort_func, NULL, table->nr);

        // mmap the input file.
        printf("mmapping input file\n");
		start = hdrstart;
		size = hdrsize + datsize;
		get_mmap_size(start, size, &mstart, &msize, &mgap);
		mapsize = msize;
		map = mmap(NULL, mapsize, PROT_READ, MAP_SHARED, fileno(fin), mstart);
		if (map == MAP_FAILED) {
			SYSERROR("Failed to mmap input file %s", infn);
            map = NULL;
            goto bailout;
		}
		tabledata = map + (off_t)mgap + (datstart - hdrstart);
		tablehdr  = map + (off_t)mgap;

        // Copy the table header without change.
        printf("Copying table header.\n");
		if (fwrite(tablehdr, 1, hdrsize, fout) != hdrsize) {
			SYSERROR("Failed to write FITS table header");
            goto bailout;
		}

		for (i=0; i<table->nr; i++) {
			unsigned char* rowptr;
            if (i % 100000 == 0)
                printf("Writing row %i\n", i);
			rowptr = tabledata + (off_t)(perm[i]) * (off_t)table->tab_w;
			if (fwrite(rowptr, 1, table->tab_w, fout) != table->tab_w) {
				SYSERROR("Failed to write FITS table row");
                goto bailout;
			}
		}

		munmap(map, mapsize);
        map = NULL;
		free(perm);
        perm = NULL;

		if (fits_pad_file(fout)) {
			ERROR("Failed to add padding to extension %i", ext);
            goto bailout;
		}

        qfits_table_close(table);
	}
	free(data);

	if (fclose(fout)) {
		SYSERROR("Error closing output file");
        fout = NULL;
        goto bailout;
	}
	fclose(fin);
    anqfits_close(anq);
    printf("Done\n");
	return 0;

 bailout:
    free(data);
    free(perm);
    if (fout)
        fclose(fout);
    fclose(fin);
    if (map)
        munmap(map, mapsize);
    return -1;
}