Commit 3b348a94 authored by Emmanuel Bertin's avatar Emmanuel Bertin
Browse files

Changed trunk directory name

parents
# Makefile.in generated by automake 1.9.4 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
SOURCES = $(ldactoasc_SOURCES) $(sex_SOURCES)
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
bin_PROGRAMS = sex$(EXEEXT) ldactoasc$(EXEEXT)
subdir = src
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/acx_urbi_resolve_dir.m4 \
$(top_srcdir)/acx_prog_cc_optim.m4 \
$(top_srcdir)/acx_prog_cc_optim.m4 \
$(top_srcdir)/acx_urbi_resolve_dir.m4 \
$(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(SHELL) $(top_srcdir)/autoconf/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
am__installdirs = "$(DESTDIR)$(bindir)"
binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(bin_PROGRAMS)
am_ldactoasc_OBJECTS = ldactoasc.$(OBJEXT)
ldactoasc_OBJECTS = $(am_ldactoasc_OBJECTS)
ldactoasc_DEPENDENCIES = $(top_builddir)/src/fits/libfits.a
am_sex_OBJECTS = analyse.$(OBJEXT) assoc.$(OBJEXT) astrom.$(OBJEXT) \
back.$(OBJEXT) bpro.$(OBJEXT) catout.$(OBJEXT) check.$(OBJEXT) \
clean.$(OBJEXT) extract.$(OBJEXT) field.$(OBJEXT) \
filter.$(OBJEXT) flag.$(OBJEXT) graph.$(OBJEXT) \
growth.$(OBJEXT) image.$(OBJEXT) interpolate.$(OBJEXT) \
main.$(OBJEXT) makeit.$(OBJEXT) manobjlist.$(OBJEXT) \
misc.$(OBJEXT) neurro.$(OBJEXT) pc.$(OBJEXT) photom.$(OBJEXT) \
plist.$(OBJEXT) poly.$(OBJEXT) prefs.$(OBJEXT) psf.$(OBJEXT) \
readimage.$(OBJEXT) refine.$(OBJEXT) retina.$(OBJEXT) \
scan.$(OBJEXT) som.$(OBJEXT) weight.$(OBJEXT) winpos.$(OBJEXT) \
xml.$(OBJEXT)
sex_OBJECTS = $(am_sex_OBJECTS)
sex_DEPENDENCIES = $(top_builddir)/src/fits/libfits.a \
$(top_builddir)/src/wcs/libwcs_c.a
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/autoconf/depcomp
am__depfiles_maybe = depfiles
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(ldactoasc_SOURCES) $(sex_SOURCES)
DIST_SOURCES = $(ldactoasc_SOURCES) $(sex_SOURCES)
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
install-exec-recursive install-info-recursive \
install-recursive installcheck-recursive installdirs-recursive \
pdf-recursive ps-recursive uninstall-info-recursive \
uninstall-recursive
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DATE2 = @DATE2@
DATE3 = @DATE3@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGER = @PACKAGER@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
ac_ct_CC = @ac_ct_CC@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build_alias = @build_alias@
datadir = @datadir@
exec_prefix = @exec_prefix@
host_alias = @host_alias@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
# Program Makefile for SEx
# Copyright (C) 2004-2007 Emmanuel Bertin.
SUBDIRS = fits wcs
sex_SOURCES = analyse.c assoc.c astrom.c back.c bpro.c catout.c \
check.c clean.c extract.c field.c filter.c \
flag.c graph.c growth.c image.c interpolate.c \
main.c makeit.c manobjlist.c misc.c neurro.c pc.c \
photom.c plist.c poly.c prefs.c psf.c readimage.c \
refine.c retina.c scan.c som.c weight.c winpos.c \
xml.c \
assoc.h astrom.h back.h bpro.h check.h clean.h \
define.h extract.h field.h filter.h flag.h \
globals.h growth.h image.h interpolate.h key.h \
neurro.h param.h photom.h plist.h poly.h prefs.h \
preflist.h psf.h retina.h sexhead1.h sexhead.h \
sexheadsc.h som.h types.h weight.h winpos.h xml.h
ldactoasc_SOURCES = ldactoasc.c ldactoasc.h
AM_CPPFLAGS = -DXSL_URL=\"file://$(pkgdatadir)/${PACKAGE_NAME}.xsl\"
sex_LDADD = $(top_builddir)/src/fits/libfits.a $(top_builddir)/src/wcs/libwcs_c.a
ldactoasc_LDADD = $(top_builddir)/src/fits/libfits.a
DATE = `date +"%Y-%m-%d"`
all: all-recursive
.SUFFIXES:
.SUFFIXES: .c .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --foreign src/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
@list='$(bin_PROGRAMS)'; for p in $$list; do \
p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
if test -f $$p \
; then \
f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
$(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
else :; fi; \
done
uninstall-binPROGRAMS:
@$(NORMAL_UNINSTALL)
@list='$(bin_PROGRAMS)'; for p in $$list; do \
f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
rm -f "$(DESTDIR)$(bindir)/$$f"; \
done
clean-binPROGRAMS:
-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
ldactoasc$(EXEEXT): $(ldactoasc_OBJECTS) $(ldactoasc_DEPENDENCIES)
@rm -f ldactoasc$(EXEEXT)
$(LINK) $(ldactoasc_LDFLAGS) $(ldactoasc_OBJECTS) $(ldactoasc_LDADD) $(LIBS)
sex$(EXEEXT): $(sex_OBJECTS) $(sex_DEPENDENCIES)
@rm -f sex$(EXEEXT)
$(LINK) $(sex_LDFLAGS) $(sex_OBJECTS) $(sex_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/analyse.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/assoc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/astrom.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/back.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bpro.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/catout.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/check.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/clean.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/extract.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/field.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filter.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flag.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/graph.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/growth.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/image.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interpolate.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ldactoasc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/makeit.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/manobjlist.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/neurro.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/photom.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/plist.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/poly.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prefs.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/psf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readimage.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/refine.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/retina.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scan.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/som.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/weight.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/winpos.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xml.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
uninstall-info-am:
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
rev=''; for subdir in $$list; do \
if test "$$subdir" = "."; then :; else \
rev="$$subdir $$rev"; \
fi; \
done; \
rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
ctags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
done
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
empty_fix=.; \
else \
include_option=--include; \
empty_fix=; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test ! -f $$subdir/TAGS || \
tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -d "$(distdir)/$$subdir" \
|| $(mkdir_p) "$(distdir)/$$subdir" \
|| exit 1; \
distdir=`$(am__cd) $(distdir) && pwd`; \
top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
(cd $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$$top_distdir" \
distdir="$$distdir/$$subdir" \
distdir) \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-recursive
all-am: Makefile $(PROGRAMS)
installdirs: installdirs-recursive
installdirs-am:
for dir in "$(DESTDIR)$(bindir)"; do \
test -z "$$dir" || $(mkdir_p) "$$dir"; \
done
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive
clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
distclean: distclean-recursive
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-recursive
dvi-am:
html: html-recursive
info: info-recursive
info-am:
install-data-am:
install-exec-am: install-binPROGRAMS
install-info: install-info-recursive
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-compile mostlyclean-generic
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am: uninstall-binPROGRAMS uninstall-info-am
uninstall-info: uninstall-info-recursive
.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am \
clean clean-binPROGRAMS clean-generic clean-recursive ctags \
ctags-recursive distclean distclean-compile distclean-generic \
distclean-recursive distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-binPROGRAMS \
install-data install-data-am install-exec install-exec-am \
install-info install-info-am install-man install-strip \
installcheck installcheck-am installdirs installdirs-am \
maintainer-clean maintainer-clean-generic \
maintainer-clean-recursive mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-recursive pdf pdf-am ps ps-am \
tags tags-recursive uninstall uninstall-am \
uninstall-binPROGRAMS uninstall-info-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
/*
analyse.c
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN (IAP)
*
* Contents: analyse(), endobject()...: measurements on detections.
*
* Last modify: 12/01/2006
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
#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 "prefs.h"
#include "fits/fitscat.h"
#include "back.h"
#include "check.h"
#include "assoc.h"
#include "astrom.h"
#include "plist.h"
#include "flag.h"
#include "growth.h"
#include "image.h"
#include "photom.h"
#include "psf.h"
#include "retina.h"
#include "som.h"
#include "winpos.h"
static obj2struct *obj2 = &outobj2;
/********************************* analyse ***********************************/
void analyse(picstruct *field, picstruct *dfield, int objnb,
objliststruct *objlist)
{
objstruct *obj = objlist->obj+objnb;
/* Do photometry on the detection image if no other image available */
obj->number = ++thecat.ndetect;
obj->bkg = (float)back(field, (int)(obj->mx+0.5), (int)(obj->my+0.5));
obj->dbkg = 0.0;
if (prefs.pback_type == LOCAL)
localback(field, obj);
else
obj->sigbkg = field->backsig;
examineiso(field, dfield, obj, objlist->plist);
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/* Put here your calls to custom functions related to isophotal measurements.
Ex:
compute_myparams(obj);
*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
return;
}
/***************************** examineiso ********************************/
/*
compute some isophotal parameters IN THE MEASUREMENT image.
*/
void examineiso(picstruct *field, picstruct *dfield, objstruct *obj,
pliststruct *pixel)
{
checkstruct *check;
pliststruct *pixt;
int i,j,k,h, photoflag,area,errflag, cleanflag,
pospeakflag, profflag, minarea, gainflag;
double tv,sigtv, ngamma,
esum, emx2,emy2,emxy, err,gain,backnoise2,dbacknoise2,
xm,ym, x,y,var,var2, profflux,proffluxvar;
float *heap,*heapt,*heapj,*heapk, swap;
PIXTYPE pix, cdpix, tpix, peak,cdpeak, thresh,dthresh;
static PIXTYPE threshs[NISO];
if (!dfield)
dfield = field;
/* Prepare computation of positional error */
esum = emx2 = emy2 = emxy = 0.0;
if ((errflag=FLAG(obj.poserr_mx2)))
{
dbacknoise2 = dfield->backsig*dfield->backsig;
xm = obj->mx;
ym = obj->my;
}
else
xm = ym = dbacknoise2 = 0.0; /* to avoid gcc -Wall warnings */
pospeakflag = FLAG(obj.peakx);
profflag = FLAG(obj.flux_prof);
gain = prefs.gain;
ngamma = field->ngamma;
photoflag = (prefs.detect_type==PHOTO);
gainflag = PLISTEXIST(var) && prefs.weightgain_flag;
h = minarea = prefs.ext_minarea;
/* Prepare selection of the heap selection for CLEANing */
if ((cleanflag = prefs.clean_flag))
{
if (obj->fdnpix < minarea)
{
obj->mthresh = 0.0;
cleanflag = 0;
heapt = heap = NULL; /* to avoid gcc -Wall warnings */
}
else
{
QMALLOC(heap, float, minarea);
heapt = heap;
}
}
else
{
obj->mthresh = 0.0;
heapt = heap = NULL; /* to avoid gcc -Wall warnings */
}
/* Measure essential isophotal parameters in the measurement image... */
tv = sigtv = profflux = proffluxvar = 0.0;
var = backnoise2 = field->backsig*field->backsig;
peak = -BIG;
cdpeak = -BIG;
thresh = field->thresh;
dthresh = dfield->dthresh;
area = 0;
for (pixt=pixel+obj->firstpix; pixt>=pixel; pixt=pixel+PLIST(pixt,nextpix))
{
pix = PLIST(pixt,value);
if (pix>peak)
peak = pix;
cdpix=PLISTPIX(pixt,cdvalue);
if (pospeakflag && cdpix>cdpeak)
{
cdpeak=cdpix;
obj->peakx = PLIST(pixt,x) + 1;
obj->peaky = PLIST(pixt,y) + 1;
}
if (PLISTEXIST(var))
var = PLISTPIX(pixt, var);
if (photoflag)
{
pix = exp(pix/ngamma);
var2 = pix*pix*var;
}
else
var2 = var;
if (gainflag && pix>0.0 && gain>0.0)
var2 += pix/gain*var/backnoise2;
sigtv += var2;
if (profflag && cdpix>0.0)
{
profflux += cdpix*pix;
proffluxvar += cdpix*var2;
}
if (pix>thresh)
area++;
tv += pix;
if (errflag)
{
err = dbacknoise2;
if (gain>0.0 && cdpix>0.0)
err += cdpix/gain;
x = PLIST(pixt,x) - xm;
y = PLIST(pixt,y) - ym;
esum += err;
emx2 += err*x*x;
emy2 += err*y*y;
emxy += err*x*y;
}
/*-- Find the minareath pixel in decreasing intensity for CLEANing */
if (cleanflag)
{
tpix = PLISTPIX(pixt, cdvalue) - (PLISTEXIST(dthresh)?
PLISTPIX(pixt, dthresh):dthresh);
if (h>0)
*(heapt++) = (float)tpix;
else if (h)
{
if ((float)tpix>*heap)
{
*heap = (float)tpix;
for (j=0; (k=(j+1)<<1)<=minarea; j=k)
{
heapk = heap+k;
heapj = heap+j;
if (k != minarea && *(heapk-1) > *heapk)
{
heapk++;
k++;
}
if (*heapj <= *(--heapk))
break;
swap = *heapk;
*heapk = *heapj;
*heapj = swap;
}
}
}
else
hmedian(heap, minarea);
h--;
}
}
/* Flagging from the flag-map */
if (PLISTEXIST(flag))
getflags(obj, pixel);
if (cleanflag)
{
obj->mthresh = *heap;
free(heap);
}
if (profflag)
{
obj->flux_prof = obj->fdflux>0.0? (float)(profflux/obj->fdflux) : 0.0;
obj->fluxerr_prof = obj->fdflux>0.0? (float)(proffluxvar/obj->fdflux):0.0;
}
if (errflag)
{
double flux2;
flux2 = obj->fdflux*obj->fdflux;
/*-- Estimation of the error ellipse moments: we re-use previous variables */
emx2 /= flux2; /* variance of xm */
emy2 /= flux2; /* variance of ym */
emxy /= flux2; /* covariance */
/*-- Handle fully correlated profiles (which cause a singularity...) */
esum *= 0.08333/flux2;
if (obj->singuflag && (emx2*emy2-emxy*emxy) < esum*esum)
{
emx2 += esum;
emy2 += esum;
}
obj->poserr_mx2 = emx2;
obj->poserr_my2 = emy2;
obj->poserr_mxy = emxy;
}
if (photoflag)
{
tv = ngamma*(tv-obj->fdnpix*exp(obj->dbkg/ngamma));
sigtv /= ngamma*ngamma;
}
else
{
tv -= obj->fdnpix*obj->dbkg;
if (!gainflag && gain > 0.0 && tv>0.0)
sigtv += tv/gain;
}
obj->npix = area;
obj->flux = tv;
obj->fluxerr = sigtv;
obj->peak = peak;
obj->thresh -= obj->dbkg;
obj->peak -= obj->dbkg;
/* Initialize isophotal thresholds so as to sample optimally the full profile*/
if (FLAG(obj.iso[0]))
{
int *iso;
PIXTYPE *thresht;
memset(obj->iso, 0, NISO*sizeof(int));
if (prefs.detect_type == PHOTO)
for (i=0; i<NISO; i++)
threshs[i] = obj->thresh + (obj->peak-obj->thresh)*i/NISO;
else
{
if (obj->peak>0.0 && obj->thresh>0.0)
for (i=0; i<NISO; i++)
threshs[i] = obj->thresh*pow(obj->peak/obj->thresh, (double)i/NISO);
else
for (i=0; i<NISO; i++)
threshs[i] = 0.0;
}
for (pixt=pixel+obj->firstpix; pixt>=pixel; pixt=pixel+PLIST(pixt,nextpix))
for (i=NISO,iso=obj->iso,thresht=threshs;
i-- && PLIST(pixt,value)>*(thresht++);)
(*(iso++))++;
}
/* Put objects in "segmentation check-image" */
if ((check = prefs.check[CHECK_SEGMENTATION]))
for (pixt=pixel+obj->firstpix; pixt>=pixel; pixt=pixel+PLIST(pixt,nextpix))
((ULONG *)check->pix)[check->width*PLIST(pixt,y)+PLIST(pixt,x)]
= (ULONG)obj->number;
if ((check = prefs.check[CHECK_OBJECTS]))
for (pixt=pixel+obj->firstpix; pixt>=pixel; pixt=pixel+PLIST(pixt,nextpix))
((PIXTYPE *)check->pix)[check->width*PLIST(pixt,y)+PLIST(pixt,x)]
= PLIST(pixt,value);
/* Compute the FWHM of the object */
if (FLAG(obj.fwhm))
{
PIXTYPE thresh0;
thresh0 = obj->peak/5.0;
if (thresh0<obj->thresh)
thresh0 = obj->thresh;
if (thresh0>0.0)
{
double mx,my, s,sx,sy,sxx,sxy, dx,dy,d2, lpix,pix, b, inverr2, sat,
dbkg, d, bmax;
mx = obj->mx;
my = obj->my;
dbkg = obj->dbkg;
sat = (double)(prefs.satur_level - obj->bkg);
s = sx = sy = sxx = sxy = 0.0;
for (pixt=pixel+obj->firstpix;pixt>=pixel;pixt=pixel+PLIST(pixt,nextpix))
{
pix = PLIST(pixt,value)-dbkg;
if (pix>thresh0 && pix<sat)
{
dx = PLIST(pixt,x) - mx;
dy = PLIST(pixt,y) - my;
lpix = log(pix);
inverr2 = pix*pix;
s += inverr2;
d2 = dx*dx+dy*dy;
sx += d2*inverr2;
sxx += d2*d2*inverr2;
sy += lpix*inverr2;
sxy += lpix*d2*inverr2;
}
}
d = s*sxx-sx*sx;
if (fabs(d)>0.0)
{
b = -(s*sxy-sx*sy)/d;
if (b<(bmax = 1/(13*obj->a*obj->b))) /* to have FWHM # 6 sigma */
b = bmax;
obj->fwhm = (float)(1.6651/sqrt(b));
/*----- correction for undersampling effects (established from simulations) */
if (obj->fwhm>0.0)
obj->fwhm -= 1/(4*obj->fwhm);
}
else
obj->fwhm = 0.0;
}
else
obj->fwhm = 0.0;
}
return;
}
/******************************* endobject **********************************/
/*
Final processing of object data, just before saving it to the catalog.
*/
void endobject(picstruct *field, picstruct *dfield, picstruct *wfield,
picstruct *dwfield, int n, objliststruct *objlist)
{
checkstruct *check;
int i,j, ix,iy,selecflag, newnumber,nsub;
objstruct *obj;
obj = &objlist->obj[n];
/* Current FITS extension */
obj2->ext_number = thecat.currext;
/* Source position */
obj2->sposx = (float)(obj2->posx = obj->mx+1.0); /* That's standard FITS */
obj2->sposy = (float)(obj2->posy = obj->my+1.0);
/* Integer coordinates */
ix=(int)(obj->mx+0.49999);
iy=(int)(obj->my+0.49999);
/* Association */
if (prefs.assoc_flag)
obj2->assoc_number = do_assoc(field, obj2->sposx, obj2->sposy);
if (prefs.assoc_flag && prefs.assocselec_type!=ASSOCSELEC_ALL)
selecflag = (prefs.assocselec_type==ASSOCSELEC_MATCHED)?
obj2->assoc_number:!obj2->assoc_number;
else
selecflag = 1;
if (selecflag)
{
/*-- Paste back to the image the object's pixels if BLANKing is on */
if (prefs.blank_flag)
{
pasteimage(field, obj->blank, obj->subw, obj->subh,
obj->subx, obj->suby);
if (obj->dblank)
pasteimage(dfield, obj->dblank, obj->subw, obj->subh,
obj->subx, obj->suby);
}
/*------------------------- Error ellipse parameters ------------------------*/
if (FLAG(obj2.poserr_a))
{
double pmx2,pmy2,temp,theta;
if (fabs(temp=obj->poserr_mx2-obj->poserr_my2) > 0.0)
theta = atan2(2.0 * obj->poserr_mxy,temp) / 2.0;
else
theta = PI/4.0;
temp = sqrt(0.25*temp*temp+obj->poserr_mxy*obj->poserr_mxy);
pmy2 = pmx2 = 0.5*(obj->poserr_mx2+obj->poserr_my2);
pmx2+=temp;
pmy2-=temp;
obj2->poserr_a = (float)sqrt(pmx2);
obj2->poserr_b = (float)sqrt(pmy2);
obj2->poserr_theta = theta*180.0/PI;
}
if (FLAG(obj2.poserr_cxx))
{
double xm2,ym2, xym, temp;
xm2 = obj->poserr_mx2;
ym2 = obj->poserr_my2;
xym = obj->poserr_mxy;
obj2->poserr_cxx = (float)(ym2/(temp=xm2*ym2-xym*xym));
obj2->poserr_cyy = (float)(xm2/temp);
obj2->poserr_cxy = (float)(-2*xym/temp);
}
/* ---- Aspect ratio */
if (FLAG(obj2.elong))
obj2->elong = obj->a/obj->b;
if (FLAG(obj2.ellip))
obj2->ellip = 1-obj->b/obj->a;
if (FLAG(obj2.polar))
obj2->polar = (obj->a*obj->a - obj->b*obj->b)
/ (obj->a*obj->a + obj->b*obj->b);
/*------------------------------- Photometry -------------------------------*/
/*-- Convert the father of photom. error estimates from variance to RMS */
obj2->flux_iso = obj->flux;
obj2->fluxerr_iso = sqrt(obj->fluxerr);
if (FLAG(obj.flux_prof))
{
obj2->flux_prof = obj->flux_prof;
obj2->fluxerr_prof = sqrt(obj->fluxerr_prof);
}
if (FLAG(obj2.flux_isocor))
computeisocorflux(field, obj);
if (FLAG(obj2.flux_aper))
for (i=0; i<prefs.naper; i++)
computeaperflux(field, wfield, obj, i);
if (FLAG(obj2.flux_auto))
computeautoflux(field, dfield, wfield, dwfield, obj);
if (FLAG(obj2.flux_petro))
computepetroflux(field, dfield, wfield, dwfield, obj);
/*-- Growth curve */
if (prefs.growth_flag)
makeavergrowth(field, wfield, obj);
/*--------------------------- Windowed barycenter --------------------------*/
if (FLAG(obj2.winpos_x))
compute_winpos(field, wfield, obj);
/*-- What about the peak of the profile? */
if (obj->peak+obj->bkg >= prefs.satur_level)
obj->flag |= OBJ_SATUR;
/*-- Check-image CHECK_APERTURES option */
if ((check = prefs.check[CHECK_APERTURES]))
{
if (FLAG(obj2.flux_aper))
for (i=0; i<prefs.naper; i++)
sexcircle(check->pix, check->width, check->height,
obj->mx, obj->my, prefs.apert[i]/2.0, check->overlay);
if (FLAG(obj2.flux_auto))
sexellips(check->pix, check->width, check->height,
obj->mx, obj->my, obj->a*obj2->kronfactor,
obj->b*obj2->kronfactor, obj->theta,
check->overlay, obj->flag&OBJ_CROWDED);
if (FLAG(obj2.flux_petro))
sexellips(check->pix, check->width, check->height,
obj->mx, obj->my, obj->a*obj2->petrofactor,
obj->b*obj2->petrofactor, obj->theta,
check->overlay, obj->flag&OBJ_CROWDED);
}
/* ---- Star/Galaxy classification */
if (FLAG(obj2.sprob))
{
double fac2, input[10], output, fwhm;
fwhm = prefs.seeing_fwhm;
fac2 = fwhm/field->pixscale;
fac2 *= fac2;
input[j=0] = log10(obj->iso[0]? obj->iso[0]/fac2: 0.01);
input[++j] = field->thresh>0.0?
log10(obj->peak>0.0? obj->peak/field->thresh: 0.1)
:-1.0;
for (i=1; i<NISO; i++)
input[++j] = log10(obj->iso[i]? obj->iso[i]/fac2: 0.01);
input[++j] = log10(fwhm);
neurresp(input, &output);
obj2->sprob = (float)output;
}
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
/*-- Put here your calls to "BLIND" custom functions. Ex:
compute_myotherparams(obj);
--*/
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&*/
newnumber = ++thecat.ntotal;
/*-- update segmentation map */
if ((check=prefs.check[CHECK_SEGMENTATION]))
{
ULONG *pix;
ULONG newsnumber = newnumber,
oldsnumber = obj->number;
int dx,dx0,dy,dpix;
pix = (ULONG *)check->pix + check->width*obj->ymin + obj->xmin;
dx0 = obj->xmax-obj->xmin+1;
dpix = check->width-dx0;
for (dy=obj->ymax-obj->ymin+1; dy--; pix += dpix)
for (dx=dx0; dx--; pix++)
if (*pix==oldsnumber)
*pix = newsnumber;
}
obj->number = newnumber;
/*-- SOM fitting */
if (prefs.somfit_flag)
{
float *input;
input = thesom->input;
copyimage(field,input,thesom->inputsize[0],thesom->inputsize[1],ix,iy);
if (thesom->nextrainput)
{
input += thesom->ninput-thesom->nextrainput;
*(input) = (obj->mx+1)/field->width;
*(input+1) = (obj->my+1)/field->height;
}
som_phot(thesom, obj->bkg, field->backsig,
(float)prefs.gain, obj->mx-ix, obj->my-iy,
FLAG(obj2.vector_somfit)?outobj2.vector_somfit:NULL, -1.0);
obj2->stderr_somfit = thesom->stderror;
obj2->flux_somfit = thesom->amp;
outobj2.fluxerr_somfit = thesom->sigamp;
}
if (FLAG(obj2.vignet))
copyimage(field,outobj2.vignet,prefs.vignetsize[0],prefs.vignetsize[1],
ix,iy);
if (FLAG(obj2.vigshift))
copyimage_center(field, outobj2.vigshift, prefs.vigshiftsize[0],
prefs.vigshiftsize[1], obj->mx, obj->my);
/*--- Express everything in magnitude units */
computemags(field, obj);
/*------------------------------- PSF fitting ------------------------------*/
nsub = 1;
if (prefs.psf_flag)
{
if (prefs.dpsf_flag)
double_psf_fit(ppsf, field, wfield, obj, thepsf, dfield, dwfield);
else
psf_fit(thepsf, field, wfield, obj);
obj2->npsf = thepsfit->npsf;
if (prefs.psfdisplay_type == PSFDISPLAY_SPLIT)
{
nsub = thepsfit->npsf;
if (nsub<1)
nsub = 1;
}
else
for (j=0; j<thepsfit->npsf; j++)
{
if (FLAG(obj2.x_psf) && j<prefs.psf_xsize)
obj2->x_psf[j] = thepsfit->x[j];
if (FLAG(obj2.y_psf) && j<prefs.psf_ysize)
obj2->y_psf[j] = thepsfit->y[j];
if (FLAG(obj2.flux_psf) && j<prefs.psf_fluxsize)
obj2->flux_psf[j] = thepsfit->flux[j];
if (FLAG(obj2.magerr_psf) && j<prefs.psf_magerrsize)
obj2->magerr_psf[j] = obj2->fluxerr_psf[j]>0.0?
1.086*obj2->fluxerr_psf[j]/thepsfit->flux[j] : 99.0;
if (FLAG(obj2.fluxerr_psf) && j<prefs.psf_fluxerrsize)
obj2->fluxerr_psf[j] = obj2->fluxerr_psf[j];
if (FLAG(obj2.mag_psf) && j<prefs.psf_magsize)
obj2->mag_psf[j] = thepsfit->flux[j]>0.0?
prefs.mag_zeropoint -2.5*log10(thepsfit->flux[j]) : 99.0;
}
}
/*-------------------------------- Astrometry ------------------------------*/
if (prefs.world_flag)
computeastrom(field, obj);
/*-- Edit min and max coordinates to follow the FITS conventions */
obj->xmin += 1;
obj->ymin += 1;
obj->xmax += 1;
obj->ymax += 1;
/*-- Go through each newly identified component */
for (j=0; j<nsub; j++)
{
if (prefs.psf_flag && prefs.psfdisplay_type == PSFDISPLAY_SPLIT)
{
if (FLAG(obj2.x_psf))
obj2->x_psf[0] = thepsfit->x[j];
if (FLAG(obj2.y_psf))
obj2->y_psf[0] = thepsfit->y[j];
if (FLAG(obj2.flux_psf))
obj2->flux_psf[0] = thepsfit->flux[j]>0.0? thepsfit->flux[j]:0.0; /*?*/
if (FLAG(obj2.mag_psf))
obj2->mag_psf[0] = thepsfit->flux[j]>0.0?
prefs.mag_zeropoint -2.5*log10(thepsfit->flux[j]) : 99.0;
if (FLAG(obj2.magerr_psf))
obj2->magerr_psf[0]=
(thepsfit->flux[j]>0.0 && obj2->fluxerr_psf[j]>0.0) ? /*?*/
1.086*obj2->fluxerr_psf[j]/thepsfit->flux[j] : 99.0;
if (FLAG(obj2.fluxerr_psf))
obj2->fluxerr_psf[0]= obj2->fluxerr_psf[j];
if (j)
obj->number = ++thecat.ntotal;
}
FPRINTF(OUTPUT, "%8d %6.1f %6.1f %5.1f %5.1f %12g "
"%c%c%c%c%c%c%c%c\n",
obj->number, obj->mx+1.0, obj->my+1.0,
obj->a, obj->b,
obj->flux,
obj->flag&OBJ_CROWDED?'C':'_',
obj->flag&OBJ_MERGED?'M':'_',
obj->flag&OBJ_SATUR?'S':'_',
obj->flag&OBJ_TRUNC?'T':'_',
obj->flag&OBJ_APERT_PB?'A':'_',
obj->flag&OBJ_ISO_PB?'I':'_',
obj->flag&OBJ_DOVERFLOW?'D':'_',
obj->flag&OBJ_OVERFLOW?'O':'_');
writecat(n, objlist);
}
}
/* Remove again from the image the object's pixels if BLANKing is on ... */
/*-- ... and free memory */
if (prefs.blank_flag && obj->blank)
{
if (selecflag)
{
if (prefs.somfit_flag && (check=prefs.check[CHECK_MAPSOM]))
blankcheck(check, obj->blank, obj->subw, obj->subh,
obj->subx, obj->suby, (PIXTYPE)*(obj2->vector_somfit));
}
blankimage(field, obj->blank, obj->subw, obj->subh,
obj->subx, obj->suby, -BIG);
free(obj->blank);
if (obj->dblank)
{
blankimage(dfield, obj->dblank, obj->subw, obj->subh,
obj->subx, obj->suby, -BIG);
free(obj->dblank);
}
}
return;
}
/*
assoc.c
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN (IAP)
*
* Contents: Routines for catalog-associations.
*
* Last modify: 26/11/2003
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
#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 "prefs.h"
#include "assoc.h"
/********************************* comp_assoc ********************************/
/*
Comparison function for sort_assoc().
*/
int comp_assoc(const void *i1, const void *i2)
{
float *f1,*f2;
f1 = (float *)i1 + 1;
f2 = (float *)i2 + 1;
if (*f1<*f2)
return -1;
else return (*f1==*f2)?0:1;
}
/********************************* sort_assoc ********************************/
/*
Make the presentation histogram, order the assoc-list and build the hash-table.
*/
void sort_assoc(picstruct *field, assocstruct *assoc)
{
int comp_assoc(const void *i1, const void *i2);
float *list, rad;
int i,j, step,nobj, *hash;
step = assoc->ncol;
nobj = assoc->nobj;
list = assoc->list;
qsort(assoc->list, assoc->nobj, step*sizeof(float), comp_assoc);
/* Build the hash table that contains the first object in the sorted list */
/* which may be in reach from the current scanline */
QMALLOC(assoc->hash, int, field->height);
list = assoc->list+1; /* This is where the 1st y coordinate is stored */
hash = assoc->hash;
rad = assoc->radius;
for (i=0, j=0; i<field->height; i++)
{
/*-- For safety, we keep a 1-pixel margin */
for (;j<nobj && (int)(*list+rad+1.5)<i; j++, list+=step);
/*-- We use -1 as a code identifying lines with no objects */
*(hash++) = (j==nobj || (int)(*list-rad-0.5)>i) ? -1 : j;
}
return;
}
/********************************* load_assoc ********************************/
/*
Read an assoc-list, and returns a pointer to the new assoc struct (or NULL if
no list was found).
*/
assocstruct *load_assoc(char *filename)
{
assocstruct *assoc;
FILE *file;
float *list, val;
char str[MAXCHAR], str2[MAXCHAR], *sstr;
int *data,
i,ispoon,j,k,l, ncol, ndata, nlist, size,spoonsize,
xindex,yindex,mindex;
if (!(file = fopen(filename, "r")))
return NULL;
assoc = NULL; /* To avoid gcc -Wall warnings */
list = NULL; /* To avoid gcc -Wall warnings */
data = NULL; /* To avoid gcc -Wall warnings */
ispoon = ncol = ndata = nlist = size = spoonsize = xindex = yindex
= mindex = 0;
NFPRINTF(OUTPUT, "Reading ASSOC input-list...");
for (i=0; fgets(str, MAXCHAR, file);)
{
/*-- Examine current input line (discard empty and comment lines) */
if (!*str || strchr("#\t\n",*str))
continue;
if (!i)
{
strcpy(str2, str);
/*---- Let's count the number of columns in the first line */
for (ncol=0; strtok(ncol?NULL:str2, " \t\v\n\r\f"); ncol++);
if (!ncol)
error(EXIT_FAILURE, "*Error*: empty line in ", filename);
/*---- Build a look-up table containing the ordering of column data */
QCALLOC(data, int, ncol);
k = 1;
for (j=0; j<prefs.nassoc_data && k<=prefs.assoc_size; j++)
if ((l=prefs.assoc_data[j]) && --l<ncol)
data[l] = k++;
ndata = k-1;
if (!ndata)
{
ndata = ncol;
if (prefs.assoc_size<ndata)
ndata = prefs.assoc_size;
for (j=0; j<ndata; j++)
data[j] = j+1;
}
if (ndata<prefs.assoc_size)
{
sprintf(gstr, "no more than %d ASSOC parameters available: ", ncol);
warning("VECTOR_ASSOC redimensioned: ", gstr);
prefs.assoc_size = ndata;
}
if ((xindex = prefs.assoc_param[0]-1) >= ncol)
error(EXIT_FAILURE, "*Error*: ASSOC_PARAMS #1 exceeds the number of ",
"fields in the ASSOC file");
if ((yindex = prefs.assoc_param[1]-1) >= ncol)
error(EXIT_FAILURE, "*Error*: ASSOC_PARAMS #2 exceeds the number of ",
"fields in the ASSOC file");
if (prefs.nassoc_param>2)
{
if ((mindex = prefs.assoc_param[2]-1) >= ncol)
error(EXIT_FAILURE,"*Error*: ASSOC_PARAMS #3 exceeds the number of ",
"fields in the ASSOC file");
}
else
{
mindex = -1;
prefs.assoc_type = ASSOC_FIRST;
}
nlist = ndata+3;
/*---- Allocate memory for the ASSOC struct and the filtered list */
QMALLOC(assoc, assocstruct, 1);
ispoon = ASSOC_BUFINC/(nlist*sizeof(float));
spoonsize = ispoon*nlist;
QMALLOC(assoc->list, float, size = spoonsize);
list = assoc->list;
}
else if (!(i%ispoon))
{
QREALLOC(assoc->list, float, size += spoonsize);
list = assoc->list + i*nlist;
}
if (!(++i%1000))
{
sprintf(str2, "Reading input list... (%d objects)", i);
NFPRINTF(OUTPUT, str2);
}
/*-- Read the data normally */
*(list+2) = 0.0;
for (sstr = str, j=0; j<ncol; j++)
{
val = (float)strtod(sstr, &sstr);
if (j==xindex)
*list = val;
else if (j==yindex)
*(list+1) = val;
else if (j==mindex)
*(list+2) = val;
if ((k=data[j]))
*(list+2+k) = val;
}
list += nlist;
}
fclose(file);
free(data);
QREALLOC(assoc->list, float, i*nlist);
assoc->nobj = i;
assoc->radius = prefs.assoc_radius;
assoc->ndata = ndata;
assoc->ncol = nlist;
return assoc;
}
/********************************* init_assoc ********************************/
/*
Initialize the association procedure.
*/
void init_assoc(picstruct *field)
{
assocstruct *assoc;
/* Load the assoc-list */
if (!(assoc = field->assoc = load_assoc(prefs.assoc_name)))
error(EXIT_FAILURE, "*Error*: Assoc-list file not found: ",
prefs.assoc_name);
/* Sort the assoc-list by y coordinates, and build the hash table */
sort_assoc(field, assoc);
/* Where data go for the current output pattern*/
assoc->data = outobj2.assoc;
return;
}
/********************************** end_assoc ********************************/
/*
Free memory related to the assoc operations.
*/
void end_assoc(picstruct *field)
{
/* Free the assoc-list */
if (field->assoc)
{
free((field->assoc)->list);
free((field->assoc)->hash);
free(field->assoc);
}
return;
}
/********************************** do_assoc *********************************/
/*
Perform the association task for a source and return the number of IDs.
*/
int do_assoc(picstruct *field, float x, float y)
{
assocstruct *assoc;
double aver;
float dx,dy, dist, rad, rad2, comp, wparam,
*list, *input, *data;
int h, step, i, flag, iy, nobj;
assoc = field->assoc;
/* Need to initialize the array */
memset(assoc->data, 0, prefs.assoc_size*sizeof(float));
aver = 0.0;
if (prefs.assoc_type == ASSOC_MIN || prefs.assoc_type == ASSOC_NEAREST)
comp = BIG;
else
comp = -BIG;
iy = (int)(y+0.499999);
if (iy<0 || iy>=field->height)
return 0;
/* If there is already no candidate in hash table, no need to go further */
if ((h=assoc->hash[iy])<0)
return 0;
/* Now loop over possible candidates */
nobj = assoc->nobj;
step = assoc->ncol;
list = assoc->list + step*h;
rad = assoc->radius;
rad2 = rad*rad;
for (flag = 0; (h++<nobj && *(list+1)-rad<y); list+=step)
{
dx = *list - x;
dy = *(list+1) - y;
if ((dist=dx*dx+dy*dy)<rad2)
{
flag++;
input = list+3;
if (prefs.assoc_type == ASSOC_FIRST)
{
memcpy(assoc->data, input, assoc->ndata*sizeof(float));
return 1;
}
wparam = *(list+2);
data = assoc->data;
switch(prefs.assoc_type)
{
case ASSOC_NEAREST:
if (dist<comp)
{
memcpy(data, input, assoc->ndata*sizeof(float));
comp = dist;
}
break;
case ASSOC_MEAN:
aver += wparam;
for (i=assoc->ndata; i--;)
*(data++) += *(input++)*wparam;
break;
case ASSOC_MAGMEAN:
wparam = fabs(wparam)<99.0?DEXP(-0.4*wparam): 0.0;
aver += wparam;
for (i=assoc->ndata; i--;)
*(data++) += *(input++)*wparam;
break;
case ASSOC_SUM:
for (i=assoc->ndata; i--;)
*(data++) += *(input++);
break;
case ASSOC_MAGSUM:
for (i=assoc->ndata; i--;)
*(data++) += fabs(wparam=*(input++))<99.0? DEXP(-0.4*wparam):0.0;
break;
case ASSOC_MIN:
if (wparam<comp)
{
memcpy(data, input, assoc->ndata*sizeof(float));
comp = wparam;
}
break;
case ASSOC_MAX:
if (wparam>comp)
{
memcpy(data, input, assoc->ndata*sizeof(float));
comp = wparam;
}
break;
default:
error(EXIT_FAILURE, "*Internal Error*: unknown ASSOC type in ",
"pixlearn()");
}
}
}
/* No candidate found? exit! */
if (!flag)
return 0;
/* Terminate the computation of the mean */
if (prefs.assoc_type == ASSOC_MEAN || prefs.assoc_type == ASSOC_MAGMEAN)
{
if (aver<1e-30)
return 0;
data = assoc->data;
for (i=assoc->ndata; i--;)
*(data++) /= aver;
}
if (prefs.assoc_type == ASSOC_MAGSUM)
{
data = assoc->data;
for (i=assoc->ndata; i--; data++)
*data = *data>0.0? -2.5*log10(*data):99.0;
}
return flag;
}
/*
assoc.h
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN, IAP & Leiden observatory
*
* Contents: Include file for assoc.c.
*
* Last modify: 25/06/97
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
#define ASSOC_BUFINC 65536 /* Assoc buffer increment (bytes) */
/*--------------------------------- typedefs --------------------------------*/
typedef struct structassoc
{
float *list; /* Pointer to the list of data */
int nobj; /* Number of data rows */
int ncol; /* Total number of columns per row */
int ndata; /* Number of retained cols per row */
int *hash; /* Pointer to the hash table */
float *data; /* Copy of current parameters */
float radius; /* Radius of search for association */
} assocstruct;
/*------------------------------ Prototypes ---------------------------------*/
assocstruct *load_assoc(char *filename);
int do_assoc(picstruct *field, float x, float y);
void init_assoc(picstruct *field),
end_assoc(picstruct *field),
sort_assoc(picstruct *field, assocstruct *assoc);
/*
astrom.c
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN (IAP)
*
* Contents: Astrometrical computations.
*
* Last modify: 13/07/2006
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "wcs/wcs.h"
#include "define.h"
#include "globals.h"
#include "prefs.h"
#include "astrom.h"
#include "wcs/tnx.h"
static obj2struct *obj2 = &outobj2;
/****************************** initastrom **********************************/
/*
Initialize astrometrical structures.
*/
void initastrom(picstruct *field)
{
astromstruct *as;
double *lm;
int l,n, lng,lat, naxis;
as = field->astrom;
naxis = as->naxis;
/* Test if the WCS is in use */
if (as->wcs_flag)
/*-- ...Yes: launch the WCS stuff! */
{
QCALLOC(as->lin, struct linprm, 1);
QMALLOC(as->cel, struct celprm, 1);
QMALLOC(as->prj, struct prjprm, 1);
QMALLOC(as->lin->cdelt, double, naxis);
QMALLOC(as->lin->crpix, double, naxis);
QMALLOC(as->lin->pc, double, naxis*naxis);
/* Set WCS flags to 0: structures will be reinitialized by the WCS library */
as->wcs->flag = as->lin->flag = as->cel->flag = as->prj->flag = 0;
as->lin->naxis = as->naxis;
/* wcsprm structure */
lng = as->lng = as->wcs->lng;
lat = as->lat = as->wcs->lat;
/*-- linprm structure */
for (l=0; l<naxis; l++)
{
as->lin->crpix[l] = as->crpix[l];
as->lin->cdelt[l] = as->cdelt[l];
as->cel->ref[l] = as->crval[l];
}
for (l=0; l<naxis*naxis; l++)
as->lin->pc[l] = as->pc[l];
/*-- celprm structure */
if (lng>=0)
{
as->cel->ref[0] = as->crval[lng];
as->cel->ref[1] = as->crval[lat];
}
else
{
as->cel->ref[0] = as->crval[0];
as->cel->ref[1] = as->crval[1];
}
as->cel->ref[2] = as->longpole;
as->cel->ref[3] = as->latpole;
/* prjprm structure */
as->prj->r0 = as->r0;
as->prj->tnx_lngcor = as->tnx_lngcor;
as->prj->tnx_latcor = as->tnx_latcor;
if (lng>=0)
{
n = 0;
for (l=100; l--;)
{
as->prj->p[l] = as->projp[l+lng*100];
as->prj->p[l+100] = as->projp[l+lat*100];
if (!n && (as->prj->p[l] || as->prj->p[l+100]))
n = l+1;
}
}
/*-- Compute an "average linear matrix" (at field center) */
compute_wcs(field, (field->width+1)/2.0, (field->height+1)/2.0);
/*---- Compute Pole coordinates in J2000 and/or B1950 for THETAs */
if (FLAG(obj2.theta2000) || FLAG(obj2.theta1950)
|| FLAG(obj2.poserr_theta2000) || FLAG(obj2.poserr_theta1950)
|| FLAG(obj2.win_theta2000) || FLAG(obj2.win_theta1950)
|| FLAG(obj2.winposerr_theta2000) || FLAG(obj2.winposerr_theta1950))
{
if (fabs(as->equinox-2000.0)>0.003)
precess(as->equinox, 0.0, 90.0, 2000.0, &as->ap2000, &as->dp2000);
else
{
as->ap2000 = 0.0;
as->dp2000 = 90.0;
}
if (FLAG(obj2.theta1950) || FLAG(obj2.poserr_theta1950))
j2b(as->equinox, as->ap2000, as->dp2000, &as->ap1950, &as->dp1950);
}
}
else
/*-- ...No: compute only the determinant */
{
/*-- Simplify the original FITS PC matrix */
lm = as->linmat;
for (l=0; l<naxis*naxis; l++)
lm[l] = as->pc[l]*as->cdelt[l/naxis];
/*-- Check valid only in 2D */
if ((as->lindet = lm[0]*lm[3] - lm[1]*lm[2]) == 0.0)
warning ("Null determinant in the global distortion matrix:\n",
" Some WORLD-parameters will be incorrect");
}
/* Override astrometric definitions only if user supplies a pixel-scale */
if (prefs.pixel_scale == 0.0)
{
as->pixscale = sqrt(fabs(as->lindet));
field->pixscale = 3600.0*as->pixscale; /* in arcsec2 */
}
else
as->pixscale = (field->pixscale=prefs.pixel_scale)/3600.0;
return;
}
/**************************** computeastrom *********************************/
/*
Compute real WORLD coordinates and dimensions according to FITS info.
*/
void computeastrom(picstruct *field, objstruct *obj)
{
astromstruct *as;
double *lm, *wcspos;
as = field->astrom;
lm = as->linmat;
/* If working with WCS, compute WORLD coordinates and local matrix */
if (FLAG(obj2.mxw))
{
if (as->wcs_flag)
{
wcspos = compute_wcs(field, obj2->posx, obj2->posy);
obj2->alphas = obj2->mxw = wcspos[0];
obj2->deltas = obj2->myw = wcspos[1];
if (FLAG(obj2.alpha2000))
{
if (fabs(as->equinox-2000.0)>0.003)
precess(as->equinox, wcspos[0], wcspos[1],
2000.0, &obj2->alpha2000, &obj2->delta2000);
else
{
obj2->alpha2000 = obj2->mxw;
obj2->delta2000 = obj2->myw;
}
if (FLAG(obj2.alpha1950))
j2b(as->equinox, obj2->alpha2000, obj2->delta2000,
&obj2->alpha1950, &obj2->delta1950);
}
}
else
{
double dx,dy;
dx = obj2->posx - as->crpix[0];
dy = obj2->posy - as->crpix[1];
obj2->mxw = as->crval[0]+ lm[0]*dx + lm[1]*dy; /* CDELT included! */
obj2->myw = as->crval[1]+ lm[2]*dx + lm[3]*dy; /* CDELT included! */
}
}
/* Idem for peak-flux positions */
if (FLAG(obj2.peakxw))
{
if (as->wcs_flag)
{
wcspos = compute_wcs(field, (double)obj->peakx, (double)obj->peaky);
obj2->peakalphas = obj2->peakxw = wcspos[0];
obj2->peakdeltas = obj2->peakyw = wcspos[1];
if (FLAG(obj2.peakalpha2000))
{
if (fabs(as->equinox-2000.0)>0.003)
precess(as->equinox, wcspos[0], wcspos[1],
2000.0, &obj2->peakalpha2000, &obj2->peakdelta2000);
else
{
obj2->peakalpha2000 = obj2->peakxw;
obj2->peakdelta2000 = obj2->peakyw;
}
if (FLAG(obj2.peakalpha1950))
j2b(as->equinox, obj2->peakalpha2000, obj2->peakdelta2000,
&obj2->peakalpha1950, &obj2->peakdelta1950);
}
}
else
{
double dx,dy;
dx = obj->peakx - as->crpix[0];
dy = obj->peaky - as->crpix[1];
obj2->peakxw = as->crval[0]+ lm[0]*dx + lm[1]*dy; /* CDELT included! */
obj2->peakyw = as->crval[1]+ lm[2]*dx + lm[3]*dy; /* CDELT included! */
}
}
/* Idem for Windowed positions */
if (FLAG(obj2.winpos_xw))
{
if (as->wcs_flag)
{
wcspos = compute_wcs(field, obj2->winpos_x, obj2->winpos_y);
obj2->winpos_alphas = obj2->winpos_xw = wcspos[0];
obj2->winpos_deltas = obj2->winpos_yw = wcspos[1];
if (FLAG(obj2.winpos_alpha2000))
{
if (fabs(as->equinox-2000.0)>0.003)
precess(as->equinox, wcspos[0], wcspos[1],
2000.0, &obj2->winpos_alpha2000, &obj2->winpos_delta2000);
else
{
obj2->winpos_alpha2000 = obj2->winpos_xw;
obj2->winpos_delta2000 = obj2->winpos_yw;
}
if (FLAG(obj2.winpos_alpha1950))
j2b(as->equinox, obj2->winpos_alpha2000, obj2->winpos_delta2000,
&obj2->winpos_alpha1950, &obj2->winpos_delta1950);
}
}
else
{
double dx,dy;
dx = obj2->winpos_x - as->crpix[0];
dy = obj2->winpos_y - as->crpix[1];
obj2->winpos_xw = as->crval[0]+ lm[0]*dx + lm[1]*dy;/* CDELT included! */
obj2->winpos_yw = as->crval[1]+ lm[2]*dx + lm[3]*dy;/* CDELT included! */
}
}
/* Custom coordinate system for the MAMA machine */
if (FLAG(obj2.mamaposx))
{
double dx,dy;
dx = obj2->posx - 0.5;
dy = obj2->posy - 0.5;
obj2->mamaposx = (as->crval[1]+lm[2]*dx+lm[3]*dy)
*(MAMA_CORFLEX+1.0); /* CDELT included! */
obj2->mamaposy = (as->crval[0]+lm[0]*dx+lm[1]*dy); /* CDELT included! */
}
/* Express shape parameters in WORLD frame */
if (FLAG(obj2.mx2w))
astrom_shapeparam(field, obj);
if (FLAG(obj2.win_mx2w))
astrom_winshapeparam(field, obj);
/* Express position error parameters in WORLD frame */
if (FLAG(obj2.poserr_mx2w))
astrom_errparam(field, obj);
if (FLAG(obj2.winposerr_mx2w))
astrom_winerrparam(field, obj);
if (FLAG(obj2.npixw))
obj2->npixw = obj->npix*as->pixscale*as->pixscale;
if (FLAG(obj2.fdnpixw))
obj2->fdnpixw = obj->fdnpix*as->pixscale*as->pixscale;
if (FLAG(obj2.fwhmw))
obj2->fwhmw = obj->fwhm*as->pixscale;
return;
}
/****************************** compute_wcs *********************************/
/*
Compute real WORLD coordinates and local distortion matrix according to the
WCS info.
*/
double *compute_wcs(picstruct *field, double mx, double my)
{
astromstruct *as;
static double pixpos[NAXIS], wcspos[NAXIS],wcspos0[2], imgcrd[NAXIS],
phi,theta;
double *lm, al,da,de,cde;
int rcode, lng,lat, naxis;
as = field->astrom;
lm = as->linmat;
naxis = as->naxis;
lng = as->lng;
lat = as->lat;
if (lng == lat)
{
lng = 0;
lat = 1;
}
pixpos[lng] = mx;
pixpos[lat] = my;
if ((rcode=wcsrev((const char(*)[9])as->ctype, as->wcs, pixpos, as->lin,
imgcrd, as->prj, &phi, &theta, as->crval, as->cel, wcspos)))
error(EXIT_FAILURE, "*Error* in WCSlib: ", (char *)wcsrev_errmsg[rcode]);
/* Compute the local distortion matrix */
al = wcspos0[lng<lat?0:1] = wcspos[lng];
de = wcspos0[lng<lat?1:0] = wcspos[lat];
/* Get world coordinates for vector 1,0 */
pixpos[lng] = mx + 1.0;
pixpos[lat] = my;
if ((rcode=wcsrev((const char(*)[9])as->ctype, as->wcs, pixpos, as->lin,
imgcrd, as->prj, &phi, &theta, as->crval, as->cel, wcspos)))
error(EXIT_FAILURE, "*Error* in WCSlib: ", (char *)wcsrev_errmsg[rcode]);
da = wcspos[lng]-al;
if (da>180.0)
da -= 360.0;
else if (da<-180.0)
da += 360.0;
lm[lng] = da*(cde=cos(de*DEG));
lm[lat] = wcspos[lat] - de;
/* Get world coordinates for vector 0,1 */
/* Second one */
pixpos[lng] = mx;
pixpos[lat] = my + 1.0;
if ((rcode=wcsrev((const char(*)[9])as->ctype, as->wcs, pixpos, as->lin,
imgcrd, as->prj, &phi, &theta, as->crval, as->cel, wcspos)))
error(EXIT_FAILURE, "*Error* in WCSlib: ", (char *)wcsrev_errmsg[rcode]);
da = wcspos[lng]-al;
if (da>180.0)
da -= 360.0;
else if (da<-180.0)
da += 360.0;
lm[2] = da*cde;
lm[3] = wcspos[lat] - de;
as->lindet = lm[lng+lng*naxis]*lm[lat+lat*naxis]
- lm[lng+lat*naxis]*lm[lat+lng*naxis];
if (as->lindet == 0.0)
warning ("Null determinant in the local distortion matrix:\n",
" Some WORLD-parameters will be incorrect");
if (prefs.pixel_scale == 0.0)
as->pixscale = sqrt(fabs(as->lindet));
return wcspos0;
}
/****************************** astrom_shapeparam ****************************/
/*
Compute shape parameters in WORLD and SKY coordinates.
*/
void astrom_shapeparam(picstruct *field, objstruct *obj)
{
astromstruct *as;
double *lm,
dx2,dy2,dxy, xm2,ym2,xym, temp,pm2, lm0,lm1,lm2,lm3;
int lng,lat, naxis;
as = field->astrom;
lm = as->linmat;
naxis = as->naxis;
lng = as->lng;
lat = as->lat;
if (lng == lat)
{
lng = 0;
lat = 1;
}
lm0 = lm[lng+naxis*lng];
lm1 = lm[lat+naxis*lng];
lm2 = lm[lng+naxis*lat];
lm3 = lm[lat+naxis*lat];
/* All WORLD params based on 2nd order moments have to pass through here */
dx2 = obj->mx2;
dy2 = obj->my2;
dxy = obj->mxy;
obj2->mx2w = xm2 = lm0*lm0*dx2 + lm1*lm1*dy2 + lm0*lm1*dxy;
obj2->my2w = ym2 = lm2*lm2*dx2 + lm3*lm3*dy2 + lm2*lm3*dxy;
obj2->mxyw = xym = lm0*lm2*dx2 + lm1*lm3*dy2 + (lm0*lm3+lm1*lm2)*dxy;
temp=xm2-ym2;
if (FLAG(obj2.thetaw))
{
obj2->thetaw = (temp == 0.0)? (45.0) : (0.5*atan2(2.0 * xym,temp)/DEG);
if (as->wcs_flag && FLAG(obj2.thetas))
obj2->thetas = obj2->thetaw + (obj2->thetaw>0.0?-90:90.0);
/*-- Compute position angles in J2000 or B1950 reference frame */
if (as->wcs_flag)
{
double da,dd;
if (FLAG(obj2.theta2000))
{
da = as->ap2000 - obj2->alpha2000;
dd = (sin(as->dp2000*DEG)
-sin(obj2->delta2000*DEG)*sin(obj2->deltas*DEG))
/(cos(obj2->delta2000*DEG)*cos(obj2->deltas*DEG));
dd = dd<1.0? (dd>-1.0?acos(dd)/DEG:180.0) : 0.0;
obj2->theta2000 = obj2->thetas
+ (((da>0.0 && da<180.0) || da<-180.0)?-dd:dd);
}
if (FLAG(obj2.theta1950))
{
da = as->ap1950 - obj2->alpha1950;
dd = (sin(as->dp1950*DEG)
-sin(obj2->delta1950*DEG)*sin(obj2->deltas*DEG))
/(cos(obj2->delta1950*DEG)*cos(obj2->deltas*DEG));
dd = dd<1.0? (dd>-1.0?acos(dd)/DEG:180.0) : 0.0;
obj2->theta1950 = obj2->thetas
+ (((da>0.0 && da<180.0) || da<-180.0)?-dd:dd);
}
}
}
if (FLAG(obj2.aw))
{
temp = sqrt(0.25*temp*temp+xym*xym);
pm2 = 0.5*(xm2+ym2);
obj2->aw = (float)sqrt(pm2+temp);
obj2->bw = (float)sqrt(pm2-temp);
obj2->polarw = temp / pm2;
}
if (FLAG(obj2.cxxw))
{
/*-- Handle large, fully correlated profiles (can cause a singularity...) */
if ((temp=xm2*ym2-xym*xym)<1e-6)
{
temp = 1e-6;
xym *= 0.99999;
}
obj2->cxxw = (float)(ym2/temp);
obj2->cyyw = (float)(xm2/temp);
obj2->cxyw = (float)(-2*xym/temp);
}
return;
}
/**************************** astrom_winshapeparam ***************************/
/*
Compute shape parameters in WORLD and SKY coordinates.
*/
void astrom_winshapeparam(picstruct *field, objstruct *obj)
{
astromstruct *as;
double *lm,
dx2,dy2,dxy, xm2,ym2,xym, temp,pm2, lm0,lm1,lm2,lm3;
int lng,lat, naxis;
as = field->astrom;
lm = as->linmat;
naxis = as->naxis;
lng = as->lng;
lat = as->lat;
if (lng == lat)
{
lng = 0;
lat = 1;
}
lm0 = lm[lng+naxis*lng];
lm1 = lm[lat+naxis*lng];
lm2 = lm[lng+naxis*lat];
lm3 = lm[lat+naxis*lat];
/* All WORLD params based on 2nd order moments have to pass through here */
dx2 = obj2->win_mx2;
dy2 = obj2->win_my2;
dxy = obj2->win_mxy;
obj2->win_mx2w = xm2 = lm0*lm0*dx2 + lm1*lm1*dy2 + lm0*lm1*dxy;
obj2->win_my2w = ym2 = lm2*lm2*dx2 + lm3*lm3*dy2 + lm2*lm3*dxy;
obj2->win_mxyw = xym = lm0*lm2*dx2 + lm1*lm3*dy2 + (lm0*lm3+lm1*lm2)*dxy;
temp=xm2-ym2;
if (FLAG(obj2.win_thetaw))
{
obj2->win_thetaw = (temp == 0.0)? (45.0) : (0.5*atan2(2.0*xym,temp)/DEG);
if (as->wcs_flag && FLAG(obj2.win_thetas))
obj2->win_thetas = obj2->win_thetaw +
(obj2->win_thetaw>0.0?-90:90.0);
/*-- Compute position angles in J2000 or B1950 reference frame */
if (as->wcs_flag)
{
double da,dd;
if (FLAG(obj2.win_theta2000))
{
da = as->ap2000 - obj2->winpos_alpha2000;
dd = (sin(as->dp2000*DEG)
-sin(obj2->winpos_delta2000*DEG)*sin(obj2->winpos_deltas*DEG))
/(cos(obj2->winpos_delta2000*DEG)*cos(obj2->winpos_deltas*DEG));
dd = dd<1.0? (dd>-1.0?acos(dd)/DEG:180.0) : 0.0;
obj2->win_theta2000 = obj2->win_thetas
+ (((da>0.0 && da<180.0) || da<-180.0)?-dd:dd);
}
if (FLAG(obj2.win_theta1950))
{
da = as->ap1950 - obj2->winpos_alpha1950;
dd = (sin(as->dp1950*DEG)
-sin(obj2->winpos_delta1950*DEG)*sin(obj2->winpos_deltas*DEG))
/(cos(obj2->winpos_delta1950*DEG)*cos(obj2->winpos_deltas*DEG));
dd = dd<1.0? (dd>-1.0?acos(dd)/DEG:180.0) : 0.0;
obj2->win_theta1950 = obj2->win_thetas
+ (((da>0.0 && da<180.0) || da<-180.0)?-dd:dd);
}
}
}
if (FLAG(obj2.win_aw))
{
temp = sqrt(0.25*temp*temp+xym*xym);
pm2 = 0.5*(xm2+ym2);
obj2->win_aw = (float)sqrt(pm2+temp);
obj2->win_bw = (float)sqrt(pm2-temp);
obj2->win_polarw = temp / pm2;
}
if (FLAG(obj2.win_cxxw))
{
/*-- Handle large, fully correlated profiles (can cause a singularity...) */
if ((temp=xm2*ym2-xym*xym)<1e-6)
{
temp = 1e-6;
xym *= 0.99999;
}
obj2->win_cxxw = (float)(ym2/temp);
obj2->win_cyyw = (float)(xm2/temp);
obj2->win_cxyw = (float)(-2*xym/temp);
}
return;
}
/******************************* astrom_errparam *****************************/
/*
Compute error ellipse parameters in WORLD and SKY coordinates.
*/
void astrom_errparam(picstruct *field, objstruct *obj)
{
astromstruct *as;
double *lm,
dx2,dy2,dxy, xm2,ym2,xym, temp,pm2, lm0,lm1,lm2,lm3;
int lng,lat, naxis;
as = field->astrom;
lm = as->linmat;
naxis = as->naxis;
lng = as->lng;
lat = as->lat;
if (lng == lat)
{
lng = 0;
lat = 1;
}
lm0 = lm[lng+naxis*lng];
lm1 = lm[lat+naxis*lng];
lm2 = lm[lng+naxis*lat];
lm3 = lm[lat+naxis*lat];
/* All WORLD params based on 2nd order moments have to pass through here */
dx2 = obj->poserr_mx2;
dy2 = obj->poserr_my2;
dxy = obj->poserr_mxy;
obj2->poserr_mx2w = xm2 = lm0*lm0*dx2 + lm1*lm1*dy2 + lm0*lm1*dxy;
obj2->poserr_my2w = ym2 = lm2*lm2*dx2 + lm3*lm3*dy2 + lm2*lm3*dxy;
obj2->poserr_mxyw = xym = lm0*lm2*dx2 + lm1*lm3*dy2 + (lm0*lm3+lm1*lm2)*dxy;
temp=xm2-ym2;
if (FLAG(obj2.poserr_thetaw))
{
obj2->poserr_thetaw = (temp==0.0)? (45.0):(0.5*atan2(2.0*xym,temp)/DEG);
if (as->wcs_flag && FLAG(obj2.poserr_thetas))
obj2->poserr_thetas = obj2->poserr_thetaw
+ (obj2->poserr_thetaw>0.0? -90:90.0);
/*-- Compute position angles in J2000 or B1950 reference frame */
if (as->wcs_flag)
{
double da,dd;
if (FLAG(obj2.poserr_theta2000))
{
da = as->ap2000 - obj2->alpha2000;
dd = (sin(as->dp2000*DEG)
-sin(obj2->delta2000*DEG)*sin(obj2->deltas*DEG))
/(cos(obj2->delta2000*DEG)*cos(obj2->deltas*DEG));
dd = dd<1.0? (dd>-1.0?acos(dd)/DEG:180.0) : 0.0;
obj2->poserr_theta2000 = obj2->poserr_thetas
+ (((da>0.0 && da<180.0) || da<-180.0)?-dd:dd);
}
if (FLAG(obj2.poserr_theta1950))
{
da = as->ap1950 - obj2->alpha1950;
dd = (sin(as->dp1950*DEG)
-sin(obj2->delta1950*DEG)*sin(obj2->deltas*DEG))
/(cos(obj2->delta1950*DEG)*cos(obj2->deltas*DEG));
dd = dd<1.0? (dd>-1.0?acos(dd)/DEG:180.0) : 0.0;
obj2->poserr_theta1950 = obj2->poserr_thetas
+ (((da>0.0 && da<180.0) || da<-180.0)?-dd:dd);
}
}
}
if (FLAG(obj2.poserr_aw))
{
temp = sqrt(0.25*temp*temp+xym*xym);
pm2 = 0.5*(xm2+ym2);
obj2->poserr_aw = (float)sqrt(pm2+temp);
obj2->poserr_bw = (float)sqrt(pm2-temp);
}
if (FLAG(obj2.poserr_cxxw))
{
/*-- Handle large, fully correlated profiles (can cause a singularity...) */
if ((temp=xm2*ym2-xym*xym)<1e-6)
{
temp = 1e-6;
xym *= 0.99999;
}
obj2->poserr_cxxw = (float)(ym2/temp);
obj2->poserr_cyyw = (float)(xm2/temp);
obj2->poserr_cxyw = (float)(-2*xym/temp);
}
return;
}
/***************************** astrom_winerrparam ***************************/
/*
Compute error ellipse parameters in WORLD and SKY coordinates.
*/
void astrom_winerrparam(picstruct *field, objstruct *obj)
{
astromstruct *as;
double *lm,
dx2,dy2,dxy, xm2,ym2,xym, temp,pm2, lm0,lm1,lm2,lm3;
int lng,lat, naxis;
as = field->astrom;
lm = as->linmat;
naxis = as->naxis;
lng = as->lng;
lat = as->lat;
if (lng == lat)
{
lng = 0;
lat = 1;
}
lm0 = lm[lng+naxis*lng];
lm1 = lm[lat+naxis*lng];
lm2 = lm[lng+naxis*lat];
lm3 = lm[lat+naxis*lat];
/* All WORLD params based on 2nd order moments have to pass through here */
dx2 = obj2->winposerr_mx2;
dy2 = obj2->winposerr_my2;
dxy = obj2->winposerr_mxy;
obj2->winposerr_mx2w = xm2 = lm0*lm0*dx2 + lm1*lm1*dy2 + lm0*lm1*dxy;
obj2->winposerr_my2w = ym2 = lm2*lm2*dx2 + lm3*lm3*dy2 + lm2*lm3*dxy;
obj2->winposerr_mxyw = xym = lm0*lm2*dx2 + lm1*lm3*dy2 + (lm0*lm3+lm1*lm2)*dxy;
temp=xm2-ym2;
if (FLAG(obj2.winposerr_thetaw))
{
obj2->winposerr_thetaw = (temp==0.0)? (45.0):(0.5*atan2(2.0*xym,temp)/DEG);
if (as->wcs_flag && FLAG(obj2.winposerr_thetas))
obj2->winposerr_thetas = obj2->winposerr_thetaw
+ (obj2->winposerr_thetaw>0.0? -90:90.0);
/*-- Compute position angles in J2000 or B1950 reference frame */
if (as->wcs_flag)
{
double da,dd;
if (FLAG(obj2.winposerr_theta2000))
{
da = as->ap2000 - obj2->winpos_alpha2000;
dd = (sin(as->dp2000*DEG)
-sin(obj2->winpos_delta2000*DEG)*sin(obj2->winpos_deltas*DEG))
/(cos(obj2->winpos_delta2000*DEG)*cos(obj2->winpos_deltas*DEG));
dd = dd<1.0? (dd>-1.0?acos(dd)/DEG:180.0) : 0.0;
obj2->winposerr_theta2000 = obj2->winposerr_thetas
+ (((da>0.0 && da<180.0) || da<-180.0)?-dd:dd);
}
if (FLAG(obj2.winposerr_theta1950))
{
da = as->ap1950 - obj2->winpos_alpha1950;
dd = (sin(as->dp1950*DEG)
-sin(obj2->winpos_delta1950*DEG)*sin(obj2->winpos_deltas*DEG))
/(cos(obj2->winpos_delta1950*DEG)*cos(obj2->winpos_deltas*DEG));
dd = dd<1.0? (dd>-1.0?acos(dd)/DEG:180.0) : 0.0;
obj2->winposerr_theta1950 = obj2->winposerr_thetas
+ (((da>0.0 && da<180.0) || da<-180.0)?-dd:dd);
}
}
}
if (FLAG(obj2.winposerr_aw))
{
temp = sqrt(0.25*temp*temp+xym*xym);
pm2 = 0.5*(xm2+ym2);
obj2->winposerr_aw = (float)sqrt(pm2+temp);
obj2->winposerr_bw = (float)sqrt(pm2-temp);
}
if (FLAG(obj2.winposerr_cxxw))
{
/*-- Handle large, fully correlated profiles (can cause a singularity...) */
if ((temp=xm2*ym2-xym*xym)<1e-6)
{
temp = 1e-6;
xym *= 0.99999;
}
obj2->winposerr_cxxw = (float)(ym2/temp);
obj2->winposerr_cyyw = (float)(xm2/temp);
obj2->winposerr_cxyw = (float)(-2*xym/temp);
}
return;
}
/******************************* copyastrom *********************************/
/*
Copy astrometrical structures.
*/
void copyastrom(picstruct *infield, picstruct *outfield)
{
astromstruct *inas, *outas;
int naxis;
if (infield->astrom)
{
QMEMCPY(infield->astrom, outfield->astrom, astromstruct, 1);
inas = infield->astrom;
outas = outfield->astrom;
naxis = inas->naxis;
if (inas->wcs_flag)
{
QMEMCPY(inas->wcs, outas->wcs, struct wcsprm, 1);
QMEMCPY(inas->lin, outas->lin, struct linprm, 1);
QMEMCPY(inas->cel, outas->cel, struct celprm, 1);
QMEMCPY(inas->prj, outas->prj, struct prjprm, 1);
QMEMCPY(inas->lin->cdelt, outas->lin->cdelt, double, naxis);
QMEMCPY(inas->lin->crpix, outas->lin->crpix, double, naxis);
QMEMCPY(inas->lin->pc, outas->lin->pc, double, naxis*naxis);
outas->tnx_lngcor = copy_tnxaxis(inas->tnx_lngcor);
outas->tnx_latcor = copy_tnxaxis(inas->tnx_latcor);
}
}
return;
}
/******************************* endastrom ***********************************/
/*
Free astrometrical structures.
*/
void endastrom(picstruct *field)
{
astromstruct *as;
as = field->astrom;
if (as->wcs_flag)
{
free(as->lin->cdelt);
free(as->lin->crpix);
free(as->lin->pc);
free(as->wcs);
free(as->lin);
free(as->cel);
free(as->prj);
free_tnxaxis(as->tnx_lngcor);
free_tnxaxis(as->tnx_latcor);
}
free(as);
return;
}
/********************************* precess ***********************************/
/*
precess equatorial coordinates according to the equinox (from Ephemerides du
Bureau des Longitudes 1992). Epoch for coordinates should be J2000
(FK5 system).
*/
void precess(double yearin, double alphain, double deltain,
double yearout, double *alphaout, double *deltaout)
{
double dzeta,theta,z, t1,t1t1, t2,t2t2,t2t2t2,
cddsadz, cddcadz, cdd, sdd, adz, cdin,sdin,ct,st,caindz;
alphain *= DEG;
deltain *= DEG;
t1 = (yearin - 2000.0)/1000.0;
t2 = (yearout - yearin)/1000.0;
t1t1 = t1*t1;
t2t2t2 = (t2t2 = t2*t2)*t2;
theta = (97171.735e-06 - 413.691e-06*t1 - 1.052e-06 * t1t1) * t2
+ (-206.846e-06 - 1.052e-06*t1) * t2t2 - 202.812e-06 * t2t2t2;
dzeta = (111808.609e-06 + 677.071e-06*t1 - 0.674e-06 * t1t1) * t2
+ (146.356e-06 - 1.673e-06*t1) * t2t2 + 87.257e-06 * t2t2t2;
z = (111808.609e-06 +677.071e-06*t1 - 0.674e-06 * t1t1) * t2
+ (530.716e-06 + 0.320e-06*t1) * t2t2 + 88.251e-06 * t2t2t2;
cddsadz = (cdin=cos(deltain)) * sin(alphain+dzeta);
cddcadz = -(sdin=sin(deltain))*(st=sin(theta))
+cdin*(ct=cos(theta))*(caindz=cos(alphain+dzeta));
sdd = sdin*ct + cdin*st*caindz;
cdd = cos(*deltaout = asin(sdd));
adz = asin(cddsadz/cdd);
if (cddcadz<0.0)
adz = PI - adz;
if (adz<0.0)
adz += 2.0*PI;
adz += z;
*alphaout = adz/DEG;
*deltaout /= DEG;
return;
}
/*********************************** j2b *************************************/
/*
conver equatorial coordinates from equinox and epoch J2000 to equinox and
epoch B1950 for extragalactic sources (from Aoki et al. 1983, after
inversion of their matrix and some custom arrangements).
*/
void j2b(double yearobs, double alphain, double deltain,
double *alphaout, double *deltaout)
{
int i,j;
static double a[3] = {-1.62557e-6, -0.31919e-6, -0.13843e-6},
ap[3] = {1.245e-3, -1.580e-3, -0.659e-3},
m[6][6] = {
{ 0.9999256794678425, 0.01118148281196562, 0.004859003848996022,
-2.423898417033081e-06,-2.710547600126671e-08,-1.177738063266745e-08},
{-0.01118148272969232, 0.9999374849247641, -2.717708936468247e-05,
2.710547578707874e-08,-2.423927042585208e-06, 6.588254898401055e-11},
{-0.00485900399622881, -2.715579322970546e-05, 0.999988194643078,
1.177738102358923e-08, 6.582788892816657e-11,-2.424049920613325e-06},
{-0.0005508458576414713, 0.2384844384742432, -0.4356144527773499,
0.9999043171308133, 0.01118145410120206, 0.004858518651645554},
{-0.2385354433560954, -0.002664266996872802, 0.01225282765749546,
-0.01118145417187502, 0.9999161290795875, -2.717034576263522e-05},
{ 0.4357269351676567, -0.008536768476441086, 0.002113420799663768,
-0.004858518477064975, -2.715994547222661e-05, 0.9999668385070383}},
a1[3], r[3], ro[3], r1[3], r2[3], v1[3], v[3];
static double cai, sai, cdi, sdi, dotp, rmod, alpha, delta, t1;
/* Convert Julian years from J2000.0 to tropic centuries from B1950.0 */
t1 = ((yearobs - 2000.0) + (MJD2000 - MJD1950)/365.25)*JU2TROP/100.0;
alphain *= DEG;
deltain *= DEG;
cai = cos(alphain);
sai = sin(alphain);
cdi = cos(deltain);
sdi = sin(deltain);
r[0] = cdi*cai;
r[1] = cdi*sai;
r[2] = sdi;
for (i=0; i<3; i++)
v[i] = r2[i] = v1[i] = 0.0;
for (j=0; j<6; j++)
for (i=0; i<6; i++)
if (j<3)
r2[j] += m[j][i]*(i<3?r[i]:v[i-3]);
else
v1[j-3] += m[j][i]*(i<3?r[i]:v[i-3]);
for (i=0; i<3; i++)
r1[i] = r2[i]+v1[i]*ARCSEC*t1;
dotp = 0.0;
for (i=0; i<3; i++)
{
a1[i] = a[i]+ap[i]*ARCSEC*t1;
dotp += a1[i]*(r1[i]+a1[i]);
}
dotp = 2.0/(sqrt(1+4.0*dotp)+1.0);
rmod = 0.0;
for (i=0; i<3; i++)
{
ro[i] = dotp*(r1[i]+a1[i]);
rmod += ro[i]*ro[i];
}
rmod = sqrt(rmod);
delta = asin(ro[2]/rmod);
alpha = acos(ro[0]/cos(delta)/rmod);
if (ro[1]<0)
alpha = 2.0*PI - alpha;
*alphaout = alpha/DEG;
*deltaout = delta/DEG;
return;
}
/*
astrom.h
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN, IAP & Leiden observatory
*
* Contents: Astrometrical stuff.
*
* Last modify: 13/07/2006
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
/*----------------------------- Internal constants --------------------------*/
#define DEG (PI/180.0) /* 1 deg in radians */
#define ARCSEC (DEG/3600.0) /* 1 arcsec in radians */
#define MJD2000 51544.50000 /* Modified Julian date for J2000.0 */
#define MJD1950 33281.92346 /* Modified Julian date for B1950.0 */
#define JU2TROP 1.0000214 /* 1 Julian century in tropical units*/
#define NAXIS 3 /* Max number of FITS axes */
#define MAMA_CORFLEX 3.3e-5 /* MAMA coordinate correction factor */
/*------------------------------- structures --------------------------------*/
typedef struct structastrom
{
int naxis; /* Number of image axes */
char ctype[NAXIS][9]; /* FITS CTYPE strings */
char cunit[NAXIS][32]; /* FITS CUNIT strings */
double crval[NAXIS]; /* FITS CRVAL parameters */
double cdelt[NAXIS]; /* FITS CDELT parameters */
double crpix[NAXIS]; /* FITS CRPIX parameters */
double projp[100*NAXIS]; /* FITS PROJP parameters */
double longpole,latpole; /* FITS LONGPOLE and LATPOLE */
double pc[NAXIS*NAXIS]; /* FITS PC matrix */
double linmat[NAXIS*NAXIS]; /* Local linear mapping matrix */
double lindet; /* Determinant of the local matrix */
double pixscale; /* (Local) pixel scale */
double ap2000,dp2000; /* J2000 coordinates of pole */
double ap1950,dp1950; /* B1950 coordinates of pole */
double equinox; /* Equinox of observations */
enum {RDSYS_ICRS, RDSYS_FK5, RDSYS_FK4, RDSYS_FK4_NO_E, RDSYS_GAPPT}
radecsys; /* FITS RADECSYS reference frame */
int wcs_flag; /* WCSLIB: can it be used? */
int lat,lng; /* longitude and latitude axes # */
double r0; /* projection "radius" */
struct wcsprm *wcs; /* WCSLIB's wcsprm structure */
struct linprm *lin; /* WCSLIB's linprm structure */
struct celprm *cel; /* WCSLIB's celprm structure */
struct prjprm *prj; /* WCSLIB's prjprm structure */
struct tnxaxis *tnx_latcor; /* IRAF's TNX latitude corrections */
struct tnxaxis *tnx_lngcor; /* IRAF's TNX longitude corrections */
} astromstruct;
/*------------------------------- functions ---------------------------------*/
extern void astrom_errparam(picstruct *, objstruct *),
astrom_winerrparam(picstruct *, objstruct *),
astrom_shapeparam(picstruct *, objstruct *),
astrom_winshapeparam(picstruct *, objstruct *),
computeastrom(picstruct *, objstruct *),
copyastrom(picstruct *infield, picstruct *outfield),
endastrom(picstruct *),
initastrom(picstruct *),
j2b(double, double, double, double *, double *),
precess(double,double,double,double,double *,double *);
extern double *compute_wcs(picstruct *, double, double);
/*
back.c
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN (IAP)
*
* Contents: functions dealing with background computation.
*
* Last modify: 16/08/2006
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
#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 "prefs.h"
#include "fits/fitscat.h"
#include "back.h"
#include "field.h"
#include "weight.h"
/******************************** makeback ***********************************/
/*
Background maps are established from the images themselves; thus we need to
make at least one first pass through the data.
*/
void makeback(picstruct *field, picstruct *wfield)
{
backstruct *backmesh,*wbackmesh, *bm,*wbm;
PIXTYPE *buf,*wbuf, *buft,*wbuft;
OFF_T fcurpos,wfcurpos, wfcurpos2,fcurpos2, bufshift, jumpsize;
size_t bufsize, bufsize2,
size,meshsize;
int i,j,k,m,n, step, nlines,
w,bw, bh, nx,ny,nb,
lflag, nr;
float *ratio,*ratiop, *weight, *sigma,
sratio;
/* If the weight-map is not an external one, no stats are needed for it */
if (wfield && wfield->flags&(INTERP_FIELD|BACKRMS_FIELD))
wfield= NULL;
w = field->width;
bw = field->backw;
bh = field->backh;
nx = field->nbackx;
ny = field->nbacky;
nb = field->nback;
NFPRINTF(OUTPUT, "Setting up background maps");
/* Decide if it is worth displaying progress each 16 lines */
lflag = (field->width*field->backh >= (size_t)65536);
/* Save current positions in files */
wfcurpos = wfcurpos2 = 0; /* to avoid gcc -Wall warnings */
QFTELL(field->file, fcurpos, field->filename);
if (wfield)
QFTELL(wfield->file, wfcurpos, wfield->filename);
/* Allocate a correct amount of memory to store pixels */
bufsize = (OFF_T)w*bh;
meshsize = (size_t)bufsize;
nlines = 0;
if (bufsize > (size_t)BACK_BUFSIZE)
{
nlines = BACK_BUFSIZE/w;
step = (field->backh-1)/nlines+1;
bufsize = (size_t)(nlines = field->backh/step)*w;
bufshift = (step/2)*(OFF_T)w;
jumpsize = (step-1)*(OFF_T)w;
}
else
bufshift = jumpsize = 0; /* to avoid gcc -Wall warnings */
/* Allocate some memory */
QMALLOC(backmesh, backstruct, nx); /* background information */
QMALLOC(buf, PIXTYPE, bufsize); /* pixel buffer */
free(field->back);
QMALLOC(field->back, float, nb); /* background map */
free(field->backline);
QMALLOC(field->backline, PIXTYPE, w); /* current background line */
free(field->sigma);
QMALLOC(field->sigma, float, nb); /* sigma map */
if (wfield)
{
QMALLOC(wbackmesh, backstruct, nx); /* background information */
QMALLOC(wbuf, PIXTYPE, bufsize); /* pixel buffer */
free(wfield->back);
QMALLOC(wfield->back, float, nb); /* background map */
free(wfield->backline);
QMALLOC(wfield->backline, PIXTYPE, w); /* current background line */
free(wfield->sigma);
QMALLOC(wfield->sigma, float, nb); /* sigma map */
wfield->sigfac = 1.0;
}
else
{
wbackmesh = NULL;
wbuf = NULL;
}
/* Loop over the data packets */
for (j=0; j<ny; j++)
{
if (lflag && j)
NPRINTF(OUTPUT, "\33[1M> Setting up background map at line:%5d\n\33[1A",
j*bh);
if (!nlines)
{
/*---- The image is small enough so that we can make exhaustive stats */
if (j == ny-1 && field->npix%bufsize)
bufsize = field->npix%bufsize;
readdata(field, buf, bufsize);
if (wfield)
{
readdata(wfield, wbuf, bufsize);
weight_to_var(wfield, wbuf, bufsize);
}
/*---- Build the histograms */
backstat(backmesh, wbackmesh, buf, wbuf, bufsize,nx, w, bw,
wfield?wfield->weight_thresh:0.0);
bm = backmesh;
for (m=nx; m--; bm++)
if (bm->mean <= -BIG)
bm->histo=NULL;
else
QCALLOC(bm->histo, LONG, bm->nlevels);
if (wfield)
{
wbm = wbackmesh;
for (m=nx; m--; wbm++)
if (wbm->mean <= -BIG)
wbm->histo=NULL;
else
QCALLOC(wbm->histo, LONG, wbm->nlevels);
}
backhisto(backmesh, wbackmesh, buf, wbuf, bufsize,nx, w, bw,
wfield?wfield->weight_thresh:0.0);
}
else
{
/*---- Image size too big, we have to skip a few data !*/
QFTELL(field->file, fcurpos2, field->filename);
if (wfield)
QFTELL(wfield->file, wfcurpos2, wfield->filename);
if (j == ny-1 && (n=field->height%field->backh))
{
meshsize = n*(size_t)w;
nlines = BACK_BUFSIZE/w;
step = (n-1)/nlines+1;
bufsize = (nlines = n/step)*(size_t)w;
bufshift = (step/2)*(OFF_T)w;
jumpsize = (step-1)*(OFF_T)w;
free(buf);
QMALLOC(buf, PIXTYPE, bufsize); /* pixel buffer */
if (wfield)
{
free(wbuf);
QMALLOC(wbuf, PIXTYPE, bufsize); /* pixel buffer */
}
}
/*---- Read and skip, read and skip, etc... */
QFSEEK(field->file, bufshift*(OFF_T)field->bytepix, SEEK_CUR,
field->filename);
buft = buf;
for (i=nlines; i--; buft += w)
{
readdata(field, buft, w);
if (i)
QFSEEK(field->file, jumpsize*(OFF_T)field->bytepix, SEEK_CUR,
field->filename);
}
if (wfield)
{
/*------ Read and skip, read and skip, etc... now on the weight-map */
QFSEEK(wfield->file, bufshift*(OFF_T)wfield->bytepix, SEEK_CUR,
wfield->filename);
wbuft = wbuf;
for (i=nlines; i--; wbuft += w)
{
readdata(wfield, wbuft, w);
weight_to_var(wfield, wbuft, w);
if (i)
QFSEEK(wfield->file, jumpsize*(OFF_T)wfield->bytepix, SEEK_CUR,
wfield->filename);
}
}
backstat(backmesh, wbackmesh, buf, wbuf, bufsize, nx, w, bw,
wfield?wfield->weight_thresh:0.0);
QFSEEK(field->file, fcurpos2, SEEK_SET, field->filename);
bm = backmesh;
for (m=nx; m--; bm++)
if (bm->mean <= -BIG)
bm->histo=NULL;
else
QCALLOC(bm->histo, LONG, bm->nlevels);
if (wfield)
{
QFSEEK(wfield->file, wfcurpos2, SEEK_SET, wfield->filename);
wbm = wbackmesh;
for (m=nx; m--; wbm++)
if (wbm->mean <= -BIG)
wbm->histo=NULL;
else
QCALLOC(wbm->histo, LONG, wbm->nlevels);
}
/*---- Build (progressively this time) the histograms */
for(size=meshsize, bufsize2=bufsize; size>0; size -= bufsize2)
{
if (bufsize2>size)
bufsize2 = size;
readdata(field, buf, bufsize2);
if (wfield)
{
readdata(wfield, wbuf, bufsize2);
weight_to_var(wfield, wbuf, bufsize2);
}
backhisto(backmesh, wbackmesh, buf, wbuf, bufsize2, nx, w, bw,
wfield?wfield->weight_thresh:0.0);
}
}
/*-- Compute background statistics from the histograms */
bm = backmesh;
for (m=0; m<nx; m++, bm++)
{
k = m+nx*j;
backguess(bm, field->back+k, field->sigma+k);
free(bm->histo);
}
if (wfield)
{
wbm = wbackmesh;
for (m=0; m<nx; m++, wbm++)
{
k = m+nx*j;
backguess(wbm, wfield->back+k, wfield->sigma+k);
free(wbm->histo);
}
}
}
/* Free memory */
free(buf);
free(backmesh);
if (wfield)
{
free(wbackmesh);
free(wbuf);
}
/* Go back to the original position */
QFSEEK(field->file, fcurpos, SEEK_SET, field->filename);
if (wfield)
QFSEEK(wfield->file, wfcurpos, SEEK_SET, wfield->filename);
/* Median-filter and check suitability of the background map */
NFPRINTF(OUTPUT, "Filtering background map(s)");
filterback(field);
if (wfield)
filterback(wfield);
/* Compute normalization for variance- or weight-maps*/
if (wfield && wfield->flags&(VAR_FIELD|WEIGHT_FIELD))
{
nr = 0;
QMALLOC(ratio, float, wfield->nback);
ratiop = ratio;
weight = wfield->back;
sigma = field->sigma;
for (i=wfield->nback; i--; sigma++)
if ((sratio=*(weight++)) > 0.0
&& (sratio = *sigma/sqrt(sratio)) > 0.0)
{
*(ratiop++) = sratio;
nr++;
}
wfield->sigfac = hmedian(ratio, nr);
for (i=0; i<nr && ratio[i]<=0.0; i++);
if (i<nr)
wfield->sigfac = hmedian(ratio+i, nr-i);
else
{
warning("Null or negative global weighting factor:","defaulted to 1");
wfield->sigfac = 1.0;
}
free(ratio);
}
/* Compute 2nd derivatives along the y-direction */
NFPRINTF(OUTPUT, "Computing background d-map");
free(field->dback);
field->dback = makebackspline(field, field->back);
NFPRINTF(OUTPUT, "Computing background-noise d-map");
free(field->dsigma);
field->dsigma = makebackspline(field, field->sigma);
/* If asked for, force the backmean parameter to the supplied value */
if (field->back_type == BACK_ABSOLUTE)
field->backmean = (float)prefs.back_val[(field->flags&DETECT_FIELD)?0:1];
/* Set detection/measurement threshold */
if (prefs.ndthresh > 1)
{
double dval;
if (fabs(dval=prefs.dthresh[0] - prefs.dthresh[1])> 70.0)
error(EXIT_FAILURE,
"*Error*: I cannot deal with such extreme thresholds!", "");
field->dthresh = field->pixscale*field->pixscale*pow(10.0, -0.4*dval);
}
else if (prefs.thresh_type[0]==THRESH_ABSOLUTE)
field->dthresh = prefs.dthresh[0];
else
field->dthresh = prefs.dthresh[0]*field->backsig;
if (prefs.nthresh > 1)
{
double dval;
if (fabs(dval=prefs.thresh[0] - prefs.thresh[1]) > 70.0)
error(EXIT_FAILURE,
"*Error*: I cannot deal with such extreme thresholds!", "");
field->thresh = field->pixscale*field->pixscale*pow(10.0, -0.4*dval);
}
else if (prefs.thresh_type[1]==THRESH_ABSOLUTE)
field->thresh = prefs.thresh[0];
else
field->thresh = prefs.thresh[0]*field->backsig;
#ifdef QUALITY_CHECK
printf("%-10g %-10g %-10g\n", field->backmean, field->backsig,
(field->flags & DETECT_FIELD)? field->dthresh : field->thresh);
#endif
if (field->dthresh<=0.0 || field->thresh<=0.0)
error(EXIT_FAILURE,
"*Error*: I cannot deal with zero or negative thresholds!", "");
if (prefs.detect_type == PHOTO
&& field->backmean+3*field->backsig > 50*field->ngamma)
error(EXIT_FAILURE,
"*Error*: The density range of this image is too large for ",
"PHOTO mode");
return;
}
/******************************** backstat **********************************/
/*
Compute robust statistical estimators in a row of meshes.
*/
void backstat(backstruct *backmesh, backstruct *wbackmesh,
PIXTYPE *buf, PIXTYPE *wbuf, size_t bufsize,
int n, int w, int bw, PIXTYPE wthresh)
{
backstruct *bm, *wbm;
double pix,wpix, sig, mean,wmean, sigma,wsigma, step;
PIXTYPE *buft,*wbuft,
lcut,wlcut, hcut,whcut;
int m,h,x,y, npix,wnpix, offset, lastbite;
h = bufsize/w;
bm = backmesh;
wbm = wbackmesh;
offset = w - bw;
step = sqrt(2/PI)*QUANTIF_NSIGMA/QUANTIF_AMIN;
wmean = wsigma = wlcut = whcut = 0.0; /* to avoid gcc -Wall warnings */
for (m = n; m--; bm++,buf+=bw)
{
if (!m && (lastbite=w%bw))
{
bw = lastbite;
offset = w-bw;
}
mean = sigma = 0.0;
buft=buf;
/*-- We separate the weighted case at this level to avoid penalty in CPU */
npix = 0;
if (wbackmesh)
{
wmean = wsigma = 0.0;
wbuft = wbuf;
for (y=h; y--; buft+=offset,wbuft+=offset)
for (x=bw; x--;)
{
pix = *(buft++);
if ((wpix = *(wbuft++)) < wthresh && pix > -BIG)
{
wmean += wpix;
wsigma += wpix*wpix;
mean += pix;
sigma += pix*pix;
npix++;
}
}
}
else
for (y=h; y--; buft+=offset)
for (x=bw; x--;)
if ((pix = *(buft++)) > -BIG)
{
mean += pix;
sigma += pix*pix;
npix++;
}
/*-- If not enough valid pixels, discard this mesh */
if ((float)npix < (float)(bw*h*BACK_MINGOODFRAC))
{
bm->mean = bm->sigma = -BIG;
if (wbackmesh)
{
wbm->mean = wbm->sigma = -BIG;
wbm++;
wbuf += bw;
}
continue;
}
if (wbackmesh)
{
wmean /= (double)npix;
wsigma = (sig = wsigma/npix - wmean*wmean)>0.0? sqrt(sig):0.0;
wlcut = wbm->lcut = (PIXTYPE)(wmean - 2.0*wsigma);
whcut = wbm->hcut = (PIXTYPE)(wmean + 2.0*wsigma);
}
mean /= (double)npix;
sigma = (sig = sigma/npix - mean*mean)>0.0? sqrt(sig):0.0;
lcut = bm->lcut = (PIXTYPE)(mean - 2.0*sigma);
hcut = bm->hcut = (PIXTYPE)(mean + 2.0*sigma);
mean = sigma = 0.0;
npix = wnpix = 0;
buft = buf;
if (wbackmesh)
{
wmean = wsigma = 0.0;
wbuft=wbuf;
for (y=h; y--; buft+=offset, wbuft+=offset)
for (x=bw; x--;)
{
pix = *(buft++);
if ((wpix = *(wbuft++))<wthresh && pix<=hcut && pix>=lcut)
{
mean += pix;
sigma += pix*pix;
npix++;
if (wpix<=whcut && wpix>=wlcut)
{
wmean += wpix;
wsigma += wpix*wpix;
wnpix++;
}
}
}
}
else
for (y=h; y--; buft+=offset)
for (x=bw; x--;)
{
pix = *(buft++);
if (pix<=hcut && pix>=lcut)
{
mean += pix;
sigma += pix*pix;
npix++;
}
}
bm->npix = npix;
mean /= (double)npix;
sig = sigma/npix - mean*mean;
sigma = sig>0.0 ? sqrt(sig):0.0;
bm->mean = mean;
bm->sigma = sigma;
if ((bm->nlevels = (int)(step*npix+1)) > QUANTIF_NMAXLEVELS)
bm->nlevels = QUANTIF_NMAXLEVELS;
bm->qscale = sigma>0.0? 2*QUANTIF_NSIGMA*sigma/bm->nlevels : 1.0;
bm->qzero = mean - QUANTIF_NSIGMA*sigma;
if (wbackmesh)
{
wbm->npix = wnpix;
wmean /= (double)wnpix;
sig = wsigma/wnpix - wmean*wmean;
wsigma = sig>0.0 ? sqrt(sig):0.0;
wbm->mean = wmean;
wbm->sigma = wsigma;
if ((wbm->nlevels = (int)(step*wnpix+1)) > QUANTIF_NMAXLEVELS)
wbm->nlevels = QUANTIF_NMAXLEVELS;
wbm->qscale = wsigma>0.0? 2*QUANTIF_NSIGMA*wsigma/wbm->nlevels : 1.0;
wbm->qzero = wmean - QUANTIF_NSIGMA*wsigma;
wbm++;
wbuf += bw;
}
}
return;
}
/******************************** backhisto *********************************/
/*
Compute robust statistical estimators in a row of meshes.
*/
void backhisto(backstruct *backmesh, backstruct *wbackmesh,
PIXTYPE *buf, PIXTYPE *wbuf, size_t bufsize,
int n, int w, int bw, PIXTYPE wthresh)
{
backstruct *bm,*wbm;
PIXTYPE *buft,*wbuft;
float qscale,wqscale, cste,wcste, wpix;
LONG *histo,*whisto;
int h,m,x,y, nlevels,wnlevels, lastbite, offset, bin;
h = bufsize/w;
bm = backmesh;
wbm = wbackmesh;
offset = w - bw;
for (m=0; m++<n; bm++ , buf+=bw)
{
if (m==n && (lastbite=w%bw))
{
bw = lastbite;
offset = w-bw;
}
/*-- Skip bad meshes */
if (bm->mean <= -BIG)
{
if (wbackmesh)
{
wbm++;
wbuf += bw;
}
continue;
}
nlevels = bm->nlevels;
histo = bm->histo;
qscale = bm->qscale;
cste = 0.499999 - bm->qzero/qscale;
buft = buf;
if (wbackmesh)
{
wnlevels = wbm->nlevels;
whisto = wbm->histo;
wqscale = wbm->qscale;
wcste = 0.499999 - wbm->qzero/wqscale;
wbuft = wbuf;
for (y=h; y--; buft+=offset, wbuft+=offset)
for (x=bw; x--;)
{
bin = (int)(*(buft++)/qscale + cste);
if ((wpix = *(wbuft++))<wthresh && bin<nlevels && bin>=0)
{
(*(histo+bin))++;
bin = (int)(wpix/wqscale + wcste);
if (bin>=0 && bin<wnlevels)
(*(whisto+bin))++;
}
}
wbm++;
wbuf += bw;
}
else
for (y=h; y--; buft += offset)
for (x=bw; x--;)
{
bin = (int)(*(buft++)/qscale + cste);
if (bin>=0 && bin<nlevels)
(*(histo+bin))++;
}
}
return;
}
/******************************* backguess **********************************/
/*
Estimate the background from a histogram;
*/
float backguess(backstruct *bkg, float *mean, float *sigma)
#define EPS (1e-4) /* a small number */
{
LONG *histo, *hilow, *hihigh, *histot;
unsigned long lowsum, highsum, sum;
double ftemp, mea, sig, sig1, med, dpix;
int i, n, lcut,hcut, nlevelsm1, pix;
/* Leave here if the mesh is already classified as `bad' */
if (bkg->mean<=-BIG)
{
*mean = *sigma = -BIG;
return -BIG;
}
histo = bkg->histo;
hcut = nlevelsm1 = bkg->nlevels-1;
lcut = 0;
sig = 10.0*nlevelsm1;
sig1 = 1.0;
mea = med = bkg->mean;
for (n=100; n-- && (sig>=0.1) && (fabs(sig/sig1-1.0)>EPS);)
{
sig1 = sig;
sum = mea = sig = 0.0;
lowsum = highsum = 0;
histot = hilow = histo+lcut;
hihigh = histo+hcut;
for (i=lcut; i<=hcut; i++)
{
if (lowsum<highsum)
lowsum += *(hilow++);
else
highsum += *(hihigh--);
sum += (pix = *(histot++));
mea += (dpix = (double)pix*i);
sig += dpix*i;
}
med = hihigh>=histo?
((hihigh-histo)+0.5+((double)highsum-lowsum)/(2.0*(*hilow>*hihigh?
*hilow:*hihigh)))
: 0.0;
if (sum)
{
mea /= (double)sum;
sig = sig/sum - mea*mea;
}
sig = sig>0.0?sqrt(sig):0.0;
lcut = (ftemp=med-3.0*sig)>0.0 ?(int)(ftemp>0.0?ftemp+0.5:ftemp-0.5):0;
hcut = (ftemp=med+3.0*sig)<nlevelsm1 ?(int)(ftemp>0.0?ftemp+0.5:ftemp-0.5)
: nlevelsm1;
}
*mean = fabs(sig)>0.0? (fabs(bkg->sigma/(sig*bkg->qscale)-1) < 0.0 ?
bkg->qzero+mea*bkg->qscale
:(fabs((mea-med)/sig)< 0.3 ?
bkg->qzero+(2.5*med-1.5*mea)*bkg->qscale
:bkg->qzero+med*bkg->qscale))
:bkg->qzero+mea*bkg->qscale;
*sigma = sig*bkg->qscale;
return *mean;
}
/******************************* filterback *********************************/
/*
Median filtering of the background map to remove the contribution from bright
sources.
*/
void filterback(picstruct *field)
{
float *back,*sigma, *back2,*sigma2, *bmask,*smask, *sigmat,
d2,d2min, fthresh, med, val,sval;
int i,j,px,py, np, nx,ny, npxm,npxp, npym,npyp, dpx,dpy, x,y, nmin;
fthresh = prefs.backfthresh;
nx = field->nbackx;
ny = field->nbacky;
np = field->nback;
npxm = field->nbackfx/2;
npxp = field->nbackfx - npxm;
npym = field->nbackfy/2;
npyp = field->nbackfy - npym;
npym *= nx;
npyp *= nx;
QMALLOC(bmask, float, field->nbackfx*field->nbackfy);
QMALLOC(smask, float, field->nbackfx*field->nbackfy);
QMALLOC(back2, float, np);
QMALLOC(sigma2, float, np);
back = field->back;
sigma = field->sigma;
val = sval = 0.0; /* to avoid gcc -Wall warnings */
/* Look for `bad' meshes and interpolate them if necessary */
for (i=0,py=0; py<ny; py++)
for (px=0; px<nx; px++,i++)
if ((back2[i]=back[i])<=-BIG)
{
/*------ Seek the closest valid mesh */
d2min = BIG;
nmin = 0.0;
for (j=0,y=0; y<ny; y++)
for (x=0; x<nx; x++,j++)
if (back[j]>-BIG)
{
d2 = (float)(x-px)*(x-px)+(y-py)*(y-py);
if (d2<d2min)
{
val = back[j];
sval = sigma[j];
nmin = 1;
d2min = d2;
}
else if (d2==d2min)
{
val += back[j];
sval += sigma[j];
nmin++;
}
}
back2[i] = nmin? val/nmin: 0.0;
sigma[i] = nmin? sval/nmin: 1.0;
}
memcpy(back, back2, (size_t)np*sizeof(float));
/* Do the actual filtering */
for (py=0; py<np; py+=nx)
for (px=0; px<nx; px++)
{
i=0;
for (dpy = -npym; dpy< npyp; dpy+=nx)
for (dpx = -npxm; dpx < npxp; dpx++)
{
y = py+dpy;
x = px+dpx;
if (y>=0 && y<np && x>=0 && x<nx)
{
bmask[i] = back[x+y];
smask[i++] = sigma[x+y];
}
}
if (fabs((med=hmedian(bmask, i))-back[px+py])>=fthresh)
{
back2[px+py] = med;
sigma2[px+py] = hmedian(smask, i);
}
else
{
back2[px+py] = back[px+py];
sigma2[px+py] = sigma[px+py];
}
}
free(bmask);
free(smask);
memcpy(back, back2, np*sizeof(float));
field->backmean = hmedian(back2, np);
free(back2);
memcpy(sigma, sigma2, np*sizeof(float));
field->backsig = hmedian(sigma2, np);
if (field->backsig<=0.0)
{
sigmat = sigma2+np;
for (i=np; i-- && *(--sigmat)>0.0;);
if (i>=0 && i<(np-1))
field->backsig = hmedian(sigmat+1, np-1-i);
else
{
if (field->flags&(DETECT_FIELD|MEASURE_FIELD))
warning("Image contains mainly constant data; ",
"I'll try to cope with that...");
field->backsig = 1.0;
}
}
free(sigma2);
return;
}
/******************************** localback *********************************/
/*
Compute Local background if possible.
*/
float localback(picstruct *field, objstruct *obj)
{
static backstruct backmesh;
int bxmin,bxmax, bymin,bymax, ixmin,ixmax, iymin,iymax,
bxnml,bynml, oxsize,oysize, npix,
i, x,y, bin, w,sh, bmn, pbs;
float bkg, bqs,cste;
LONG *bmh;
PIXTYPE *backpix, *bp, *strip, *st,
pix;
strip = field->strip;
w = field->width;
sh = field->stripheight;
pbs = prefs.pback_size;
/* Estimate background in a 'rectangular annulus' around the object */
oxsize = obj->xmax - obj->xmin + 1;
oysize = obj->ymax - obj->ymin + 1;
bxnml = oxsize<w/2? oxsize/4 : (w-oxsize)/4;
bynml = oysize<field->height/2? oysize/4 : (field->height-oysize)/4;
bxmin = (ixmin = obj->xmin - bxnml) - pbs;
bxmax = (ixmax = obj->xmax+1 + bxnml) + pbs;
bymin = (iymin = obj->ymin - bynml) - pbs;
bymax = (iymax = obj->ymax+1 + bynml) + pbs;
if (bymin>=field->ymin && bymax<field->ymax
&& bxmin>=0 && bxmax<w)
{
npix = (bxmax-bxmin)*(bymax-bymin) - (ixmax-ixmin)*(iymax-iymin);
QMALLOC(backpix, PIXTYPE, npix);
bp = backpix;
/*--store all the pixels*/
npix = 0;
for (y=bymin; y<bymax; y++)
{
st = strip + (y%sh)*w + bxmin;
for (x=pbs; x--;)
if ((pix=*(st++))>-BIG)
{
*(bp++) = pix;
npix++;
}
st += ixmax-ixmin;
for (x=pbs; x--;)
if ((pix=*(st++))>-BIG)
{
*(bp++) = pix;
npix++;
}
}
for (y=bymin; y<iymin; y++)
{
st = strip + (y%sh)*w + ixmin;
for (x=ixmax-ixmin; x--;)
if ((pix=*(st++))>-BIG)
{
*(bp++) = pix;
npix++;
}
}
for (y=iymax; y<bymax; y++)
{
st = strip + (y%sh)*w + ixmin;
for (x=ixmax-ixmin; x--;)
if ((pix=*(st++))>-BIG)
{
*(bp++) = pix;
npix++;
}
}
if (npix)
{
backstat(&backmesh, NULL, backpix, NULL, npix, 1, 1, 1, 0.0);
QCALLOC(backmesh.histo, LONG, backmesh.nlevels);
bmh = backmesh.histo;
bmn = backmesh.nlevels;
cste = 0.499999 - backmesh.qzero/(bqs = backmesh.qscale);
bp = backpix;
for (i=npix; i--;)
{
bin = (int)(*(bp++)/bqs + cste);
if (bin>=0 && bin<bmn)
(*(bmh+bin))++;
}
backguess(&backmesh, &bkg, &obj->sigbkg);
obj->bkg += (obj->dbkg = bkg);
free(backmesh.histo);
}
else
{
obj->dbkg = 0.0;
obj->sigbkg = field->backsig;
}
free(backpix);
}
else
{
obj->dbkg = bkg = 0.0;
obj->sigbkg = field->backsig;
}
return bkg;
}
/************************************ back ***********************************/
/*
return background at position x,y (linear interpolation between background
map vertices).
*/
PIXTYPE back(picstruct *field, int x, int y)
{
int nx,ny, xl,yl, pos;
double dx,dy, cdx;
float *b, b0,b1,b2,b3;
b = field->back;
nx = field->nbackx;
ny = field->nbacky;
dx = (double)x/field->backw - 0.5;
dy = (double)y/field->backh - 0.5;
dx -= (xl = (int)dx);
dy -= (yl = (int)dy);
if (xl<0)
{
xl = 0;
dx -= 1.0;
}
else if (xl>=nx-1)
{
xl = nx<2 ? 0 : nx-2;
dx += 1.0;
}
if (yl<0)
{
yl = 0;
dy -= 1.0;
}
else if (yl>=ny-1)
{
yl = ny<2 ? 0 : ny-2;
dy += 1.0;
}
pos = yl*nx + xl;
cdx = 1 - dx;
b0 = *(b+=pos); /* consider when nbackx or nbacky = 1 */
b1 = nx<2? b0:*(++b);
b2 = ny<2? *b:*(b+=nx);
b3 = nx<2? *b:*(--b);
return (PIXTYPE)((1-dy)*(cdx*b0 + dx*b1) + dy*(dx*b2 + cdx*b3));
}
/******************************* makebackspline ******************************/
/*
Pre-compute 2nd derivatives along the y direction at background nodes.
*/
float *makebackspline(picstruct *field, float *map)
{
int x,y, nbx,nby,nbym1;
float *dmap,*dmapt,*mapt, *u, temp;
nbx = field->nbackx;
nby = field->nbacky;
nbym1 = nby - 1;
QMALLOC(dmap, float, field->nback);
for (x=0; x<nbx; x++)
{
mapt = map+x;
dmapt = dmap+x;
if (nby>1)
{
QMALLOC(u, float, nbym1); /* temporary array */
*dmapt = *u = 0.0; /* "natural" lower boundary condition */
mapt += nbx;
for (y=1; y<nbym1; y++, mapt+=nbx)
{
temp = -1/(*dmapt+4);
*(dmapt += nbx) = temp;
temp *= *(u++) - 6*(*(mapt+nbx)+*(mapt-nbx)-2**mapt);
*u = temp;
}
*(dmapt+=nbx) = 0.0; /* "natural" upper boundary condition */
for (y=nby-2; y--;)
{
temp = *dmapt;
dmapt -= nbx;
*dmapt = (*dmapt*temp+*(u--))/6.0;
}
free(u);
}
else
*dmapt = 0.0;
}
return dmap;
}
/******************************* subbackline *********************************/
/*
Interpolate background at line y (bicubic spline interpolation between
background map vertices) and subtract it from the current line.
*/
void subbackline(picstruct *field, int y, PIXTYPE *line)
{
int i,j,x,yl, nbx,nbxm1,nby, nx,width, ystep, changepoint;
float dx,dx0,dy,dy3, cdx,cdy,cdy3, temp, xstep,
*node,*nodep,*dnode, *blo,*bhi,*dblo,*dbhi, *u;
PIXTYPE *backline, bval;
width = field->width;
backline = field->backline;
if (field->back_type==BACK_ABSOLUTE)
{
/*-- In absolute background mode, just subtract a cste */
bval = field->backmean;
for (i=width; i--;)
*(line++) -= ((*backline++)=bval);
return;
}
nbx = field->nbackx;
nbxm1 = nbx - 1;
nby = field->nbacky;
if (nby > 1)
{
dy = (float)y/field->backh - 0.5;
dy -= (yl = (int)dy);
if (yl<0)
{
yl = 0;
dy -= 1.0;
}
else if (yl>=nby-1)
{
yl = nby<2 ? 0 : nby-2;
dy += 1.0;
}
/*-- Interpolation along y for each node */
cdy = 1 - dy;
dy3 = (dy*dy*dy-dy);
cdy3 = (cdy*cdy*cdy-cdy);
ystep = nbx*yl;
blo = field->back + ystep;
bhi = blo + nbx;
dblo = field->dback + ystep;
dbhi = dblo + nbx;
QMALLOC(node, float, nbx); /* Interpolated background */
nodep = node;
for (x=nbx; x--;)
*(nodep++) = cdy**(blo++) + dy**(bhi++) + cdy3**(dblo++) + dy3**(dbhi++);
/*-- Computation of 2nd derivatives along x */
QMALLOC(dnode, float, nbx); /* 2nd derivative along x */
if (nbx>1)
{
QMALLOC(u, float, nbxm1); /* temporary array */
*dnode = *u = 0.0; /* "natural" lower boundary condition */
nodep = node+1;
for (x=nbxm1; --x; nodep++)
{
temp = -1/(*(dnode++)+4);
*dnode = temp;
temp *= *(u++) - 6*(*(nodep+1)+*(nodep-1)-2**nodep);
*u = temp;
}
*(++dnode) = 0.0; /* "natural" upper boundary condition */
for (x=nbx-2; x--;)
{
temp = *(dnode--);
*dnode = (*dnode*temp+*(u--))/6.0;
}
free(u);
dnode--;
}
}
else
{
/*-- No interpolation and no new 2nd derivatives needed along y */
node = field->back;
dnode = field->dback;
}
/*-- Interpolation along x */
if (nbx>1)
{
nx = field->backw;
xstep = 1.0/nx;
changepoint = nx/2;
dx = (xstep - 1)/2; /* dx of the first pixel in the row */
dx0 = ((nx+1)%2)*xstep/2; /* dx of the 1st pixel right to a bkgnd node */
blo = node;
bhi = node + 1;
dblo = dnode;
dbhi = dnode + 1;
for (x=i=0,j=width; j--; i++, dx += xstep)
{
if (i==changepoint && x>0 && x<nbxm1)
{
blo++;
bhi++;
dblo++;
dbhi++;
dx = dx0;
}
cdx = 1 - dx;
*(line++) -= (*(backline++) = (PIXTYPE)(cdx*(*blo+(cdx*cdx-1)**dblo)
+ dx*(*bhi+(dx*dx-1)**dbhi)));
if (i==nx)
{
x++;
i = 0;
}
}
}
else
for (j=width; j--;)
*(line++) -= (*(backline++) = (PIXTYPE)*node);
if (nby>1)
{
free(node);
free(dnode);
}
return;
}
/******************************* backrmsline ********************************
PROTO void backrmsline(picstruct *field, int y, PIXTYPE *line)
PURPOSE Bicubic-spline interpolation of the background noise along the current
scanline (y).
INPUT Measurement or detection field pointer,
Current line position.
Where to put the data.
OUTPUT -.
NOTES Most of the code is a copy of subbackline(), for optimization reasons.
AUTHOR E. Bertin (IAP & Leiden & ESO)
VERSION 02/02/98
***/
void backrmsline(picstruct *field, int y, PIXTYPE *line)
{
int i,j,x,yl, nbx,nbxm1,nby, nx,width, ystep, changepoint;
float dx,dx0,dy,dy3, cdx,cdy,cdy3, temp, xstep,
*node,*nodep,*dnode, *blo,*bhi,*dblo,*dbhi, *u;
nbx = field->nbackx;
nbxm1 = nbx - 1;
nby = field->nbacky;
if (nby > 1)
{
dy = (float)y/field->backh - 0.5;
dy -= (yl = (int)dy);
if (yl<0)
{
yl = 0;
dy -= 1.0;
}
else if (yl>=nby-1)
{
yl = nby<2 ? 0 : nby-2;
dy += 1.0;
}
/*-- Interpolation along y for each node */
cdy = 1 - dy;
dy3 = (dy*dy*dy-dy);
cdy3 = (cdy*cdy*cdy-cdy);
ystep = nbx*yl;
blo = field->sigma + ystep;
bhi = blo + nbx;
dblo = field->dsigma + ystep;
dbhi = dblo + nbx;
QMALLOC(node, float, nbx); /* Interpolated background */
nodep = node;
for (x=nbx; x--;)
*(nodep++) = cdy**(blo++) + dy**(bhi++) + cdy3**(dblo++) + dy3**(dbhi++);
/*-- Computation of 2nd derivatives along x */
QMALLOC(dnode, float, nbx); /* 2nd derivative along x */
if (nbx>1)
{
QMALLOC(u, float, nbxm1); /* temporary array */
*dnode = *u = 0.0; /* "natural" lower boundary condition */
nodep = node+1;
for (x=nbxm1; --x; nodep++)
{
temp = -1/(*(dnode++)+4);
*dnode = temp;
temp *= *(u++) - 6*(*(nodep+1)+*(nodep-1)-2**nodep);
*u = temp;
}
*(++dnode) = 0.0; /* "natural" upper boundary condition */
for (x=nbx-2; x--;)
{
temp = *(dnode--);
*dnode = (*dnode*temp+*(u--))/6.0;
}
free(u);
dnode--;
}
}
else
{
/*-- No interpolation and no new 2nd derivatives needed along y */
node = field->sigma;
dnode = field->dsigma;
}
/*-- Interpolation along x */
width = field->width;
if (nbx>1)
{
nx = field->backw;
xstep = 1.0/nx;
changepoint = nx/2;
dx = (xstep - 1)/2; /* dx of the first pixel in the row */
dx0 = ((nx+1)%2)*xstep/2; /* dx of the 1st pixel right to a bkgnd node */
blo = node;
bhi = node + 1;
dblo = dnode;
dbhi = dnode + 1;
for (x=i=0,j=width; j--; i++, dx += xstep)
{
if (i==changepoint && x>0 && x<nbxm1)
{
blo++;
bhi++;
dblo++;
dbhi++;
dx = dx0;
}
cdx = 1 - dx;
*(line++) = (PIXTYPE)(cdx*(*blo+(cdx*cdx-1)**dblo)
+ dx*(*bhi+(dx*dx-1)**dbhi));
if (i==nx)
{
x++;
i = 0;
}
}
}
else
for (j=width; j--;)
*(line++) = (PIXTYPE)*node;
if (nby>1)
{
free(node);
free(dnode);
}
return;
}
/********************************* copyback **********************************/
/*
Copy sub-structures related to background procedures (mainly freeing memory).
*/
void copyback(picstruct *infield, picstruct *outfield)
{
QMEMCPY(infield->back, outfield->back, float, infield->nback);
QMEMCPY(infield->dback, outfield->dback, float, infield->nback);
QMEMCPY(infield->sigma, outfield->sigma, float, infield->nback);
QMEMCPY(infield->dsigma, outfield->dsigma, float, infield->nback);
QMEMCPY(infield->backline, outfield->backline, PIXTYPE, infield->width);
return;
}
/********************************* endback ***********************************/
/*
Terminate background procedures (mainly freeing memory).
*/
void endback(picstruct *field)
{
free(field->back);
free(field->dback);
free(field->sigma);
free(field->dsigma);
free(field->backline);
return;
}
/*
back.h
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN (IAP)
*
* Contents: functions dealing with background computation.
*
* Last modify: 02/05/99
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
/*----------------------------- Internal constants --------------------------*/
#define BACK_BUFSIZE 1048576 /* bkgnd buffer */
#define BACK_MINGOODFRAC 0.5 /* min frac with good weights*/
#define QUANTIF_NSIGMA 5 /* histogram limits */
#define QUANTIF_NMAXLEVELS 4096 /* max nb of quantif. levels */
#define QUANTIF_AMIN 4 /* min nb of "mode pixels" */
/* NOTES:
One must have: BACK_BUFSIZE >= MAXPICSIZE
0 < QUANTIF_NSIGMA <= 10
QUANTIF_AMIN > 0
*/
/*------------------------------- structures --------------------------------*/
/* Background info */
typedef struct structback
{
float mode, mean, sigma; /* Background mode, mean and sigma */
LONG *histo; /* Pointer to a histogram */
int nlevels; /* Nb of histogram bins */
float qzero, qscale; /* Position of histogram */
float lcut, hcut; /* Histogram cuts */
int npix; /* Number of pixels involved */
} backstruct;
/*------------------------------- functions ---------------------------------*/
void backhisto(backstruct *, backstruct *, PIXTYPE *, PIXTYPE *,
size_t, int, int, int, PIXTYPE),
backstat(backstruct *, backstruct *, PIXTYPE *, PIXTYPE *,
size_t, int, int, int, PIXTYPE),
backrmsline(picstruct *, int, PIXTYPE *),
copyback(picstruct *infield, picstruct *outfield),
endback(picstruct *),
filterback(picstruct *),
makeback(picstruct *, picstruct *),
subbackline(picstruct *, int, PIXTYPE *);
float backguess(backstruct *, float *, float *),
localback(picstruct *, objstruct *),
*makebackspline(picstruct *, float *);
extern PIXTYPE back(picstruct *, int, int);
/*
bpro.c
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: Any back-propagation-ANN-oriented software
*
* Author: E.BERTIN (IAP)
*
* Contents: Routines for BP-neural network management ("read-only"
* mode).
*
* Requirements: The LDACTools.
*
* Last modify: 13/12/2002
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
#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"
#include "bpro.h"
/******************************** play_bpann *********************************/
/*
Single forward pass through the ANN.
*/
void play_bpann(bpannstruct *bpann, NFLOAT *invec, NFLOAT *outvec)
{
NFLOAT u, *neuroni,*neuronj, *weight;
int i,j,l,lp,ll, lflag;
ll = bpann->nlayers-1;
memcpy(bpann->neuron[0], invec, bpann->nn[0]*sizeof(float));
lflag = bpann->linearoutflag;
for (lp=0,l=1; lp<ll; l++, lp++)
{
neuronj = bpann->neuron[l];
weight = bpann->weight[lp];
for (j=bpann->nn[l]; j--; neuronj++)
{ /* note we don't touch the "bias" neuron (=-1) */
neuroni = bpann->neuron[lp];
u = *(weight++)**(neuroni++);
for (i=bpann->nn[lp]; i--;) /* The last one is the bias */
u += *(weight++)**(neuroni++);
if (l == ll)
*(outvec++)= lflag?u:SIGMOID(u);
else
*neuronj = SIGMOID(u);
}
}
return;
}
/******************************* loadtab_bpann *******************************/
/*
Load the relevant ANN structure (using the LDACTools).
*/
bpannstruct *loadtab_bpann(tabstruct *tab, char *filename)
{
bpannstruct *bpann;
keystruct *key;
char *head, str[80];
int l;
/* OK, we now allocate memory for the ANN structure itself */
QCALLOC(bpann, bpannstruct, 1);
/* Load important scalars (which are stored as FITS keywords) */
head = tab->headbuf;
if (fitsread(head, "BPNLAYER", &bpann->nlayers, H_INT, T_LONG) != RETURN_OK)
error(EXIT_FAILURE, "*Error*: incorrect BP-ANN header in ", filename);
if (fitsread(head, "BPLINEAR",&bpann->linearoutflag, H_INT,T_LONG)!=RETURN_OK)
bpann->linearoutflag = 0;
/* Load all vectors!! */
read_keys(tab, NULL, NULL, 0, NULL);
/* Now interpret the result */
if (!(key = name_to_key(tab, "NNEUR_PER_LAYER")))
error(EXIT_FAILURE, "*Error*: incorrect BP-ANN header in ", filename);
bpann->nn = key->ptr; key->ptr = 0;
QMALLOC(bpann->neuron, NFLOAT *, bpann->nlayers);
QMALLOC(bpann->weight, NFLOAT *, bpann->nlayers-1);
for (l=0; l<bpann->nlayers-1; l++)
{
QMALLOC(bpann->neuron[l], NFLOAT, bpann->nn[l]+1);
bpann->neuron[l][bpann->nn[l]] = -1.0;
sprintf(str, "WEIGHT_LAYER%d", l+1);
if (!(key = name_to_key(tab, str)))
error(EXIT_FAILURE, "*Error*: incorrect BP-ANN header in ", filename);
bpann->weight[l] = key->ptr; key->ptr = 0;
}
QMALLOC(bpann->neuron[l], NFLOAT, bpann->nn[l]); /* no bias in this layer */
return bpann;
}
/******************************** free_bpann *********************************/
/*
Free all memory modules allocated for a Back-Propagation ANN structure.*/
void free_bpann(bpannstruct *bpann)
{
int i;
/* Loop over the "true" layers */
for (i=0; i<bpann->nlayers-1; i++)
{
free(bpann->neuron[i]);
free(bpann->weight[i]);
}
free(bpann->neuron[i]); /* Because of the input layer */
/* Then free pointers of pointers */
free(bpann->neuron);
free(bpann->weight);
free(bpann->nn);
/* And finally free the ANN structure itself */
free(bpann);
return;
}
/*
bpro.h
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: Any back-propagation-ANN-oriented software
*
* Author: E.BERTIN, IAP/LDAC
*
* Contents: Routines for BP-neural network management ("read-only"
* mode).
*
* Requirements: The LDACTools.
*
* Last modify: 08/10/96
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
/*------------------------------- definitions -------------------------------*/
#define SIGMOID(u) ((u)<15.0?((u)>-15.0?1/(1+exp(-(u))):0.0):1.0)
/* In-line activation function */
/*---------------------------------- types ----------------------------------*/
typedef float NFLOAT; /* Floating point units for neural data */
/*------------------------------- structures --------------------------------*/
typedef struct structbpann
{
int nlayers; /* Number of "active" layers */
int *nn; /* Nb of neurons per "active" layer */
/*------ The ANN itself */
NFLOAT **neuron; /* Neuron array (layer,pos in layer) */
NFLOAT **weight; /* Weight array (layer,pos in layer) */
int linearoutflag; /* Flag: 0 if outputs are non-linear */
} bpannstruct;
/*------------------------------ Prototypes ---------------------------------*/
bpannstruct *loadtab_bpann(tabstruct *tab, char *filename);
void free_bpann(bpannstruct *bpann),
play_bpann(bpannstruct *bpann, NFLOAT *invec, NFLOAT *outvec);
/*
catout.c
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN (IAP)
*
* Contents: functions for output of catalog data.
*
* Last modify: 13/07/2006
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
#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 "prefs.h"
#include "fits/fitscat.h"
#include "param.h"
#include "sexhead.h"
#include "sexhead1.h"
#include "sexheadsc.h"
#include "xml.h"
catstruct *fitscat;
tabstruct *objtab = NULL;
FILE *ascfile;
char *buf;
int catopen_flag = 0;
/******************************* readcatparams *******************************/
/*
Read the catalog config file
*/
void readcatparams(char *filename)
{
keystruct *key;
FILE *infile;
char str[MAXCHAR], *keyword, *sstr;
int i, size;
/* Prepare the OBJECTS tables*/
objtab = new_tab("OBJECTS");
if ((infile = fopen(filename,"r")) == NULL)
error(EXIT_FAILURE, "*ERROR*: can't read ", filename);
/* Scan the catalog config file*/
thecat.nparam = 0;
while (fgets(str, MAXCHAR, infile))
{
sstr = str + strspn(str," \t");
if (*sstr!=(char)'#' && *sstr!=(char)'\n')
{
keyword = strtok(sstr, " \t{[(\n\r");
if (keyword &&
(i = findkey(keyword,(char *)objkey,sizeof(keystruct)))!=RETURN_ERROR)
{
key = objkey+i;
add_key(key, objtab, 0);
*((char *)key->ptr) = (char)'\1';
thecat.nparam++;
if (key->naxis)
{
for (i=0; i<key->naxis; i++)
key->naxisn[i] = 1;
size=t_size[key->ttype];
for (i=0; (sstr = strtok(NULL, " \t,;.)]}\r")) && *sstr!=(char)'#'
&& *sstr!=(char)'\n'; i++)
{
if (i>=key->naxis)
error(EXIT_FAILURE, "*Error*: too many dimensions for keyword ",
keyword);
if (!(size*=(key->naxisn[i]=atoi(sstr))))
error(EXIT_FAILURE, "*Error*: wrong array syntax for keyword ",
keyword);
}
key->nbytes = size;
}
}
else
warning(keyword, " catalog parameter unknown");
}
}
fclose(infile);
/* Now we copy the flags to the proper structures */
flagobj = outobj;
flagobj2 = outobj2;
/* Differentiate between outobj and outobj2 vectors */
memset(&outobj2, 0, sizeof(outobj2));
updateparamflags();
/* Go back to multi-dimensional arrays for memory allocation */
if (thecat.nparam)
for (i=objtab->nkey, key=objtab->key; i--; key = key->nextkey)
if (key->naxis)
{
/*------ Only outobj2 vectors are dynamic */
if (!*((char **)key->ptr))
{
QMALLOC(*((char **)key->ptr), char, key->nbytes);
key->ptr = *((char **)key->ptr);
key->allocflag = 1;
}
}
return;
}
/***************************** updateparamflags ******************************/
/*
Update parameter flags according to their mutual dependencies.
*/
void updateparamflags()
{
int i;
/*------------------------------ Astrometry ---------------------------------*/
FLAG(obj2.win_aw) |= FLAG(obj2.win_bw) | FLAG(obj2.win_polarw);
FLAG(obj2.win_cxxw) |= FLAG(obj2.win_cyyw) | FLAG(obj2.win_cxyw);
FLAG(obj2.win_thetas) |= FLAG(obj2.win_theta1950)
| FLAG(obj2.win_theta2000);
FLAG(obj2.win_thetaw) |= FLAG(obj2.win_thetas);
FLAG(obj2.win_mx2w) |= FLAG(obj2.win_my2w)
| FLAG(obj2.win_mxyw)
| FLAG(obj2.win_thetaw) | FLAG(obj2.win_aw)
| FLAG(obj2.win_cxxw);
FLAG(obj2.win_a) |= FLAG(obj2.win_b) | FLAG(obj2.win_theta)
| FLAG(obj2.win_polar) | FLAG(obj2.win_aw);
FLAG(obj2.win_cxx) |= FLAG(obj2.win_cyy)
| FLAG(obj2.win_cxy) | FLAG(obj2.win_cxxw);
FLAG(obj2.win_mx2) |= FLAG(obj2.win_my2)
| FLAG(obj2.win_mxy)
| FLAG(obj2.win_a) | FLAG(obj2.win_cxx)
| FLAG(obj2.win_mx2w);
FLAG(obj2.winposerr_aw) |= FLAG(obj2.winposerr_bw);
FLAG(obj2.winposerr_cxxw) |= FLAG(obj2.winposerr_cyyw)
| FLAG(obj2.winposerr_cxyw);
FLAG(obj2.winposerr_thetas) |= FLAG(obj2.winposerr_theta1950)
| FLAG(obj2.winposerr_theta2000);
FLAG(obj2.winposerr_thetaw) |= FLAG(obj2.winposerr_thetas);
FLAG(obj2.winposerr_mx2w) |= FLAG(obj2.winposerr_my2w)
| FLAG(obj2.winposerr_mxyw)
| FLAG(obj2.winposerr_thetaw) | FLAG(obj2.winposerr_aw)
| FLAG(obj2.winposerr_cxxw);
FLAG(obj2.winposerr_a) |= FLAG(obj2.winposerr_b) | FLAG(obj2.winposerr_theta);
FLAG(obj2.winposerr_cxx) |= FLAG(obj2.winposerr_cyy)
| FLAG(obj2.winposerr_cxy);
FLAG(obj2.winposerr_mx2) |= FLAG(obj2.winposerr_my2)
| FLAG(obj2.winposerr_mxy)
| FLAG(obj2.winposerr_a) | FLAG(obj2.winposerr_cxx)
| FLAG(obj2.winposerr_mx2w);
FLAG(obj2.winpos_alpha1950) |= FLAG(obj2.winpos_delta1950)
| FLAG(obj2.win_theta1950)
| FLAG(obj2.winposerr_theta1950);
FLAG(obj2.winpos_alpha2000) |= FLAG(obj2.winpos_delta2000)
| FLAG(obj2.winpos_alpha1950)
| FLAG(obj2.win_theta2000)
| FLAG(obj2.winposerr_theta2000);
FLAG(obj2.winpos_alphas) |= FLAG(obj2.winpos_deltas)
| FLAG(obj2.winpos_alpha2000);
FLAG(obj2.winpos_xw) |= FLAG(obj2.winpos_yw)
| FLAG(obj2.winpos_alphas);
FLAG(obj2.poserr_aw) |= FLAG(obj2.poserr_bw);
FLAG(obj2.poserr_cxxw) |= FLAG(obj2.poserr_cyyw) | FLAG(obj2.poserr_cxyw);
FLAG(obj2.poserr_thetas) |= FLAG(obj2.poserr_theta1950)
| FLAG(obj2.poserr_theta2000);
FLAG(obj2.poserr_thetaw) |= FLAG(obj2.poserr_thetas);
FLAG(obj2.poserr_mx2w) |= FLAG(obj2.poserr_my2w) | FLAG(obj2.poserr_mxyw)
| FLAG(obj2.poserr_thetaw) | FLAG(obj2.poserr_aw)
| FLAG(obj2.poserr_cxxw);
FLAG(obj2.poserr_a) |= FLAG(obj2.poserr_b) | FLAG(obj2.poserr_theta)
| FLAG(obj2.winposerr_a);
FLAG(obj2.poserr_cxx) |= FLAG(obj2.poserr_cyy) | FLAG(obj2.poserr_cxy);
FLAG(obj.poserr_mx2) |= FLAG(obj.poserr_my2) | FLAG(obj.poserr_mxy)
| FLAG(obj2.poserr_a) | FLAG(obj2.poserr_cxx)
| FLAG(obj2.poserr_mx2w) | FLAG(obj2.winposerr_mx2);
FLAG(obj2.peakalpha1950) |= FLAG(obj2.peakdelta1950);
FLAG(obj2.alpha1950) |= FLAG(obj2.delta1950) | FLAG(obj2.theta1950)
| FLAG(obj2.poserr_theta1950);
FLAG(obj2.peakalpha2000) |= FLAG(obj2.peakdelta2000)
| FLAG(obj2.peakalpha1950);
FLAG(obj2.alpha2000) |= FLAG(obj2.delta2000) | FLAG(obj2.alpha1950)
| FLAG(obj2.theta2000)
| FLAG(obj2.poserr_theta2000);
FLAG(obj2.peakalphas) |= FLAG(obj2.peakdeltas) | FLAG(obj2.peakalpha2000);
FLAG(obj2.alphas) |= FLAG(obj2.deltas) | FLAG(obj2.alpha2000);
FLAG(obj2.thetas) |= FLAG(obj2.theta1950) | FLAG(obj2.theta2000);
FLAG(obj2.thetaw) |= FLAG(obj2.thetas);
FLAG(obj2.aw) |= FLAG(obj2.bw) | FLAG(obj2.polarw);
FLAG(obj2.cxxw) |= FLAG(obj2.cyyw) | FLAG(obj2.cxyw);
FLAG(obj2.mx2w) |= FLAG(obj2.my2w) | FLAG(obj2.mxyw)
| FLAG(obj2.thetaw) | FLAG(obj2.aw) | FLAG(obj2.cxxw)
| FLAG(obj2.npixw) | FLAG(obj2.fdnpixw)
| FLAG(obj2.fwhmw);
FLAG(obj2.peakxw) |= FLAG(obj2.peakyw) | FLAG(obj2.peakalphas);
FLAG(obj.peakx) |= FLAG(obj.peaky) | FLAG(obj2.peakxw);
FLAG(obj2.mxw) |= FLAG(obj2.myw) | FLAG(obj2.mx2w) | FLAG(obj2.alphas)
| FLAG(obj2.poserr_mx2w);
FLAG(obj2.mamaposx) |= FLAG(obj2.mamaposy);
FLAG(obj2.flux_win) |= FLAG(obj2.mag_win)|FLAG(obj2.magerr_win)
| FLAG(obj2.flux_win) | FLAG(obj2.fluxerr_win);
FLAG(obj2.winpos_x) |= FLAG(obj2.winpos_y)
| FLAG(obj2.winposerr_mx2) | FLAG(obj2.win_mx2)
| FLAG(obj2.winpos_xw) | FLAG(obj2.win_flag)
| FLAG(obj2.flux_win) |FLAG(obj2.winpos_niter);
/*------------------------------ Photometry ---------------------------------*/
FLAG(obj2.fluxerr_best) |= FLAG(obj2.magerr_best);
FLAG(obj2.flux_best) |= FLAG(obj2.mag_best) | FLAG(obj2.fluxerr_best);
FLAG(obj2.hl_radius) |= FLAG(obj2.winpos_x);
FLAG(obj2.flux_auto) |= FLAG(obj2.mag_auto) | FLAG(obj2.magerr_auto)
| FLAG(obj2.fluxerr_auto)
| FLAG(obj2.kronfactor)
| FLAG(obj2.flux_best)
| FLAG(obj2.flux_radius)
| FLAG(obj2.hl_radius);
FLAG(obj2.flux_petro) |= FLAG(obj2.mag_petro) | FLAG(obj2.magerr_petro)
| FLAG(obj2.fluxerr_petro)
| FLAG(obj2.petrofactor);
FLAG(obj2.fluxerr_isocor) |= FLAG(obj2.magerr_isocor)
| FLAG(obj2.fluxerr_best);
FLAG(obj2.flux_isocor) |= FLAG(obj2.mag_isocor) | FLAG(obj2.fluxerr_isocor)
| FLAG(obj2.flux_best);
FLAG(obj2.flux_aper) |= FLAG(obj2.mag_aper)|FLAG(obj2.magerr_aper)
| FLAG(obj2.fluxerr_aper);
FLAG(obj.flux_prof) |= FLAG(obj2.mag_prof)|FLAG(obj2.magerr_prof)
| FLAG(obj2.flux_prof) | FLAG(obj2.fluxerr_prof);
FLAG(obj2.flux_galfit) |= FLAG(obj2.mag_galfit) | FLAG(obj2.magerr_galfit)
| FLAG(obj2.fluxerr_galfit);
/*---------------------------- External flags -------------------------------*/
VECFLAG(obj.imaflag) |= VECFLAG(obj.imanflag);
/*------------------------------ PSF-fitting --------------------------------*/
FLAG(obj2.poserraw_psf) |= FLAG(obj2.poserrbw_psf);
FLAG(obj2.poserrcxxw_psf) |= FLAG(obj2.poserrcyyw_psf)
| FLAG(obj2.poserrcxyw_psf);
FLAG(obj2.poserrthetas_psf) |= FLAG(obj2.poserrtheta1950_psf)
| FLAG(obj2.poserrtheta2000_psf);
FLAG(obj2.poserrthetaw_psf) |= FLAG(obj2.poserrthetas_psf);
FLAG(obj2.poserrmx2w_psf) |= FLAG(obj2.poserrmy2w_psf)
| FLAG(obj2.poserrmxyw_psf)
| FLAG(obj2.poserrthetaw_psf) | FLAG(obj2.poserraw_psf)
| FLAG(obj2.poserrcxxw_psf);
FLAG(obj2.poserra_psf) |= FLAG(obj2.poserrb_psf)
| FLAG(obj2.poserrtheta_psf);
FLAG(obj2.poserrcxx_psf) |= FLAG(obj2.poserrcyy_psf)
| FLAG(obj2.poserrcxy_psf);
FLAG(obj2.poserrmx2_psf) |= FLAG(obj2.poserrmy2_psf)
| FLAG(obj2.poserrmxy_psf)
| FLAG(obj2.poserra_psf) | FLAG(obj2.poserrcxx_psf)
| FLAG(obj2.poserrmx2w_psf);
FLAG(obj2.alpha1950_psf) |= FLAG(obj2.delta1950_psf)
| FLAG(obj2.poserrtheta1950_psf);
FLAG(obj2.alpha2000_psf) |= FLAG(obj2.delta2000_psf)
| FLAG(obj2.alpha1950_psf)
| FLAG(obj2.poserrtheta2000_psf);
FLAG(obj2.alphas_psf) |= FLAG(obj2.deltas_psf) | FLAG(obj2.alpha2000_psf);
FLAG(obj2.xw_psf) |= FLAG(obj2.yw_psf) | FLAG(obj2.poserrmx2w_psf)
| FLAG(obj2.alphas_psf);
FLAG(obj2.fluxerr_psf) |= FLAG(obj2.poserrmx2_psf) | FLAG(obj2.magerr_psf);
FLAG(obj2.mx2_pc) |= FLAG(obj2.my2_pc) | FLAG(obj2.mxy_pc)
| FLAG(obj2.a_pc) | FLAG(obj2.b_pc)
| FLAG(obj2.theta_pc) | FLAG(obj2.vector_pc)
| FLAG(obj2.gdposang) | FLAG(obj2.gdscale)
| FLAG(obj2.gdaspect) | FLAG(obj2.flux_galfit)
| FLAG(obj2.gde1) | FLAG(obj2.gde2)
| FLAG(obj2.gbposang) | FLAG(obj2.gbscale)
| FLAG(obj2.gbaspect) | FLAG(obj2.gbratio);
FLAG(obj2.flux_psf) |= FLAG(obj2.mag_psf) | FLAG(obj2.x_psf)
| FLAG(obj2.y_psf) | FLAG(obj2.xw_psf)
| FLAG(obj2.fluxerr_psf)
| FLAG(obj2.niter_psf)
| FLAG(obj2.chi2_psf)
| FLAG(obj2.mx2_pc);
/*-------------------------------- Others -----------------------------------*/
FLAG(obj.fwhm) |= FLAG(obj2.fwhmw);
FLAG(obj.iso[0]) |= FLAG(obj2.sprob);
for (i=0; i<NISO; i++)
FLAG(obj.iso[0]) |= FLAG(obj.iso[i]);
return;
}
/********************************** initcat **********************************/
/*
Initialize the catalog header
*/
void initcat(void)
{
keystruct *key;
int i, n;
if (prefs.cat_type == CAT_NONE)
return;
update_tab(objtab);
if (prefs.cat_type == ASCII_HEAD || prefs.cat_type == ASCII ||
prefs.cat_type == ASCII_SKYCAT || prefs.cat_type == ASCII_VO)
{
if (prefs.pipe_flag)
ascfile = stdout;
else
if (!(ascfile = fopen(prefs.cat_name, "w+")))
error(EXIT_FAILURE,"*Error*: cannot open ", prefs.cat_name);
if (prefs.cat_type == ASCII_HEAD && (key = objtab->key))
for (i=0,n=1; i++<objtab->nkey; key=key->nextkey)
{
if (*key->unit)
fprintf(ascfile, "# %3d %-15.15s %-47.47s [%s]\n",
n, key->name,key->comment, key->unit);
else
fprintf(ascfile, "# %3d %-15.15s %.47s\n",
n, key->name,key->comment);
n += key->nbytes/t_size[key->ttype];
}
else if (prefs.cat_type == ASCII_SKYCAT && (key = objtab->key))
{
if (objtab->nkey<3)
error(EXIT_FAILURE,"The SkyCat format requires at least 4 parameters:",
" Id Ra Dec Mag");
/*--- We add a tab between rows, as required by Skycat */
fprintf(ascfile, skycathead, 8.0);
for (i=1,key=key->nextkey; i++<objtab->nkey; key=key->nextkey)
{
if (i>4)
fprintf(ascfile, "\t%s", key->name);
sprintf(gstr, "\t%s", key->printf);
strcpy(key->printf, gstr);
}
fprintf(ascfile, "\n------------------\n");
}
else if (prefs.cat_type == ASCII_VO && objtab->key)
{
write_xml_header(ascfile);
write_vo_fields(ascfile);
fprintf(ascfile, " <DATA><TABLEDATA>\n");
}
}
else
{
fitscat = new_cat(1);
init_cat(fitscat);
strcpy(fitscat->filename, prefs.cat_name);
if (open_cat(fitscat, WRITE_ONLY) != RETURN_OK)
error(EXIT_FAILURE,"*Error*: cannot open for writing ",prefs.cat_name);
switch(prefs.cat_type)
{
case FITS_LDAC:
case FITS_TPX:
/*------ Save a "pure" primary HDU */
save_tab(fitscat, fitscat->tab);
break;
case FITS_10:
/*------ Add to the primary HDU extraction parameters */
key = headkey1;
while (*key->name)
addkeyto_head(fitscat->tab, key++);
save_tab(fitscat, fitscat->tab);
break;
default:
error (EXIT_FAILURE, "*Internal Error*: Unknown FITS type in ",
"initcat()");
}
}
catopen_flag = 1;
return;
}
/****** write_vo_fields *******************************************************
PROTO int write_vo_fields(FILE *file)
PURPOSE Write the list of columns to an XML-VOTable file or stream
INPUT Pointer to the output file (or stream).
OUTPUT -.
NOTES -.
AUTHOR E. Bertin (IAP)
VERSION 14/07/2006
***/
void write_vo_fields(FILE *file)
{
keystruct *key;
char datatype[40], arraysize[40], str[40];
int i, d;
if (!objtab || !objtab->key)
return;
key=objtab->key;
for (i=0; i++<objtab->nkey; key=key->nextkey)
{
/*--- indicate datatype, arraysize, width and precision attributes */
/*--- Handle multidimensional arrays */
arraysize[0] = '\0';
if (key->naxis>1)
{
for (d=0; d<key->naxis; d++)
{
sprintf(str, "%s%d", d?"x":" arraysize=\"", key->naxisn[d]);
strcat(arraysize, str);
}
strcat(arraysize, "\"");
}
switch(key->ttype)
{
case T_BYTE: strcpy(datatype, "unsignedByte"); break;
case T_SHORT: strcpy(datatype, "short"); break;
case T_LONG: strcpy(datatype, "int"); break;
case T_FLOAT: strcpy(datatype, "float"); break;
case T_DOUBLE: strcpy(datatype, "double"); break;
default: error(EXIT_FAILURE,
"*Internal Error*: Unknown datatype in ",
"initcat()");
}
fprintf(file,
" <FIELD name=\"%s\" ucd=\"%s\" datatype=\"%s\" unit=\"%s\"%s>\n",
key->name, key->voucd, datatype,key->vounit, arraysize);
fprintf(file, " <DESCRIPTION>%s</DESCRIPTION>\n", key->comment);
fprintf(file, " </FIELD>\n");
}
return;
}
/********************************* reinitcat *********************************/
/*
Initialize the catalog header
*/
void reinitcat(picstruct *field)
{
tabstruct *tab, *asctab;
keystruct *key;
if (prefs.cat_type == CAT_NONE)
return;
if (prefs.cat_type != ASCII_HEAD && prefs.cat_type != ASCII &&
prefs.cat_type != ASCII_SKYCAT && prefs.cat_type != ASCII_VO)
{
update_tab(objtab);
switch(prefs.cat_type)
{
case FITS_LDAC:
/*------ We create a dummy table (only used through its header) */
QCALLOC(asctab, tabstruct, 1);
asctab->headnblock = field->fitsheadsize/FBSIZE;
QMALLOC(asctab->headbuf, char, asctab->headnblock*FBSIZE);
memcpy(asctab->headbuf, field->fitshead, asctab->headnblock*FBSIZE);
key = headkey;
while (*key->name)
addkeyto_head(asctab, key++);
tab = new_tab("LDAC_IMHEAD");
add_tab(tab, fitscat, 0);
key = new_key("Field Header Card");
key->ptr = asctab->headbuf;
asctab->headbuf = NULL;
free_tab(asctab);
key->htype = H_STRING;
key->ttype = T_STRING;
key->nobj = 1;
key->nbytes = 80*(fitsfind(key->ptr, "END ")+1);
key->naxis = 2;
QMALLOC(key->naxisn, int, key->naxis);
key->naxisn[0] = 80;
key->naxisn[1] = key->nbytes/80;
add_key(key, tab, 0);
save_tab(fitscat, tab);
strcpy(objtab->extname, "LDAC_OBJECTS");
break;
case FITS_TPX:
/*------ We create a dummy table (only used through its header) */
QCALLOC(asctab, tabstruct, 1);
asctab->headnblock = field->fitsheadsize/FBSIZE;
QMALLOC(asctab->headbuf, char, asctab->headnblock*FBSIZE);
memcpy(asctab->headbuf, field->fitshead, asctab->headnblock*FBSIZE);
key = headkey;
while (*key->name)
addkeyto_head(asctab, key++);
tab = new_tab("TPX_IMHEAD");
add_tab(tab, fitscat, 0);
key = new_key("Field Header Card");
key->ptr = asctab->headbuf;
asctab->headbuf = NULL;
free_tab(asctab);
key->htype = H_STRING;
key->ttype = T_STRING;
key->nobj = fitsfind(key->ptr, "END ")+1;
key->nbytes = 80;
key->naxis = 1;
QMALLOC(key->naxisn, int, key->naxis);
key->naxisn[0] = 80;
add_key(key, tab, 0);
save_tab(fitscat, tab);
strcpy(objtab->extname, "TPX_OBJECTS");
break;
case FITS_10:
/*------ Add to the primary HDU extraction parameters */
/*
key = headkey1;
while (*key->name)
addkeyto_head(fitscat->tab, key++);
save_tab(fitscat, fitscat->tab);
*/
break;
default:
error (EXIT_FAILURE, "*Internal Error*: Unknown FITS type in ",
"reinitcat()");
}
objtab->cat = fitscat;
init_writeobj(fitscat, objtab, &buf);
}
return;
}
/********************************* writecat **********************************/
/*
Write out in the catalog each one object.
*/
void writecat(int n, objliststruct *objlist)
{
outobj = objlist->obj[n];
switch(prefs.cat_type)
{
case FITS_10:
case FITS_LDAC:
case FITS_TPX:
write_obj(objtab, buf);
break;
case ASCII:
case ASCII_HEAD:
case ASCII_SKYCAT:
print_obj(ascfile, objtab);
break;
case ASCII_VO:
voprint_obj(ascfile, objtab);
break;
case CAT_NONE:
break;
default:
error (EXIT_FAILURE, "*Internal Error*: Unknown catalog type", "");
}
return;
}
/********************************** endcat ***********************************/
/*
Terminate the catalog output.
*/
void endcat(char *error)
{
keystruct *key;
int i;
if (!catopen_flag)
{
if (prefs.cat_type == ASCII_VO)
write_xmlerror(prefs.cat_name, error);
return;
}
switch(prefs.cat_type)
{
case ASCII:
case ASCII_HEAD:
if (!prefs.pipe_flag)
fclose(ascfile);
break;
case ASCII_SKYCAT:
fprintf(ascfile, skycattail);
if (!prefs.pipe_flag)
fclose(ascfile);
break;
case ASCII_VO:
fprintf(ascfile, " </TABLEDATA></DATA>\n");
fprintf(ascfile, " </TABLE>\n");
/*---- Add configuration file meta-data */
write_xml_meta(ascfile, error);
fprintf(ascfile, "</RESOURCE>\n");
fprintf(ascfile, "</VOTABLE>\n");
if (!prefs.pipe_flag)
fclose(ascfile);
break;
case FITS_LDAC:
case FITS_TPX:
case FITS_10:
free_cat(&fitscat,1);
break;
case CAT_NONE:
break;
default:
break;
}
/* Free allocated memory for arrays */
key = objtab->key;
for (i=objtab->nkey; i--; key=key->nextkey)
if (key->naxis && key->allocflag)
free(key->ptr);
objtab->key = NULL;
objtab->nkey = 0;
free_tab(objtab);
objtab = NULL;
return;
}
/******************************** reendcat ***********************************/
/*
Terminate the catalog output.
*/
void reendcat()
{
keystruct *key;
tabstruct *tab;
OFF_T pos;
char *head;
switch(prefs.cat_type)
{
case ASCII:
case ASCII_HEAD:
case ASCII_SKYCAT:
case ASCII_VO:
break;
case FITS_LDAC:
case FITS_TPX:
end_writeobj(fitscat, objtab, buf);
key = NULL;
if (!(tab=fitscat->tab->prevtab)
|| !(key=name_to_key(tab, "Field Header Card")))
error(EXIT_FAILURE,"*Error*: cannot update table ", "ASCFIELD");
head = key->ptr;
fitswrite(head, "SEXNDET ", &thecat.ndetect,H_INT,T_LONG);
fitswrite(head, "SEXNFIN ", &thecat.ntotal, H_INT,T_LONG);
fitswrite(head, "SEXDATE ", thecat.ext_date, H_STRING, 0);
fitswrite(head, "SEXTIME ", thecat.ext_time, H_STRING, 0);
fitswrite(head, "SEXELAPS", &thecat.ext_elapsed, H_FLOAT, T_DOUBLE);
QFTELL(fitscat->file, pos, fitscat->filename);
QFSEEK(fitscat->file, tab->headpos, SEEK_SET, fitscat->filename);
save_tab(fitscat, tab);
QFSEEK(fitscat->file, pos, SEEK_SET, fitscat->filename);
break;
case FITS_10:
end_writeobj(fitscat, objtab, buf);
fitswrite(fitscat->tab->headbuf,"SEXNDET ",&thecat.ndetect,H_INT,T_LONG);
fitswrite(fitscat->tab->headbuf,"SEXNFIN ",&thecat.ntotal, H_INT,T_LONG);
QFTELL(fitscat->file, pos, fitscat->filename);
QFSEEK(fitscat->file, fitscat->tab->headpos, SEEK_SET,fitscat->filename);
save_tab(fitscat, fitscat->tab);
QFSEEK(fitscat->file, pos, SEEK_SET, fitscat->filename);
break;
case CAT_NONE:
break;
default:
break;
}
return;
}
/*
check.c
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN (IAP)
*
* Contents: handling of "check-images".
*
* Last modify: 15/06/2004
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
#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"
#include "astrom.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; 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)
{
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)
{
astromstruct *as;
char *buf;
int i, ival;
size_t padsize;
double dval;
ULONG *ptri;
PIXTYPE *ptrf;
/* Inherit the field FITS header */
check->fitsheadsize = field->fitsheadsize;
QMALLOC(check->fitshead, char, check->fitsheadsize);
memcpy(check->fitshead, field->fitshead, 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->compress_type != ICOMPRESS_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_SUBPSFPROTOS:
case CHECK_PSFPROTOS:
case CHECK_SUBPCPROTOS:
case CHECK_PCPROTOS:
case CHECK_PCOPROTOS:
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 ((as=field->astrom))
{
dval = as->cdelt[0]*field->backw;
fitswrite(check->fitshead, "CDELT1 ", &dval, H_EXPO, T_DOUBLE);
dval = as->cdelt[1]*field->backh;
fitswrite(check->fitshead, "CDELT2 ", &dval, H_EXPO, T_DOUBLE);
dval = (as->crpix[0]-0.5)/field->backw + 0.5;
fitswrite(check->fitshead, "CRPIX1 ", &dval, H_EXPO, T_DOUBLE);
dval = (as->crpix[1]-0.5)/field->backh + 0.5;
fitswrite(check->fitshead, "CRPIX2 ", &dval, H_EXPO, T_DOUBLE);
dval = as->pc[0]*as->cdelt[0]*field->backw;
fitswrite(check->fitshead, "CD1_1 ", &dval, H_EXPO, T_DOUBLE);
dval = as->pc[1]*as->cdelt[1]*field->backh;
fitswrite(check->fitshead, "CD1_2 ", &dval, H_EXPO, T_DOUBLE);
dval = as->pc[2]*as->cdelt[0]*field->backw;
fitswrite(check->fitshead, "CD2_1 ", &dval, H_EXPO, T_DOUBLE);
dval = as->pc[3]*as->cdelt[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;
default:
error(EXIT_FAILURE, "*Internal Error* in ", "initcheck()!");
}
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)
{
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_SUBPSFPROTOS:
case CHECK_PSFPROTOS:
case CHECK_SUBPCPROTOS:
case CHECK_PCPROTOS:
case CHECK_PCOPROTOS:
case CHECK_ASSOC:
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; y<field->ymax; 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;
}
case CHECK_MAPSOM:
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(USHORT))%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;
}
/*
check.h
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN, IAP/Leiden
*
* Contents: handling of "check-images".
*
* Last modify: 15/12/2002
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
/*--------------------------------- structures ------------------------------*/
/* Check-image parameters */
typedef struct structcheck
{
char filename[MAXCHAR]; /* ptr to check-image filename */
FILE *file; /* ptr to check-image file structure */
char *fitshead; /* ptr to check-image FITS header */
int fitsheadsize; /* size of check-image FITS header */
void *pix; /* ptr to check-image pixmap */
int width, height; /* size of check-image */
size_t npix; /* number of pixels in check-image */
int y; /* current line in check-image */
PIXTYPE overlay; /* intensity of the overlayed plots */
PIXTYPE *line; /* buffered image line */
checkenum type; /* CHECKIMAGE_TYPE */
} checkstruct;
/*------------------------------- functions ---------------------------------*/
checkstruct *initcheck(char *, checkenum, int next);
void addcheck(checkstruct *, float *, int,int, int,int, float),
blankcheck(checkstruct *, PIXTYPE *, int,int,int,int,PIXTYPE),
endcheck(checkstruct *),
reendcheck(picstruct *field, checkstruct *),
reinitcheck(picstruct *, checkstruct *),
writecheck(checkstruct *, PIXTYPE *, int);
/*
clean.c
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN (IAP)
*
* Contents: functions that remove spurious detections from the
* catalog
*
* Last modify: 15/02/2005
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "define.h"
#include "globals.h"
#include "prefs.h"
#include "check.h"
#include "clean.h"
#include "flag.h"
#include "image.h"
/*------------------------------- variables ---------------------------------*/
static LONG *cleanvictim;
/******************************* initclean **********************************
PROTO void initclean(void)
PURPOSE Initialize things for CLEANing.
INPUT -.
OUTPUT -.
NOTES -.
AUTHOR E. Bertin (IAP & Leiden & ESO)
VERSION 03/07/97
***/
void initclean(void)
{
if (prefs.clean_flag)
QMALLOC(cleanvictim, LONG, prefs.clean_stacksize);
QMALLOC(cleanobjlist, objliststruct, 1);
cleanobjlist->obj = NULL;
cleanobjlist->plist = NULL;
cleanobjlist->nobj = cleanobjlist->npix = 0;
return;
}
/******************************** endclean **********************************
PROTO void endclean(void)
PURPOSE End things related to CLEANing.
INPUT -.
OUTPUT -.
NOTES -.
AUTHOR E. Bertin (IAP & Leiden & ESO)
VERSION 03/07/97
***/
void endclean(void)
{
if (prefs.clean_flag)
free(cleanvictim);
free(cleanobjlist);
return;
}
/********************************** clean ***********************************
PROTO int clean(int objnb, objliststruct *objlistin)
PURPOSE Remove object from frame -buffer and put it in the "CLEANlist".
INPUT Object number,
Object list (source).
OUTPUT 0 if the object was CLEANed, 1 otherwise.
NOTES -.
AUTHOR E. Bertin (IAP, Leiden & ESO)
VERSION 08/02/2001
***/
int clean(picstruct *field, picstruct *dfield, int objnb,
objliststruct *objlistin)
{
objstruct *objin, *obj;
int i,j,k;
double amp,ampin,alpha,alphain, unitarea,unitareain,beta,val;
float dx,dy,rlim;
objin = objlistin->obj+objnb;
beta = prefs.clean_param;
unitareain = PI*objin->a*objin->b;
ampin = objin->fdflux/(2*unitareain*objin->abcor);
alphain = (pow(ampin/objin->dthresh, 1.0/beta)-1)*unitareain/objin->fdnpix;
j=0;
obj = cleanobjlist->obj;
for (i=0; i<cleanobjlist->nobj; i++, obj++)
{
dx = objin->mx - obj->mx;
dy = objin->my - obj->my;
rlim = objin->a+obj->a;
rlim *= rlim;
if (dx*dx+dy*dy<rlim*CLEAN_ZONE*CLEAN_ZONE)
{
if (obj->fdflux < objin->fdflux)
{
val = 1+alphain*(objin->cxx*dx*dx+objin->cyy*dy*dy+objin->cxy*dx*dy);
if (val>1.0
&& ((float)(val<1e10?ampin*pow(val,-beta) : 0.0) > obj->mthresh))
/*------- the newcomer puts that object in its menu! */
cleanvictim[j++] = i;
}
else
{
unitarea = PI*obj->a*obj->b;
amp = obj->fdflux/(2*unitarea*obj->abcor);
alpha = (pow(amp/obj->dthresh, 1.0/beta) - 1)*unitarea/obj->fdnpix;
val = 1+alpha*(obj->cxx*dx*dx+obj->cyy*dy*dy+obj->cxy*dx*dy);
if (val>1.0
&& ((float)(val<1e10?amp*pow(val,-beta) : 0.0) > objin->mthresh))
{
/*------- the newcomer is eaten!! */
mergeobject(objin, obj);
if (prefs.blank_flag)
{
/*---------- Paste back ``CLEANed'' object pixels before forgetting them */
if (objin->blank)
{
pasteimage(field, objin->blank, objin->subw, objin->subh,
objin->subx, objin->suby);
free(objin->blank);
}
if (objin->dblank)
{
pasteimage(dfield, objin->dblank, objin->subw, objin->subh,
objin->subx, objin->suby);
free(objin->dblank);
}
}
return 0;
}
}
}
}
/* the newcomer eats the content of the menu */
for (i=j; i--;)
{
k = cleanvictim[i];
obj = cleanobjlist->obj + k;
mergeobject(obj, objin);
if (prefs.blank_flag)
{
/*---- Paste back ``CLEANed'' object pixels before forgetting them */
if (obj->blank)
{
pasteimage(field, obj->blank, obj->subw, obj->subh,
obj->subx, obj->suby);
free(obj->blank);
}
if (obj->dblank)
{
pasteimage(dfield, obj->dblank, obj->subw, obj->subh,
obj->subx, obj->suby);
free(obj->dblank);
}
}
subcleanobj(k);
}
return 1;
}
/******************************* addcleanobj ********************************/
/*
Add an object to the "cleanobjlist".
*/
void addcleanobj(objstruct *objin)
{
int margin, y;
float hh1,hh2;
/*Update the object list */
if (cleanobjlist->nobj)
{
if (!(cleanobjlist->obj = (objstruct *)realloc(cleanobjlist->obj,
(++cleanobjlist->nobj) * sizeof(objstruct))))
error(EXIT_FAILURE, "Not enough memory for ", "CLEANing");
}
else
{
if (!(cleanobjlist->obj = (objstruct *)malloc((++cleanobjlist->nobj)
* sizeof(objstruct))))
error(EXIT_FAILURE, "Not enough memory for ", "CLEANing");
}
/* Compute the max. vertical extent of the object: */
/* First from 2nd order moments, compute y-limit of the 3-sigma ellips... */
hh1 = objin->cyy - objin->cxy*objin->cxy/(4.0*objin->cxx);
hh1 = hh1 > 0.0 ? 1/sqrt(3*hh1) : 0.0;
/* ... then from the isophotal limit, which should not be TOO different... */
hh2 = (objin->ymax-objin->ymin+1.0);
margin = (int)((hh1>hh2?hh1:hh2)*MARGIN_SCALE+1.49999);
objin->ycmax = objin->ymax+margin;
/* ... and finally compare with the predefined margin */
if ((y=(int)(objin->my+0.49999)+prefs.cleanmargin)>objin->ycmax)
objin->ycmax = y;
objin->ycmin = objin->ymin-margin;
if ((y=(int)(objin->my+0.49999)-prefs.cleanmargin)<objin->ycmin)
objin->ycmin = y;
cleanobjlist->obj[cleanobjlist->nobj-1] = *objin;
return;
}
/******************************** mergeobject *******************************/
/*
Merge twos objects from "objlist".
*/
void mergeobject(objstruct *objslave,objstruct *objmaster)
{
checkstruct *check;
if ((check = prefs.check[CHECK_SEGMENTATION]))
{
ULONG *pix;
ULONG colorslave = objslave->number,
colormaster = objmaster->number;
int dx,dx0,dy,dpix;
pix = (ULONG *)check->pix+check->width*objslave->ymin + objslave->xmin;
dx0 = objslave->xmax-objslave->xmin+1;
dpix = check->width-dx0;
for (dy=objslave->ymax-objslave->ymin+1; dy--; pix += dpix)
for (dx=dx0; dx--; pix++)
if (*pix==colorslave)
*pix = colormaster;
}
if (FLAG(obj.flux_prof))
{
objmaster->flux_prof = (objmaster->flux_prof*objmaster->fdflux
+ objslave->flux_prof*objslave->fdflux)
/ (objmaster->fdflux + objslave->fdflux);
objmaster->fluxerr_prof = (objmaster->fluxerr_prof*objmaster->fdflux
+ objslave->fluxerr_prof*objslave->fdflux)
/ (objmaster->fdflux + objslave->fdflux);
}
objmaster->fdnpix += objslave->fdnpix;
objmaster->dnpix += objslave->dnpix;
objmaster->fdflux += objslave->fdflux;
objmaster->dflux += objslave->dflux;
objmaster->flux += objslave->flux;
objmaster->fluxerr += objslave->fluxerr;
if (objslave->fdpeak>objmaster->fdpeak)
{
objmaster->fdpeak = objslave->fdpeak;
objmaster->peakx = objslave->peakx;
objmaster->peaky = objslave->peaky;
}
if (objslave->dpeak>objmaster->dpeak)
objmaster->dpeak = objslave->dpeak;
if (objslave->peak>objmaster->peak)
objmaster->peak = objslave->peak;
if (objslave->xmin<objmaster->xmin)
objmaster->xmin = objslave->xmin;
if (objslave->xmax>objmaster->xmax)
objmaster->xmax = objslave->xmax;
if (objslave->ymin<objmaster->ymin)
objmaster->ymin = objslave->ymin;
if (objslave->ymax>objmaster->ymax)
objmaster->ymax = objslave->ymax;
objmaster->flag |= (objslave->flag & (~(OBJ_MERGED|OBJ_CROWDED)));
mergeflags(objmaster, objslave);
return;
}
/******************************* subcleanobj ********************************/
/*
remove an object from a "cleanobjlist".
*/
void subcleanobj(int objnb)
{
/* Update the object list */
if (objnb>=cleanobjlist->nobj)
error(EXIT_FAILURE, "*Internal Error*: no CLEAN object to remove ",
"in subcleanobj()");
if (--cleanobjlist->nobj)
{
if (cleanobjlist->nobj != objnb)
cleanobjlist->obj[objnb] = cleanobjlist->obj[cleanobjlist->nobj];
if (!(cleanobjlist->obj = (objstruct *)realloc(cleanobjlist->obj,
cleanobjlist->nobj * sizeof(objstruct))))
error(EXIT_FAILURE, "Not enough memory for ", "CLEANing");
}
else
free(cleanobjlist->obj);
return;
}
/*
clean.h
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN, IAP & Leiden observatory & ESO
*
* Contents: functions that remove spurious detections from the
* catalog
*
* Last modify: 06/04/99
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
/*------------------------------ definitions --------------------------------*/
#define CLEAN_ZONE 10.0 /* zone (in sigma) to */
/* consider for processing */
/*------------------------------- variables ---------------------------------*/
objliststruct *cleanobjlist; /* laconic, isn't it? */
/*------------------------------- functions ---------------------------------*/
extern void addcleanobj(objstruct *),
endclean(void),
initclean(void),
subcleanobj(int);
extern int clean(picstruct *field, picstruct *dfield,
int, objliststruct *);
/*
define.h
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN (IAP)
*
* Contents: global definitions.
*
* Last modify: 12/07/2006
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
/* Check if we are using a configure script here */
#ifndef HAVE_CONFIG_H
#define VERSION "2.x"
#define DATE "2006-01-12"
#define THREADS_NMAX 16 /* max. number of threads */
#endif
/*------------------------ what, who, when and where ------------------------*/
#define BANNER "SExtractor"
#define EXECUTABLE "sex"
#define MYVERSION VERSION
#define COPYRIGHT "Emmanuel BERTIN (bertin@iap.fr)"
#define WEBSITE "http://terapix.iap.fr/soft/sextractor"
#define MAILINGLIST "sextractor@iap.fr"
#define MAILINGLISTREQ "sextractor-request@iap.fr"
#define INSTITUTE "TERAPIX team at IAP http://terapix.iap.fr"
/*--------------------------- Internal constants ----------------------------*/
#define BIG 1e+30 /* a huge number */
#define LESSBIG 1e+25 /* a somewhat smaller number */
#define DATA_BUFSIZE 262144 /* data buffer size */
#define MARGIN_SCALE 2.0 /* Margin / object height */
#define MAXCHAR 512 /* max. number of characters */
#define MAXCHARL 16384 /* max.nb of chars in strlist*/
#define MAXCHECK 32 /* max. # of CHECKimages */
#define MAXDEBAREA 3 /* max. area for deblending */
#define MAXFLAG 4 /* max. # of FLAG-images */
#define MAXIMAGE 2 /* max. # of input images */
#define MAXNAPER 32 /* max. number of apertures */
#define MAXNASSOC 32 /* max. number of assoc. */
#define MAXPICSIZE 1048576 /* max. image size */
#define NISO 8 /* number of isophotes */
#define OUTPUT stdout /* where all msgs are sent */
#define PSF_NPSFMAX 9 /* Max number of fitted PSFs */
#ifndef PI
#define PI 3.1415926535898 /* never met before? */
#endif
/* NOTES:
*
*One must have: BIG < the biggest element a float can store
* DATA_BUFSIZE >= 2880 with DATA_BUFSIZE%8 = 0
* MAXCHAR >= 16
* 1 <= MAXCHECK <= MAXLIST (see prefs.h)
* 1 <= MAXDEBAREA (see prefs.c & extract.c)
* 1 <= MAXFLAG <= MAXLIST (see prefs.h)
* 1 <= MAXIMAGE <= MAXLIST (see prefs.h)
* 1 <= MAXNAPER <= MAXLIST (see prefs.h)
* 1 <= MAXNASSOC <= MAXLIST (see prefs.h)
* MAXPICSIZE > size of any image!!
* NISO = 8 (otherwise need to change prefs.h)
* 1 <= PSF_NPSFMAX
*/
/*---- Set defines according to machine's specificities and customizing -----*/
#if _LARGEFILE_SOURCE
#define FSEEKO fseeko
#define FTELLO ftello
#else
#define FSEEKO fseek
#define FTELLO ftell
#endif
/*--------------------- in case of missing constants ------------------------*/
#ifndef SEEK_SET
#define SEEK_SET 0
#endif
#ifndef SEEK_CUR
#define SEEK_CUR 1
#endif
#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS 0
#endif
#ifndef EXIT_FAILURE
#define EXIT_FAILURE -1
#endif
/*---------------------------- return messages ------------------------------*/
#define RETURN_OK 0
#define RETURN_ERROR (-1)
#define RETURN_FATAL_ERROR (-2)
/*------------------- a few definitions to read FITS parameters ------------*/
#define FBSIZE 2880L /* size (in bytes) of one FITS block */
#define FITSTOF(k, def) \
(st[0]=0,((point = fitsnfind(buf, k, n))? \
fixexponent(point), \
atof(strncat(st, &point[10], 70)) \
:(def)))
#define FITSTOI(k, def) \
(st[0]=0,(point = fitsnfind(buf, k, n))? \
atoi(strncat(st, &point[10], 70)) \
:(def))
#define FITSTOS(k, str, def) \
{ if (fitsread(buf,k,str,H_STRING,T_STRING)!= RETURN_OK) \
strcpy(str, (def)); \
}
/*------------------------------- Other Macros -----------------------------*/
#define DEXP(x) exp(2.30258509299*(x)) /* 10^x */
#define QFREAD(ptr, size, afile, fname) \
if (fread(ptr, (size_t)(size), (size_t)1, afile)!=1) \
error(EXIT_FAILURE, "*Error* while reading ", fname)
#define QFWRITE(ptr, size, afile, fname) \
if (fwrite(ptr, (size_t)(size), (size_t)1, afile)!=1) \
error(EXIT_FAILURE, "*Error* while writing ", fname)
#define QFSEEK(afile, offset, pos, fname) \
if (FSEEKO(afile, (offset), pos)) \
error(EXIT_FAILURE,"*Error*: file positioning failed in ", \
fname)
#define QFTELL(afile, pos, fname) \
if ((pos=FTELLO(afile))==-1) \
error(EXIT_FAILURE,"*Error*: file position unknown in ", \
fname)
#define QCALLOC(ptr, typ, nel) \
{if (!(ptr = (typ *)calloc((size_t)(nel),sizeof(typ)))) \
error(EXIT_FAILURE, "Not enough memory for ", \
#ptr " (" #nel " elements) !");;}
#define QMALLOC(ptr, typ, nel) \
{if (!(ptr = (typ *)malloc((size_t)(nel)*sizeof(typ)))) \
error(EXIT_FAILURE, "Not enough memory for ", \
#ptr " (" #nel " elements) !");;}
#define QFREE(ptr) \
{free(ptr); \
ptr = NULL;}
#define QREALLOC(ptr, typ, nel) \
{if (!(ptr = (typ *)realloc(ptr, (size_t)(nel)*sizeof(typ)))) \
error(EXIT_FAILURE, "Not enough memory for ", \
#ptr " (" #nel " elements) !");;}
#define QMEMCPY(ptrin, ptrout, typ, nel) \
{if (ptrin) \
{if (!(ptrout = (typ *)malloc((size_t)(nel)*sizeof(typ)))) \
error(EXIT_FAILURE, "Not enough memory for ", \
#ptrout " (" #nel " elements) !"); \
memcpy(ptrout, ptrin, (size_t)(nel)*sizeof(typ));};}
#define RINT(x) (int)(floor(x+0.5))
#define PIX(pic, x, y) pic->strip[(((int)y)%pic->stripheight) \
*pic->width +(int)x]
#define NPRINTF if (prefs.verbose_type == NORM \
|| prefs.verbose_type==WARN) fprintf
#define NFPRINTF(w,x) {if (prefs.verbose_type==NORM \
|| prefs.verbose_type==WARN) \
fprintf(w, "\33[1M> %s\n\33[1A",x); \
else if (prefs.verbose_type == FULL) \
fprintf(w, "%s.\n", x);}
#define QPRINTF if (prefs.verbose_type != QUIET) fprintf
#define FPRINTF if (prefs.verbose_type == FULL) fprintf
#define QWARNING if (prefs.verbose_type==WARN \
|| prefs.verbose_type==FULL) warning
#define FLAG(x) (*((char *)&flag##x))
#define VECFLAG(x) (*((char *)flag##x))
/*
extract.c
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN (IAP)
*
* Contents: functions for extraction of connected pixels from
* a bitmap.
*
* Last modify: 26/11/2003
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include "define.h"
#include "globals.h"
#include "prefs.h"
#include "extract.h"
#include "plist.h"
/*------------------------- Static buffers for lutz() -----------------------*/
static infostruct *info, *store;
static char *marker;
static status *psstack;
static int *start, *end, *discan, xmin,ymin,xmax,ymax;
/******************************* lutzalloc ***********************************/
/*
Allocate once for all memory space for buffers used by lutz().
*/
void lutzalloc(int width, int height)
{
int *discant,
stacksize, i;
stacksize = width+1;
xmin = ymin = 0;
xmax = width-1;
ymax = height-1;
QMALLOC(info, infostruct, stacksize);
QMALLOC(store, infostruct, stacksize);
QMALLOC(marker, char, stacksize);
QMALLOC(psstack, status, stacksize);
QMALLOC(start, int, stacksize);
QMALLOC(end, int, stacksize);
QMALLOC(discan, int, stacksize);
discant = discan;
for (i=stacksize; i--;)
*(discant++) = -1;
return;
}
/******************************* lutzfree ************************************/
/*
Free once for all memory space for buffers used by lutz().
*/
void lutzfree()
{
free(discan);
free(info);
free(store);
free(marker);
free(psstack);
free(start);
free(end);
return;
}
/********************************** lutz *************************************/
/*
C implementation of R.K LUTZ' algorithm for the extraction of 8-connected pi-
xels in an image
*/
int lutz(objliststruct *objlistroot, int nroot, objstruct *objparent,
objliststruct *objlist)
{
static infostruct curpixinfo,initinfo;
objstruct *obj, *objroot;
pliststruct *plist,*pixel, *plistin, *plistint;
char newmarker;
int cn, co, luflag, objnb, pstop, xl,xl2,yl,
out, minarea, stx,sty,enx,eny, step,
nobjm = NOBJ,
inewsymbol, *iscan;
short trunflag;
PIXTYPE thresh;
status cs, ps;
out = RETURN_OK;
minarea = prefs.deb_maxarea;
plistint = plistin = objlistroot->plist;
objroot = &objlistroot->obj[nroot];
stx = objparent->xmin;
sty = objparent->ymin;
enx = objparent->xmax;
eny = objparent->ymax;
thresh = objlist->dthresh;
initinfo.pixnb = 0;
initinfo.flag = 0;
initinfo.firstpix = initinfo.lastpix = -1;
cn = 0;
iscan = objroot->submap + (sty-objroot->suby)*objroot->subw
+ (stx-objroot->subx);
/* As we only analyse a fraction of the map, a step occurs between lines */
step = objroot->subw - (++enx-stx);
eny++;
/*------Allocate memory to store object data */
free(objlist->obj);
if (!(obj=objlist->obj=(objstruct *)malloc(nobjm*sizeof(objstruct))))
{
out = RETURN_FATAL_ERROR;
plist = NULL; /* To avoid gcc -Wall warnings */
goto exit_lutz;
}
/*------Allocate memory for the pixel list */
free(objlist->plist);
if (!(objlist->plist
= (pliststruct *)malloc((eny-sty)*(enx-stx)*plistsize)))
{
out = RETURN_FATAL_ERROR;
plist = NULL; /* To avoid gcc -Wall warnings */
goto exit_lutz;
}
pixel = plist = objlist->plist;
/*----------------------------------------*/
for (xl=stx; xl<=enx; xl++)
marker[xl] = 0 ;
objnb = objlist->nobj = 0;
co = pstop = 0;
curpixinfo.pixnb = 1;
for (yl=sty; yl<=eny; yl++, iscan += step)
{
ps = COMPLETE;
cs = NONOBJECT;
trunflag = (yl==0 || yl==ymax) ? OBJ_TRUNC : 0;
if (yl==eny)
iscan = discan;
for (xl=stx; xl<=enx; xl++)
{
newmarker = marker[xl];
marker[xl] = 0;
if ((inewsymbol = (xl!=enx)?*(iscan++):-1) < 0)
luflag = 0;
else
{
curpixinfo.flag = trunflag;
plistint = plistin+inewsymbol;
luflag = (PLISTPIX(plistint, cdvalue) > thresh?1:0);
}
if (luflag)
{
if (xl==0 || xl==xmax)
curpixinfo.flag |= OBJ_TRUNC;
memcpy(pixel, plistint, (size_t)plistsize);
PLIST(pixel, nextpix) = -1;
curpixinfo.lastpix = curpixinfo.firstpix = cn;
cn += plistsize;
pixel += plistsize;
if (cs != OBJECT)
/*------------------------------- Start Segment -----------------------------*/
{
cs = OBJECT;
if (ps == OBJECT)
{
if (start[co] == UNKNOWN)
{
marker[xl] = 'S';
start[co] = xl;
}
else marker[xl] = 's';
}
else
{
psstack[pstop++] = ps;
marker[xl] = 'S';
start[++co] = xl;
ps = COMPLETE;
info[co] = initinfo;
}
}
}
/*---------------------------------------------------------------------------*/
if (newmarker)
/*---------------------------- Process New Marker ---------------------------*/
{
if (newmarker == 'S')
{
psstack[pstop++] = ps;
if (cs == NONOBJECT)
{
psstack[pstop++] = COMPLETE;
info[++co] = store[xl];
start[co] = UNKNOWN;
}
else
update (&info[co],&store[xl], plist);
ps = OBJECT;
}
else if (newmarker == 's')
{
if ((cs == OBJECT) && (ps == COMPLETE))
{
pstop--;
xl2 = start[co];
update (&info[co-1],&info[co], plist);
if (start[--co] == UNKNOWN)
start[co] = xl2;
else
marker[xl2] = 's';
}
ps = OBJECT;
}
else if (newmarker == 'f')
ps = INCOMPLETE;
else if (newmarker == 'F')
{
ps = psstack[--pstop];
if ((cs == NONOBJECT) && (ps == COMPLETE))
{
if (start[co] == UNKNOWN)
{
if ((int)info[co].pixnb >= minarea)
{
if (objlist->nobj>=nobjm)
if (!(obj = objlist->obj = (objstruct *)
realloc(obj, (nobjm+=nobjm/2)* sizeof(objstruct))))
{
out = RETURN_FATAL_ERROR;
goto exit_lutz;
}
lutzsort(&info[co], objlist);
}
}
else
{
marker[end[co]] = 'F';
store[start[co]] = info[co];
}
co--;
ps = psstack[--pstop];
}
}
}
/*---------------------------------------------------------------------------*/
if (luflag)
update (&info[co],&curpixinfo, plist);
else
{
if (cs == OBJECT)
/*-------------------------------- End Segment ------------------------------*/
{
cs = NONOBJECT;
if (ps != COMPLETE)
{
marker[xl] = 'f';
end[co] = xl;
}
else
{
ps = psstack[--pstop];
marker[xl] = 'F';
store[start[co]] = info[co];
co--;
}
}
}
/*---------------------------------------------------------------------------*/
}
}
exit_lutz:
if (objlist->nobj && out == RETURN_OK)
{
if (!(objlist->obj=(objstruct *)realloc(obj,
objlist->nobj*sizeof(objstruct))))
error(EXIT_FAILURE,"problem with mem. realloc. in lutz()","");
}
else
{
free(obj);
objlist->obj = NULL;
}
if (cn && out == RETURN_OK)
{
if (!(objlist->plist=(pliststruct *)realloc(plist,cn)))
error(EXIT_FAILURE,"problem with mem. realloc. in lutz()","");
}
else
{
free(objlist->plist);
objlist->plist = NULL;
}
return out;
}
/********************************* lutzsort ***********************************/
/*
Build the object structure.
*/
void lutzsort(infostruct *info, objliststruct *objlist)
{
objstruct *obj = objlist->obj+objlist->nobj;
memset(obj, 0, (size_t)sizeof(objstruct));
obj->firstpix = info->firstpix;
obj->lastpix = info->lastpix;
obj->flag = info->flag;
objlist->npix += info->pixnb;
preanalyse(objlist->nobj, objlist, ANALYSE_FAST);
objlist->nobj++;
return;
}
/*
extract.h
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN (IAP, Leiden observatory & ESO)
*
* Contents: functions for extraction of connected pixels from
* a bitmap.
*
* Last modify: 29/11/2005
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
/*------------------------------ definitions --------------------------------*/
#define NOBJ 256 /* starting number of obj. */
#define UNKNOWN -1 /* flag for LUTZ */
/*--------------------------------- typedefs --------------------------------*/
typedef enum {COMPLETE, INCOMPLETE, NONOBJECT, OBJECT}
status; /* Extraction status */
/*--------------------------------- variables -------------------------------*/
PIXTYPE *dumscan;
/*------------------------------- structures --------------------------------*/
/* Temporary object parameters during extraction */
typedef struct structinfo
{
LONG pixnb; /* Number of pixels included */
LONG firstpix; /* Pointer to first pixel of pixlist */
LONG lastpix; /* Pointer to last pixel of pixlist */
short flag; /* Extraction flag */
} infostruct;
/*------------------------------- functions ---------------------------------*/
void lutzalloc(int, int),
lutzfree(void),
lutzsort(infostruct *, objliststruct *),
sortit(picstruct *, picstruct *, picstruct *, picstruct *,
infostruct *, objliststruct *, PIXTYPE *, PIXTYPE *),
update(infostruct *, infostruct *, pliststruct *);
int lutz(objliststruct *, int, objstruct *, objliststruct *);
/*
field.c
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN (IAP)
*
* Contents: Handling of field structures.
*
* Last modify: 29/06/2006
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
#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 "prefs.h"
#include "fits/fitscat.h"
#include "assoc.h"
#include "astrom.h"
#include "back.h"
#include "field.h"
#include "filter.h"
#include "interpolate.h"
/********************************* newfield **********************************/
/*
Returns a pointer to a new field, ready to go!
*/
picstruct *newfield(char *filename, int flags, int nok)
{
picstruct *field;
catstruct *cat;
tabstruct *tab;
OFF_T mefpos = 0; /* To avoid gcc -Wall warnings */
int nok2, ntab, margin;
/* Move to nok'th valid FITS image extension */
if (!(cat = read_cat(filename)))
error(EXIT_FAILURE, "*Error*: cannot open ", filename);
close_cat(cat);
tab = cat->tab;
nok++; /* At least one pass through the loop */
nok2 = nok;
for (ntab=cat->ntab; nok && ntab--; tab=tab->nexttab)
{
if ((tab->naxis < 2)
|| !strncmp(tab->xtension, "BINTABLE", 8)
|| !strncmp(tab->xtension, "ASCTABLE", 8))
continue;
mefpos = tab->headpos;
nok--;
}
if (ntab<0)
error(EXIT_FAILURE, "Not enough valid FITS image extensions in ",filename);
/* First allocate memory for the new field (and nullify pointers) */
QCALLOC(field, picstruct, 1);
field->mefpos = mefpos;
field->flags = flags;
strcpy (field->filename, filename);
/* A short, "relative" version of the filename */
if (!(field->rfilename = strrchr(field->filename, '/')))
field->rfilename = field->filename;
else
field->rfilename++;
sprintf(gstr, "Looking for %s", field->rfilename);
NFPRINTF(OUTPUT, gstr);
/* Check the image exists and read important info (image size, etc...) */
readimagehead(field);
if (cat->ntab>1)
sprintf(gstr, "[%d/%d]", nok2, cat->ntab-1);
QPRINTF(OUTPUT, "%s \"%.20s\" %s / %d x %d / %d bits %s data\n",
flags&FLAG_FIELD? "Flagging from:" :
(flags&(RMS_FIELD|VAR_FIELD|WEIGHT_FIELD)?
"Weighting from:" :
(flags&MEASURE_FIELD? "Measuring from:" :
"Detecting from:")),
field->ident,
cat->ntab>1? gstr : "",
field->width, field->height, field->bytepix*8,
field->bitpix>0?
(field->compress_type!=ICOMPRESS_NONE?"COMPRESSED":"INTEGER")
:"FLOATING POINT");
/* Provide a buffer for compressed data */
if (field->compress_type != ICOMPRESS_NONE)
QMALLOC(field->compress_buf, char, FBSIZE);
/* 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;
/* 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]<field->width ? prefs.backsize[0]
: field->width;
field->backh = prefs.backsize[1]<field->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 */
int margin;
if (field->stripheight < thefilter->convh)
field->stripheight = thefilter->convh;
if (field->stripmargin < (margin = (thefilter->convh-1)/2))
field->stripmargin = margin;
}
free_cat(&cat, 1);
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;
copyastrom(infield, field);
QMEMCPY(infield->fitshead, field->fitshead, char, infield->fitsheadsize);
field->interp_flag = 0;
field->assoc = NULL;
field->strip = NULL;
field->fstrip = NULL;
field->reffield = infield;
field->compress_buf = NULL;
field->compress_type = ICOMPRESS_NONE;
field->file = NULL;
return field;
}
/********************************* endfield **********************************/
/*
Free and close everything related to a field structure.
*/
void endfield(picstruct *field)
{
if (field->file)
fclose(field->file);
free(field->fitshead);
free(field->strip);
free(field->fstrip);
free(field->compress_buf);
if (field->astrom)
endastrom(field);
if (field->interp_flag)
end_interpolate(field);
endback(field);
free(field);
return;
}
/*
field.h
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* Part of: SExtractor
*
* Author: E.BERTIN (IAP, Leiden observatory & ESO)
*
* Contents: Handling of field structures.
*
* Last modify: 22/03/98
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
/*------------------------------ field flags -------------------------------*/
#define DETECT_FIELD 0x01 /* Detection */
#define MEASURE_FIELD 0x02 /* Measurement */
#define FLAG_FIELD 0x04 /* Flagging */
#define RMS_FIELD 0x08 /* Weighting with std deviations */
#define VAR_FIELD 0x10 /* Weighting with variances */
#define WEIGHT_FIELD 0x20 /* Weighting with weights */
#define BACKRMS_FIELD 0x40 /* Weighting from a backrms matrix */
#define INTERP_FIELD 0x80 /* Purely interpolated data */
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment