/* * check.c * * Manage "check-images". * *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% * * This file part of: SExtractor * * Copyright: (C) 1993,1998-2010 IAP/CNRS/UPMC * (C) 1994,1997 ESO * (C) 1995,1996 Sterrewacht Leiden * * Author: Emmanuel Bertin (IAP) * * 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 . * * Last modified: 11/10/2010 * *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include #include "define.h" #include "globals.h" #include "fits/fitscat.h" #include "fitswcs.h" #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) { psf -= xmin; w2 += xmin; xmin = 0; } dwpsf = w-w2; /* Subtract the right pixels to the destination */ for (y=ymin; ypix+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; ypix + 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) { catstruct *fitscat; checkstruct *check; QCALLOC(check, checkstruct, 1); strcpy(check->filename, filename); check->type = check_type; if (next>1) /*-- Create a "pure" primary HDU */ { fitscat = new_cat(1); init_cat(fitscat); strcpy(fitscat->filename, filename); fitsadd(fitscat->tab->headbuf, "NEXTEND ", "Number of extensions"); fitswrite(fitscat->tab->headbuf, "NEXTEND ", &next, H_INT, T_LONG); if (open_cat(fitscat, WRITE_ONLY) != RETURN_OK) error(EXIT_FAILURE,"*Error*: cannot open for writing ", filename); save_tab(fitscat, fitscat->tab); check->file = fitscat->file; fitscat->file = NULL; free_cat(&fitscat, 1); } else if (!(check->file = fopen(check->filename, "wb"))) error(EXIT_FAILURE, "*Error*: Cannot open for output ", check->filename); return check; } /******************************** reinitcheck ********************************/ /* initialize check-image (for subsequent writing). */ void reinitcheck(picstruct *field, checkstruct *check) { wcsstruct *wcs; char *buf; int i, ival; size_t padsize; double dval; ULONG *ptri; PIXTYPE *ptrf; /* Inherit the field FITS header */ check->fitsheadsize = field->tab->headnblock*FBSIZE; QMEMCPY(field->tab->headbuf, check->fitshead, char, check->fitsheadsize); check->y = 0; /* Neutralize possible scaling factors */ dval = 1.0;fitswrite(check->fitshead, "BSCALE ", &dval, H_FLOAT, T_DOUBLE); dval = 0.0;fitswrite(check->fitshead, "BZERO ", &dval, H_FLOAT, T_DOUBLE); ival = 1;fitswrite(check->fitshead, "BITSGN ", &ival, H_INT, T_LONG); if (field->tab->compress_type != COMPRESS_NONE) fitswrite(check->fitshead, "IMAGECOD", "NONE", H_STRING, T_STRING); fitswrite(check->fitshead, "ORIGIN ", BANNER, H_STRING, T_STRING); switch(check->type) { case CHECK_IDENTICAL: case CHECK_BACKGROUND: case CHECK_FILTERED: case CHECK_SUBTRACTED: ival = -32; fitswrite(check->fitshead, "BITPIX ", &ival, H_INT, T_LONG); check->width = field->width; check->height = field->height; check->npix = field->npix; QMALLOC(ptrf, PIXTYPE, check->width); check->pix = (void *)ptrf; QFWRITE(check->fitshead,check->fitsheadsize,check->file,check->filename); free(check->fitshead); break; case CHECK_BACKRMS: case CHECK_SUBOBJECTS: ival = -32; fitswrite(check->fitshead, "BITPIX ", &ival, H_INT, T_LONG); check->width = field->width; check->height = field->height; check->npix = field->npix; QMALLOC(ptrf, PIXTYPE, check->width); check->pix = (void *)ptrf; QFWRITE(check->fitshead,check->fitsheadsize,check->file,check->filename); free(check->fitshead); /*---- 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_PCPROTOS: case CHECK_SUBPCPROTOS: case CHECK_PCOPROTOS: case CHECK_PROFILES: case CHECK_SUBPROFILES: case CHECK_SPHEROIDS: case CHECK_SUBSPHEROIDS: case CHECK_DISKS: case CHECK_SUBDISKS: case CHECK_PATTERNS: ival = -32; fitswrite(check->fitshead, "BITPIX ", &ival, H_INT, T_LONG); check->width = field->width; check->height = field->height; check->npix = field->npix; check->overlay = 30*field->backsig; QCALLOC(ptrf, PIXTYPE, check->npix); check->pix = (void *)ptrf; QFWRITE(check->fitshead,check->fitsheadsize,check->file,check->filename); free(check->fitshead); break; case CHECK_SEGMENTATION: ival = 32; fitswrite(check->fitshead, "BITPIX ", &ival, H_INT, T_LONG); check->width = field->width; check->height = field->height; check->npix = field->npix; QCALLOC(ptri, ULONG, check->npix); check->pix = (void *)ptri; QFWRITE(check->fitshead,check->fitsheadsize,check->file,check->filename); free(check->fitshead); break; case CHECK_ASSOC: ival = -32; fitswrite(check->fitshead, "BITPIX ", &ival, H_INT, T_LONG); check->width = field->width; check->height = field->height; check->npix = field->npix; QMALLOC(ptrf, PIXTYPE, check->npix); check->pix = (void *)ptrf; /*---- Initialize the pixmap to IEEE NaN */ memset(ptrf, 0xFF, check->npix*sizeof(LONG)); QFWRITE(check->fitshead,check->fitsheadsize,check->file,check->filename); free(check->fitshead); break; case CHECK_MINIBACKGROUND: case CHECK_MINIBACKRMS: ival = -32; fitswrite(check->fitshead, "BITPIX ", &ival, H_INT, T_LONG); check->width = field->nbackx; fitswrite(check->fitshead, "NAXIS1 ", &check->width, H_INT, T_LONG); check->height = field->nbacky; fitswrite(check->fitshead, "NAXIS2 ", &check->height, H_INT, T_LONG); /*---- Scale the WCS information if present */ if ((wcs=field->wcs)) { dval = wcs->cdelt[0]*field->backw; fitswrite(check->fitshead, "CDELT1 ", &dval, H_EXPO, T_DOUBLE); dval = wcs->cdelt[1]*field->backh; fitswrite(check->fitshead, "CDELT2 ", &dval, H_EXPO, T_DOUBLE); dval = (wcs->crpix[0]-0.5)/field->backw + 0.5; fitswrite(check->fitshead, "CRPIX1 ", &dval, H_EXPO, T_DOUBLE); dval = (wcs->crpix[1]-0.5)/field->backh + 0.5; fitswrite(check->fitshead, "CRPIX2 ", &dval, H_EXPO, T_DOUBLE); dval = wcs->cd[0]*field->backw; fitswrite(check->fitshead, "CD1_1 ", &dval, H_EXPO, T_DOUBLE); dval = wcs->cd[1]*field->backh; fitswrite(check->fitshead, "CD1_2 ", &dval, H_EXPO, T_DOUBLE); dval = wcs->cd[wcs->naxis]*field->backw; fitswrite(check->fitshead, "CD2_1 ", &dval, H_EXPO, T_DOUBLE); dval = wcs->cd[wcs->naxis+1]*field->backh; fitswrite(check->fitshead, "CD2_2 ", &dval, H_EXPO, T_DOUBLE); } check->npix = check->width*check->height; QMALLOC(ptrf, PIXTYPE, check->npix); check->pix = (void *)ptrf; if (check->type==CHECK_MINIBACKRMS) memcpy(check->pix, field->sigma, check->npix*sizeof(float)); else memcpy(check->pix, field->back, check->npix*sizeof(float)); QFWRITE(check->fitshead,check->fitsheadsize,check->file,check->filename); free(check->fitshead); if (bswapflag) swapbytes(check->pix, sizeof(float), (int)check->npix); QFWRITE(check->pix,check->npix*sizeof(float),check->file, check->filename); /*---- Put the buffer back to its original state */ if (bswapflag) swapbytes(check->pix, sizeof(float), (int)check->npix); free(check->pix); QCALLOC(buf, char, FBSIZE); padsize = (FBSIZE -((check->npix*sizeof(PIXTYPE))%FBSIZE))% FBSIZE; if (padsize) QFWRITE (buf, padsize, check->file, check->filename); free(buf); break; case CHECK_MAPSOM: ival = -32; fitswrite(check->fitshead, "BITPIX ", &ival, H_INT, T_LONG); check->width = field->width; 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; QFWRITE(check->fitshead,check->fitsheadsize,check->file,check->filename); free(check->fitshead); break; case CHECK_OTHER: ival = -32; fitswrite(check->fitshead, "BITPIX ", &ival, H_INT, T_LONG); fitswrite(check->fitshead, "NAXIS1 ", &check->width, H_INT, T_LONG); fitswrite(check->fitshead, "NAXIS2 ", &check->height, H_INT, T_LONG); check->npix = check->width*check->height; QMALLOC(ptrf, PIXTYPE, check->npix); check->pix = (void *)ptrf; for (i=check->npix; i--;) *(ptrf++) = -10.0; QFWRITE(check->fitshead,check->fitsheadsize,check->file,check->filename); free(check->fitshead); break; default: 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; } if (bswapflag) swapbytes(data, sizeof(PIXTYPE), w); QFWRITE(data, w*sizeof(PIXTYPE), check->file, check->filename); if (bswapflag) /*-- Put the buffer back to its original state */ swapbytes(data, sizeof(PIXTYPE), w); return; } /********************************* reendcheck ********************************/ /* Finish current check-image. */ void reendcheck(picstruct *field, checkstruct *check) { char *buf; size_t padsize; padsize = 0; /* To avoid gcc -Wall warnings */ 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; padsize = (FBSIZE -((check->npix*sizeof(PIXTYPE))%FBSIZE)) % FBSIZE; break; case CHECK_OBJECTS: case CHECK_APERTURES: case CHECK_PSFPROTOS: case CHECK_SUBPSFPROTOS: case CHECK_PCPROTOS: case CHECK_SUBPCPROTOS: case CHECK_PCOPROTOS: case CHECK_PROFILES: case CHECK_SUBPROFILES: case CHECK_SPHEROIDS: case CHECK_SUBSPHEROIDS: case CHECK_DISKS: case CHECK_SUBDISKS: case CHECK_ASSOC: case CHECK_PATTERNS: case CHECK_MAPSOM: case CHECK_OTHER: if (bswapflag) swapbytes(check->pix, sizeof(PIXTYPE), (int)check->npix); QFWRITE(check->pix,check->npix*sizeof(PIXTYPE), check->file,check->filename); free(check->pix); padsize = (FBSIZE-((check->npix*sizeof(PIXTYPE))%FBSIZE)) % FBSIZE; break; case CHECK_SEGMENTATION: if (bswapflag) swapbytes(check->pix, sizeof(ULONG), (int)check->npix); QFWRITE(check->pix,check->npix*sizeof(ULONG), check->file,check->filename); free(check->pix); padsize = (FBSIZE -((check->npix*sizeof(ULONG))%FBSIZE)) % FBSIZE; break; case CHECK_SUBOBJECTS: { int y; for (y=field->ymin; yymax; y++) writecheck(check, &PIX(field, 0, y), field->width); free(check->pix); free(check->line); check->line = NULL; padsize = (FBSIZE -((check->npix*sizeof(PIXTYPE))%FBSIZE)) % FBSIZE; break; } default: error(EXIT_FAILURE, "*Internal Error* in ", "endcheck()!"); } QCALLOC(buf, char, FBSIZE); if (padsize) QFWRITE (buf, padsize, check->file, check->filename); free(buf); return; } /********************************* endcheck **********************************/ /* close check-image. */ void endcheck(checkstruct *check) { fclose(check->file); free(check); return; }