From 42c34f54936cba803e66e457a0aecfa00411c4e1 Mon Sep 17 00:00:00 2001 From: Emmanuel Bertin Date: Thu, 12 Jul 2012 16:05:39 +0000 Subject: [PATCH] Fixed regression with FITS image extension numbering. Fixed issues with PSF image extension numbering. Fixed crashes when calling FFT routines with the MKL library. Pushed version number to 2.18.2. --- configure | 20 ++++++------- configure.ac | 2 +- man/sex.1 | 2 +- src/fft.c | 12 ++++---- src/fft.h | 7 +++-- src/field.c | 32 +++++++++++++------- src/header.c | 8 ++--- src/makeit.c | 85 ++++++++++++++++++++++++++++------------------------ src/profit.c | 38 ++++++++--------------- src/psf.c | 6 ++-- 10 files changed, 110 insertions(+), 102 deletions(-) diff --git a/configure b/configure index 12fbbed..e2f01fb 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.68 for sextractor 2.18.1. +# Generated by GNU Autoconf 2.68 for sextractor 2.18.2. # # Report bugs to . # @@ -570,8 +570,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='sextractor' PACKAGE_TARNAME='sextractor' -PACKAGE_VERSION='2.18.1' -PACKAGE_STRING='sextractor 2.18.1' +PACKAGE_VERSION='2.18.2' +PACKAGE_STRING='sextractor 2.18.2' PACKAGE_BUGREPORT='bertin@iap.fr' PACKAGE_URL='' @@ -1324,7 +1324,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures sextractor 2.18.1 to adapt to many kinds of systems. +\`configure' configures sextractor 2.18.2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1394,7 +1394,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of sextractor 2.18.1:";; + short | recursive ) echo "Configuration of sextractor 2.18.2:";; esac cat <<\_ACEOF @@ -1524,7 +1524,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -sextractor configure 2.18.1 +sextractor configure 2.18.2 generated by GNU Autoconf 2.68 Copyright (C) 2010 Free Software Foundation, Inc. @@ -1947,7 +1947,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by sextractor $as_me 2.18.1, which was +It was created by sextractor $as_me 2.18.2, which was generated by GNU Autoconf 2.68. Invocation command line was $ $0 $@ @@ -2752,7 +2752,7 @@ fi # Define the identity of the package. PACKAGE='sextractor' - VERSION='2.18.1' + VERSION='2.18.2' cat >>confdefs.h <<_ACEOF @@ -15512,7 +15512,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by sextractor $as_me 2.18.1, which was +This file was extended by sextractor $as_me 2.18.2, which was generated by GNU Autoconf 2.68. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -15578,7 +15578,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -sextractor config.status 2.18.1 +sextractor config.status 2.18.2 configured by $0, generated by GNU Autoconf 2.68, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 925e6c4..42c48a6 100644 --- a/configure.ac +++ b/configure.ac @@ -31,7 +31,7 @@ define([AC_CACHE_LOAD],) define([AC_CACHE_SAVE],) # This is your standard Bertin source code... -AC_INIT(sextractor, 2.18.1, [bertin@iap.fr]) +AC_INIT(sextractor, 2.18.2, [bertin@iap.fr]) AC_CONFIG_SRCDIR(src/makeit.c) AC_CONFIG_AUX_DIR(autoconf) AC_CONFIG_HEADERS(config.h) diff --git a/man/sex.1 b/man/sex.1 index bd99e99..6a0b2ee 100644 --- a/man/sex.1 +++ b/man/sex.1 @@ -1,4 +1,4 @@ -.TH SEXTRACTOR "1" "July 2012" "SExtractor 2.18.1" "User Commands" +.TH SEXTRACTOR "1" "July 2012" "SExtractor 2.18.2" "User Commands" .SH NAME sex \- extract a source catalogue from an astronomical FITS image .SH SYNOPSIS diff --git a/src/fft.c b/src/fft.c index d0f1f15..60fc091 100644 --- a/src/fft.c +++ b/src/fft.c @@ -22,7 +22,7 @@ * You should have received a copy of the GNU General Public License * along with SExtractor. If not, see . * -* Last modified: 09/07/2012 +* Last modified: 12/07/2012 * *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ @@ -120,7 +120,7 @@ void fft_reset(void) { if (fplan) { - QFFTWFREE(fdata1); + QFFTWF_FREE(fdata1); fftwf_destroy_plan(fplan); } if (bplan) @@ -141,7 +141,7 @@ OUTPUT -. NOTES For data1 and fdata2, memory must be allocated for size[0]* ... * 2*(size[naxis-1]/2+1) floats (padding required). AUTHOR E. Bertin (IAP) -VERSION 09/07/2012 +VERSION 12/07/2012 ***/ void fft_conv(float *data1, float *fdata2, int *size) { @@ -156,7 +156,7 @@ void fft_conv(float *data1, float *fdata2, int *size) /* Forward FFT "in place" for data1 */ if (!fplan) { - QFFTWMALLOC(fdata1, fftwf_complex, npix2); + QFFTWF_MALLOC(fdata1, fftwf_complex, npix2); fplan = fftwf_plan_dft_r2c_2d(size[1], size[0], data1, (fftwf_complex *)fdata1, FFTW_ESTIMATE); } @@ -196,7 +196,7 @@ INPUT ptr to the image, OUTPUT Pointer to the compressed, memory-allocated Fourier transform. NOTES Input data may end up corrupted. AUTHOR E. Bertin (IAP) -VERSION 08/10/2009 +VERSION 12/07/2012 ***/ float *fft_rtf(float *data, int *size) { @@ -208,7 +208,7 @@ float *fft_rtf(float *data, int *size) npix2 = ((size[0]/2) + 1) * size[1]; /* Forward FFT "in place" for data1 */ - QFFTWMALLOC(fdata, fftwf_complex, npix2); + QFFTWF_MALLOC(fdata, fftwf_complex, npix2); plan = fftwf_plan_dft_r2c_2d(size[1], size[0], data, fdata, FFTW_ESTIMATE); fftwf_execute(plan); fftwf_destroy_plan(plan); diff --git a/src/fft.h b/src/fft.h index d7a1ae4..4a4fd33 100644 --- a/src/fft.h +++ b/src/fft.h @@ -22,7 +22,7 @@ * You should have received a copy of the GNU General Public License * along with SExtractor. If not, see . * -* Last modified: 09/07/2012 +* Last modified: 12/07/2012 * *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ @@ -33,11 +33,12 @@ /*---------------------------- Internal constants ---------------------------*/ /*------------------------------- Other Macros ------------------------------*/ -#define QFFTWMALLOC(ptr, typ, nel) \ +#define QFFTWF_MALLOC(ptr, typ, nel) \ {if (!(ptr = (typ *)fftwf_malloc((size_t)(nel)*sizeof(typ)))) \ error(EXIT_FAILURE, "Not enough memory for ", \ #ptr " (" #nel " elements) !");;} -#define QFFTWFREE(ptr) fftwf_free(ptr) +#define QFFTWF_FREE(ptr) \ + {fftwf_free(ptr); ptr=NULL;} /*--------------------------- structure definitions -------------------------*/ diff --git a/src/field.c b/src/field.c index ef989cf..8d11ce8 100644 --- a/src/field.c +++ b/src/field.c @@ -22,7 +22,7 @@ * You should have received a copy of the GNU General Public License * along with SExtractor. If not, see . * -* Last modified: 26/06/2012 +* Last modified: 12/07/2012 * *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ @@ -50,18 +50,17 @@ /********************************* newfield **********************************/ /* -Returns a pointer to a new field, ready to go! +Returns a pointer to a new field for extension ext, ready to go! */ -picstruct *newfield(char *filename, int flags, int nok) +picstruct *newfield(char *filename, int flags, int ext) { picstruct *field; catstruct *cat; tabstruct *tab; char *pstr; - int nok2, ntab, margin; + int ext2, nok, ntab, margin; -/* Move to nok'th valid FITS image extension */ if (!(cat = read_cat(filename))) error(EXIT_FAILURE, "*Error*: cannot open ", filename); @@ -69,12 +68,25 @@ picstruct *newfield(char *filename, int flags, int nok) QCALLOC(field, picstruct, 1); field->flags = flags; field->cat = cat; + nok = 0; tab = cat->tab; - nok2 = nok; - for (ntab=cat->ntab; nok-- && ntab--;) + if (tab->naxis >= 2 + && strncmp(tab->xtension, "BINTABLE", 8) + && strncmp(tab->xtension, "ASCTABLE", 8)) + nok++; + ext2 = ext; + for (ntab=cat->ntab; ext2-- && ntab--;) + { tab=tab->nexttab; - field->tab = tab; + if (tab->naxis >= 2 + && strncmp(tab->xtension, "BINTABLE", 8) + && strncmp(tab->xtension, "ASCTABLE", 8)) + nok++; + } + if (!nok) + error(EXIT_FAILURE, "Not a valid FITS image in ",filename); + field->tab = tab; if (ntab<0) error(EXIT_FAILURE, "Not enough valid FITS image extensions in ",filename); @@ -96,11 +108,11 @@ picstruct *newfield(char *filename, int flags, int nok) /* Check the image exists and read important info (image size, etc...) */ field->file = cat->file; - field->headflag = !read_aschead(field->hfilename, nok2 - 1, field->tab); + field->headflag = !read_aschead(field->hfilename, nok, field->tab); readimagehead(field); if (cat->ntab>1) - sprintf(gstr, " [%d/%d]", nok2, cat->tab->naxis<2? cat->ntab-1 : cat->ntab); + sprintf(gstr, " [%d/%d]", ext, cat->tab->naxis<2? cat->ntab-1 : cat->ntab); QPRINTF(OUTPUT, "----- %s %s%s\n", flags&FLAG_FIELD? "Flagging from:" : (flags&(RMS_FIELD|VAR_FIELD|WEIGHT_FIELD)? diff --git a/src/header.c b/src/header.c index 5e893e3..da03d52 100644 --- a/src/header.c +++ b/src/header.c @@ -22,7 +22,7 @@ * You should have received a copy of the GNU General Public License * along with SExtractor. If not, see . * -* Last modified: 11/10/2010 +* Last modified: 12/07/2012 * *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ @@ -44,12 +44,12 @@ PROTO int read_aschead(char *filename, int frameno, tabstruct *tab) PURPOSE Read a ASCII header file and update the current field's tab INPUT Name of the ASCII file, - Frame number (if extensions), + Frame number (if extensions): 0=first, Tab structure. OUTPUT RETURN_OK if the file was found, RETURN_ERROR otherwise. NOTES -. AUTHOR E. Bertin (IAP) -VERSION 05/02/2010 +VERSION 12/07/2012 ***/ int read_aschead(char *filename, int frameno, tabstruct *tab) { @@ -62,7 +62,7 @@ int read_aschead(char *filename, int frameno, tabstruct *tab) if ((file=fopen(filename, "r"))) { /*- Skip previous ENDs in multi-FITS extension headers */ - for (i=frameno; i--;) + for (i=frameno-1; i--;) while (fgets(str, MAXCHAR, file) && strncmp(str,"END ",4) && strncmp(str,"END\n",4)); diff --git a/src/makeit.c b/src/makeit.c index 6a075c6..11770d5 100644 --- a/src/makeit.c +++ b/src/makeit.c @@ -22,7 +22,7 @@ * You should have received a copy of the GNU General Public License * along with SExtractor. If not, see . * -* Last modified: 13/06/2012 +* Last modified: 12/07/2012 * *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ @@ -78,7 +78,7 @@ void makeit() unsigned int modeltype; int nflag[MAXFLAG], nparam2[2], i, nok, ntab, next, ntabmax, forcextflag, - nima0,nima1, nweight0,nweight1, npat,npat0; + nima0,nima1, nweight0,nweight1, npsf0,npsf1, npat,npat0; /* Install error logging */ error_installfunc(write_error); @@ -108,17 +108,40 @@ void makeit() readcatparams(prefs.param_name); useprefs(); /* update things accor. to prefs parameters */ +/* Check if a specific extension should be loaded */ + if ((nima0=selectext(prefs.image_name[0])) != RETURN_ERROR) + { + forcextflag = 1; + ntabmax = next = 1; + } + else + forcextflag = 0; + +/* Do the same for other data (but do not force single extension mode) */ + nima1 = selectext(prefs.image_name[1]); + nweight0 = selectext(prefs.wimage_name[0]); + nweight1 = selectext(prefs.wimage_name[1]); + if (prefs.dpsf_flag) + { + npsf0 = selectext(prefs.psf_name[0]); + npsf1 = selectext(prefs.psf_name[1]); + } + else + npsf0 = selectext(prefs.psf_name[0]); + for (i=0; inexttab) { /*-- Check for the next valid image extension */ @@ -302,11 +308,12 @@ printf("%d\n", nima0); || !strncmp(imatab->xtension, "BINTABLE", 8) || !strncmp(imatab->xtension, "ASCTABLE", 8))) continue; + nok++; /*-- Initial time measurement*/ time(&thetime1); - thecat.currext = nok+1; + thecat.currext = nok; dfield = field = wfield = dwfield = NULL; @@ -314,9 +321,9 @@ printf("%d\n", nima0); { /*---- Init the Detection and Measurement-images */ dfield = newfield(prefs.image_name[0], DETECT_FIELD, - nima0<0? nok:nima0); + nima0<0? ntab:nima0); field = newfield(prefs.image_name[1], MEASURE_FIELD, - nima1<0? nok:nima1); + nima1<0? ntab:nima1); if ((field->width!=dfield->width) || (field->height!=dfield->height)) error(EXIT_FAILURE, "*Error*: Frames have different sizes",""); /*---- Prepare interpolation */ @@ -328,7 +335,7 @@ printf("%d\n", nima0); else { field = newfield(prefs.image_name[0], DETECT_FIELD | MEASURE_FIELD, - nima0<0? nok:nima0); + nima0<0? ntab:nima0); /*-- Prepare interpolation */ if ((prefs.dweight_flag || prefs.weight_flag) @@ -349,7 +356,7 @@ printf("%d\n", nima0); { /*-------- First: the "measurement" weights */ wfield = newweight(prefs.wimage_name[1],field,prefs.weight_type[1], - nweight1<0? nok:nweight1); + nima1<0? ntab : (nweight1<0?1:nweight1)); wtype = prefs.weight_type[1]; interpthresh = prefs.weight_thresh[1]; /*-------- Convert the interpolation threshold to variance units */ @@ -366,13 +373,13 @@ printf("%d\n", nima0); if (prefs.weight_type[0] == WEIGHT_FROMINTERP) { dwfield=newweight(prefs.wimage_name[0],wfield,prefs.weight_type[0], - nweight0<0? nok:nweight0); + nima0<0? ntab : (nweight0<0? 1 :nweight0)); weight_to_var(wfield, &interpthresh, 1); } else { dwfield = newweight(prefs.wimage_name[0], dfield?dfield:field, - prefs.weight_type[0], nweight0<0? nok:nweight0); + prefs.weight_type[0], nima0<0? ntab : (nweight0<0?1:nweight0)); weight_to_var(dwfield, &interpthresh, 1); } dwfield->weight_thresh = interpthresh; @@ -385,7 +392,7 @@ printf("%d\n", nima0); { /*------ Single-weight-map mode */ wfield = newweight(prefs.wimage_name[0], dfield?dfield:field, - prefs.weight_type[0], nweight0<0? nok:nweight0); + prefs.weight_type[0], nima0<0? ntab : (nweight0<0?1:nweight0)); wtype = prefs.weight_type[0]; interpthresh = prefs.weight_thresh[0]; /*------ Convert the interpolation threshold to variance units */ @@ -401,7 +408,7 @@ printf("%d\n", nima0); for (i=0; iwidth!=field->width) || (pffield[i]->height!=field->height)) error(EXIT_FAILURE, @@ -452,7 +459,7 @@ printf("%d\n", nima0); if ((check=prefs.check[i])) reinitcheck(field, check); - if (nok || forcextflag) + if (!forcextflag && nok>1) { if (prefs.psf_flag) { @@ -462,11 +469,11 @@ printf("%d\n", nima0); if (prefs.dpsf_flag) { psf_end(thedpsf, thedpsfit); - thedpsf = psf_load(prefs.psf_name[0], nima0<0? nok:nima0); - thepsf = psf_load(prefs.psf_name[1], nima1<0? nok:nima1); + thedpsf = psf_load(prefs.psf_name[0], nok); + thepsf = psf_load(prefs.psf_name[1], nok); } else - thepsf = psf_load(prefs.psf_name[0],nima0<0? nok:nima0); + thepsf = psf_load(prefs.psf_name[0], nok); } if (prefs.prof_flag) @@ -548,8 +555,8 @@ printf("%d\n", nima0); reendcat(); /* Update XML data */ - if (prefs.xml_flag || prefs.cat_type==ASCII_VO) - update_xml(&thecat, dfield? dfield:field, field, + if (prefs.xml_flag || prefs.cat_type==ASCII_VO) + update_xml(&thecat, dfield? dfield:field, field, dwfield? dwfield:wfield, wfield); @@ -570,7 +577,7 @@ printf("%d\n", nima0); thecat.ndetect, thecat.ntotal); } - if (nok<0) + if (nok<=0) error(EXIT_FAILURE, "Not enough valid FITS image extensions in ", prefs.image_name[0]); free_cat(&imacat, 1); diff --git a/src/profit.c b/src/profit.c index aee3493..2038436 100644 --- a/src/profit.c +++ b/src/profit.c @@ -22,7 +22,7 @@ * You should have received a copy of the GNU General Public License * along with SExtractor. If not, see . * -* Last modified: 06/06/2012 +* Last modified: 12/07/2012 * *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ @@ -39,10 +39,6 @@ #include #include -#ifndef FFTW3_H -#include FFTW_H -#endif - #include "define.h" #include "globals.h" #include "prefs.h" @@ -130,7 +126,7 @@ INPUT Prof structure. OUTPUT -. NOTES -. AUTHOR E. Bertin (IAP) -VERSION 06/04/2010 +VERSION 12/07/2012 ***/ void profit_end(profitstruct *profit) { @@ -149,7 +145,7 @@ void profit_end(profitstruct *profit) free(profit->resi); free(profit->prof); free(profit->covar); - fftwf_free(profit->psfdft); + QFFTWF_FREE(profit->psfdft); free(profit); return; @@ -170,7 +166,7 @@ OUTPUT Pointer to an allocated fit structure (containing details about the fit). NOTES It is a modified version of the lm_minimize() of lmfit. AUTHOR E. Bertin (IAP) -VERSION 06/06/2012 +VERSION 12/07/2012 ***/ void profit_fit(profitstruct *profit, picstruct *field, picstruct *wfield, @@ -196,10 +192,8 @@ void profit_fit(profitstruct *profit, nprof = profit->nprof; if (profit->psfdft) - { - fftwf_free(profit->psfdft); - profit->psfdft = NULL; - } + QFFTWF_FREE(profit->psfdft); + psf = profit->psf; profit->pixstep = psf->pixstep; @@ -761,9 +755,7 @@ profit->niter = profit_minimize(profit, PROFIT_MAXITER); pprofit = thepprofit; nparam = pprofit->nparam; if (pprofit->psfdft) - { - QFREE(pprofit->psfdft); - } + QFFTWF_FREE(pprofit->psfdft); psf = pprofit->psf; pprofit->pixstep = profit->pixstep; pprofit->guesssigbkg = profit->guesssigbkg; @@ -802,9 +794,7 @@ profit->niter = profit_minimize(profit, PROFIT_MAXITER); qprofit = theqprofit; nparam = qprofit->nparam; if (qprofit->psfdft) - { - QFREE(qprofit->psfdft); - } + QFFTWF_FREE(qprofit->psfdft); qprofit->pixstep = profit->pixstep; qprofit->guesssigbkg = profit->guesssigbkg; qprofit->guessdx = profit->guessdx; @@ -898,7 +888,7 @@ OUTPUT Pointer to an allocated fit structure (containing details about the fit). NOTES It is a modified version of the lm_minimize() of lmfit. AUTHOR E. Bertin (IAP) -VERSION 08/12/2011 +VERSION 12/07/2012 ***/ void profit_dfit(profitstruct *profit, profitstruct *dprofit, picstruct *field, picstruct *dfield, @@ -921,9 +911,7 @@ void profit_dfit(profitstruct *profit, profitstruct *dprofit, nparam2 = nparam*nparam; nprof = dprofit->nprof; if (dprofit->psfdft) - { - QFREE(dprofit->psfdft); - } + QFFTWF_FREE(dprofit->psfdft); dpsf = dprofit->psf; dprofit->pixstep = dpsf->pixstep; @@ -2418,7 +2406,7 @@ INPUT Profile-fitting structure. OUTPUT Vector of residuals. NOTES -. AUTHOR E. Bertin (IAP) -VERSION 18/05/2011 +VERSION 12/07/2012 ***/ float profit_spiralindex(profitstruct *profit) { @@ -2513,8 +2501,8 @@ float profit_spiralindex(profitstruct *profit) free(dx); free(dy); - free(fdx); - free(fdy); + QFFTWF_FREE(fdx); + QFFTWF_FREE(fdy); free(gdx); free(gdy); diff --git a/src/psf.c b/src/psf.c index b1d11f9..015f832 100644 --- a/src/psf.c +++ b/src/psf.c @@ -22,7 +22,7 @@ * You should have received a copy of the GNU General Public License * along with SExtractor. If not, see . * -* Last modified: 13/06/2012 +* Last modified: 12/07/2012 * *%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/ @@ -127,7 +127,6 @@ psfstruct *psf_load(char *filename, int ext) char *head, *ci,*co; int deg[POLY_MAXDIM], group[POLY_MAXDIM], ndim, ngroup, e,i,k; - /* Open the cat (well it is not a "cat", but simply a FITS file */ if (!(cat = read_cat(filename))) error(EXIT_FAILURE, "*Error*: PSF file not found: ", filename); @@ -142,7 +141,8 @@ psfstruct *psf_load(char *filename, int ext) strcpy(psf->name, filename); tab = cat->tab; - for (i=cat->ntab, e=ext; i-- && (strcmp("PSF_DATA",tab->extname) || e--); + for (i=cat->ntab, e=ext?ext-1 : 0; + i-- && (strcmp("PSF_DATA",tab->extname) || e--); tab = tab->nexttab); if (i<0) error(EXIT_FAILURE, "*Error*: PSF_DATA table not found in catalog ", -- GitLab