/*--------------------------------------------------------------------------- qfits test suite ---------------------------------------------------------------------------*/ /* $Id: test_qfits.c,v 1.3 2001/12/13 15:41:00 ndevilla Exp $ $Author: ndevilla $ $Date: 2001/12/13 15:41:00 $ $Revision: 1.3 $ */ /*--------------------------------------------------------------------------- Includes ---------------------------------------------------------------------------*/ #include #include #include #include #include "qfits.h" #define QFITSTESTFILENAME "QFITS.fits" #define BINDUMPNAME "bindump.dat" #define say(s) fprintf(stderr, "qtest:\t\t%s\n", s) #define _fail(s,l) fprintf(stderr, "qtest(%d): %s\n", l, s) #define fail(s) _fail(s,__LINE__) #define REFSIG "6569daba7b124febfa0cd7813f555774" typedef unsigned char byte ; static float float_array_orig[] = { 1.0, 2.0, 0.0, -1.0, -2.0, 1e-4, -1e-4, 1e-6, -1e-6, 1.2345678, 3.1415926535, 19.71 }; static byte float_array_byte[] = { 0x3f, 0x80, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0x80, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x38, 0xd1, 0xb7, 0x17, 0xb8, 0xd1, 0xb7, 0x17, 0x35, 0x86, 0x37, 0xbd, 0xb5, 0x86, 0x37, 0xbd, 0x3f, 0x9e, 0x06, 0x51, 0x40, 0x49, 0x0f, 0xdb, 0x41, 0x9d, 0xae, 0x14 }; static int int_array_orig[] = { -32768, -16384, -8192, -4096, -1023, 0, 1023, 2048, 8191, 16387, 32767, 65536 }; static byte int_array_byte[] = { 0xff, 0xff, 0x80, 0x00, 0xff, 0xff, 0xc0, 0x00, 0xff, 0xff, 0xe0, 0x00, 0xff, 0xff, 0xf0, 0x00, 0xff, 0xff, 0xfc, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xff, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1f, 0xff, 0x00, 0x00, 0x40, 0x03, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x01, 0x00, 0x00 }; static double double_array_orig[] = { 1.0, 2.0, 0.0, -1.0, -2.0, 1e-4, -1e-4, 1e-6, -1e-6, 1.2345678, 3.1415926535, 19.71 }; static byte double_array_byte[] = { 0x3f, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x1a, 0x36, 0xe2, 0xeb, 0x1c, 0x43, 0x2d, 0xbf, 0x1a, 0x36, 0xe2, 0xeb, 0x1c, 0x43, 0x2d, 0x3e, 0xb0, 0xc6, 0xf7, 0xa0, 0xb5, 0xed, 0x8d, 0xbe, 0xb0, 0xc6, 0xf7, 0xa0, 0xb5, 0xed, 0x8d, 0x3f, 0xf3, 0xc0, 0xca, 0x2a, 0x5b, 0x1d, 0x5d, 0x40, 0x09, 0x21, 0xfb, 0x54, 0x41, 0x17, 0x44, 0x40, 0x33, 0xb5, 0xc2, 0x8f, 0x5c, 0x28, 0xf6 }; /*--------------------------------------------------------------------------- main ---------------------------------------------------------------------------*/ int test_qfitsheader_create(void) { qfits_header * qh ; FILE * out ; say("-----> Header creation test"); /* Test qfits_header creation */ say("creating blank header"); qh = qfits_header_new(); if (qh==NULL) { fail("qfits_header_new() failed"); return 1 ; } say("destroying blank header"); /* Destroy header now */ qfits_header_destroy(qh); /* Create minimal header (SIMPLE/END) */ say("creating minimal header"); qh = qfits_header_default(); if (qh==NULL) { fail("qfits_header_default() failed"); return 1 ; } say("inserting primary keywords"); /* Insert XTENSION marker */ qfits_header_add(qh, "EXTEND", "T", "xtension might be present", NULL); /* Insert a string */ qfits_header_add(qh, "KEY01", "value01", "comment 01", NULL); /* Insert an int */ qfits_header_add(qh, "KEY02", "2", "comment 02", NULL); /* Insert a double */ qfits_header_add(qh, "KEY03", "3.0", "comment 03", NULL); /* Insert a complex */ qfits_header_add(qh, "KEY04", "4.0 4.2", "comment 04", NULL); /* Insert a boolean */ qfits_header_add(qh, "KEY05", "T", "comment 05", NULL); say("inserting history keywords"); /* Insert HISTORY keys */ qfits_header_add(qh, "HISTORY", "1 history field", NULL, NULL); qfits_header_add(qh, "HISTORY", "2 history field", NULL, NULL); qfits_header_add(qh, "HISTORY", "3 history field", NULL, NULL); qfits_header_add(qh, "HISTORY", "4 history field", NULL, NULL); say("inserting comment keywords"); /* Insert COMMENT keys */ qfits_header_add(qh, "COMMENT", "1 comment field", NULL, NULL); qfits_header_add(qh, "COMMENT", "2 comment field", NULL, NULL); qfits_header_add(qh, "COMMENT", "3 comment field", NULL, NULL); qfits_header_add(qh, "COMMENT", "4 comment field", NULL, NULL); say("inserting hierarch keywords"); /* Insert HIERARCH ESO keys in reverse DICB order */ qfits_header_add(qh, "HIERARCH ESO NULL A", "0.0", "not DICB", NULL); qfits_header_add(qh, "HIERARCH ESO NULL B", "0.0", "not DICB", NULL); qfits_header_add(qh, "HIERARCH ESO NULL C", "0.0", "not DICB", NULL); qfits_header_add(qh, "PRO.A", "0.0", "DICB compliant", NULL); qfits_header_add(qh, "PRO.B", "0.0", "DICB compliant", NULL); qfits_header_add(qh, "PRO.C", "0.0", "DICB compliant", NULL); qfits_header_add(qh, "HIERARCH ESO LOG A", "0.0", "DICB compliant", NULL); qfits_header_add(qh, "HIERARCH ESO LOG B", "0.0", "DICB compliant", NULL); qfits_header_add(qh, "HIERARCH ESO LOG C", "0.0", "DICB compliant", NULL); qfits_header_add(qh, "INS.A", "0.0", "DICB compliant", NULL); qfits_header_add(qh, "INS.B", "0.0", "DICB compliant", NULL); qfits_header_add(qh, "INS.C", "0.0", "DICB compliant", NULL); qfits_header_add(qh, "HIERARCH ESO TEL A", "0.0", "DICB compliant", NULL); qfits_header_add(qh, "HIERARCH ESO TEL B", "0.0", "DICB compliant", NULL); qfits_header_add(qh, "HIERARCH ESO TEL C", "0.0", "DICB compliant", NULL); qfits_header_add(qh, "GEN.A", "0.0", "DICB compliant", NULL); qfits_header_add(qh, "GEN.B", "0.0", "DICB compliant", NULL); qfits_header_add(qh, "GEN.C", "0.0", "DICB compliant", NULL); qfits_header_add(qh, "HIERARCH ESO TPL A", "0.0", "DICB compliant", NULL); qfits_header_add(qh, "HIERARCH ESO TPL B", "0.0", "DICB compliant", NULL); qfits_header_add(qh, "HIERARCH ESO TPL C", "0.0", "DICB compliant", NULL); qfits_header_add(qh, "OBS.A", "0.0", "DICB compliant", NULL); qfits_header_add(qh, "OBS.B", "0.0", "DICB compliant", NULL); qfits_header_add(qh, "OBS.C", "0.0", "DICB compliant", NULL); say("inserting mandatory keywords"); /* Insert mandatory keys in reverse order */ qfits_header_add(qh, "NAXIS2", "10", "NAXIS2 comment", NULL); qfits_header_add(qh, "NAXIS1", "11", "NAXIS1 comment", NULL); qfits_header_add(qh, "NAXIS", "2", "NAXIS comment", NULL); qfits_header_add(qh, "BITPIX", "-32", "BITPIX comment", NULL); /* qfits_header_consoledump(qh); */ /* Dump header to file */ say("opening file for output"); out = fopen(QFITSTESTFILENAME, "w"); if (out==NULL) { fail("cannot create test file"); qfits_header_destroy(qh); return 1 ; } say("dumping header to file"); if (qfits_header_dump(qh, out)!=0) { fail("cannot dump header"); qfits_header_destroy(qh); return 1 ; } fclose(out); say("destroying built header"); qfits_header_destroy(qh); return 0 ; } int check_key(qfits_header * qh, char * key, char * expval) { char * val ; int err=0 ; val = qfits_header_getstr(qh, key); if (val==NULL) { fail("missing key in header"); err++ ; } else { val = qfits_pretty_string(val); if (strcmp(val, expval)) { fail("wrong value for key in header"); err++ ; } } return err ; } int test_qfitsheader_read(void) { qfits_header * qh ; char * val ; int err ; int keytype ; err=0 ; say("-----> Header reading test"); /* Read header from source */ say("reading header from file"); qh = qfits_header_read(QFITSTESTFILENAME); if (qh==NULL) { fail("cannot read test file"); return 1 ; } say("querying mandatory keys"); err += check_key(qh, "SIMPLE", "T"); err += check_key(qh, "NAXIS", "2"); err += check_key(qh, "NAXIS1", "11"); err += check_key(qh, "NAXIS2", "10"); err += check_key(qh, "BITPIX", "-32"); say("querying base keys"); err += check_key(qh, "KEY01", "value01"); err += check_key(qh, "KEY02", "2"); err += check_key(qh, "KEY03", "3.0"); err += check_key(qh, "KEY04", "4.0 4.2"); err += check_key(qh, "KEY05", "T"); say("checking key types"); val = qfits_header_getstr(qh, "KEY01"); keytype = qfits_get_type(val); if (keytype!=QFITS_STRING) { printf("val=[%s] type is %d\n", val, keytype); fail("wrong identified type for KEY01 (string)"); err++; } val = qfits_header_getstr(qh, "KEY02"); keytype = qfits_get_type(val); if (keytype!=QFITS_INT) { fail("wrong identified type for KEY02 (int)"); err++; } val = qfits_header_getstr(qh, "KEY03"); keytype = qfits_get_type(val); if (keytype!=QFITS_FLOAT) { fail("wrong identified type for KEY03 (float)"); err++; } val = qfits_header_getstr(qh, "KEY04"); keytype = qfits_get_type(val); if (keytype!=QFITS_COMPLEX) { fail("wrong identified type for KEY04 (complex)"); err++; } val = qfits_header_getstr(qh, "KEY05"); keytype = qfits_get_type(val); if (keytype!=QFITS_BOOLEAN) { fail("wrong identified type for KEY05 (boolean)"); err++; } say("querying hierarch keys"); err += check_key(qh, "HIERARCH ESO PRO A", "0.0"); err += check_key(qh, "PRO.B", "0.0"); err += check_key(qh, "pro.c", "0.0"); err += check_key(qh, "ins.a", "0.0"); err += check_key(qh, "ins.b", "0.0"); err += check_key(qh, "ins.c", "0.0"); err += check_key(qh, "gen.a", "0.0"); err += check_key(qh, "gen.b", "0.0"); err += check_key(qh, "gen.c", "0.0"); err += check_key(qh, "obs.a", "0.0"); err += check_key(qh, "obs.b", "0.0"); err += check_key(qh, "obs.c", "0.0"); err += check_key(qh, "tpl.a", "0.0"); err += check_key(qh, "tpl.b", "0.0"); err += check_key(qh, "tpl.c", "0.0"); err += check_key(qh, "tel.a", "0.0"); err += check_key(qh, "tel.b", "0.0"); err += check_key(qh, "tel.c", "0.0"); err += check_key(qh, "log.a", "0.0"); err += check_key(qh, "log.b", "0.0"); err += check_key(qh, "log.c", "0.0"); err += check_key(qh, "null.a", "0.0"); err += check_key(qh, "null.b", "0.0"); err += check_key(qh, "null.c", "0.0"); say("removing keys"); qfits_header_del(qh, "PRO.A"); qfits_header_del(qh, "pro.b"); qfits_header_del(qh, "HIERARCH ESO PRO C"); if (qfits_header_getstr(qh, "HIERARCH ESO PRO A")!=NULL) err ++ ; if (qfits_header_getstr(qh, "PRO.B")!=NULL) err ++ ; if (qfits_header_getstr(qh, "pro.c")!=NULL) err ++ ; say("modifying keys"); qfits_header_destroy(qh); return err ; } int test_qfitsheader_browse(void) { qfits_header * qh ; char key[80], val[80], com[80] ; int i ; int err ; say("-----> Header browsing test"); /* Read header from source */ say("reading header from file"); qh = qfits_header_read(QFITSTESTFILENAME); if (qh==NULL) { fail("cannot read test file"); return 1 ; } err=0 ; for (i=0 ; in ; i++) { if (qfits_header_getitem(qh, i, key, val, com, NULL)!=0) { fail("cannot read header item"); err++ ; } } qfits_header_destroy(qh); return err ; } int test_qfitspix_dump(void) { qfitsdumper qd ; FILE * testfile ; byte testbuf[96] ; int i ; int err ; /* Test various dumps to check pixel conversion works fine */ say("-----> Pixel dumping tests: float pix"); qd.filename = BINDUMPNAME; qd.npix = 12 ; /* Test float dump */ qd.ptype = PTYPE_FLOAT ; qd.fbuf = float_array_orig ; qd.out_ptype= -32 ; say("dumping dat file"); remove(BINDUMPNAME); if (qfits_pixdump(&qd)!=0) { fail("cannot save test buffer"); return 1 ; } say("opening dat file"); if ((testfile=fopen(BINDUMPNAME, "r"))==NULL) { fail("cannot open test file"); return 1 ; } say("reading dat file"); fread(testbuf, 4, 12, testfile); fclose(testfile); remove(BINDUMPNAME); /* Compare arrays */ say("comparing arrays"); err=0 ; for (i=0 ; i<48 ; i++) { if (testbuf[i]!=float_array_byte[i]) { printf("failed: expected %02x got %02x\n", float_array_byte[i], testbuf[i]); err++ ; } } /* Test int dump */ say("-----> Pixel dumping tests: int pix"); qd.ptype = PTYPE_INT ; qd.ibuf = int_array_orig ; qd.out_ptype = 32 ; say("dumping dat file"); if (qfits_pixdump(&qd)!=0) { fail("cannot save test buffer"); return 1 ; } say("opening dat file"); if ((testfile=fopen(BINDUMPNAME, "r"))==NULL) { fail("cannot open test file"); return 1 ; } say("reading dat file"); fread(testbuf, 4, 12, testfile); fclose(testfile); remove(BINDUMPNAME); /* Compare arrays */ say("comparing arrays"); err=0 ; for (i=0 ; i<48 ; i++) { if (testbuf[i]!=int_array_byte[i]) { printf("failed: expected %02x got %02x\n", int_array_byte[i], testbuf[i]); err++ ; } } remove(BINDUMPNAME); /* Test double dump */ say("-----> Pixel dumping tests: double pix"); qd.ptype = PTYPE_DOUBLE ; qd.dbuf = double_array_orig ; qd.out_ptype = -64 ; say("dumping dat file"); if (qfits_pixdump(&qd)!=0) { fail("cannot save test buffer"); return 1 ; } say("opening dat file"); if ((testfile=fopen(BINDUMPNAME, "r"))==NULL) { fail("cannot open test file"); return 1 ; } say("reading dat file"); fread(testbuf, 8, 12, testfile); fclose(testfile); remove(BINDUMPNAME); /* Compare arrays */ say("comparing arrays"); err=0 ; for (i=0 ; i<96 ; i++) { if (testbuf[i]!=double_array_byte[i]) { printf("failed: expected %02x got %02x\n", double_array_byte[i], testbuf[i]); err++ ; } } remove(BINDUMPNAME); return err ; ; } int test_qfitsdata_dump(void) { qfitsdumper qd ; int i ; say("-----> Data dumping test"); /* Allocate data segment and save it to FITS file */ qd.fbuf = malloc(11 * 10 * sizeof(float)); for (i=0 ; i<(11*10) ; i++) { qd.fbuf[i]=i*0.2 ; } qd.filename = QFITSTESTFILENAME ; qd.npix = 11 * 10 ; qd.ptype = PTYPE_FLOAT ; qd.out_ptype = -32 ; if (qfits_pixdump(&qd)!=0) { fail("cannot save data to test file"); free(qd.fbuf); return 1 ; } free(qd.fbuf); /* Zero-pad the output file */ qfits_zeropad(QFITSTESTFILENAME); return 0 ; } int test_qfitsdata_load(void) { qfitsloader ql ; int i ; int err ; float diff ; err=0 ; say("-----> Data loading test"); ql.filename = QFITSTESTFILENAME ; ql.xtnum = 0 ; ql.pnum = 0 ; ql.ptype = PTYPE_FLOAT ; say("initializing loader"); if (qfitsloader_init(&ql)!=0) { fail("cannot initialize loader on test file"); return 1 ; } if (ql.lx != 11) { fail("wrong size in X"); err++ ; } if (ql.ly != 10) { fail("wrong size in Y"); err++ ; } say("loading pixel buffer"); if (qfits_loadpix(&ql)!=0) { fail("cannot load data from test file"); return 1 ; } for (i=0 ; i<(11*10) ; i++) { diff = ql.fbuf[i] - (float)i * 0.2 ; if (diff>1e-4) { fail("diff in pix value"); err++ ; } } free(ql.fbuf); return err ; } int test_qfits_extdump(void) { qfits_header * qh ; qfitsdumper qd ; FILE * out ; char * sig ; say("-----> File with multiple extensions"); /* Create minimal FITS header for main */ say("creating default header"); qh = qfits_header_default() ; if (qh==NULL) { fail("cannot create default header"); return 1 ; } qfits_header_add(qh, "BITPIX", "8", "no data in main section", NULL); qfits_header_add(qh, "NAXIS", "0", "no data in main section", NULL); qfits_header_add(qh, "EXTEND", "T", "Extensions are present", NULL); say("dumping header to test file"); out = fopen(QFITSTESTFILENAME, "w"); if (out==NULL) { fail("cannot create test file"); qfits_header_destroy(qh); return 1 ; } qfits_header_dump(qh, out); fclose(out); qfits_header_destroy(qh); say("creating first extension with float pixels"); qh = qfits_header_new(); if (qh==NULL) { fail("cannot create extension header 1"); return 1 ; } qfits_header_append(qh, "XTENSION", "T", "Ext 1", NULL); qfits_header_append(qh, "BITPIX", "-32", "bpp", NULL); qfits_header_append(qh, "NAXIS", "2", "axes", NULL); qfits_header_append(qh, "NAXIS1", "6", "size in x", NULL); qfits_header_append(qh, "NAXIS2", "2", "size in y", NULL); qfits_header_append(qh, "END", NULL, NULL, NULL); say("dumping ext header 1 to test file"); out = fopen(QFITSTESTFILENAME, "a"); if (out==NULL) { fail("cannot append to test file"); qfits_header_destroy(qh); return 1 ; } qfits_header_dump(qh, out); fclose(out); qfits_header_destroy(qh); say("dumping float array"); qd.filename = QFITSTESTFILENAME ; qd.npix = 12 ; qd.ptype = PTYPE_FLOAT ; qd.out_ptype = -32 ; qd.fbuf = float_array_orig ; if (qfits_pixdump(&qd)!=0) { fail("cannot save data to test file"); free(qd.fbuf); return 1 ; } /* Zero-pad the output file */ qfits_zeropad(QFITSTESTFILENAME); say("creating second extension with int pixels"); qh = qfits_header_new(); if (qh==NULL) { fail("cannot create extension header 1"); return 1 ; } qfits_header_append(qh, "XTENSION", "T", "Ext 1", NULL); qfits_header_append(qh, "BITPIX", "32", "bpp", NULL); qfits_header_append(qh, "NAXIS", "2", "axes", NULL); qfits_header_append(qh, "NAXIS1", "6", "size in x", NULL); qfits_header_append(qh, "NAXIS2", "2", "size in y", NULL); qfits_header_append(qh, "END", NULL, NULL, NULL); say("dumping ext header 2 to test file"); out = fopen(QFITSTESTFILENAME, "a"); if (out==NULL) { fail("cannot append to test file"); qfits_header_destroy(qh); return 1 ; } qfits_header_dump(qh, out); fclose(out); qfits_header_destroy(qh); say("dumping int array"); qd.filename = QFITSTESTFILENAME ; qd.npix = 12 ; qd.ptype = PTYPE_INT ; qd.out_ptype = 32 ; qd.ibuf = int_array_orig ; if (qfits_pixdump(&qd)!=0) { fail("cannot save data to test file"); free(qd.fbuf); return 1 ; } /* Zero-pad the output file */ qfits_zeropad(QFITSTESTFILENAME); say("creating third extension with double pixels"); qh = qfits_header_new(); if (qh==NULL) { fail("cannot create extension header 3"); return 1 ; } qfits_header_append(qh, "XTENSION", "T", "Ext 1", NULL); qfits_header_append(qh, "BITPIX", "-64", "bpp", NULL); qfits_header_append(qh, "NAXIS", "2", "axes", NULL); qfits_header_append(qh, "NAXIS1", "6", "size in x", NULL); qfits_header_append(qh, "NAXIS2", "2", "size in y", NULL); qfits_header_append(qh, "END", NULL, NULL, NULL); say("dumping ext header 3 to test file"); out = fopen(QFITSTESTFILENAME, "a"); if (out==NULL) { fail("cannot append to test file"); qfits_header_destroy(qh); return 1 ; } qfits_header_dump(qh, out); fclose(out); qfits_header_destroy(qh); say("dumping double array"); qd.filename = QFITSTESTFILENAME ; qd.npix = 12 ; qd.ptype = PTYPE_DOUBLE ; qd.out_ptype = -64 ; qd.dbuf = double_array_orig ; if (qfits_pixdump(&qd)!=0) { fail("cannot save data to test file"); free(qd.fbuf); return 1 ; } /* Zero-pad the output file */ qfits_zeropad(QFITSTESTFILENAME); /* Get MD5 for the test file */ sig = qfits_datamd5(QFITSTESTFILENAME); if (strcmp(sig, REFSIG)) { fail("test file signature does not match"); return 1 ; } say("file DATAMD5 signature is Ok"); return 0 ; } int main(int argc, char * argv[]) { int err ; err=0 ; /* Header tests */ err += test_qfitsheader_create(); err += test_qfitsheader_read(); err += test_qfitsheader_browse(); /* Data tests */ err += test_qfitsdata_dump(); err += test_qfitsdata_load(); err += test_qfitspix_dump() ; /* Extension tests */ err += test_qfits_extdump(); remove(QFITSTESTFILENAME); fprintf(stderr, "total error(s): %d\n", err); return err ; }