/*
* prefs.c
*
* Functions related to run-time configurations.
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*
* This file part of: SExtractor
*
* Copyright: (C) 1993-2020 IAP/CNRS/SorbonneU
*
* License: GNU General Public License
*
* SExtractor is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* SExtractor is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with SExtractor. If not, see .
*
* Last modified: 15/07/2020
*
*%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include
#include
#include
#include
#include
#include
#if defined(USE_THREADS) \
&& (defined(__APPLE__) || defined(FREEBSD) || defined(NETBSD)) /* BSD, Apple */
#include
#include
#elif defined(USE_THREADS) && defined(HAVE_MPCTL) /* HP/UX */
#include
#endif
#ifdef HAVE_MKL
#include MKL_H
#endif
#include "define.h"
#include "globals.h"
#include "back.h"
#include "prefs.h"
#include "preflist.h"
#include "fits/fitscat.h"
int findkeys(char *str, char key[][32], int mode);
prefstruct prefs;
/********************************* dumpprefs ********************************/
/*
Print the default preference parameters.
*/
void dumpprefs(int state)
{
char **dp;
dp = default_prefs;
while (**dp)
if (**dp != '*')
printf("%s\n",*(dp++));
else if (state)
printf("%s\n",*(dp++)+1);
else
dp++;
return;
}
/********************************* readprefs ********************************/
/*
Read a configuration file in ``standard'' format (see the SExtractor
documentation)
*/
void readprefs(char *filename, char **argkey, char **argval, int narg)
{
FILE *infile;
char *cp, str[MAXCHARL], *keyword, *value, **dp;
int i, ival, nkey, warn, argi, flagc, flagd, flage, flagz;
float dval;
#ifndef NO_ENVVAR
static char value2[MAXCHARL],envname[MAXCHAR];
char *dolpos;
#endif
if ((infile = fopen(filename,"r")) == NULL)
{
flage = 1;
warning(filename, " not found, using internal defaults");
}
else
flage = 0;
/*Build the keyword-list from pkeystruct-array */
for (i=0; key[i].name[0]; i++)
strcpy(keylist[i], key[i].name);
keylist[i][0] = '\0';
/*Scan the configuration file*/
argi=0;
flagc = 0;
flagd = 1;
dp = default_prefs;
for (warn=0;;)
{
if (flagd)
{
if (**dp)
{
if (**dp=='*')
strcpy(str, *(dp++)+1);
else
strcpy(str, *(dp++));
}
else
flagd = 0;
}
if (!flagc && !flagd)
if (flage || !fgets(str, MAXCHARL, infile))
flagc=1;
if (flagc)
{
if (argi=10)
error(EXIT_FAILURE, "*Error*: No valid keyword found in ", filename);
nkey = findkeys(keyword, keylist, FIND_STRICT);
if (nkey!=RETURN_ERROR)
{
value = strtok((char *)NULL, notokstr);
#ifndef NO_ENVVAR
/*------ Expansion of environment variables (preceded by '$') */
if (value && (dolpos=strchr(value, '$')))
{
int nc;
char *valuet,*value2t, *envval;
value2t = value2;
valuet = value;
while (dolpos)
{
while (valuet=key[nkey].dmin && dval<=key[nkey].dmax)
*(double *)(key[nkey].ptr) = dval;
else
error(EXIT_FAILURE, keyword," keyword out of range");
break;
case P_INT:
if (!value || value[0]==(char)'#')
error(EXIT_FAILURE, keyword," keyword has no value!");
ival = atoi(value);
if (ival>=key[nkey].imin && ival<=key[nkey].imax)
*(int *)(key[nkey].ptr) = ival;
else
error(EXIT_FAILURE, keyword, " keyword out of range");
break;
case P_STRING:
if (!value || value[0]==(char)'#')
error(EXIT_FAILURE, keyword," string is empty!");
strcpy((char *)key[nkey].ptr, value);
break;
case P_BOOL:
if (!value || value[0]==(char)'#')
error(EXIT_FAILURE, keyword," keyword has no value!");
if ((cp = strchr("yYnN", (int)value[0])))
*(int *)(key[nkey].ptr) = (tolower((int)*cp)=='y')?1:0;
else
error(EXIT_FAILURE, keyword, " value must be Y or N");
break;
case P_KEY:
if (!value || value[0]==(char)'#')
error(EXIT_FAILURE, keyword," keyword has no value!");
if ((ival = findkeys(value, key[nkey].keylist,FIND_STRICT))
!= RETURN_ERROR)
*(int *)(key[nkey].ptr) = ival;
else
error(EXIT_FAILURE, keyword, " set to an unknown keyword");
break;
case P_BOOLLIST:
for (i=0; i=key[nkey].nlistmax)
error(EXIT_FAILURE, keyword, " has too many members");
if ((cp = strchr("yYnN", (int)value[0])))
((int *)(key[nkey].ptr))[i] = (tolower((int)*cp)=='y')?1:0;
else
error(EXIT_FAILURE, keyword, " value must be Y or N");
value = strtok((char *)NULL, notokstr);
}
if (i=key[nkey].nlistmax)
error(EXIT_FAILURE, keyword, " has too many members");
ival = strtol(value, NULL, 0);
if (ival>=key[nkey].imin && ival<=key[nkey].imax)
((int *)key[nkey].ptr)[i] = ival;
else
error(EXIT_FAILURE, keyword, " keyword out of range");
value = strtok((char *)NULL, notokstr);
}
if (i=key[nkey].nlistmax)
error(EXIT_FAILURE, keyword, " has too many members");
dval = atof(value);
if (dval>=key[nkey].dmin && dval<=key[nkey].dmax)
((double *)key[nkey].ptr)[i] = dval;
else
error(EXIT_FAILURE, keyword, " keyword out of range");
value = strtok((char *)NULL, notokstr);
}
if (i=key[nkey].nlistmax)
error(EXIT_FAILURE, keyword, " has too many members");
if ((ival = findkeys(value, key[nkey].keylist, FIND_STRICT))
!= RETURN_ERROR)
((int *)(key[nkey].ptr))[i] = ival;
else
error(EXIT_FAILURE, keyword, " set to an unknown keyword");
value = strtok((char *)NULL, notokstr);
}
if (i=key[nkey].nlistmax)
error(EXIT_FAILURE, keyword, " has too many members");
free(((char **)key[nkey].ptr)[i]);
QMALLOC(((char **)key[nkey].ptr)[i], char, MAXCHAR);
strcpy(((char **)key[nkey].ptr)[i], value);
value = strtok((char *)NULL, notokstr);
}
if (i0)
prefs.nthreads = ((prefs.nthreads) && nproc>(-prefs.nthreads))?
-prefs.nthreads : nproc;
else
{
prefs.nthreads = prefs.nthreads? -prefs.nthreads : 2;
sprintf(str, "NTHREADS defaulted to %d", prefs.nthreads);
warning("Cannot find the number of CPUs on this system:", str);
}
}
#ifndef HAVE_ATLAS_MP
if (prefs.nthreads>1)
warning("This executable has been compiled using a version of the ATLAS "
"library without support for multithreading. ",
"Performance will be degraded.");
#endif
#else
if (prefs.nthreads != 1)
{
prefs.nthreads = 1;
warning("NTHREADS != 1 ignored: ",
"this build of " BANNER " is single-threaded");
}
#endif
/* We temporarily allow threads for non-multithreaded code (defaulted to 1)*/
#ifdef HAVE_MKL
mkl_set_num_threads(prefs.nthreads);
#endif
/* Override INTEL CPU detection routine to help performance on 3rd-party CPUs */
#if defined(__INTEL_COMPILER) && defined (USE_CPUREDISPATCH)
__get_cpuid(1, &eax, &ebx, &ecx, &edx);
if (ecx&bit_AVX)
__intel_cpu_indicator = 0x20000;
else if (ecx&bit_SSE4_2)
__intel_cpu_indicator = 0x8000;
else if (ecx&bit_SSE4_1)
__intel_cpu_indicator = 0x2000;
else if (ecx&bit_SSSE3)
__intel_cpu_indicator = 0x1000;
else if (ecx&bit_SSE3)
__intel_cpu_indicator = 0x0800;
else if (edx&bit_SSE2)
__intel_cpu_indicator = 0x0200;
else if (edx&bit_SSE)
__intel_cpu_indicator = 0x0080;
else if (edx&bit_MMX)
__intel_cpu_indicator = 0x0008;
else
__intel_cpu_indicator = 0x0001;
#endif
}
/********************************* useprefs **********************************/
/*
Update various structures according to the prefs.
*/
void useprefs()
{
int i, margin, naper;
char *str;
/*-------------------------------- Images ----------------------------------*/
prefs.dimage_flag = (prefs.nimage_name>1);
if(!prefs.dimage_flag)
strcpy(prefs.image_name[1], prefs.image_name[0]);
/*--------------------------------- ASSOC ----------------------------------*/
prefs.assoc_flag = FLAG(obj2.assoc) || FLAG(obj2.assoc_number);
/*-------------------------------- Extracting ------------------------------*/
if (prefs.nthresh_type<2)
prefs.thresh_type[1] = prefs.thresh_type[0];
/*-------------------------------- Deblending ------------------------------*/
prefs.deb_maxarea = (prefs.ext_minareanaper)
naper = prefs.fluxerr_apersize;
if (prefs.mag_apersize>naper)
naper = prefs.mag_apersize;
if (prefs.magerr_apersize>naper)
naper = prefs.magerr_apersize;
if (naper>prefs.naper)
{
warning("Not enough apertures provided in config.:\n",
" some APER photometric values will remain blank ");
naper = prefs.naper;
}
else
prefs.naper = naper;
}
else
naper = 0; /* To avoid gcc -Wall warnings */
/* Find the largest "minimum margin" necessary for apertures */
prefs.cleanmargin = 0;
if (FLAG(obj2.vignet)
&& (margin=(prefs.vignetsize[1]+1)/2) > prefs.cleanmargin)
prefs.cleanmargin = margin;
if (FLAG(obj2.vigshift)
&& (margin=(prefs.vigshiftsize[1]+1)/2+3)>prefs.cleanmargin)
prefs.cleanmargin = margin;
if (FLAG(obj2.flux_aper))
for (i=0; i prefs.cleanmargin)
prefs.cleanmargin = margin;
/* Growth-curve flag */
if (FLAG(obj2.flux_growth)
|| FLAG(obj2.mag_growth)
|| FLAG(obj2.flux_radius)
|| FLAG(obj2.hl_radius)
|| FLAG(obj2.flux_growthstep)
|| FLAG(obj2.mag_growthstep))
prefs.growth_flag = 1;
if (FLAG(obj2.flux_radius) && prefs.flux_radiussize)
if (prefs.nflux_frac>prefs.flux_radiussize)
prefs.nflux_frac = prefs.flux_radiussize;
/*------------------------------- MASKing ----------------------------------*/
prefs.blank_flag = (prefs.mask_type!=MASK_NONE);
/*--------------------------- SOM-fitting ----------------------------------*/
prefs.somfit_flag = FLAG(obj2.flux_somfit);
/*------------------------------ Background --------------------------------*/
if (prefs.nback_type<2)
prefs.back_type[1] = prefs.back_type[0];
if (prefs.nback_val<2)
prefs.back_val[1] = prefs.back_val[0];
if (prefs.nbacksize<2)
prefs.backsize[1] = prefs.backsize[0];
if (prefs.nbackfsize<2)
prefs.backfsize[1] = prefs.backfsize[0];
/*------------------------------ FLAG-images -------------------------------*/
prefs.nimaisoflag = (prefs.imaflag_size > prefs.imanflag_size) ?
prefs.imaflag_size : prefs.imanflag_size;
prefs.nimaflag = (prefs.nimaisoflag < prefs.nfimage_name) ?
prefs.nimaisoflag : prefs.nfimage_name;
/*----------------------------- CHECK-images -------------------------------*/
prefs.check_flag = 0;
for (i=0; i1);
*/
}
if (prefs.check_flag)
for (i=0; i= prefs.nweight_thresh;)
prefs.weight_thresh[i] = (prefs.weight_type[i]==WEIGHT_FROMWEIGHTMAP)?
0.0 : BIG;
/*-- Weight rescaling flags */
if (prefs.nwscale_flag<2)
prefs.wscale_flag[1] = (prefs.weight_type[1]==WEIGHT_FROMBACK)?
BACK_WSCALE : prefs.wscale_flag[0];
/*-- Check WEIGHT_IMAGE parameter(s) */
if ((!prefs.nwimage_name
&& ((prefs.weight_type[0]!=WEIGHT_FROMBACK
&& prefs.weight_type[0]!=WEIGHT_NONE)
|| (prefs.weight_type[1]!=WEIGHT_FROMBACK
&& prefs.weight_type[1]!=WEIGHT_NONE)))
|| (prefs.nwimage_name<2
&& prefs.weight_type[0]!=WEIGHT_FROMBACK
&& prefs.weight_type[0]!=WEIGHT_NONE
&& prefs.weight_type[1]!=WEIGHT_FROMBACK
&& prefs.weight_type[1]!=WEIGHT_NONE
&& prefs.weight_type[0]!=prefs.weight_type[1]))
error(EXIT_FAILURE, "*Error*: WEIGHT_IMAGE missing","");
if (prefs.nwimage_name && prefs.nwimage_name<2)
prefs.wimage_name[1] = prefs.wimage_name[0];
if (prefs.nwimage_name==2 && prefs.nweight_type==1)
prefs.nweight_type = 2;
/*-- If detection-only interpolation is needed with 1 Weight image... */
/*-- ...pretend we're using 2, with only one being interpolated */
if (prefs.nweight_type==1
&& prefs.nwimage_name && prefs.nwimage_name < 2
&& prefs.interp_type[0]==INTERP_VARONLY )
{
prefs.nwimage_name = prefs.nweight_type = 2;
prefs.weight_type[0] = WEIGHT_FROMINTERP;
QMEMCPY(prefs.wimage_name[0], prefs.wimage_name[1], char,
strlen(prefs.wimage_name[0])+1);
prefs.interp_type[1] = INTERP_NONE;
prefs.dweight_flag = 1;
if (prefs.nweight_thresh<2)
{
prefs.nweight_thresh = 2;
prefs.weight_thresh[1] = prefs.weight_thresh[0];
}
}
}
/*------------------------------ Catalogue ---------------------------------*/
if (!strcmp(prefs.cat_name, "STDOUT"))
prefs.pipe_flag = 1;
if ((str=strrchr(prefs.filter_name, '/')))
strcpy(thecat.filter_name, str+1);
else
strcpy(thecat.filter_name, prefs.filter_name);
if ((str=strrchr(prefs.prefs_name, '/')))
strcpy(thecat.prefs_name, str+1);
else
strcpy(thecat.prefs_name, prefs.prefs_name);
if ((str=strrchr(prefs.nnw_name, '/')))
strcpy(thecat.nnw_name, str+1);
else
strcpy(thecat.nnw_name, prefs.nnw_name);
if ((str=strrchr(prefs.image_name[prefs.nimage_name-1], '/')))
strcpy(thecat.image_name, str+1);
else
strcpy(thecat.image_name, prefs.image_name[prefs.nimage_name-1]);
sprintf(thecat.soft_name, "%s %s", BANNER, VERSION);
return;
}
/********************************* endprefs *********************************/
/*
Mostly free memory allocate for static arrays.
*/
void endprefs(void)
{
int i;
for (i=0; i