def setFolderName(self, name): # Turn the result folder path into absolute path if name.startswith('/home') or name.startswith('~'): self._FolderName = name else: self._FolderName = os.path.join(af.CurrentPath, name) if self._ScanMethod in af._post: if not os.path.exists(self._FolderName): af.ErrorStop("The result folder %s does not exist."%self._FolderName) if self._ScanMethod == af._postprocess: # Backup previous results self.backup_result(self._FolderName, cp=True) # rm Figure and SavedFile folder os.system(r"find %s -type f -name '*' | xargs rm" %os.path.join(self._FolderName,'SavedFile')) os.system(r"find %s -type f -name '*' | xargs rm" %os.path.join(self._FolderName,'Figures')) # rename data file if not os.path.exists(os.path.join(self._FolderName,af.ResultFile_post)): if not os.path.exists(os.path.join(self._FolderName,af.ResultFile)): af.ErrorStop("No result data file in %s."%self._FolderName) else: os.system(r"mv %s %s"%(os.path.join(self._FolderName, af.ResultFile), os.path.join(self._FolderName, af.ResultFile_post))) else: if af.flag_resume: # TODO Add resume af.ErrorStop("no resume function") else: # af._plot if not os.path.exists(os.path.join(self._FolderName,af.ResultFile)): af.ErrorStop("No result data file in %s."%self._FolderName) else: # Deal with the situation that the result folder already exists. if os.path.exists(self._FolderName): af.Info(("* The Result file [%s] already exists." % name )) while True: c = input("Choose: (r)replace, (b)backup, (s)stop\n") if c == "r": os.system(r"rm -r %s" %self._FolderName) break elif c == "b": self.backup_result(self._FolderName) break elif c == "s": exit(1) else: af.Info("Wrong input! Please type in one of ('r','b','s')") # Create result folder os.mkdir(self._FolderName) os.mkdir(os.path.join(self._FolderName,'SavedFile')) if self._ScanMethod == af._multinest: self.MNOutputFile = os.path.join(self._FolderName, "MultiNestData/") os.mkdir(self.MNOutputFile) af.Info('...............................................') af.Info('Result file name = %s'%self._FolderName)
def setRandomSeed(self, iseed): self._RandomSeed = int(iseed) # If iseed is provided in the input file, initialize the basic random number generator # Otherwise, it will be initialized by current system time, and self._RandomSeed = -1, # which means also initialized by current system time in MultiNest random.seed( self._RandomSeed ) af.Info('Random seed = %s'%self._RandomSeed)
def postprocessrun(LnLike, n_params, inpar, fixedpar, outpar, bin_num, n_print, outputfolder): data_file = open(os.path.join(outputfolder, af.ResultFile), 'a') file_path = os.path.join(outputfolder, "SavedFile") n_dims = len(inpar) if not os.path.exists(file_path): os.makedirs(file_path) # Read data using ploter Data = ploter.PLOTER() Data.setPlotPar(outputfolder, af._plot, postprocess=True) data = Data._data if not Data.checkPar([i for i in inpar], n_dims, section_name="scan"): af.ErrorStop('Can not postprocess it.') ntotal = data.shape[0] # Initialise cube cube = [af.NaN] * n_params af.Info('Begin read scan ...') Naccept = 0 for Nrun in range(ntotal): for i, name in enumerate(inpar): cube[i] = data[name][Nrun] lnlike = LnLike(cube, n_dims, n_params) if lnlike > af.log_zero: Naccept += 1 saveCube(cube, data_file, file_path, str(Naccept), True) if (Nrun + 1) % n_print == 0: printPoint(Nrun + 1, cube, n_dims, inpar, fixedpar, outpar, lnlike, Naccept)
def randomrun(LnLike, Prior, n_params, inpar, fixedpar, outpar, n_live_points, n_print, outputfolder): data_file = open(os.path.join(outputfolder, af.ResultFile), 'a') file_path = os.path.join(outputfolder, "SavedFile") n_dims = len(inpar) # Initialise cube cube = [af.NaN] * n_params af.Info('Begin random scan ...') Naccept = 0 for Nrun in range(n_live_points): for j in range(n_dims): cube[j] = random() Prior(cube, n_dims, n_params) lnlike = LnLike(cube, n_dims, n_params) if lnlike > af.log_zero: Naccept += 1 saveCube(cube, data_file, file_path, str(Naccept), True) if (Nrun + 1) % n_print == 0: printPoint(Nrun + 1, cube, n_dims, inpar, fixedpar, outpar, lnlike, Naccept)
def setPrintNum(self, nprint): self._PrintNum = int(nprint) if self._PrintNum < 1 : af.ErrorStop('"Interval of print" should be larger than 0') af.Info('Interval of print = %s'%self._PrintNum) af.Info(' If all elements defined in "Output variable" are read by easyscan successfully,') af.Info(' easyscan would show information as following every interval') af.Info(' ------------ Num: # ------------') af.Info(' Input - = ') af.Info(' Output - = ') af.Info(' LnLike = ') af.Info(' Accepted Num = ') af.Info(' Total Num = ')
def backup_result(self, FolderName, cp=False): if not os.path.exists(os.path.join(af.CurrentPath,"Backup")): os.mkdir(os.path.join(af.CurrentPath,"Backup")) BackupTime = time.strftime("_%Y_%m_%d_%H_%M_%S", time.localtime()) name = os.path.basename(os.path.normpath(FolderName)) BackupPath = os.path.join(af.CurrentPath,"Backup/%s%s"%(name, BackupTime)) action = r'cp -r ' if cp else r'mv ' af.Info('Back up previous result into %s.'%BackupPath) os.system(action+r" %s %s" %(FolderName, BackupPath))
def setFreeFormChi2(self, var): var = af.string2nestlist(var) af.Info('FreeFormChi2:') for ii in var: if len(ii) in [1, 2]: if len(ii) == 1: jj = ii + ['FreeFormChi2_%s' % ii[0]] else: jj = ii self._FreeFormChi2.append(jj) af.Info(' varID= %s\tName= %s' % (jj[0], jj[1])) self.Chi2[jj[1]] = af.NaN else: af.ErrorStop( 'The "FreeFormChi2" constraint on "%s" need 1 item or 2 items( VarID [, Name] ).' % (ii[0])) self.Chi2 = af.sortDic(self.Chi2)
def printPoint4MCMC(Chisq, CurChisq, MinChisq, AccRat, FlagTuneR, kcovar): af.Info('........... MCMC info .............') af.Info('Test Chi^2 = ' + str(Chisq)) af.Info('Current Chi^2 = ' + str(CurChisq)) af.Info('Mimimum Chi^2 = ' + str(MinChisq)) af.Info('Accepted Ratio = ' + str(AccRat)) if FlagTuneR: af.Info('StepZize factor= ' + str(exp(kcovar)))
def printPoint(Numrun, cube, n_dims, inpar, fixedpar, outpar, lnlike, Naccept): if Numrun == 0: af.Info('------------ Start Point ------------') else: af.Info('------------ Num: %i ------------' % Numrun) for i, name in enumerate(inpar): af.Info('Input - %s = %s ' % (name, cube[i])) for i, name in enumerate(fixedpar): af.Info('Input - %s = %s ' % (name, cube[i + n_dims])) for i, name in enumerate(outpar): outVar = cube[i + n_dims + len(fixedpar)] try: float(outVar) af.Info('Output - %s = %s ' % (name, outVar)) except: if '/' not in outVar: af.Info('Output - %s = %s ' % (name, outVar)) af.Info('LnLike = ' + str(lnlike)) if Numrun == 0: af.Info('Initial lnlike = ' + str(-2 * lnlike)) af.Info('Accepted Num = ' + str(Naccept)) af.Info('Total Num = ' + str(Numrun))
def setGaussian(self, var): var = af.string2nestlist(var) af.Info('Gaussian Constraint:') for ii in var: if len(ii) in [3]: jj = ii + ['symm', 'Gaussian_%s' % ii[0]] self._Gaussian.append(jj) self.Chi2[jj[4]] = af.NaN af.Info( ' varID= %s\tMean= %e\tDeviation= %e\tType= %s\tName= %s' % (jj[0], jj[1], jj[2], jj[3], jj[4])) elif len(ii) in [4, 5]: if not ii[3].lower() in ['symm', 'lower', 'upper']: af.ErrorStop( 'For the "Gaussian" constraint on "%s", the "Type" can only be "symm", "upper" or "lower", not "%s".' % (ii[0], ii[3])) ## new 20180428 liang if len(ii) == 4: jj = ii + ['Gaussian_%s' % ii[0]] else: jj = ii self._Gaussian.append(jj) self.Chi2[jj[4]] = af.NaN af.Info( ' varID= %s\tMean= %e\tDeviation= %e\tType= %s\tName= %s' % (jj[0], jj[1], jj[2], jj[3], jj[4])) else: af.ErrorStop( 'The "Gaussian" constraint on "%s" need 4 or 5 items( ID, Mean, Deviation, Type [, Name] ).' % (ii[0])) ## new 20180428 liang self.Chi2 = af.sortDic(self.Chi2)
def gridrun(LnLike, Prior, n_params, inpar, fixedpar, outpar, bin_num, n_print, outputfolder): data_file = open(os.path.join(outputfolder, af.ResultFile), 'a') file_path = os.path.join(outputfolder, "SavedFile") n_dims = len(inpar) ntotal = 1 interval = {} for i, name in enumerate(inpar): try: interval[name] = 1.0 / bin_num[name] except ZeroDivisionError: af.ErrorStop( 'The number of intervals in grid scanning could not be zero.') bin_num[name] += 1 ntotal *= bin_num[name] # Initialise cube cube = [af.NaN] * n_params af.Info('Begin grid scan ...') Naccept = 0 for Nrun in range(ntotal): iner = 1 for i, name in enumerate(inpar): cube[i] = (int(Nrun / iner)) % bin_num[name] * interval[name] iner *= bin_num[name] for i, name in enumerate(outpar): cube[i + n_dims] = af.NaN Prior(cube, n_dims, n_params) lnlike = LnLike(cube, n_dims, n_params) if lnlike > af.log_zero: Naccept += 1 saveCube(cube, data_file, file_path, str(Naccept), True) if (Nrun + 1) % n_print == 0: printPoint(Nrun + 1, cube, n_dims, inpar, fixedpar, outpar, lnlike, Naccept)
def getPlot(self, ScanMethod): try: import matplotlib except ImportError: af.ErrorStop("No matplotlib module. No plot will be generated.") matplotlib.use('Agg') import matplotlib.pyplot as plt if len(self._Histogram) + len(self._Scatter) + len(self._Color) + len( self._Contour) == 0: return af.Info('Start to plot the result ... ') FigNames = [] for ii in self._Histogram: histconf = { 'bins': 50, 'normed': False, 'facecolor': 'green', 'alpha': 0.7 } af.Info('Generate histogram plot of parameter %s' % ii[0]) if not self.checkPar(ii, 1): continue f = plt.figure(**figconf) subplot = f.add_subplot(111) subplot.hist(self._data[ii[0]], **histconf) subplot.set_xlabel(ii[0], **labelconf) subplot.set_ylabel('Count', **labelconf) subplot.tick_params(which='both', direction='out') plt.savefig(os.path.join(self._path, ii[1])) for ii in self._Scatter: scatterconf = { 's': 50, 'marker': 'o', 'edgecolors': 'None', 'alpha': 0.9 } af.Info('Generate scatter plot of parameter %s and %s' % (ii[0], ii[1])) if not self.checkPar(ii, 2): continue f = plt.figure(**figconf) subplot = f.add_subplot(111) subplot.scatter(self._data[ii[0]], self._data[ii[1]], **scatterconf) subplot.set_xlabel(ii[0], **labelconf) subplot.set_ylabel(ii[1], **labelconf) subplot.tick_params(which='both', direction='out') plt.savefig(os.path.join(self._path, ii[2])) if ScanMethod == af._mcmc: f = plt.figure(**figconf) subplot = f.add_subplot(111) subplot.scatter(self._dataAllTry[ii[0]], self._dataAllTry[ii[1]], label='All', **scatterconf) subplot.scatter(self._data[ii[0]], self._data[ii[1]], label='Surviving', **scatterconf) plt.legend(**legendconf) subplot.set_xlabel(ii[0], **labelconf) subplot.set_ylabel(ii[1], **labelconf) subplot.tick_params(which='both', direction='out') plt.savefig(os.path.join(self._path, 'Compare_%s' % ii[2])) for ii in self._Color: colorconf = {'edgecolors': 'None', 'cmap': plt.get_cmap('winter')} af.Info( 'Generate color plot of parameter %s and %s with color %s' % (ii[0], ii[1], ii[2])) if not self.checkPar(ii, 3): continue f = plt.figure(**figconf) subplot = f.add_subplot(111) weigh = 50 if "probability" in self._data.columns: weigh = self._data["probability"] * 100 / self._data[ "probability"].max() + 20 elif "mult" in self._data.columns: weigh = self._data["mult"] * 100 / self._data["mult"].max() + 20 sc1 = subplot.scatter(self._data[ii[0]], self._data[ii[1]], c=self._data[ii[2]], s=weigh, **colorconf) cb1 = plt.colorbar(sc1) cb1.set_label(ii[2], **labelconf) subplot.set_xlabel(ii[0], **labelconf) subplot.set_ylabel(ii[1], **labelconf) subplot.tick_params(which='both', direction='out') plt.savefig(os.path.join(self._path, ii[3])) for ii in self._Contour: try: from scipy.interpolate import griddata except ImportError: af.WarningNoWait( "No scipy module. Contour plot will not be generated.") break af.Info( 'Generate contour plot of parameter %s and %s with contour %s' % (ii[0], ii[1], ii[2])) if not self.checkPar(ii, 3): continue f = plt.figure(**figconf) subplot = f.add_subplot(111) x = self._data[ii[0]] X = numpy.linspace(min(x), max(x), 100) y = self._data[ii[1]] Y = numpy.linspace(min(y), max(y), 100) # z = [ numpy.log10(abs(u)) for u in self._data[ii[2]] ] # log10 z = self._data[ii[2]] Z = griddata(x, y, z, X, Y, interp='linear') #C = subplot.contour(X,Y,Z, 3,linewidths=2) #plt.clabel(C, inline=True, fontsize=8) ## debug #Cpoint = self.get_contour_verts(C) #numpy.savetxt(os.path.join(self._path, "contour_1_1.dat"),Cpoint[0][0]) C = subplot.contourf(X, Y, Z, 3, cmap=plt.cm.rainbow) cb1 = plt.colorbar(C) cb1.set_label(ii[2], **labelconf) subplot.set_xlabel(ii[0], **labelconf) subplot.set_ylabel(ii[1], **labelconf) subplot.tick_params(which='both', direction='out') plt.savefig(os.path.join(self._path, ii[3]))
def setScanMethod(self, method): self._ScanMethod = method.upper() if self._ScanMethod not in af._all: af.ErrorStop('%s is not a supported scan method'%method) af.Info('Scan method = %s'%self._ScanMethod)
def setInputPar(self, inputvar): inputvar = af.string2nestlist(inputvar) # inputvar is list of list of input parameters define in section [scan] af.Info('Input parameters = ') for ii in inputvar: lenii = len(ii) if self._ScanMethod == af._postprocess: self.InPar[ii[0]] = af.NaN self.AllPar[ii[0]] = af.NaN af.Info(' ID= %s, read from previous '%(ii[0])) continue if lenii < 3 : af.ErrorStop(self.InputCheck(ii[0], 3, "Value")) # Set fixed par if ii[1].upper() == "FIXED": if lenii > 3 : af.WarningNoWait(self.InputCheck(ii[0], 3, "Value")) af.WarningWait("The rest %i values will be ignore."%(lenii-3) ) af.Info(' ID= %s\tPrior= %s\t =%f'%(ii[0],ii[1],ii[2])) self.FixedPar[ii[0]] = ii[2] self.AllPar[ii[0]] = ii[2] continue # Initialize other input par to NaN self.InputPar[ii[0]] = ii self.InPar[ii[0]] = af.NaN self.AllPar[ii[0]] = af.NaN if lenii < 4 : af.ErrorStop(self.InputCheck(ii[0], 4, "Minimum, Maximum")) if self._ScanMethod in [af._random, af._multinest]: if lenii > 4 : af.WarningNoWait(self.InputCheck(ii[0], 4, "Minimum, Maximum")) af.WarningWait("The rest %i values will be ignore."%(lenii-4) ) af.Info(' ID= %s\tPrior= %s\tMin= %f\tMax= %f'%(ii[0],ii[1],ii[2],ii[3])) continue if self._ScanMethod == af._grid: if lenii == 4: self.GridBin[ii[0]]=20 af.WarningNoWait(self.InputCheck(ii[0], 5, "Minimum, Maximum, Number of bins")) af.WarningWait("'Number of bins' will take default value, 20.") else: self.GridBin[ii[0]]=ii[4] if self.GridBin[ii[0]] < 0 or type(ii[4]) != int: af.WarningNoWait(InputCheck(ii[0], 5, "Minimum, Maximum, Number of bins")) af.ErrorStop("'Number of bins' is not a positive integer.") if lenii> 5: af.WarningNoWait(self.InputCheck(ii[0], 5, "Minimum, Maximum, Number of bins")) af.WarningWait("The rest %i values will be ignore."%(lenii-5) ) af.Info(' ID= %s\tPrior= %s\tMin= %f\tMax= %f\tNbin=%i'%(ii[0],ii[1],ii[2],ii[3],self.GridBin[ii[0]])) continue if self._ScanMethod == af._mcmc: if lenii < 6: af.WarningNoWait(self.InputCheck(ii[0], 6, "Minimum, Maximum, Interval, Initial value")) self.MCMCiv[ii[0]] = 1./2. IniV = float(ii[3]+ii[2])/2. af.WarningWait("'Initial value' will take default value, (Max-Min)/2.") if lenii < 5: self.MCMCss[ii[0]] = 1./30. Step = float(ii[3]-ii[2])/30. af.WarningWait("'Interval' will take default value, (Max-Min)/30.") else: # The scan range is normalized to 1 self.MCMCss[ii[0]] = 1.0/float(ii[4]) Step = float(ii[3]-ii[2])/float(ii[4]) if ii[1].lower() == 'flat': self.MCMCiv[ii[0]] = float(ii[5]-ii[2])/float(ii[3]-ii[2]) elif ii[1].lower() == 'log': self.MCMCiv[ii[0]] = (log10(ii[5])-log10(ii[2]))/(log10(ii[3]) - log10(ii[2])) IniV = ii[5] if lenii > 6: af.WarningNoWait(self.InputCheck(ii[0], 6, "Minimum, Maximum, Interval, Initial value")) af.WarningWait("The rest %i values will be ignore."%(lenii-6) ) af.Info(' ID= %s\tPrior= %s\tMin= %f\tMax= %f\tStep=%f\tIniV=%f'%(ii[0],ii[1],ii[2],ii[3],Step,self.MCMCiv[ii[0]])) continue
def setPointNum(self, ntot): self._PointNum = int(ntot) if self._PointNum < 1 : af.ErrorStop('"Number of points" should larger than 0') af.Info('Number of points = %s'%self._PointNum)
def setAccepRate(self, AccepRate): self._AccepRate = float(AccepRate) if self._AccepRate >= 1 or self._AccepRate <= 0: af.ErrorStop('"Acceptance rate" must be in [0,1]. The suggest value is 0.5 for d<=2, 0.25 otherwise.') self._FlagTuneR = True af.Info('Acceptance rate = %s'%self._AccepRate)
def ReadIn(Configfile, ES, Programs, Constraint, Ploter): cf = configparser.ConfigParser() cf.read(Configfile) # Read the basic scan parameters if not ('scan' in cf.sections()): af.ErrorStop(notFind('[scan] section')) try: ES.setScanMethod(cf.get('scan', 'Scan method')) except configparser.NoOptionError: af.ErrorStop(notFind('Scan method')) try: ES.setFolderName(cf.get('scan', 'Result folder name')) except configparser.NoOptionError: af.ErrorStop(notFind('Result folder name')) # Read the plot information # This part is put here, because if ScanMethod = PLOT, the rest of sections can be ignore. plot_items = [] try: plot_items = cf.options("plot") except configparser.NoSectionError: if ES.getScanMethod() == af._plot: af.ErrorStop(notFind('[plot] section')) if 'histogram' in plot_items: Ploter.setHistogram(cf.get('plot', 'Histogram')) if 'scatter' in plot_items: Ploter.setScatter(cf.get('plot', 'Scatter')) if 'color' in plot_items: Ploter.setColor(cf.get('plot', 'Color')) if 'contour' in plot_items: Ploter.setContour(cf.get('plot', 'Contour')) checkDuplicatedName(Ploter._FigNames, "Figure", False) if ES.getScanMethod() == af._plot: return [] # Back to read the basic scan parameters try: ES.setPointNum(cf.getint('scan', 'Number of points')) if ES.getScanMethod() in af._no_random: af.WarningNoWait( '"Number of points" in configure file is not used.') except configparser.NoOptionError: if ES.getScanMethod() in af._no_random: pass else: af.WarningWait(notFind('Number of points') + takeDefault('2')) except ValueError: af.ErrorStop(notInteger("Number of points")) try: ES.setRandomSeed(cf.getint('scan', 'Random seed')) except configparser.NoOptionError: if ES.getScanMethod() not in af._no_random: af.Info("Use current system time as random seed.") except ValueError: af.ErrorStop(notInteger("Random seed")) try: ES.setPrintNum(cf.getint('scan', 'Interval of print')) except configparser.NoOptionError: af.Info(notFind('Interval of print') + takeDefault('1')) ES.setPrintNum('1') except ValueError: af.WarningNoWait(notInteger("Interval of print") + takeDefault('1')) ES.setPrintNum('1') try: ES.setInputPar(cf.get('scan', 'Input parameters')) except configparser.NoOptionError: af.ErrorStop(notFind('Input parameters')) checkDuplicatedName(list(ES.InPar.keys()), "Input parameter") try: ES.setAccepRate(cf.get('scan', 'Acceptance rate')) except configparser.NoOptionError: if ES.getScanMethod() == af._mcmc: af.Info(notFind('Acceptance rate') + takeDefault('0.25')) else: pass ## sort programs by ID ProgID = [x for x in cf.sections() if x.startswith('program')] if len(ProgID) == 0: af.ErrorStop(notFind('[program] section')) for ii in ProgID: if not str.isdigit(ii[7:]): af.ErrorStop('The section name of [%s] is wrong' % ii) ProgID = sorted(ProgID, key=lambda x: int(x[7:])) ## Read the programs sections outputVarNames = [] for ii in ProgID: items = cf.options(ii) Programs[ii] = PROGRAM() if 'program name' in items: Programs[ii].setProgName(cf.get(ii, 'Program name')) else: Programs[ii].setProgName(ii) if 'execute command' in items: Programs[ii].setCommand(cf.get(ii, 'Execute command')) else: af.ErrorStop('No "Execute command" in "%s".' % ii) if 'command path' in items: Programs[ii].setComPath(cf.get(ii, 'Command path')) else: Programs[ii].setComPath('') af.WarningNoWait('Use current path as "Command path" for "%s".' % ii) if 'input file' in items and 'input variable' in items: Programs[ii].setInputFile(cf.get(ii, 'Input file')) Programs[ii].setInputVar(cf.get(ii, 'Input variable')) if 'output file' in items and 'output variable' in items: Programs[ii].setOutputFile(cf.get(ii, 'Output file')) Programs[ii].setOutputVar(cf.get(ii, 'Output variable')) for key, item in Programs[ii]._OutputVar.items(): for subitem in item: outputVarNames.append(subitem[0]) checkDuplicatedName(outputVarNames, "Output variable") # Additional optional commands try: Programs[ii].setExecutor(cf.get(ii, 'Command executor')) except: af.Info('Use "os.system" execute commands.') try: Programs[ii].setOutputClean(cf.get(ii, 'Clean output file')) except: af.Info('Delete output file(s) of %s before execute it. ' % ii) try: Programs[ii].setBound(cf.get(ii, 'Bound')) except: af.Info('No Bound.') if Programs[ii]._executor: # 'os.system' try: Programs[ii].setTimeLimit( cf.getfloat(ii, 'Time limit in minute')) af.WarningNoWait('Time limit of %s is not used.' % ii) except: pass else: # 'subprocess.popen' try: Programs[ii].setTimeLimit( cf.getfloat(ii, 'Time limit in minute')) except: af.Info('No time limit setting. Using defaut value 60 min.') ## Read the constraints constraint_items = [] try: constraint_items = cf.options("constraint") if len(constraint_items) == 0 and (ES.getScanMethod() not in af._no_like): af.ErrorStop( 'Section [constraint] is empty in the configure file.') except configparser.NoSectionError: if ES.getScanMethod() in af._no_like: pass else: af.ErrorStop(notFind('[constraint] section')) af.Info('...............................................') af.Debug('Constraint items:', constraint_items) if 'gaussian' in constraint_items: Constraint.setGaussian(cf.get('constraint', 'Gaussian')) # In order to add "math .." in "Gaussian" to self.AllPar TODO if Programs: Programs[ProgID[0]].setGaussian(cf.get('constraint', 'Gaussian')) if 'freeformchi2' in constraint_items: Constraint.setFreeFormChi2(cf.get('constraint', 'FreeFormChi2')) if Programs: Programs[ProgID[0]].setFreeFormChi2( cf.get('constraint', 'FreeFormChi2')) if ('gaussian' not in constraint_items) and ( 'freeformchi2' not in constraint_items) and (ES.getScanMethod() not in af._no_like): af.ErrorStop('No valid iterm in [constraint] section.') ES.setProgram(Programs) return ProgID