/*
* field.c
*
* Handle field (image) structures.
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* This file part of: SExtractor
*
* Copyright: (C) 1993-2012 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 .
*
* Last modified: 12/07/2012
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include
#include
#include
#include
#include "define.h"
#include "globals.h"
#include "prefs.h"
#include "fits/fitscat.h"
#include "assoc.h"
#include "astrom.h"
#include "back.h"
#include "field.h"
#include "filter.h"
#include "fitswcs.h"
#include "header.h"
#include "interpolate.h"
/********************************* newfield **********************************/
/*
Returns a pointer to a new field for extension ext, ready to go!
*/
picstruct *newfield(char *filename, int flags, int ext)
{
picstruct *field;
catstruct *cat;
tabstruct *tab;
char *pstr;
int ext2, nok, ntab, margin;
if (!(cat = read_cat(filename)))
error(EXIT_FAILURE, "*Error*: cannot open ", filename);
/* First allocate memory for the new field (and nullify pointers) */
QCALLOC(field, picstruct, 1);
field->flags = flags;
field->cat = cat;
nok = 0;
tab = cat->tab;
if(tab->isTileCompressed) nok++;
if (tab->naxis >= 2
&& strncmp(tab->xtension, "BINTABLE", 8)
&& strncmp(tab->xtension, "ASCTABLE", 8))
nok++;
ext2 = ext;
for (ntab=cat->ntab; ext2-- && ntab--;)
{
tab=tab->nexttab;
if(tab->isTileCompressed) nok++;
if (tab->naxis >= 2
&& strncmp(tab->xtension, "BINTABLE", 8)
&& strncmp(tab->xtension, "ASCTABLE", 8))
nok++;
}
if (!nok)
error(EXIT_FAILURE, "Not a valid FITS image in ",filename);
field->tab = tab;
if (ntab<0)
error(EXIT_FAILURE, "Not enough valid FITS image extensions in ",filename);
strcpy (field->filename, filename);
/* A short, "relative" version of the filename */
if (!(field->rfilename = strrchr(field->filename, '/')))
field->rfilename = field->filename;
else
field->rfilename++;
/* Create a file name with a "header" extension */
strcpy(field->hfilename, filename);
if (!(pstr = strrchr(field->hfilename, '.')))
pstr = field->hfilename+strlen(field->hfilename);
sprintf(pstr, "%s", prefs.head_suffix);
sprintf(gstr, "Looking for %s", field->rfilename);
NFPRINTF(OUTPUT, gstr);
/* Check the image exists and read important info (image size, etc...) */
field->file = cat->file;
field->headflag = !read_aschead(field->hfilename, nok, field->tab);
readimagehead(field);
if (cat->ntab>1)
sprintf(gstr, " [%d/%d]", ext, cat->tab->naxis<2? cat->ntab-1 : cat->ntab);
QPRINTF(OUTPUT, "----- %s %s%s\n",
flags&DGEO_FIELD? "Shifting from:" :
(flags&FLAG_FIELD? "Flagging from:" :
(flags&(RMS_FIELD|VAR_FIELD|WEIGHT_FIELD)?
"Weighting from:" :
(flags&MEASURE_FIELD? "Measuring from:" :
"Detecting from:"))),
field->rfilename,
cat->ntab>1? gstr : "");
QPRINTF(OUTPUT, " \"%.20s\" / %s / %dx%d / %d bits %s\n",
field->ident,
field->headflag? "EXT. HEADER" : "no ext. header",
field->width, field->height, field->bytepix*8,
field->bitpix>0?
(field->tab->compress_type!=COMPRESS_NONE?"(compressed)":"(integers)")
:"(floats)");
/* Check the astrometric system and do the setup of the astrometric stuff */
if (prefs.world_flag && (flags & (MEASURE_FIELD|DETECT_FIELD)))
initastrom(field);
else
field->pixscale=prefs.pixel_scale;
/* Gain and Saturation */
if (flags & (DETECT_FIELD|MEASURE_FIELD))
{
if (fitsread(field->tab->headbuf, prefs.gain_key, &field->gain,
H_FLOAT, T_DOUBLE) != RETURN_OK)
field->gain = prefs.gain;
if (fitsread(field->tab->headbuf, prefs.satur_key, &field->satur_level,
H_FLOAT, T_DOUBLE) !=RETURN_OK)
field->satur_level = prefs.satur_level;
}
/* Background */
if (flags & (DETECT_FIELD|MEASURE_FIELD|WEIGHT_FIELD|VAR_FIELD|RMS_FIELD))
{
field->ngamma = prefs.mag_gamma/log(10.0);
field->backw = prefs.backsize[0]width ? prefs.backsize[0]
: field->width;
field->backh = prefs.backsize[1]height ? prefs.backsize[1]
: field->height;
field->nbackp = field->backw * field->backh;
if ((field->nbackx = (field->width-1)/field->backw + 1) < 1)
field->nbackx = 1;
if ((field->nbacky = (field->height-1)/field->backh + 1) < 1)
field->nbacky = 1;
field->nback = field->nbackx * field->nbacky;
field->nbackfx = field->nbackx>1 ? prefs.backfsize[0] : 1;
field->nbackfy = field->nbacky>1 ? prefs.backfsize[1] : 1;
/*-- Set the back_type flag if absolute background is selected */
if (((flags & DETECT_FIELD) && prefs.back_type[0]==BACK_ABSOLUTE)
|| ((flags & MEASURE_FIELD) && prefs.back_type[1]==BACK_ABSOLUTE))
field->back_type = BACK_ABSOLUTE;
}
/* Add a comfortable margin for local background estimates */
margin = (prefs.pback_type == LOCAL)? prefs.pback_size + prefs.mem_bufsize/4
: 0;
field->stripheight = prefs.mem_bufsize + margin;
if (field->stripheight>field->height)
field->stripheight = field->height;
/* Compute the image buffer size */
/* Basically, only one margin line is sufficient... */
field->stripmargin = 1 + margin;
/* ...but : */
if (prefs.filter_flag)
{
/*-- If filtering is on, one should consider the height of the conv. mask */
/*-- + 1 line for detectinhg zero-weight neighbours */
if (field->stripheight < thefilter->convh)
field->stripheight = thefilter->convh;
if (field->stripmargin < (margin = (thefilter->convh-1)/2+1))
field->stripmargin = margin;
}
return field;
}
/******************************* inheritfield *******************************/
/*
Make a copy of a field structure, e.g. for interpolation purposes.
*/
picstruct *inheritfield(picstruct *infield, int flags)
{
picstruct *field;
/* First allocate memory for the new field (and nullify pointers) */
QCALLOC(field, picstruct, 1);
/* Copy what is important and reset the remaining */
*field = *infield;
field->flags = flags;
if (infield->wcs)
field->wcs = copy_wcs(infield->wcs);
field->interp_flag = 0;
field->assoc = NULL;
field->strip = NULL;
field->fstrip = NULL;
field->dgeostrip[0] = field->dgeostrip[1] = NULL;
field->reffield = infield;
field->file = NULL;
return field;
}
/********************************* endfield **********************************/
/*
Free and close everything related to a field structure.
*/
void endfield(picstruct *field)
{
/* Free cat only if associated with an open file */
if (field->file)
free_cat(&field->cat, 1);
free(field->strip);
free(field->fstrip);
free(field->dgeostrip[0]);
free(field->dgeostrip[1]);
if (field->wcs)
end_wcs(field->wcs);
if (field->interp_flag)
end_interpolate(field);
endback(field);
free(field);
return;
}