File: image2xy-files.c

package info (click to toggle)
astrometry.net 0.93%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 19,372 kB
  • sloc: ansic: 163,192; python: 18,357; makefile: 1,522; sh: 138; cpp: 78; pascal: 67; awk: 56; perl: 9
file content (277 lines) | stat: -rw-r--r-- 10,275 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
/*
 # This file is part of the Astrometry.net suite.
 # Licensed under a 3-clause BSD style license - see LICENSE
 */

#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <assert.h>
#include <sys/types.h>
#include <unistd.h>
#include <math.h>

#include "os-features.h"
#include "image2xy-files.h"
#include "image2xy.h"
#include "fitsio.h"
#include "ioutils.h"
#include "simplexy.h"
#include "errors.h"
#include "log.h"
#include "cfitsutils.h"

int image2xy_files(const char* infn, const char* outfn,
                   anbool do_u8, int downsample, int downsample_as_required,
                   int extension, int plane,
                   simplexy_t* params) {
    fitsfile *fptr = NULL;
    fitsfile *ofptr = NULL;
    int status = 0; // FIXME should have ostatus too
    int naxis;
    long naxisn[3];
    int kk;
    int nhdus, hdutype, nimgs;
    char* str;
    simplexy_t myparams;

    if (params == NULL) {
        memset(&myparams, 0, sizeof(simplexy_t));
        params = &myparams;
    }

    // QFITS to CFITSIO extension convention switch
    extension++;

    fits_open_file(&fptr, infn, READONLY, &status);
    CFITS_CHECK("Failed to open FITS input file %s", infn);

    // Are there multiple HDU's?
    fits_get_num_hdus(fptr, &nhdus, &status);
    CFITS_CHECK("Failed to read number of HDUs for input file %s", infn);
    logverb("nhdus=%d\n", nhdus);

    if (extension > nhdus) {
        logerr("Requested extension %i is greater than number of extensions (%i) in file %s\n",
               extension, nhdus, infn);
        return -1;
    }

    // Create output file
    fits_create_file(&ofptr, outfn, &status);
    CFITS_CHECK("Failed to open FITS output file %s", outfn);

    fits_create_img(ofptr, 8, 0, NULL, &status);
    CFITS_CHECK("Failed to create output image");

    fits_write_key(ofptr, TSTRING, "SRCFN", (char*)infn, "Source image", &status);
    if (extension)
        fits_write_key(ofptr, TINT, "SRCEXT", &extension, "Source image extension (1=primary)", &status);

    /* Parameters for simplexy; save for debugging */
    fits_write_comment(ofptr, "Parameters used for source extraction", &status);

    fits_write_history(ofptr, "Created by Astrometry.net's image2xy program.", &status);
    CFITS_CHECK("Failed to write HISTORY headers");

    asprintf_safe(&str, "GIT URL: %s", AN_GIT_URL);
    fits_write_history(ofptr, str, &status);
    CFITS_CHECK("Failed to write GIT HISTORY headers");
    free(str);
    asprintf_safe(&str, "GIT Rev: %s", AN_GIT_REVISION);
    fits_write_history(ofptr, str, &status);
    CFITS_CHECK("Failed to write GIT HISTORY headers");
    free(str);
    asprintf_safe(&str, "GIT Date: %s", AN_GIT_DATE);
    fits_write_history(ofptr, str, &status);
    CFITS_CHECK("Failed to write GIT HISTORY headers");
    free(str);
    fits_write_history(ofptr, "Visit us on the web at http://astrometry.net/", &status);
    CFITS_CHECK("Failed to write GIT HISTORY headers");

    nimgs = 0;

    // Run simplexy on each HDU
    for (kk=1; kk <= nhdus; kk++) {
        char* ttype[] = {"X","Y","FLUX","BACKGROUND", "LFLUX", "LBG"};
        char* tform[] = {"E","E","E","E","E","E"};
        char* tunit[] = {"pix","pix","unknown","unknown","unknown","unknown"};
        long* fpixel;
        int a;
        int w, h;
        int bitpix;
        int ncols;

        if (extension && kk != extension)
            continue;

        fits_movabs_hdu(fptr, kk, &hdutype, &status);
        fits_get_hdu_type(fptr, &hdutype, &status);

        if (hdutype != IMAGE_HDU) {
            if (extension)
                logerr("Requested extension %i in file %s is not an image.\n", extension, infn);
            continue;
        }

        fits_get_img_dim(fptr, &naxis, &status);
        CFITS_CHECK("Failed to find image dimensions for HDU %i", kk);

        fits_get_img_size(fptr, 2, naxisn, &status);
        CFITS_CHECK("Failed to find image dimensions for HDU %i", kk);

        nimgs++;

        logverb("Got naxis=%d, na1=%lu, na2=%lu\n", naxis, naxisn[0], naxisn[1]);

        fits_get_img_type(fptr, &bitpix, &status);
        CFITS_CHECK("Failed to get FITS image type");

        fpixel = malloc(naxis * sizeof(long));
        for (a=0; a<naxis; a++)
            fpixel[a] = 1;

        if (plane && naxis == 3) {
            if (plane <= naxisn[2]) {
                logmsg("Grabbing image plane %i\n", plane);
                fpixel[2] = plane;
            } else
                logerr("Requested plane %i but only %i are available.\n", plane, (int)naxisn[2]);
        } else if (plane)
            logmsg("Plane %i requested but this image has NAXIS = %i (not 3).\n", plane, naxis);
        else if (naxis > 2)
            logmsg("This looks like a multi-color image: processing the first image plane only.  (NAXIS=%i)\n", naxis);
		
        if (bitpix == 8 && do_u8 && !downsample) {
            simplexy_fill_in_defaults_u8(params);

            // u8 image.
            params->image_u8 = malloc(naxisn[0] * naxisn[1]);
            if (!params->image_u8) {
                SYSERROR("Failed to allocate u8 image array");
                goto bailout;
            }
            fits_read_pix(fptr, TBYTE, fpixel, naxisn[0]*naxisn[1], NULL,
                          params->image_u8, NULL, &status);

        } else {
            simplexy_fill_in_defaults(params);

            params->image = malloc(naxisn[0] * naxisn[1] * sizeof(float));
            if (!params->image) {
                SYSERROR("Failed to allocate image array");
                goto bailout;
            }
            fits_read_pix(fptr, TFLOAT, fpixel, naxisn[0]*naxisn[1], NULL,
                          params->image, NULL, &status);
        }
        free(fpixel);
        CFITS_CHECK("Failed to read image pixels");

        params->nx = naxisn[0];
        params->ny = naxisn[1];

        image2xy_run(params, downsample, downsample_as_required);

        if (params->Lorder)
            ncols = 6;
        else
            ncols = 4;
        fits_create_tbl(ofptr, BINARY_TBL, params->npeaks, ncols, ttype, tform,
                        tunit, "SOURCES", &status);
        CFITS_CHECK("Failed to create output table");

        fits_write_col(ofptr, TFLOAT, 1, 1, 1, params->npeaks, params->x, &status);
        CFITS_CHECK("Failed to write X column");

        fits_write_col(ofptr, TFLOAT, 2, 1, 1, params->npeaks, params->y, &status);
        CFITS_CHECK("Failed to write Y column");

        fits_write_col(ofptr, TFLOAT, 3, 1, 1, params->npeaks, params->flux, &status);
        CFITS_CHECK("Failed to write FLUX column");

        fits_write_col(ofptr, TFLOAT, 4, 1, 1, params->npeaks, params->background, &status);
        CFITS_CHECK("Failed to write BACKGROUND column");

        if (params->Lorder) {
            fits_write_col(ofptr, TFLOAT, 5, 1, 1, params->npeaks, params->fluxL, &status);
            CFITS_CHECK("Failed to write LFLUX column");

            fits_write_col(ofptr, TFLOAT, 6, 1, 1, params->npeaks, params->backgroundL, &status);
            CFITS_CHECK("Failed to write LBG column");
        }

        fits_modify_comment(ofptr, "TTYPE1", "X coordinate", &status);
        CFITS_CHECK("Failed to set X TTYPE");

        fits_modify_comment(ofptr, "TTYPE2", "Y coordinate", &status);
        CFITS_CHECK("Failed to set Y TTYPE");

        fits_modify_comment(ofptr, "TTYPE3", "Flux of source", &status);
        CFITS_CHECK("Failed to set FLUX TTYPE");

        fits_modify_comment(ofptr, "TTYPE4", "Sky background of source", &status);
        CFITS_CHECK("Failed to set BACKGROUND TTYPE");

        fits_write_key(ofptr, TINT, "SRCEXT", &kk,
                       "Extension number in src image", &status);
        CFITS_CHECK("Failed to write SRCEXT");

        w = naxisn[0];
        h = naxisn[1];
        fits_write_key(ofptr, TINT, "IMAGEW", &w, "Input image width", &status);
        CFITS_CHECK("Failed to write IMAGEW");

        fits_write_key(ofptr, TINT, "IMAGEH", &h, "Input image height", &status);
        CFITS_CHECK("Failed to write IMAGEH");

        fits_write_key(ofptr, TFLOAT, "ESTSIGMA", &(params->sigma),
                       "Estimated source image variance", &status);
        CFITS_CHECK("Failed to write ESTSIGMA");

        fits_write_key(ofptr, TFLOAT, "DPSF", &(params->dpsf), "image2xy Assumed gaussian psf width", &status);
        fits_write_key(ofptr, TFLOAT, "PLIM", &(params->plim), "image2xy Significance to keep", &status);
        fits_write_key(ofptr, TFLOAT, "DLIM", &(params->dlim), "image2xy Closest two peaks can be", &status);
        fits_write_key(ofptr, TFLOAT, "SADDLE", &(params->saddle), "image2xy Saddle difference (in sig)", &status);
        fits_write_key(ofptr, TINT, "MAXPER", &(params->maxper), "image2xy Max num of peaks per object", &status);
        fits_write_key(ofptr, TINT, "MAXPEAKS", &(params->maxnpeaks), "image2xy Max num of peaks total", &status);
        fits_write_key(ofptr, TINT, "MAXSIZE", &(params->maxsize), "image2xy Max size for extended objects", &status);
        fits_write_key(ofptr, TINT, "HALFBOX", &(params->halfbox), "image2xy Half-size for sliding sky window", &status);


        fits_write_comment(ofptr,
                           "The X and Y points are specified assuming 1,1 is "
                           "the center of the leftmost bottom pixel of the "
                           "image in accordance with the FITS standard.", &status);
        CFITS_CHECK("Failed to write comments");

        simplexy_free_contents(params);
    }

    // Put in the optional NEXTEND keywoard
    fits_movabs_hdu(ofptr, 1, &hdutype, &status);
    assert(hdutype == IMAGE_HDU);
    fits_write_key(ofptr, TINT, "NEXTEND", &nimgs, "Number of extensions", &status);
    if (status == END_OF_FILE)
        status = 0; /* Reset after normal error */
    CFITS_CHECK("Failed to write NEXTEND");

    fits_close_file(fptr, &status);
    CFITS_CHECK("Failed to close FITS input file");
    fptr = NULL;

    fits_close_file(ofptr, &status);
    CFITS_CHECK("Failed to close FITS output file");

    // for valgrind
    simplexy_clean_cache();

    return 0;

 bailout:
    if (fptr)
        fits_close_file(fptr, &status);
    if (ofptr)
        fits_close_file(ofptr, &status);
    return -1;
}