00001
00030 #include <string.h>
00031 #include <stdio.h>
00032 #include <fitsio.h>
00033 #include <malloc.h>
00034 #include <unistd.h>
00035
00037 #include "mex.h"
00038 #include "matrix.h"
00039
00041 #include "mfitsio.h"
00042
00043
00044
00045
00046
00053 void
00054 mfitsio_free_record (mfitsio_record * record)
00055 {
00056 MFITSIO_FREE (record->key);
00057 MFITSIO_FREE (record->value);
00058 }
00059
00066 void
00067 mfitsio_free_header (mfitsio_header * header)
00068 {
00069 int i;
00070 for (i = 0; i < header->length; i++)
00071 {
00072 mfitsio_free_record (header->records[i]);
00073 }
00074 MFITSIO_FREE (header->records);
00075 }
00076
00083 void
00084 mfitsio_free_info (mfitsio_info * info)
00085 {
00086 MFITSIO_FREE (info->naxes);
00087 MFITSIO_FREE (info);
00088 }
00089
00103 mfitsio_record *
00104 mfitsio_parse_card (const char *cardtext)
00105 {
00106 int i = 0, j = 0, k = 0, len_card = 0, len_key = 0, len_value = 0;
00107 char value = 0;
00108 mfitsio_record *record = 0;
00109
00111 if (!mfitsio_ignore_card (cardtext))
00112 {
00114 record = (mfitsio_record *) MFITSIO_MALLOC (sizeof (mfitsio_record));
00115 record->key = 0;
00116 record->value = 0;
00117
00119 len_card = strlen (cardtext);
00120
00123 for (i = 0; i < len_card; i++)
00124 {
00126 if (cardtext[i] == ' ')
00127 {
00128 break;
00129 }
00133 else if (cardtext[i] == '=')
00134 {
00135 k = 1;
00136 break;
00137 }
00138 }
00139
00141 len_key = i + 1;
00142 record->key = (char *) MFITSIO_MALLOC (len_key * sizeof (char));
00143
00145 memcpy (record->key, cardtext, i);
00146
00148 record->key[i] = 0;
00149
00151 j = i + 1;
00152
00155 if (k == 0)
00156 {
00157 for (; j < len_card; j++)
00158 {
00159 if (cardtext[j] == '=')
00160 {
00161 j++;
00162 break;
00163 }
00164 }
00165 }
00166
00168 for (; j < len_card; j++)
00169 {
00170 if (cardtext[j] != ' ')
00171 {
00172 break;
00173 }
00174 }
00175
00177 len_value = (len_card - j + 1);
00178
00180 record->value = (char *) MFITSIO_MALLOC (len_value * sizeof (char));
00181 memcpy (record->value, cardtext + j, len_value - 1);
00182
00184 record->value[len_value - 1] = 0;
00185
00191 for (j = len_value - 1; j >= 0; j--)
00192 {
00193 value = record->value[j];
00194 if (value == '\'')
00195 {
00196 break;
00197 }
00198 else if (value == '/' || value == ' ')
00199 {
00200 record->value[j] = '\0';
00201 };
00202 }
00203 }
00204
00208 return record;
00209 }
00210
00222 mfitsio_header *
00223 mfitsio_read_header (const char *filename)
00224 {
00225 fitsfile *fptr = 0;
00226 mfitsio_header *header = 0, *new_header = 0;
00227 char card[FLEN_CARD];
00228 int status = 0, nkeys = 0, jkeys = 0, i = 0, j = 0;
00229 mfitsio_record *record = 0;
00230
00232 fits_open_file (&fptr, filename, MFITSIO_READONLY, &status);
00233 if (status)
00234 {
00235 MFITSIO_PRINTF ("1 An error occurred: %d\n", status);
00236 MFITSIO_ERR ("Unable to open FITS file.");
00237 }
00238
00240 fits_get_hdrspace (fptr, &nkeys, NULL, &status);
00241 if (status)
00242 {
00243 MFITSIO_PRINTF ("2 An error occurred: %d\n", status);
00244 MFITSIO_ERR ("Could not access header.");
00245 }
00246
00248 header = (mfitsio_header *) MFITSIO_MALLOC (sizeof (mfitsio_header));
00249
00251 header->length = nkeys;
00252
00254 header->records =
00255 (mfitsio_record **) MFITSIO_MALLOC (nkeys * sizeof (mfitsio_record *));
00256
00259 for (i = 1; i <= nkeys; i++)
00260 {
00261 fits_read_record (fptr, i, card, &status);
00262 if (status)
00263 {
00264 MFITSIO_PRINTF ("3 An error occurred: %d\n", status);
00265 MFITSIO_ERR ("Could not access header.");
00266 }
00267 record = mfitsio_parse_card (card);
00268 header->records[i - 1] = record;
00269
00271 if (record != 0)
00272 {
00273 jkeys++;
00274 }
00275 }
00276
00280 if (jkeys != nkeys)
00281 {
00283 new_header =
00284 (mfitsio_header *) MFITSIO_MALLOC (sizeof (mfitsio_header));
00285 new_header->records =
00286 (mfitsio_record **) MFITSIO_MALLOC (jkeys *
00287 sizeof (mfitsio_record *));
00288
00290 new_header->length = jkeys;
00291 j = 0;
00292 for (i = 0; i < nkeys; i++)
00293 {
00294 if (header->records[i] != 0)
00295 {
00296 new_header->records[j++] = header->records[i];
00297 }
00298 }
00300 MFITSIO_FREE (header->records);
00301 MFITSIO_FREE (header);
00302
00304 header = new_header;
00305 }
00306
00308 fits_close_file (fptr, &status);
00309 if (status)
00310 {
00311 MFITSIO_PRINTF ("4 An error occurred: %d\n", status);
00312 MFITSIO_ERR ("Could not close file.");
00313 }
00314
00315 return (status != 0) ? 0 : header;
00316 }
00317
00327 mxArray *
00328 mfitsio_adapt_frecord (const mfitsio_record * record)
00329 {
00330 int len = 0, i, j;
00331 char *temp = 0;
00332 char f = 0;
00333
00335 mxArray *retval = 0;
00336 mxArray *iargs[] = { 0 };
00337 mxArray *oargs[] = { 0 };
00338
00340 len = strlen (record->value);
00341
00343 if (len)
00344 {
00345
00347 f = record->value[0];
00348
00351 if (f == '\'')
00352 {
00354 temp = (char *) MFITSIO_MALLOC ((len - 1) * sizeof (char));
00355
00358 memcpy (temp, record->value + 1, len - 2);
00359
00361 temp[len - 2] = 0;
00362
00365 i = -1;
00366 for (j = strlen (temp) - 1; j >= 0; j--)
00367 {
00368 if (temp[j] != ' ')
00369 {
00370 i = j + 1;
00371 break;
00372 }
00373 }
00374 if (i != -1)
00375 {
00376 temp[i] = '\0';
00377 }
00378
00380 retval = mxCreateString (temp);
00381 }
00383 else if (f == 'T' || f == 'F' || f == 't' || f == 'f')
00384 {
00385 retval = mxCreateLogicalScalar (f == 'T' || f == 't');
00386 }
00388 else if ((f >= '0' && f <= '9') || f == '-' || f == '.')
00389 {
00392 if (strchr (record->value, '.'))
00393 {
00394 retval = mxCreateDoubleScalar (atof (record->value));
00395 }
00397 else
00398 {
00400 retval = mxCreateDoubleScalar (atof (record->value));
00401 iargs[0] = retval;
00402
00404 mexCallMATLAB (1, oargs, 1, iargs, "int32");
00405 retval = oargs[0];
00406 }
00407 }
00409 else
00410 {
00411 retval = mxCreateString (strdup (record->value));
00412 i = -1;
00413 for (j = strlen (record->value) - 1; j >= 0; j--)
00414 {
00415 if (record->value[j] != ' ')
00416 {
00417 i = j + 1;
00418 break;
00419 }
00420 }
00421 if (i != -1)
00422 {
00423 record->value[i] = '\0';
00424 }
00425 }
00426 }
00428 else
00429 {
00430 retval = mxCreateDoubleScalar (0);
00431 }
00432 return retval;
00433 }
00434
00444 mxArray *
00445 mfitsio_adapt_fheader (const mfitsio_header * header)
00446 {
00447 const char **fnames = 0;
00448 int buflen, status = 0, i;
00449 char *temp = 0;
00450 mxArray *retval = 0;
00451
00452 if (header == 0)
00453 {
00454 MFITSIO_ERR ("33 Header unreadable.");
00455 }
00457 fnames = MFITSIO_CALLOC (header->length, sizeof (*fnames));
00458
00461 for (i = 0; i < header->length; i++)
00462 {
00464 buflen = strlen (header->records[i]->key);
00465
00467 temp = (char *) MFITSIO_MALLOC (sizeof (char) * buflen + 1);
00468
00470 memcpy (temp, header->records[i]->key, buflen);
00471
00473 temp[buflen] = 0;
00474
00476 fnames[i] = temp;
00477 }
00478
00480 retval = mxCreateStructMatrix (1, 1, header->length, fnames);
00481
00486 for (i = 0; i < header->length; i++)
00487 {
00488 mxSetFieldByNumber (retval, 0, i,
00489 mfitsio_adapt_frecord (header->records[i]));
00490 }
00491 return retval;
00492 }
00493
00502 mfitsio_info *
00503 mfitsio_read_info (const char * filename)
00504 {
00505 mfitsio_info *retval = 0;
00506 fitsfile *fptr = 0;
00507 long *naxes;
00508 int status = 0, i;
00509
00511 fits_open_file (&fptr, filename, MFITSIO_READONLY, &status);
00512 if (status)
00513 {
00514 MFITSIO_PRINTF ("5 An error occurred: %d\n", status);
00515 MFITSIO_ERR ("Could not open file for reading.");
00516 }
00517
00519 retval = (mfitsio_info *) MFITSIO_MALLOC (sizeof (mfitsio_info));
00520
00522 fits_get_img_type(fptr, &(retval->bitpix), &status);
00523 if (status)
00524 {
00525 MFITSIO_PRINTF ("6 An error occurred: %d\n", status);
00526 MFITSIO_ERR ("Could not retrieve BITPIX keyword.");
00527 }
00528
00530 fits_get_img_dim(fptr, &(retval->naxis), &status);
00531 if (status)
00532 {
00533 MFITSIO_PRINTF ("7 An error occurred: %d\n", status);
00534 MFITSIO_ERR ("Could not retrieve NAXIS, total number of dimensions.");
00535 }
00536
00538 naxes = MFITSIO_MALLOC (sizeof (long) * retval->naxis);
00539
00541 fits_get_img_size(fptr, retval->naxis, naxes, &status);
00542 if (status)
00543 {
00544 MFITSIO_PRINTF ("8 An error occurred: %d\n", status);
00545 MFITSIO_ERR ("Could not open file for reading.");
00546 }
00547 retval->naxes = (int *) MFITSIO_MALLOC (retval->naxis * sizeof (int));
00548
00550 for (i = 1; i <= retval->naxis; i++)
00551 {
00552 retval->naxes[i - 1] = (int) naxes[i - 1];
00553 }
00554
00556 MFITSIO_FREE ( naxes );
00557
00559 return retval;
00560 }
00561
00571 mxArray *
00572 mfitsio_read_image (const char *filename, const mfitsio_info * info) {
00573 mxArray *image = 0;
00574 long *fpixels = 0, *lpixels = 0, *lnaxes = 0, *inc = 0;
00575 int i = 0;
00576 fpixels = (long *) MFITSIO_MALLOC (sizeof (long) * info->naxis);
00577 lpixels = (long *) MFITSIO_MALLOC (sizeof (long) * info->naxis);
00578 lnaxes = (long *) MFITSIO_MALLOC (sizeof (long) * info->naxis);
00579 inc = (long *) MFITSIO_MALLOC (sizeof (long) * info->naxis);
00581 for (i = 0; i < info->naxis; i++)
00582 {
00583 lpixels[i] = info->naxes[i];
00584 fpixels[i] = 1;
00585 inc[i] = 1;
00586 lnaxes[i] = info->naxes[i];
00587 }
00588 image = mfitsio_read_image_impl(filename, info, fpixels,
00589 lpixels, lnaxes, inc);
00590 MFITSIO_FREE (fpixels);
00591 MFITSIO_FREE (lpixels);
00592 MFITSIO_FREE (inc);
00593 MFITSIO_FREE (lnaxes);
00594 return image;
00595 }
00596
00606 mxArray *
00607 mfitsio_read_image_impl (const char *filename, const mfitsio_info * info,
00608 long *fpixels, long *lpixels,
00609 long *lnaxes, long *inc)
00610 {
00611 fitsfile *fptr = 0;
00612 mxArray *img = 0;
00613 double *pr = 0;
00614 int status = 0, i = 0;
00615 int *diff = 0;
00616
00617 diff = mfitsio_get_region_size(fpixels, lpixels, info->naxis);
00621 fits_open_file (&fptr, filename, MFITSIO_READONLY, &status);
00622 if (status)
00623 {
00624 MFITSIO_PRINTF ("9 An error occurred: %d\n", status);
00625 MFITSIO_ERR ("Could not open file for reading.");
00626 }
00627
00629 img = mfitsio_read_image_execute(info, diff, fptr, 0, info->naxis, lnaxes,
00630 fpixels, lpixels, inc, 0, &status);
00631
00632 MFITSIO_FREE (diff);
00633
00635 fits_close_file (fptr, &status);
00636 if (status)
00637 {
00638 MFITSIO_PRINTF ("12 An error occurred: %d\n", status);
00639 MFITSIO_ERR ("Could not close file.");
00640 }
00641
00643 return img;
00644 }
00645
00646 mxArray *mfitsio_read_image_execute(const mfitsio_info *info, int *diff,
00647 fitsfile *fptr,
00648 int group, int naxis, long *lnaxes,
00649 long *fpixel, long *lpixel,
00650 long *inc, int *anynul, int *status) {
00651 mxArray *img;
00652 void *data;
00653 switch (info->bitpix)
00654 {
00655 case BYTE_IMG:
00656 img = mxCreateNumericArray (info->naxis, diff, mxUINT8_CLASS, mxREAL);
00657 data = mxGetData(img);
00658 fits_read_subset_byt (fptr, group, info->naxis, lnaxes, fpixel, lpixel,
00659 inc, 0, (unsigned char*)data, anynul, status);
00660 break;
00661 case SHORT_IMG:
00662 img = mxCreateNumericArray (info->naxis, diff, mxINT16_CLASS, mxREAL);
00663 data = mxGetData(img);
00664 fits_read_subset_sht (fptr, 0, info->naxis, lnaxes, fpixel, lpixel,
00665 inc, 0, (short*)data, 0, status);
00666 break;
00667 case LONG_IMG:
00668 img = mxCreateNumericArray (info->naxis, diff, mxINT32_CLASS, mxREAL);
00669 data = mxGetData(img);
00670 fits_read_subset_int (fptr, 0, info->naxis, lnaxes, fpixel, lpixel,
00671 inc, 0, (int*)data, 0, status);
00672 break;
00673 case FLOAT_IMG:
00674 img = mxCreateNumericArray (info->naxis, diff, mxSINGLE_CLASS, mxREAL);
00675 data = mxGetData(img);
00676 fits_read_subset_flt (fptr, 0, info->naxis, lnaxes, fpixel, lpixel,
00677 inc, 0, (float*)data, 0, status);
00678 break;
00679 case DOUBLE_IMG:
00680 img = mxCreateNumericArray (info->naxis, diff, mxDOUBLE_CLASS, mxREAL);
00681 data = mxGetData(img);
00682 fits_read_subset_dbl (fptr, 0, info->naxis, lnaxes, fpixel, lpixel,
00683 inc, 0, (double*)data, 0, status);
00684 break;
00685 default:
00686 MFITSIO_PRINTF ("52 Unsupported input BITPIX: %d\n", info->bitpix);
00687 MFITSIO_ERR ("Cannot continue.");
00688 }
00689 return img;
00690 }
00691
00692
00693
00703 void
00704 mfitsio_write_image (const char *filename, const mxArray * header,
00705 mxArray * img)
00706 {
00707
00708 mfitsio_info *info = 0;
00709 long *fpixels = 0, *lpixels = 0, *lnaxes = 0, *inc = 0;
00710 int i;
00712 info = mfitsio_calc_info (img);
00713
00715 fpixels = (long *) MFITSIO_MALLOC (sizeof (long) * info->naxis);
00716 lpixels = (long *) MFITSIO_MALLOC (sizeof (long) * info->naxis);
00717 lnaxes = (long *) MFITSIO_MALLOC (sizeof (long) * info->naxis);
00718 inc = (long *) MFITSIO_MALLOC (sizeof (long) * info->naxis);
00719
00721 for (i = 0; i < info->naxis; i++)
00722 {
00723 lpixels[i] = info->naxes[i];
00724 fpixels[i] = 1;
00725 inc[i] = 1;
00726 lnaxes[i] = info->naxes[i];
00727 }
00728
00729 mfitsio_write_image_impl(filename, header, img, fpixels,
00730 lpixels, lnaxes, inc, info);
00731 MFITSIO_FREE (fpixels);
00732 MFITSIO_FREE (lpixels);
00733 MFITSIO_FREE (inc);
00734 MFITSIO_FREE (lnaxes);
00735 mfitsio_free_info(info);
00736 }
00737
00750 void
00751 mfitsio_write_image_impl (const char *filename, const mxArray * header,
00752 mxArray * img, long *fpixels, long *lpixels,
00753 long *lnaxes, long *inc, mfitsio_info *info)
00754 {
00755
00756 fitsfile *fptr = 0;
00757 mxArray *newImg = 0;
00758 int status = 0, nkeys, i, j;
00759 double *pr = 0;
00760
00762 mfitsio_write_header (filename, header);
00763
00765 fits_open_file (&fptr, filename, MFITSIO_READWRITE, &status);
00766 if (status)
00767 {
00768 MFITSIO_PRINTF ("13 An error occurred: %d\n", status);
00769 MFITSIO_ERR ("Could not open file for writing.");
00770 }
00771
00773 newImg = img;
00791 if (info->check == 0) {
00792 fits_resize_img (fptr, info->bitpix, info->naxis, lnaxes, &status);
00793 }
00794 if (status)
00795 {
00796 MFITSIO_PRINTF ("14 An error occurred: %d\n", status);
00797 MFITSIO_ERR ("Could not resize FITS file image.");
00798 }
00799
00807 mfitsio_write_image_execute(fptr, img, 0, info->naxis, lnaxes, fpixels,
00808 lpixels, &status);
00809
00810 if (status)
00811 {
00812 MFITSIO_PRINTF ("15 An error occurred: %d\n", status);
00813 MFITSIO_ERR ("Could not write the image to the FITS file.");
00814 }
00815
00817 fits_close_file (fptr, &status);
00818 if (status)
00819 {
00820 MFITSIO_PRINTF ("39 An error occurred: %d\n", status);
00821 MFITSIO_ERR ("Could not close file.");
00822 }
00823 }
00824
00825 void mfitsio_write_image_execute(fitsfile *file,
00826 mxArray *img, long group, long naxis,
00827 long *naxes, long *fpixel, long *lpixel,
00828 int *status) {
00829 mxClassID classId;
00830 void *data;
00831 data = mxGetData(img);
00832 classId = mxGetClassID (img);
00833 switch (classId)
00834 {
00835 case mxSINGLE_CLASS:
00836 fits_write_subset_flt(file, group, naxis, naxes, fpixel, lpixel,
00837 (float*)data, status);
00838 break;
00839 case mxDOUBLE_CLASS:
00841 fits_write_subset_dbl(file, group, naxis, naxes, fpixel, lpixel,
00842 (double*)data, status);
00843 break;
00844 case mxUINT8_CLASS:
00846 fits_write_subset_byt(file, group, naxis, naxes, fpixel, lpixel,
00847 (unsigned char*)data, status);
00848 break;
00849 case mxUINT16_CLASS:
00851 fits_write_subset_usht(file, group, naxis, naxes, fpixel, lpixel,
00852 (unsigned short int*)data, status);
00853 break;
00854 case mxINT16_CLASS:
00856 fits_write_subset_sht(file, group, naxis, naxes, fpixel, lpixel,
00857 (short int*)data, status);
00858 break;
00859 case mxUINT32_CLASS:
00862 fits_write_subset_uint(file, group, naxis, naxes, fpixel, lpixel,
00863 (unsigned int*)data, status);
00864 break;
00865 case mxINT32_CLASS:
00867 fits_write_subset_int(file, group, naxis, naxes, fpixel, lpixel,
00868 (int*)data, status);
00869 break;
00870 case mxLOGICAL_CLASS:
00872 break;
00873 case mxUINT64_CLASS:
00875 #ifdef HAVE_LONGLONG
00876 fits_write_subset_lnglng(file, group, naxis, naxes, fpixel, lpixel,
00877 (LONGLONG*)data);
00878
00879 break;
00880 #endif
00881 case mxINT64_CLASS:
00883 #ifdef HAVE_LONGLONG
00884 fits_write_subset_lnglng(file, group, naxis, naxes, fpixel, lpixel,
00885 (LONGLONG*)data);
00886 break;
00887 #endif
00888 default:
00890 MFITSIO_PRINTF
00891 ("51 Unsupported data type for image.\n");
00892 MFITSIO_ERR ("Cannot continue.");
00893 break;
00894 }
00895 }
00896
00904 void
00905 mfitsio_delete_keyword (const char *filename, const char *keyword)
00906 {
00907 fitsfile *fptr = 0;
00908 int status = 0;
00909 mfitsio_record *record = 0;
00910 char *tmp = 0;
00911
00912 fits_open_file (&fptr, filename, MFITSIO_READWRITE, &status);
00913 if (status)
00914 {
00915 MFITSIO_PRINTF ("16 An error occurred: %d\n", status);
00916 MFITSIO_ERR ("Could not open file for writing.");
00917 }
00918 fits_movabs_hdu (fptr, 1, 0, &status);
00919 if (status)
00920 {
00921 MFITSIO_PRINTF ("17 An error occurred: %d\n", status);
00922 MFITSIO_ERR ("Could not access header.");
00923 }
00924 if (!mfitsio_forbidden (keyword))
00925 {
00926 tmp = strdup (keyword);
00927 fits_delete_key (fptr, tmp, &status);
00928 free (tmp);
00929 }
00930 else
00931 {
00932 MFITSIO_PRINTF ("19 It is forbidden to delete the keyword '%s'\n", keyword);
00933 MFITSIO_ERR ("Could not delete keyword.");
00934 }
00935
00936 if (status)
00937 {
00938 MFITSIO_PRINTF ("18 An error occurred: %d\n", status);
00939 MFITSIO_ERR ("Could not delete keyword.");
00940 }
00941 }
00942
00950 void
00951 mfitsio_write_header (const char *filename, const mxArray * header)
00952 {
00953 fitsfile *fptr = 0;
00954 int numFields = 0, i = 0, status = 0, singleton = 0, buflen = 0;
00955 mxClassID classId;
00956 char *fieldName = 0, *stringval = 0;
00957 float floatval = 0.0f;
00958 double dblval = 0.0;
00959 unsigned char ucharval = 0;
00960 char charval = 0;
00961 short shortval = 0;
00962 unsigned short ushortval = 0;
00963 int intval = 0;
00964 unsigned int uintval = 0;
00965 long longval = 0;
00966 unsigned long ulongval = 0;
00967 mxArray *field = 0;
00968
00969 int naxis = 2;
00970 int bitpix = 8;
00971 long naxes[] = { 1, 1, 1 };
00972
00975 if (access (filename, F_OK))
00976 {
00977 fits_create_file (&fptr, filename, &status);
00978 if (status)
00979 {
00980 MFITSIO_PRINTF ("20 An error occurred: %d\n", status);
00981 MFITSIO_ERR ("Could not create new FITS file.");
00982 }
00984 fits_create_img (fptr, bitpix, naxis, naxes, &status);
00985 if (status)
00986 {
00987 MFITSIO_PRINTF ("21 An error occurred: %d\n", status);
00988 MFITSIO_ERR ("Could not create an image within the FITS file.");
00989 }
00992 fits_write_key_longwarn (fptr, &status);
00993 if (status)
00994 {
00995 MFITSIO_PRINTF ("22 An error occurred: %d\n", status);
00996 MFITSIO_ERR ("Could not write information to header.");
00997 }
00998 }
00999 else
01000 {
01002 fits_open_file (&fptr, filename, MFITSIO_READWRITE, &status);
01003 }
01004 if (status)
01005 {
01006 MFITSIO_PRINTF ("23 An error occurred: %d\n", status);
01007 MFITSIO_ERR ("Could not open file for writing.");
01008 }
01010 fits_movabs_hdu (fptr, 1, 0, &status);
01011 if (status)
01012 {
01013 MFITSIO_PRINTF ("24 An error occurred: %d\n", status);
01014 MFITSIO_ERR ("Could not access header.");
01015 }
01017 numFields = mxGetNumberOfFields (header);
01018
01021 for (i = 0; i < numFields; i++)
01022 {
01024 fieldName = (char *) mxGetFieldNameByNumber (header, i);
01025
01030 if (!mfitsio_forbidden (fieldName))
01031 {
01033 field = mxGetField (header, 0, fieldName);
01034 classId = mxGetClassID (field);
01035
01038 singleton = mfitsio_is_scalar (field);
01039
01040 if (singleton || classId == mxCHAR_CLASS)
01041 {
01042
01044 switch (classId)
01045 {
01046 case mxSINGLE_CLASS:
01048 floatval = (float) mfitsio_get_mscalar (field);
01049 fits_update_key (fptr, TFLOAT, fieldName, &floatval, 0, &status);
01050 break;
01051 case mxDOUBLE_CLASS:
01053 dblval = (double) mfitsio_get_mscalar (field);
01054 fits_update_key (fptr, TDOUBLE, fieldName, &dblval, 0, &status);
01055 break;
01056 case mxCHAR_CLASS:
01058 buflen = (mxGetM (field) * mxGetN (field)) + 1;
01059 stringval = MFITSIO_CALLOC (buflen, sizeof (char));
01060
01061 status = mxGetString (field, stringval, buflen);
01062 fits_update_key_longstr (fptr, fieldName, stringval, 0, &status);
01063 break;
01064 case mxUINT8_CLASS:
01066 ucharval = (unsigned char) mfitsio_get_mscalar (field);
01067 fits_update_key (fptr, TBYTE, fieldName, &ucharval, 0, &status);
01068 break;
01069 case mxINT8_CLASS:
01071 charval = (char) mfitsio_get_mscalar (field);
01072 fits_update_key (fptr, TBYTE, fieldName, &charval, 0, &status);
01073 break;
01074 case mxUINT16_CLASS:
01077 ushortval = (unsigned short) mfitsio_get_mscalar (field);
01078 fits_update_key (fptr, TUSHORT, fieldName, &ushortval, 0, &status);
01079 break;
01080 case mxINT16_CLASS:
01082 shortval = (short) mfitsio_get_mscalar (field);
01083 fits_update_key (fptr, TSHORT, fieldName, &shortval, 0, &status);
01084 break;
01085 case mxUINT32_CLASS:
01087 ulongval = (unsigned int) mfitsio_get_mscalar (field);
01088 fits_update_key (fptr, TUINT, fieldName, &ulongval, 0, &status);
01089 break;
01090 case mxINT32_CLASS:
01092 longval = (int) mfitsio_get_mscalar (field);
01093 fits_update_key (fptr, TINT, fieldName, &longval, 0, &status);
01094 break;
01095 case mxLOGICAL_CLASS:
01097 intval = (int) mfitsio_get_mscalar (field);
01098 fits_update_key (fptr, TLOGICAL, fieldName, &intval, 0, &status);
01099 break;
01100 default:
01102 MFITSIO_PRINTF
01103 ("25 Unsupported data type for header field \'%s\'.\n", fieldName);
01104 MFITSIO_ERR ("Cannot continue.");
01105 break;
01106 }
01107 }
01108 else
01109 {
01112 MFITSIO_PRINTF
01113 ("26 There exists a non-singleton dimension in the value of \'"
01114 "%s\'. A scalar is required. The field will be ignored.\n");
01115 MFITSIO_WARN ("A header field will not be written.");
01116 }
01118 if (status)
01119 {
01120 MFITSIO_PRINTF
01121 ("27 An error occurred: %d\n. Could not write key for field "
01122 "\'%s\'.", status, fieldName);
01123 MFITSIO_ERR ("Could not write key.");
01124 }
01125 }
01126 }
01128 fits_close_file (fptr, &status);
01129 if (status)
01130 {
01131 MFITSIO_PRINTF ("28 An error occurred: %d\n", status);
01132 MFITSIO_ERR ("Could not create an image within the FITS file.");
01133 }
01134 }
01135
01144 void
01145 mfitsio_write_info (fitsfile * fptr, const mfitsio_info * info)
01146 {
01147 char naxisf[8];
01148 int status = 0, i = 0, val = 0;
01153 val = info->naxis;
01154 fits_update_key (fptr, TINT, "NAXIS", &val, "", &status);
01155 if (status)
01156 {
01157 MFITSIO_PRINTF ("29 An error occurred: %d\n", status);
01158 MFITSIO_ERR ("Could not store NAXIS information.");
01159 }
01160 val = info->bitpix;
01161 fits_update_key (fptr, TINT, "BITPIX", &val, "", &status);
01162 if (status)
01163 {
01164 MFITSIO_PRINTF ("30 An error occurred: %d\n", status);
01165 MFITSIO_ERR ("Could not store BITPIX information.");
01166 }
01168 for (i = 0; i < info->naxis; i++)
01169 {
01170 snprintf (naxisf, 7, "NAXIS%d", i);
01171 fits_update_key (fptr, TINT, naxisf, (info->naxes + i), "", &status);
01172 if (status)
01173 {
01174 MFITSIO_PRINTF ("31 An error occurred: %d\n", status);
01175 MFITSIO_ERR ("Could not store NAXISX information.");
01176 }
01177 }
01178 }
01179
01189 mfitsio_info *
01190 mfitsio_calc_info (const mxArray * img)
01191 {
01192 mfitsio_info *retval = 0;
01193 const int *naxesm;
01194 int i;
01195 mxClassID classId;
01197 retval = (mfitsio_info *) MFITSIO_MALLOC (sizeof (mfitsio_info));
01198
01200 retval->naxis = mxGetNumberOfDimensions (img);
01201 retval->naxes = (int *) MFITSIO_MALLOC (sizeof (int) * retval->naxis);
01202 retval->check = 0;
01203
01205 naxesm = mxGetDimensions (img);
01206 for (i = 0; i < retval->naxis; i++)
01207 {
01208 retval->naxes[i] = naxesm[i];
01209 }
01210
01212 classId = mxGetClassID (img);
01213 switch (classId)
01214 {
01215 case mxSINGLE_CLASS:
01216 retval->bitpix = FLOAT_IMG;
01217 break;
01218 case mxDOUBLE_CLASS:
01219 retval->bitpix = DOUBLE_IMG;
01220 break;
01221 case mxUINT8_CLASS:
01222 retval->bitpix = BYTE_IMG;
01223 break;
01224 case mxINT8_CLASS:
01225 retval->bitpix = BYTE_IMG;
01226 break;
01227 case mxUINT16_CLASS:
01228 retval->bitpix = SHORT_IMG;
01229 break;
01230 case mxINT16_CLASS:
01231 retval->bitpix = SHORT_IMG;
01232 break;
01233 case mxUINT32_CLASS:
01234 retval->bitpix = LONG_IMG;
01235 break;
01236 case mxINT32_CLASS:
01237 retval->bitpix = LONG_IMG;
01238 break;
01239 case mxCHAR_CLASS:
01240 case mxUINT64_CLASS:
01241 case mxINT64_CLASS:
01242 case mxLOGICAL_CLASS:
01243 default:
01244 MFITSIO_PRINTF ("32 Unsupported data type for header image.\n");
01245 MFITSIO_ERR ("Cannot continue.");
01246 break;
01247 }
01248 return retval;
01249 }
01250
01259 int
01260 mfitsio_is_scalar (const mxArray * array)
01261 {
01262 int ndim = 0, nsd = 1, i = 0;
01263 const int *dims;
01265 ndim = mxGetNumberOfDimensions (array);
01266
01268 dims = mxGetDimensions (array);
01269
01271 for (i = 0; i < ndim; i++)
01272 {
01273
01275 if (dims[i] != 1)
01276 {
01277 nsd = 0;
01278 break;
01279 }
01280 }
01281 return nsd;
01282 }
01283
01296 int
01297 mfitsio_forbidden (const char *s)
01298 {
01299 return !strncmp (s, "NAXIS", 5) || !strcmp (s, "SIMPLE")
01300 || !strcmp (s, "_nil_") || !strcmp (s, "BITPIX");
01301 }
01302
01315 int
01316 mfitsio_ignore_card (const char *s)
01317 {
01318 return !strncmp (s, "COMMENT ", 9) || !strncmp (s, "LONGSTRN=", 9)
01319 || !strncmp (s, "EXTEND =", 9) || !strncmp (s, "SIMPLE =", 9);
01320 }
01321
01333 mxArray *
01334 mfitsio_get_mfield (const mxArray * array, int index, const char *field_name)
01335 {
01336 mxArray *field;
01337 if (array == 0)
01338 {
01339 MFITSIO_PRINTF ("34 Header does not exist.\n");
01340 MFITSIO_ERR ("Cannot continue.");
01341 }
01342 field = mxGetField (array, index, field_name);
01343 if (field == 0)
01344 {
01345 MFITSIO_PRINTF ("35 Field '%s' not found in MATLAB struct array.\n",
01346 field_name);
01347 MFITSIO_ERR ("Cannot continue.");
01348 }
01349 return field;
01350 }
01351
01363 double
01364 mfitsio_get_mscalar (const mxArray * array)
01365 {
01366 return (array) ? mfitsio_get_mscalar (array) : 0;
01367 }
01368
01380 void mfitsio_check_coordinate(const mxArray *crd1, const mxArray *crd2,
01381 const int naxis, const int *naxes) {
01382 int i;
01383 double *data1 = 0, *data2 = 0;
01384 if (mxGetNumberOfDimensions(crd1) > 2) {
01385 MFITSIO_PRINTF ("40 Too many in your starting pixel coordinate."
01386 " It must be a 1x%d vector.\n", naxis);
01387 MFITSIO_ERR ("Invalid coordinate.");
01388 }
01389 if (mxGetNumberOfDimensions(crd2) > 2) {
01390 MFITSIO_PRINTF ("41 Too many dimensions in your ending pixel coordinate. "
01391 "It must be a 1x%d vector.\n", naxis);
01392 MFITSIO_ERR ("Invalid coordinate.");
01393 }
01394 if (mxGetM(crd1) != 1) {
01395 MFITSIO_PRINTF ("42 Too many rows in your starting pixel coordinate. "
01396 "It must be a 1x%d vector.\n", naxis);
01397 MFITSIO_ERR ("Invalid coordinate.");
01398 }
01399 if (mxGetM(crd2) != 1) {
01400 MFITSIO_PRINTF ("43 Too many rows in your ending pixel coordinate. "
01401 "It must be a 1x%d vector.\n", naxis);
01402 MFITSIO_ERR ("Invalid coordinate.");
01403 }
01404 if (mxGetN(crd1)<naxis) {
01405 MFITSIO_PRINTF ("44 Not enough values in row vector defining"
01406 " starting pixel coordinate. "
01407 "It must be a 1x%d vector.\n", naxis);
01408 MFITSIO_ERR ("Invalid coordinate.");
01409 }
01410 if (mxGetN(crd1)>naxis) {
01411 MFITSIO_PRINTF ("45 Too many values in row vector defining"
01412 " starting pixel coordinate. "
01413 "It must be a 1x%d vector.\n", naxis);
01414 MFITSIO_ERR ("Invalid coordinate.");
01415 }
01416 if (mxGetN(crd2)<naxis) {
01417 MFITSIO_PRINTF ("46 Not enough values in row vector defining"
01418 " end pixel coordinate."
01419 "It must be a 1x%d vector.\n", naxis);
01420 MFITSIO_ERR ("Invalid coordinate.");
01421 }
01422 if (mxGetN(crd2)>naxis) {
01423 MFITSIO_PRINTF ("47 Too many values in row vector defining"
01424 " starting pixel coordinate."
01425 "It must be a 1x%d vector.\n", naxis);
01426 MFITSIO_ERR ("Invalid coordinate.");
01427 }
01428 data1 = mxGetData(crd1);
01429 data2 = mxGetData(crd2);
01430 for (i = 0; i < naxis; i++ ) {
01431 if (data1[ i ] < 1 || data1[ i ] > naxes[ i ]) {
01432 MFITSIO_PRINTF("36 Invalid component at index %d of starting"
01433 " pixel: %d\n", i + 1, (int)data1[ i ]);
01434 MFITSIO_ERR("Starting coordinate out of range.");
01435 }
01436 if (data2[ i ] < 1 || data2[ i ] > naxes[ i ]) {
01437 MFITSIO_PRINTF("37 Invalid component at index %d of ending"
01438 " pixel: %d\n", i + 1, (int)data2[ i ]);
01439 MFITSIO_ERR("Ending coordinate out of range.");
01440 }
01441 if (data2[ i ] < data1[ i ]) {
01442 MFITSIO_PRINTF("38 Component at index %d of starting pixel must be
01443 less than or equal to component %d of ending pixel.\n");
01444 MFITSIO_ERR("Invalid subset (hyper)region.");
01445 }
01446 }
01447 }
01448
01456 void mfitsio_check_size_info(const mxArray *size_unit) {
01457
01458 int i;
01459 double *data = 0;
01460 int naxis;
01461 if (mxGetNumberOfDimensions(size_unit) > 2) {
01462 MFITSIO_PRINTF ("48 Too many dimensions defining your axes."
01463 " The size unit must be a 1xN vector.\n");
01464 MFITSIO_ERR ("Invalid coordinate.");
01465 }
01466
01467 if (mxGetM(size_unit) != 1) {
01468 MFITSIO_PRINTF ("49 Too many rows defining your axes. "
01469 " The size unit must be a 1xN vector.\n", naxis);
01470 MFITSIO_ERR ("Invalid coordinate.");
01471 }
01472 data = mxGetData(size_unit);
01473 naxis = mxGetN(size_unit);
01474 for (i = 0; i < naxis; i++ ) {
01475 if (data[ i ] < 0) {
01476 MFITSIO_PRINTF("50 Invalid component at index %d of size unit"
01477 ": %d\n", i + 1, (int)data[ i ]);
01478 MFITSIO_ERR("Size unit out of range.");
01479 }
01480 }
01481 }
01482
01483
01493 long *mfitsio_convert_dbl2long(const double *dbl, const int size) {
01494 int i;
01495 long *l = (long*)MFITSIO_MALLOC(sizeof(long)*size);
01496 for (i = 0; i < size; i++ ) {
01497 l[ i ] = (long)dbl[ i ];
01498 }
01499 return l;
01500 }
01501
01511 long *mfitsio_convert_int2long(const int *in, const int size) {
01512 int i;
01513 long *l = (long*)MFITSIO_MALLOC(sizeof(long)*size);
01514 for (i = 0; i < size; i++ ) {
01515 l[ i ] = (long)in[ i ];
01516 }
01517 return l;
01518 }
01519
01528 long *mfitsio_create_ones_vector(const int size) {
01529 int i;
01530 long *l = (long*)MFITSIO_MALLOC(sizeof(long)*size);
01531 for (i = 0; i < size; i++ ) {
01532 l[ i ] = 1;
01533 }
01534 return l;
01535 }
01536
01547 int *mfitsio_get_region_size(const long *crd1, const long *crd2,
01548 const int naxis) {
01549 int i;
01550 int *diff = 0;
01551 diff = (int*)MFITSIO_MALLOC(sizeof(int)*naxis);
01552 for (i = 0; i < naxis; i++ ) {
01553 diff[ i ] = (int)(crd2[ i ] - crd1[ i ]) + 1;
01554 }
01555 return diff;
01556 }
01557
01568 mxArray *mfitsio_get_lpixels(const mxArray *spixels,
01569 const mxArray *img,
01570 int naxis) {
01571 int i;
01572 int dim[] = { 1, 1 };
01573 mxArray *array;
01574 double *sdata;
01575 double *ldata;
01576 const int *imgdims;
01577 int nimgdims;
01578 dim[ 1 ] = naxis;
01579 imgdims = mxGetDimensions(img);
01580 array = mxCreateNumericArray (2, dim, mxDOUBLE_CLASS, mxREAL);
01581 sdata = mxGetData(spixels);
01582 ldata = mxGetData(array);
01583 nimgdims = mxGetNumberOfDimensions(img);
01584 for (i = 0; i < nimgdims; i++ ) {
01585 ldata[ i ] = sdata[ i ] + (double)imgdims[ i ] - 1;
01586 }
01587 for (; i < naxis; i++ ) {
01588 ldata[ i ] = sdata[ i ];
01589 }
01590 return array;
01591 }
01592
01593 char *mfitsio_logical_m2f(const mxArray *img) {
01594 const int *imgdims;
01595 mxLogical *logicals;
01596 char *retval = 0;
01597 long prod = 1, j;
01598 int nimgdims, i;
01599 logicals = mxGetLogicals(img);
01600 imgdims = mxGetDimensions(img);
01601 nimgdims = mxGetNumberOfDimensions(img);
01602 for (i = 0; i < nimgdims; i++ ) {
01603 prod *= ((long)imgdims[ i ]);
01604 }
01605 retval = (char*)MFITSIO_MALLOC(sizeof(char) * prod);
01606 for (j = 0; j < prod; j++ ) {
01607 retval[ j ] = logicals[ j ] ? 'T' : 'F';
01608 }
01609 return retval;
01610 }