/* * 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