Newer
Older
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
* Copyright: (C) 1993-2011 Emmanuel Bertin -- IAP/CNRS/UPMC
*
* 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/>.
*
* Last modified: 11/03/2011
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#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"
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)
{
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)
{
Emmanuel Bertin
committed
catstruct *cat;
checkstruct *check;
QCALLOC(check, checkstruct, 1);
check->type = check_type;
Emmanuel Bertin
committed
check->next = next;
cat = check->cat = new_cat(1);
strcpy(cat->filename, filename);
if (next>1)
/*-- Create a "pure" primary HDU */
{
Emmanuel Bertin
committed
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)
error(EXIT_FAILURE,"*Error*: cannot open for writing ", filename);
Emmanuel Bertin
committed
save_head(cat, cat->tab);
remove_tabs(cat);
Emmanuel Bertin
committed
open_cat(cat, WRITE_ONLY);
return check;
}
/******************************** reinitcheck ********************************/
/*
initialize check-image (for subsequent writing).
*/
void reinitcheck(picstruct *field, checkstruct *check)
{
Emmanuel Bertin
committed
catstruct *cat;
tabstruct *tab;
Emmanuel Bertin
committed
char *fitshead;
Emmanuel Bertin
committed
double dval;
int i;
Emmanuel Bertin
committed
cat = check->cat;
Emmanuel Bertin
committed
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
committed
fitshead = tab->headbuf;
/* Neutralize possible scaling factors */
Emmanuel Bertin
committed
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);
switch(check->type)
{
case CHECK_IDENTICAL:
case CHECK_BACKGROUND:
case CHECK_FILTERED:
case CHECK_SUBTRACTED:
Emmanuel Bertin
committed
tab->bitpix = -32;
tab->bitsgn = 0;
tab->naxisn[0] = check->width = field->width;
tab->naxisn[1] = check->height = field->height;
check->npix = field->npix;
QMALLOC(ptrf, PIXTYPE, check->width);
check->pix = (void *)ptrf;
Emmanuel Bertin
committed
save_head(cat, cat->tab);
break;
case CHECK_BACKRMS:
case CHECK_SUBOBJECTS:
Emmanuel Bertin
committed
tab->bitpix = -32;
tab->bitsgn = 0;
tab->naxisn[0] = check->width = field->width;
tab->naxisn[1] = check->height = field->height;
Emmanuel Bertin
committed
QMALLOC(check->pix, PIXTYPE, check->width);
save_head(cat, cat->tab);
/*---- 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:
case CHECK_SUBPSFPROTOS:
case CHECK_SUBPCPROTOS:
case CHECK_SUBPROFILES:
case CHECK_SPHEROIDS:
case CHECK_SUBSPHEROIDS:
case CHECK_DISKS:
case CHECK_SUBDISKS:
Emmanuel Bertin
committed
tab->bitpix = -32;
tab->bitsgn = 0;
tab->naxisn[0] = check->width = field->width;
tab->naxisn[1] = check->height = field->height;
check->npix = field->npix;
check->overlay = 30*field->backsig;
Emmanuel Bertin
committed
QCALLOC(check->pix, PIXTYPE, check->npix);
save_head(cat, cat->tab);
Emmanuel Bertin
committed
tab->bitpix = 32;
tab->bitsgn = 1;
tab->naxisn[0] = check->width = field->width;
tab->naxisn[1] = check->height = field->height;
Emmanuel Bertin
committed
QCALLOC(check->pix, ULONG, check->npix);
save_head(cat, cat->tab);
Emmanuel Bertin
committed
tab->bitpix = -32;
tab->bitsgn = 0;
tab->naxisn[0] = check->width = field->width;
tab->naxisn[1] = check->height = field->height;
Emmanuel Bertin
committed
QMALLOC(check->pix, PIXTYPE, check->npix);
/*---- Initialize the pixmap to IEEE NaN */
Emmanuel Bertin
committed
memset(check->pix, 0xFF, check->npix*sizeof(LONG));
save_head(cat, cat->tab);
break;
case CHECK_MINIBACKGROUND:
case CHECK_MINIBACKRMS:
Emmanuel Bertin
committed
tab->bitpix = -32;
tab->bitsgn = 0;
tab->naxisn[0] = check->width = field->nbackx;
tab->naxisn[1] = check->height = field->nbacky;
/*---- Scale the WCS information if present */
Emmanuel Bertin
committed
fitswrite(fitshead, "CDELT1 ", &dval, H_EXPO, T_DOUBLE);
Emmanuel Bertin
committed
fitswrite(fitshead, "CDELT2 ", &dval, H_EXPO, T_DOUBLE);
dval = (wcs->crpix[0]-0.5)/field->backw + 0.5;
Emmanuel Bertin
committed
fitswrite(fitshead, "CRPIX1 ", &dval, H_EXPO, T_DOUBLE);
dval = (wcs->crpix[1]-0.5)/field->backh + 0.5;
Emmanuel Bertin
committed
fitswrite(fitshead, "CRPIX2 ", &dval, H_EXPO, T_DOUBLE);
Emmanuel Bertin
committed
fitswrite(fitshead, "CD1_1 ", &dval, H_EXPO, T_DOUBLE);
Emmanuel Bertin
committed
fitswrite(fitshead, "CD1_2 ", &dval, H_EXPO, T_DOUBLE);
Emmanuel Bertin
committed
fitswrite(fitshead, "CD2_1 ", &dval, H_EXPO, T_DOUBLE);
Emmanuel Bertin
committed
fitswrite(fitshead, "CD2_2 ", &dval, H_EXPO, T_DOUBLE);
}
check->npix = check->width*check->height;
Emmanuel Bertin
committed
QMALLOC(check->pix, PIXTYPE, check->npix);
if (check->type==CHECK_MINIBACKRMS)
memcpy(check->pix, field->sigma, check->npix*sizeof(float));
else
memcpy(check->pix, field->back, check->npix*sizeof(float));
Emmanuel Bertin
committed
save_head(cat, cat->tab);
write_body(cat->tab, check->pix, check->npix);
free(check->pix);
break;
case CHECK_MAPSOM:
Emmanuel Bertin
committed
tab->bitpix = -32;
tab->bitsgn = 0;
tab->naxisn[0] = check->width = field->width;
tab->naxisn[1] = check->height = field->height;
check->npix = field->npix;
QMALLOC(ptrf, PIXTYPE, check->npix);
check->pix = (void *)ptrf;
for (i=check->npix; i--;)
*(ptrf++) = -10.0;
Emmanuel Bertin
committed
save_head(cat, cat->tab);
Emmanuel Bertin
committed
tab->bitpix = -32;
tab->bitsgn = 0;
tab->naxisn[0] = check->width;
tab->naxisn[1] = check->height;
check->npix = check->width*check->height;
Emmanuel Bertin
committed
QCALLOC(check->pix, PIXTYPE, check->npix);
save_head(cat, cat->tab);
error(EXIT_FAILURE, "*Internal Error* in ", "reinitcheck()!");
}
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
|| check->type == CHECK_SUBPCPROTOS || check->type == CHECK_PCOPROTOS
|| check->type == CHECK_SUBPROFILES || check->type == CHECK_SUBSPHEROIDS
|| check->type == CHECK_SUBDISKS)
{
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;
}
Emmanuel Bertin
committed
write_body(check->cat->tab, data, w);
return;
}
/********************************* reendcheck ********************************/
/*
Finish current check-image.
*/
void reendcheck(picstruct *field, checkstruct *check)
{
Emmanuel Bertin
committed
catstruct *cat;
Emmanuel Bertin
committed
cat = check->cat;
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;
Emmanuel Bertin
committed
pad_tab(cat, check->npix*sizeof(PIXTYPE));
break;
case CHECK_OBJECTS:
case CHECK_APERTURES:
case CHECK_PSFPROTOS:
case CHECK_SUBPSFPROTOS:
case CHECK_SUBPCPROTOS:
case CHECK_SUBPROFILES:
case CHECK_SPHEROIDS:
case CHECK_SUBSPHEROIDS:
case CHECK_DISKS:
case CHECK_SUBDISKS:
case CHECK_MAPSOM:
case CHECK_OTHER:
Emmanuel Bertin
committed
write_body(cat->tab, check->pix, check->npix);
Emmanuel Bertin
committed
pad_tab(cat, check->npix*sizeof(PIXTYPE));
Emmanuel Bertin
committed
write_ibody(cat->tab, check->pix, check->npix);
Emmanuel Bertin
committed
pad_tab(cat, check->npix*sizeof(FLAGTYPE));
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;
Emmanuel Bertin
committed
pad_tab(cat, check->npix*sizeof(PIXTYPE));
break;
}
default:
error(EXIT_FAILURE, "*Internal Error* in ", "endcheck()!");
}
return;
}
/********************************* endcheck **********************************/
/*
close check-image.
*/
void endcheck(checkstruct *check)
{
Emmanuel Bertin
committed
free_cat(&check->cat,1);