check.c 12.4 KB
Newer Older
Emmanuel Bertin's avatar
Emmanuel Bertin committed
1
/*
2
*				check.c
Emmanuel Bertin's avatar
Emmanuel Bertin committed
3
*
4
* Manage "check-images".
Emmanuel Bertin's avatar
Emmanuel Bertin committed
5
*
6
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Emmanuel Bertin's avatar
Emmanuel Bertin committed
7
*
8
*	This file part of:	SExtractor
Emmanuel Bertin's avatar
Emmanuel Bertin committed
9
*
10
*	Copyright:		(C) 1993-2011 Emmanuel Bertin -- IAP/CNRS/UPMC
11
12
13
14
15
16
17
18
19
20
21
22
23
24
*
*	License:		GNU General Public License
*
*	SExtractor is free software: you can redistribute it and/or modify
*	it under the terms of the GNU General Public License as published by
*	the Free Software Foundation, either version 3 of the License, or
*	(at your option) any later version.
*	SExtractor is distributed in the hope that it will be useful,
*	but WITHOUT ANY WARRANTY; without even the implied warranty of
*	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*	GNU General Public License for more details.
*	You should have received a copy of the GNU General Public License
*	along with SExtractor. If not, see <http://www.gnu.org/licenses/>.
*
25
*	Last modified:		11/03/2011
26
27
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
Emmanuel Bertin's avatar
Emmanuel Bertin committed
28
29
30
31
32
33
34
35
36
37
38
39
40

#ifdef HAVE_CONFIG_H
#include        "config.h"
#endif

#include	<math.h>
#include	<stdio.h>
#include	<stdlib.h>
#include	<string.h>

#include	"define.h"
#include	"globals.h"
#include	"fits/fitscat.h"
Emmanuel Bertin's avatar
Emmanuel Bertin committed
41
#include	"fitswcs.h"
Emmanuel Bertin's avatar
Emmanuel Bertin committed
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
#include	"check.h"

/********************************* addcheck **********************************/
/*
Add a PSF to a CHECK-image (with a multiplicative factor).
Outside boundaries are taken into account.
*/
void	addcheck(checkstruct *check, float *psf,
			int w,int h, int ix,int iy, float amplitude)
  {
   PIXTYPE	*pix;
   int		x,y, xmin,xmax,ymin,ymax,w2, dwpsf;

/* Set the image boundaries */
  w2 = w;
  ymin = iy-h/2;
  ymax = ymin + h;
  if (ymin<0)
    {
    psf -= ymin*w;
    ymin = 0;
    }
  if (ymax>check->height)
    ymax = check->height;

  xmin = ix-w/2;
  xmax = xmin + w;
  if (xmax>check->width)
    {
    w2 -= xmax-check->width;
    xmax = check->width;
    }
  if (xmin<0)
    {
Emmanuel Bertin's avatar
Emmanuel Bertin committed
76
77
    psf -= xmin;
    w2 += xmin;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
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
    xmin = 0;
    }

  dwpsf = w-w2;
/* Subtract the right pixels to the destination */
  for (y=ymin; y<ymax; y++, psf += dwpsf)
    {
    pix = (float *)check->pix+y*check->width+xmin;
    for (x=w2; x--;)
      *(pix++) += amplitude**(psf++);
    }

  return;
  }


/********************************* blankcheck *******************************/
/*
Blank a part of the CHECK-image according to a mask.
*/
void	blankcheck(checkstruct *check, PIXTYPE *mask, int w,int h,
		int xmin,int ymin, PIXTYPE val)
  {
   PIXTYPE	*pixt;
   int		x,y, xmax,ymax,w2,wc;

/* Don't go further if out of frame!! */
  if (xmin+w<0 || xmin>=check->width
	|| ymin+h<0 || ymin>=check->height)
    return;
 
/* Set the image boundaries */
  w2 = w;
  ymax = ymin + h;
  if (ymin<0)
    {
    mask -= ymin*w;
    ymin = 0;
    }
  if (ymax>check->height)
    ymax = check->height;

  xmax = xmin + w;
  if (xmax>check->width)
    {
    w2 -= xmax - check->width;
    xmax = check->width;
    }
  if (xmin<0)
    {
    mask += -xmin;
    w2 -= -xmin;
    xmin = 0;
    }

  w -= w2;
  wc = check->width;
  ymin = ymin*wc+xmin;
  ymax = ymax*wc+xmin;

/* Blank the right pixels in the image */
  for (y=ymin; y<ymax; y+=wc, mask += w)
    {
    pixt = (float *)check->pix + y;
    for (x=w2; x--; pixt++)
      if (*(mask++) > -BIG)
        *pixt = val;
    }

  return;
  }


/******************************** initcheck **********************************/
/*
initialize check-image.
*/
checkstruct	*initcheck(char *filename, checkenum check_type, int next)

  {
158
   catstruct	*cat;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
159
160
161
162
   checkstruct	*check;

  QCALLOC(check, checkstruct, 1);
  check->type = check_type;
163
164
165
  check->next = next;
  cat = check->cat = new_cat(1);
  strcpy(cat->filename, filename);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
166
167
168
169

  if (next>1)
/*-- Create a "pure" primary HDU */
    {
170
171
172
173
    init_cat(cat);
    addkeywordto_head(cat->tab, "NEXTEND ", "Number of extensions");
    fitswrite(cat->tab->headbuf, "NEXTEND ", &next, H_INT, T_LONG);
    if (open_cat(cat, WRITE_ONLY) != RETURN_OK)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
174
      error(EXIT_FAILURE,"*Error*: cannot open for writing ", filename);
175
176
    save_head(cat, cat->tab);
    remove_tabs(cat);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
177
178
    }
  else
179
    open_cat(cat, WRITE_ONLY);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
180
181
182
183
184
185
186
187
188
189
190
191

  return check;
  }


/******************************** reinitcheck ********************************/
/*
initialize check-image (for subsequent writing).
*/
void	reinitcheck(picstruct *field, checkstruct *check)

  {
192
193
   catstruct	*cat;
   tabstruct	*tab;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
194
   wcsstruct	*wcs;
195
   char		*fitshead;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
196
   PIXTYPE	*ptrf;
197
198
   double	dval;
   int		i;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
199

200
  cat = check->cat;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
201
/* Inherit the field FITS header */
202
203
204
205
206
207
  remove_tabs(cat);
  copy_tab_fromptr(field->tab, cat, 0);
  tab = cat->tab;
  tab->cat = cat;
  if (check->next<=1)
    prim_head(tab);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
208
  check->y = 0;
209
  fitshead = tab->headbuf;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
210
/* Neutralize possible scaling factors */
211
212
213
214
215
216
217
218
219
220
221
222
  tab->bytepix = 4;
  tab->bscale = 1.0;
  tab->bzero = 0.0;
  fitswrite(fitshead, "BSCALE  ", &tab->bscale, H_FLOAT, T_DOUBLE);
  fitswrite(fitshead, "BZERO   ", &tab->bzero, H_FLOAT, T_DOUBLE);
  fitswrite(fitshead, "BITSGN  ", &tab->bitsgn, H_INT, T_LONG);
  if (tab->compress_type != COMPRESS_NONE)
    {
    tab->compress_type = COMPRESS_NONE;
    fitswrite(fitshead, "IMAGECOD", "NONE", H_STRING, T_STRING);
    }
  fitswrite(fitshead, "ORIGIN  ", BANNER, H_STRING, T_STRING);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
223
224
225
226
227
228
229

  switch(check->type)
    {
    case CHECK_IDENTICAL:
    case CHECK_BACKGROUND:
    case CHECK_FILTERED:
    case CHECK_SUBTRACTED:
230
231
232
233
      tab->bitpix = -32;
      tab->bitsgn = 0;
      tab->naxisn[0] = check->width = field->width;
      tab->naxisn[1] = check->height = field->height;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
234
235
236
      check->npix = field->npix;
      QMALLOC(ptrf, PIXTYPE, check->width);
      check->pix = (void *)ptrf;
237
      save_head(cat, cat->tab);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
238
239
240
241
      break;

    case CHECK_BACKRMS:
    case CHECK_SUBOBJECTS:
242
243
244
245
      tab->bitpix = -32;
      tab->bitsgn = 0;
      tab->naxisn[0] = check->width = field->width;
      tab->naxisn[1] = check->height = field->height;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
246
      check->npix = field->npix;
247
248
      QMALLOC(check->pix, PIXTYPE, check->width);
      save_head(cat, cat->tab);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
249
250
251
252
253
254
255
256
/*---- Allocate memory for replacing the blanked pixels by 0 */
      if (!check->line)
        QMALLOC(check->line, PIXTYPE, field->width);
      break;

    case CHECK_OBJECTS:
    case CHECK_APERTURES:
    case CHECK_PSFPROTOS:
257
    case CHECK_SUBPSFPROTOS:
Emmanuel Bertin's avatar
Emmanuel Bertin committed
258
    case CHECK_PCPROTOS:
259
    case CHECK_SUBPCPROTOS:
Emmanuel Bertin's avatar
Emmanuel Bertin committed
260
    case CHECK_PCOPROTOS:
Emmanuel Bertin's avatar
Emmanuel Bertin committed
261
    case CHECK_PROFILES:
262
263
264
265
266
    case CHECK_SUBPROFILES:
    case CHECK_SPHEROIDS:
    case CHECK_SUBSPHEROIDS:
    case CHECK_DISKS:
    case CHECK_SUBDISKS:
Emmanuel Bertin's avatar
Emmanuel Bertin committed
267
    case CHECK_PATTERNS:
268
269
270
271
      tab->bitpix = -32;
      tab->bitsgn = 0;
      tab->naxisn[0] = check->width = field->width;
      tab->naxisn[1] = check->height = field->height;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
272
273
      check->npix = field->npix;
      check->overlay = 30*field->backsig;
274
275
      QCALLOC(check->pix, PIXTYPE, check->npix);
      save_head(cat, cat->tab);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
276
277
278
      break;

    case CHECK_SEGMENTATION:
279
280
281
282
      tab->bitpix = 32;
      tab->bitsgn = 1;
      tab->naxisn[0] = check->width = field->width;
      tab->naxisn[1] = check->height = field->height;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
283
      check->npix = field->npix;
284
285
      QCALLOC(check->pix, ULONG, check->npix);
      save_head(cat, cat->tab);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
286
287
288
      break;

    case CHECK_ASSOC:
289
290
291
292
      tab->bitpix = -32;
      tab->bitsgn = 0;
      tab->naxisn[0] = check->width = field->width;
      tab->naxisn[1] = check->height = field->height;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
293
      check->npix = field->npix;
294
      QMALLOC(check->pix, PIXTYPE, check->npix);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
295
/*---- Initialize the pixmap to IEEE NaN */
296
297
      memset(check->pix, 0xFF, check->npix*sizeof(LONG));
      save_head(cat, cat->tab);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
298
299
300
301
      break;

    case CHECK_MINIBACKGROUND:
    case CHECK_MINIBACKRMS:
302
303
304
305
      tab->bitpix = -32;
      tab->bitsgn = 0;
      tab->naxisn[0] = check->width = field->nbackx;
      tab->naxisn[1] = check->height = field->nbacky;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
306
/*---- Scale the WCS information if present */
Emmanuel Bertin's avatar
Emmanuel Bertin committed
307
      if ((wcs=field->wcs))
Emmanuel Bertin's avatar
Emmanuel Bertin committed
308
        {
Emmanuel Bertin's avatar
Emmanuel Bertin committed
309
        dval = wcs->cdelt[0]*field->backw;
310
        fitswrite(fitshead, "CDELT1  ", &dval, H_EXPO, T_DOUBLE);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
311
        dval = wcs->cdelt[1]*field->backh;
312
        fitswrite(fitshead, "CDELT2  ", &dval, H_EXPO, T_DOUBLE);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
313
        dval = (wcs->crpix[0]-0.5)/field->backw + 0.5;
314
        fitswrite(fitshead, "CRPIX1  ", &dval, H_EXPO, T_DOUBLE);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
315
        dval = (wcs->crpix[1]-0.5)/field->backh + 0.5;
316
        fitswrite(fitshead, "CRPIX2  ", &dval, H_EXPO, T_DOUBLE);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
317

Emmanuel Bertin's avatar
Emmanuel Bertin committed
318
        dval = wcs->cd[0]*field->backw;
319
        fitswrite(fitshead, "CD1_1   ", &dval, H_EXPO, T_DOUBLE);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
320
        dval = wcs->cd[1]*field->backh;
321
        fitswrite(fitshead, "CD1_2  ", &dval, H_EXPO, T_DOUBLE);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
322
        dval = wcs->cd[wcs->naxis]*field->backw;
323
        fitswrite(fitshead, "CD2_1   ", &dval, H_EXPO, T_DOUBLE);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
324
        dval = wcs->cd[wcs->naxis+1]*field->backh;
325
        fitswrite(fitshead, "CD2_2  ", &dval, H_EXPO, T_DOUBLE);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
326
327
        }
      check->npix = check->width*check->height;
328
      QMALLOC(check->pix, PIXTYPE, check->npix);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
329
330
331
332
      if (check->type==CHECK_MINIBACKRMS)
        memcpy(check->pix, field->sigma, check->npix*sizeof(float));
      else
        memcpy(check->pix, field->back, check->npix*sizeof(float));
333
334
      save_head(cat, cat->tab);
      write_body(cat->tab, check->pix, check->npix);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
335
336
337
338
      free(check->pix);
      break;

    case CHECK_MAPSOM:
339
340
341
342
      tab->bitpix = -32;
      tab->bitsgn = 0;
      tab->naxisn[0] = check->width = field->width;
      tab->naxisn[1] = check->height = field->height;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
343
344
345
346
347
      check->npix = field->npix;
      QMALLOC(ptrf, PIXTYPE, check->npix);
      check->pix = (void *)ptrf;
      for (i=check->npix; i--;)
        *(ptrf++) = -10.0;
348
      save_head(cat, cat->tab);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
349
350
      break;

351
    case CHECK_OTHER:
352
353
354
355
      tab->bitpix = -32;
      tab->bitsgn = 0;
      tab->naxisn[0] = check->width;
      tab->naxisn[1] = check->height;
356
      check->npix = check->width*check->height;
357
358
      QCALLOC(check->pix, PIXTYPE, check->npix);
      save_head(cat, cat->tab);
359
360
      break;

Emmanuel Bertin's avatar
Emmanuel Bertin committed
361
    default:
Emmanuel Bertin's avatar
Emmanuel Bertin committed
362
      error(EXIT_FAILURE, "*Internal Error* in ", "reinitcheck()!");
Emmanuel Bertin's avatar
Emmanuel Bertin committed
363
364
365
366
367
368
369
370
371
372
373
374
375
376
    }

  return;
  }


/******************************** writecheck *********************************/
/*
Write ONE line of npix pixels of a check-image.
*/
void	writecheck(checkstruct *check, PIXTYPE *data, int w)

  {
  if (check->type == CHECK_APERTURES || check->type == CHECK_SUBPSFPROTOS
Emmanuel Bertin's avatar
Emmanuel Bertin committed
377
	|| check->type == CHECK_SUBPCPROTOS || check->type == CHECK_PCOPROTOS
378
379
	|| check->type == CHECK_SUBPROFILES || check->type == CHECK_SUBSPHEROIDS
	|| check->type == CHECK_SUBDISKS)
Emmanuel Bertin's avatar
Emmanuel Bertin committed
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
    {
    memcpy((PIXTYPE *)check->pix + w*(check->y++), data, w*sizeof(PIXTYPE));
    return;
    }
  else if (check->type == CHECK_SUBOBJECTS)
    {
     int	i;
     PIXTYPE	*pixt;

    pixt = check->line;
    for (i=w; i--; data++)
      *(pixt++) = (*data>-BIG)? *data:0.0;
    data = check->line;
    }

395
  write_body(check->cat->tab, data, w);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
396
397
398
399
400
401
402
403
404
405
406

  return;
  }


/********************************* reendcheck ********************************/
/*
Finish current check-image.
*/
void	reendcheck(picstruct *field, checkstruct *check)
  {
407
   catstruct	*cat;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
408

409
  cat = check->cat;
Emmanuel Bertin's avatar
Emmanuel Bertin committed
410
411
412
413
414
415
416
417
418
419
420
421
422
423
  switch(check->type)
    {
    case CHECK_MINIBACKGROUND:
    case CHECK_MINIBACKRMS:
      return;

    case CHECK_IDENTICAL:
    case CHECK_BACKGROUND:
    case CHECK_BACKRMS:
    case CHECK_FILTERED:
    case CHECK_SUBTRACTED:
      free(check->pix);
      free(check->line);
      check->line = NULL;
424
      pad_tab(cat, check->npix*sizeof(PIXTYPE));
Emmanuel Bertin's avatar
Emmanuel Bertin committed
425
426
427
428
429
      break;

    case CHECK_OBJECTS:
    case CHECK_APERTURES:
    case CHECK_PSFPROTOS:
430
    case CHECK_SUBPSFPROTOS:
Emmanuel Bertin's avatar
Emmanuel Bertin committed
431
    case CHECK_PCPROTOS:
432
    case CHECK_SUBPCPROTOS:
Emmanuel Bertin's avatar
Emmanuel Bertin committed
433
    case CHECK_PCOPROTOS:
Emmanuel Bertin's avatar
Emmanuel Bertin committed
434
    case CHECK_PROFILES:
435
436
437
438
439
    case CHECK_SUBPROFILES:
    case CHECK_SPHEROIDS:
    case CHECK_SUBSPHEROIDS:
    case CHECK_DISKS:
    case CHECK_SUBDISKS:
Emmanuel Bertin's avatar
Emmanuel Bertin committed
440
    case CHECK_ASSOC:
Emmanuel Bertin's avatar
Emmanuel Bertin committed
441
    case CHECK_PATTERNS:
442
443
    case CHECK_MAPSOM:
    case CHECK_OTHER:
444
      write_body(cat->tab, check->pix, check->npix);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
445
      free(check->pix);
446
      pad_tab(cat, check->npix*sizeof(PIXTYPE));
Emmanuel Bertin's avatar
Emmanuel Bertin committed
447
448
449
      break;

    case CHECK_SEGMENTATION:
450
      write_ibody(cat->tab, check->pix, check->npix);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
451
      free(check->pix);
452
      pad_tab(cat, check->npix*sizeof(FLAGTYPE));
Emmanuel Bertin's avatar
Emmanuel Bertin committed
453
454
455
456
457
458
459
460
461
462
463
      break;

    case CHECK_SUBOBJECTS:
      {
       int	y;

      for (y=field->ymin; y<field->ymax; y++)
        writecheck(check, &PIX(field, 0, y), field->width);
      free(check->pix);
      free(check->line);
      check->line = NULL;
464
      pad_tab(cat, check->npix*sizeof(PIXTYPE));
Emmanuel Bertin's avatar
Emmanuel Bertin committed
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
      break;
      }

    default:
      error(EXIT_FAILURE, "*Internal Error* in ", "endcheck()!");
    }

  return;
  }

/********************************* endcheck **********************************/
/*
close check-image.
*/
void	endcheck(checkstruct *check)
  {
481
  free_cat(&check->cat,1);
Emmanuel Bertin's avatar
Emmanuel Bertin committed
482
483
484
485
486
  free(check);

  return;
  }