00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <stdio.h>
00013 #include <string.h>
00014 #include <math.h>
00015 #include <unistd.h>
00016 #include <fitsio.h>
00017 #include "mex2c_util.h"
00018 #include "mex.h"
00019 #include "mexhead.h"
00020
00021
00022 extern char *mex2c_progname;
00023 extern char mex2c_phase[];
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 void
00035 printerror(int status)
00036 {
00037 fprintf(stderr, "%s: Runtime error (%s). Exiting.\n",
00038 mex2c_progname,
00039 status == 0 ? "not a FITSIO error" : "FITSIO trace follows");
00040 if (*mex2c_phase)
00041 fprintf(stderr, "%s: error while: %s\n",
00042 mex2c_progname,
00043 mex2c_phase);
00044 fits_report_error(stderr, status);
00045 exit(status != 0 ? status : 1);
00046 }
00047
00048
00049
00050
00051
00052 void
00053 compute_range(double *data, long n, double *dmin, double *dmax)
00054 {
00055 long i;
00056 double min1, max1;
00057
00058 max1 = -1.0 * mxt_getinfd();
00059 min1 = mxt_getinfd();
00060 for (i = 0; i < n; i++, data++) {
00061 if (!isnan(*data)) {
00062 if (*data < min1) min1 = *data;
00063 if (*data > max1) max1 = *data;
00064 }
00065 }
00066
00067
00068
00069
00070
00071 *dmin = min1; *dmax = max1;
00072 }
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 mxArray *
00085 GetFITS(char *filename, int file_transpose)
00086 {
00087 mxArray *pm;
00088 fitsfile *fptr;
00089 int status = 0;
00090 int naxis;
00091 mwSize *naxesI;
00092 long *naxesL;
00093 int nfound;
00094 long nelements;
00095 int i;
00096 int bitpix;
00097 double bscale, bzero;
00098 double nullval;
00099 double datamin, datamax;
00100
00101 fits_open_file(&fptr, filename, READONLY, &status);
00102
00103 fits_read_key(fptr, TINT, "NAXIS", &naxis, NULL, &status);
00104 if (status)
00105 printerror(status);
00106
00107 naxesI = (mwSize *) calloc((size_t) naxis, sizeof(*naxesI));
00108 naxesL = (long *) calloc((size_t) naxis, sizeof(*naxesL));
00109 if (naxesI == NULL || naxesL == NULL) {
00110 fprintf(stderr, "Failed to input-convert matrix (failed calloc)\n");
00111 printerror(0);
00112 }
00113
00114 fits_read_keys_lng(fptr, "NAXIS", 1, naxis, naxesL, &nfound, &status);
00115 for (i = 0; i < naxis; i++)
00116 naxesI[i] = (mwSize) naxesL[i];
00117 if (status)
00118 printerror(status);
00119
00120 fits_read_key(fptr, TLONG, "BITPIX", &bitpix, NULL, &status);
00121 if (status)
00122 printerror(status);
00123
00124 if (bitpix < 0)
00125
00126
00127
00128
00129 nullval = 0.0;
00130 else
00131
00132
00133
00134 nullval = mxt_getnand();
00135
00136 pm = mxCreateNumericArray((mwSize) naxis, naxesI, mxDOUBLE_CLASS, mxREAL);
00137 nelements = (long) mxGetNumberOfElements(pm);
00138
00139 fits_read_img(fptr, TDOUBLE, 1L, nelements, &nullval,
00140 mxGetPr(pm), &nfound, &status);
00141
00142 if (fits_read_key(fptr, TDOUBLE, "BSCALE", &bscale, NULL, &status)) {
00143 bscale = 1.0; status = 0; fits_clear_errmsg();
00144 }
00145 if (fits_read_key(fptr, TDOUBLE, "BZERO", &bzero, NULL, &status)) {
00146 bzero = 0.0; status = 0; fits_clear_errmsg();
00147 }
00148
00149 if (fits_close_file(fptr, &status))
00150 printerror(status);
00151
00152
00153 if (file_transpose && !mxt_transpose_double_mxArray(pm)) {
00154 fprintf(stderr, "Failed to input-convert matrix (failed malloc)\n");
00155 printerror(0);
00156 }
00157
00158 switch (bitpix) {
00159 case 8:
00160 datamin = bscale * ( 0.0) + bzero;
00161 datamax = bscale * (254.0) + bzero;
00162 break;
00163 case 16:
00164
00165 datamin = bscale * (-32767.0) + bzero;
00166 datamax = bscale * ( 32767.0) + bzero;
00167 break;
00168 case 32:
00169
00170 datamin = bscale * (-2147483647.0) + bzero;
00171 datamax = bscale * ( 2147483647.0) + bzero;
00172 break;
00173 case -32:
00174 case -64:
00175
00176
00177 datamin = datamax = mxt_getnand();
00178 break;
00179 default:
00180 datamin = datamax = mxt_getnand();
00181 fprintf(stderr, "getfits: illegal bitpix = %d", bitpix);
00182 printerror(0);
00183 break;
00184 }
00185 setrange(pm, datamin, datamax);
00186 return(pm);
00187 }
00188
00189
00190
00191
00192 void
00193 PutFITS(mxArray *pm, char *filename, int bitpix, int file_transpose, double scaling)
00194 {
00195 fitsfile *fptr;
00196 int status;
00197 int naxis;
00198 const mwSize *naxesI;
00199 long *naxesL;
00200 long nelements;
00201 long i;
00202 double datamin, datamax;
00203 double min, max;
00204 double bscale, bzero;
00205 int blank;
00206
00207
00208
00209 if (file_transpose && !mxt_transpose_double_mxArray(pm)) {
00210 fprintf(stderr, "Failed to output-convert matrix (failed malloc)\n");
00211 printerror(0);
00212 }
00213
00214 unlink(filename);
00215 status = 0;
00216 if (fits_create_file(&fptr, filename, &status))
00217 printerror(status);
00218
00219 naxis = (int) mxGetNumberOfDimensions(pm);
00220 nelements = (long) mxGetNumberOfElements(pm);
00221 naxesI = mxGetDimensions(pm);
00222 naxesL = (long *) calloc(naxis, sizeof(long));
00223 if (naxesL == NULL) {
00224 fprintf(stderr, "Failed to output-convert matrix (failed calloc)\n");
00225 printerror(0);
00226 }
00227 for (i = 0; i < naxis; i++)
00228 naxesL[i] = (long) naxesI[i];
00229 if (fits_create_img(fptr, bitpix, naxis, naxesL, &status))
00230 printerror(status);
00231 free(naxesL);
00232
00233
00234
00235
00236 getrange(pm, &datamin, &datamax);
00237 if ((isnan(datamin) || isnan(datamax)) && (bitpix > 0)) {
00238
00239 compute_range(mxGetPr(pm), nelements, &datamin, &datamax);
00240 }
00241
00242
00243
00244
00245
00246
00247
00248
00249 switch (bitpix) {
00250 case 8:
00251 min = 0;
00252 max = 254;
00253 blank = 255;
00254 if (scaling > 0) {
00255 bzero = 0; bscale = scaling;
00256 } else if (scaling == 0) {
00257 bzero = 0; bscale = 1;
00258 } else if (datamax > datamin) {
00259 bscale = (0.5 * datamax - 0.5 * datamin) / (0.5 * max - 0.5 * min);
00260 bzero = datamin - min * bscale;
00261 } else if (datamax == datamin) {
00262 bscale = 1; bzero = datamax;
00263 } else {
00264 bscale = 1; bzero = 0;
00265 }
00266 break;
00267 case 16:
00268 max = 32767.0; min = -max;
00269 blank = min-1;
00270 if (scaling > 0) {
00271 bzero = 0; bscale = scaling;
00272 } else if (scaling == 0) {
00273 bzero = 0; bscale = 1;
00274 } else if (datamax > datamin) {
00275 bscale = (0.5 * datamax - 0.5 * datamin) / (0.5 * max - 0.5 * min);
00276 bzero = datamin - min * bscale;
00277 } else if (datamax == datamin) {
00278 bscale = 1; bzero = datamax;
00279 } else {
00280 bscale = 1; bzero = 0;
00281 }
00282 break;
00283 case 32:
00284 max = 2147483647.0; min = -max;
00285 blank = min-1;
00286 if (scaling > 0) {
00287 bzero = 0; bscale = scaling;
00288 } else if (scaling == 0) {
00289 bzero = 0; bscale = 1;
00290 } else if (datamax > datamin) {
00291 bscale = (0.5 * datamax - 0.5 * datamin) / (0.5 * max - 0.5 * min);
00292 bzero = datamin - min * bscale;
00293 } else if (datamax == datamin) {
00294 bscale = 1; bzero = datamax;
00295 } else {
00296 bscale = 1; bzero = 0;
00297 }
00298 break;
00299 case -32:
00300 case -64:
00301 bscale = 1; bzero = 0;
00302 break;
00303 default:
00304 fprintf(stderr, "putfits: illegal bitpix = %d", bitpix);
00305 printerror(0);
00306 break;
00307 }
00308
00309 if (bscale != 1 || bzero != 0) {
00310 fits_write_key(fptr, TDOUBLE, "BSCALE", &bscale, "bscale", &status);
00311 fits_write_key(fptr, TDOUBLE, "BZERO", &bzero, "bzero", &status);
00312 }
00313
00314 if (bitpix > 0) {
00315 fits_write_key(fptr, TINT, "BLANK", &blank, "blank", &status);
00316 }
00317
00318 fits_write_date(fptr, &status);
00319 fits_write_history(fptr, "Generated by mex2c version 4.0", &status);
00320 if (status)
00321 printerror(status);
00322
00323
00324
00325
00326
00327
00328
00329
00330 if (bitpix >= 0) {
00331 double *data = mxGetPr(pm);
00332 double blank_data = bscale * blank + bzero;
00333 long i;
00334
00335 for (i = 0; i < nelements; i++)
00336 if (isnan(data[i]))
00337 data[i] = blank_data;
00338 }
00339
00340 fits_write_img(fptr, TDOUBLE, 1L, nelements, mxGetPr(pm), &status);
00341
00342 fits_close_file(fptr, &status);
00343
00344 if (status)
00345 printerror(status);
00346 }
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 mxArray *
00359 GetNumericMatrix(char *value)
00360 {
00361 size_t N;
00362 mwSize Nd;
00363 mwSize *dimsM;
00364 double *data;
00365 mwSize n_data = 16384;
00366 double datamin, datamax;
00367 mxArray *pm;
00368
00369 if (!(data = calloc((size_t) n_data, sizeof(*data))))
00370 return NULL;
00371 if (!(dimsM = string_to_array(n_data, value, &Nd, data))) {
00372 free(data);
00373 return NULL;
00374 }
00375
00376 if (!(pm = mxCreateNumericArray((mwSize) Nd, dimsM, mxDOUBLE_CLASS, mxREAL))) {
00377 free(dimsM);
00378 free(data);
00379 return NULL;
00380 }
00381
00382 N = (size_t) mxGetNumberOfElements(pm);
00383 memcpy(mxGetPr(pm), data, (size_t) N*sizeof(double));
00384 compute_range(data, (long) N, &datamin, &datamax);
00385 setrange(pm, datamin, datamax);
00386
00387 free(dimsM);
00388 free(data);
00389 return pm;
00390 }
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401 mxArray *
00402 GetStringMatrix(char *value)
00403 {
00404 mxArray *pm;
00405 char **strs;
00406 int Nrow;
00407 int i;
00408 char *s, *s1, *s2;
00409 char *value_end;
00410 int quote_level;
00411
00412 value_end = value + strlen(value);
00413
00414
00415
00416
00417 if (*value != '[') {
00418 fprintf(stderr, "invalid ([ bracket) string matrix %s\n", value);
00419 printerror(0);
00420 }
00421 if (*(value_end-1) != ']') {
00422 fprintf(stderr, "invalid (] bracket) string matrix %s\n", value);
00423 printerror(0);
00424 }
00425
00426
00427 quote_level = 1;
00428 for (Nrow = 1, s = value + 1; s < value_end-1; s++) {
00429 if (quote_level == 2) {
00430
00431 if (*s == '\'')
00432 quote_level = 0;
00433 } else if (quote_level == 0) {
00434
00435 if (*s != ';') {
00436 fprintf(stderr, "invalid (missing ;) string matrix %s\n", value);
00437 printerror(0);
00438 }
00439 Nrow++;
00440 quote_level++;
00441 } else if (quote_level == 1) {
00442
00443 if (*s != '\'') {
00444 fprintf(stderr, "invalid (missing ') string matrix %s\n", value);
00445 printerror(0);
00446 }
00447 quote_level++;
00448 }
00449 }
00450
00451 if (quote_level != 0) {
00452 fprintf(stderr, "invalid (mismatched ') string matrix %s\n", value);
00453 printerror(0);
00454 }
00455
00456
00457
00458
00459 strs = (char **) calloc(Nrow, sizeof(char *));
00460 if (strs == NULL) {
00461 fprintf(stderr, "failed calloc for string matrix %s\n", value);
00462 printerror(0);
00463 }
00464
00465
00466 s2 = value;
00467 for (i = 0; i < Nrow; i++) {
00468 s1 = strchr(s2+1, '\'');
00469 s2 = strchr(s1+1, '\'');
00470
00471 strs[i] = (char *) calloc(s2 - s1, sizeof(char));
00472 if (strs[i] == NULL) {
00473 fprintf(stderr, "failed calloc for string matrix %s\n", value);
00474 printerror(0);
00475 }
00476 memcpy(strs[i], s1+1, (size_t) (s2-(s1+1)));
00477 }
00478
00479
00480
00481
00482 pm = mxCreateCharMatrixFromStrings((mwSize) Nrow, (const char **) strs);
00483 if (pm == NULL) {
00484 fprintf(stderr, "object creation failed for string matrix %s\n", value);
00485 printerror(0);
00486 }
00487
00488 setrange(pm, 0.0, 254.0);
00489
00490 for (i = 0; i < Nrow; i++)
00491 free(strs[i]);
00492 free(strs);
00493
00494 return(pm);
00495 }
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511 static
00512 void
00513 PutNumericMatrix_level(FILE *fp,
00514 int ndim,
00515 const int *dims,
00516 int stride,
00517 double *pr,
00518 char *delim[])
00519 {
00520 if (ndim > 2) {
00521
00522 int i;
00523
00524 fputs(delim[0], fp);
00525 for (i = 0; i < dims[0]; i++) {
00526 if (i > 0) fputs(delim[4], fp);
00527 PutNumericMatrix_level(fp, ndim-1, dims+1, stride/dims[0],
00528 pr+(stride/dims[0])*i, delim);
00529 }
00530 fputs(delim[1], fp);
00531 } else {
00532
00533 int i, j;
00534 double num;
00535
00536 fputs(delim[0], fp);
00537 for (i = 0; i < dims[0]; i++) {
00538 if (i > 0) fputs(delim[5], fp);
00539 fputs(delim[2], fp);
00540 for (j = 0; j < dims[1]; j++) {
00541 if (j > 0) fputs(delim[6], fp);
00542
00543 num = pr[i*dims[1]+j];
00544 if (isnan(num))
00545 fputs("NaN", fp);
00546 else if (!finite(num) && num < 0)
00547 fputs("-Inf", fp);
00548 else if (!finite(num) && num > 0)
00549 fputs("Inf", fp);
00550 else
00551 fprintf(fp, delim[7], num);
00552 }
00553 fputs(delim[3], fp);
00554 }
00555 fputs(delim[1], fp);
00556 }
00557 }
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576 void
00577 PutNumericArray(FILE *fp,
00578 mxArray *pa,
00579 char *head, char *tail, char *delim[])
00580 {
00581 int d, Nd;
00582 const mwSize *dimsM;
00583 int *dimsI;
00584
00585
00586 Nd = (int) mxGetNumberOfDimensions(pa);
00587 dimsI = (int *) mxMalloc((size_t) (Nd * sizeof(int)));
00588 dimsM = mxGetDimensions(pa);
00589 for (d = 0; d < Nd; d++)
00590 dimsI[d] = (int) dimsM[d];
00591
00592
00593
00594
00595
00596 mxt_transpose_double_mxArray(pa);
00597 fputs(head, fp);
00598
00599
00600
00601
00602 PutNumericMatrix_level(fp, Nd, dimsI, (int) mxGetNumberOfElements(pa),
00603 mxGetPr(pa), delim);
00604 fputs(tail, fp);
00605 mxFree((void *) dimsI);
00606 }
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620 void
00621 PutStringMatrix(FILE *fp,
00622 mxArray *pm,
00623 char *head, char *tail, char *delim[])
00624 {
00625 int m = mxGetM(pm);
00626 int n = mxGetN(pm);
00627 char *pc;
00628 int i,j;
00629
00630 pc = mxArrayToString(pm);
00631
00632 if (pc == NULL) {
00633 fprintf(stderr, "object creation failed on printing string matrix\n");
00634 printerror(0);
00635 }
00636 fputs(head, fp);
00637 fputs(delim[0], fp);
00638 for(i = 0; i < m; i++) {
00639 fputs(delim[2], fp);
00640 for(j = 0; j < n; j++) {
00641 fprintf(fp, "%c", pc[j*m+i]);
00642 }
00643 fputs(delim[3], fp);
00644 if( i != m-1 )
00645 fputs(delim[4], fp);
00646 }
00647 fputs(delim[1], fp);
00648 fputs(tail, fp);
00649
00650 free(pc);
00651 }
00652