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 checkDuplicatedName(List, name, check_forbidden=True): for item in List: if check_forbidden: if item in af.forbidden_names: af.ErrorStop('%s name "%s" can be used as variable name.' % (name, item)) counter = List.count(item) if counter > 1: af.ErrorStop( '%s name "%s" duplicates %i times in configure file.' % (name, item, counter))
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 setPlotPar(self, path, ScanMethod, postprocess=False): try: import pandas except ImportError: af.ErrorStop("No pandas module. No plot will be generated.") # read result if ScanMethod not in af._post: self._data = pandas.read_csv(os.path.join(path, af.ResultFile), header=0, index_col=False) if ScanMethod == af._mcmc: self._dataAllTry = pandas.read_csv(os.path.join( path, af.ResultFile_MCMC), header=0, index_col=False) elif ScanMethod == af._multinest: column_names = pandas.read_csv( os.path.join(path, af.ResultFile), header=0, index_col=False).columns.str.strip() self._data = pandas.read_csv(os.path.join( path, af.ResultFile_MultiNest), header=None, names=column_names, delim_whitespace=True, index_col=False) else: # ScanMethod == plot or postprocess ResultFile_name = af.ResultFile_post if postprocess else af.ResultFile if os.path.exists(os.path.join(path, af.ResultFile_MultiNest)): column_names = pandas.read_csv( os.path.join(path, ResultFile_name), header=0, index_col=False).columns.str.strip() self._data = pandas.read_csv(os.path.join( path, af.ResultFile_MultiNest), header=None, names=column_names, delim_whitespace=True, index_col=False) else: self._data = pandas.read_csv(os.path.join( path, ResultFile_name), header=0, index_col=False) # make figure folder self._path = os.path.join(path, 'Figures') if not os.path.exists(self._path): os.mkdir(self._path) else: __import__("shutil").rmtree(self._path) os.mkdir(self._path)
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 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 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 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 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 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 mcmcrun(LnLike, Prior, n_params, n_live_points, inpar, fixedpar, outpar, StepSize, AccepRate, FlagTuneR, InitVal, n_print, outputfolder): data_file = open(os.path.join(outputfolder, af.ResultFile), 'a') all_data_file = open(os.path.join(outputfolder, af.ResultFile_MCMC), 'a') file_path = os.path.join(outputfolder, "SavedFile") n_dims = len(inpar) # Initialise cube cube = [af.NaN] * n_params covar = [] # the sigma of gauss distribution, normalized to 1 par = [] # test par, normalized to 1 CurPar = [] # current par, normalized to 1 for i, name in enumerate(inpar): covar.append(StepSize[name]) cube[i] = InitVal[name] par.append(cube[i]) CurPar.append(cube[i]) n_init = 0 while True: Prior(cube, n_dims, n_params) # normalized to cube to real value lnlike = LnLike(cube, n_dims, n_params) AllOutMCMC = cube.copy() AllOutMCMC.append(1) #"True" for saving files of initial physical point saveCube(AllOutMCMC, all_data_file, file_path, '0', False) if lnlike > af.log_zero / 2.0: break if n_init == 0: af.WarningNoWait( 'The initial point is unphysical, it will find the physical initial points randmly.' ) n_init = n_init + 1 if n_init > 100: af.ErrorStop( 'Can not find physical initial points with 100 tries.') for i in range(n_dims): cube[i] = random() CurPar[i] = cube[i] CurObs = [] CurChisq = -2.0 * lnlike for i in range(n_params): CurObs.append(cube[i]) CurObs.append(0) # mult printPoint(0, cube, n_dims, inpar, fixedpar, outpar, lnlike, 0) # Initialize the MCMC parameters MinChisq = CurChisq Chisq = CurChisq Nrun = 0 Naccept = 0 Nout = 0 mult = 1 kcovar = 0 while Naccept < n_live_points: #Nrun += 1 RangeFlag = True for j in range(n_dims): par[j] = gauss(CurPar[j], exp(kcovar) * covar[j]) # normalized to 1 #rd = random() #par[j] = CurPar[j] + covar[j] * (0.5-rd)*2 if max(par) > 1 or min(par) < 0: RangeFlag = False Nout = Nout + 1 if Nout % 100 == 0: af.WarningNoWait("Too many points out of range!") else: Nrun += 1 Nout = 0 for i in range(n_dims): cube[i] = par[i] Prior(cube, n_dims, n_params) lnlike = LnLike(cube, n_dims, n_params) AllOutMCMC = cube.copy() AllOutMCMC.append(1) saveCube(AllOutMCMC, all_data_file, file_path, '0', False) Chisq = -2.0 * lnlike Flag_accept = RangeFlag and (Chisq < CurChisq + 20) if Flag_accept: if CurChisq > Chisq: Flag_accept = True else: Flag_accept = random() < exp(CurChisq - Chisq) if Flag_accept: CurObs[-1] = mult #"Naccept+1" due to file of Chisq have covered file of CurChisq saveCube(CurObs, data_file, file_path, str(Naccept + 1), True) CurChisq = Chisq for i in range(n_params): CurObs[i] = cube[i] for i in range(n_dims): CurPar[i] = par[i] if Chisq < MinChisq: MinChisq = Chisq Naccept += 1 mult = 1 else: if RangeFlag: mult += 1 AccRat = float(Naccept) / float(Nrun) if FlagTuneR and Nrun < 1000: kcovar = kcovar + 1.0 / (float(Nrun)**0.7) * (AccRat - AccepRate) else: kcovar = 1 if Nrun % n_print == 0: if RangeFlag: printPoint(Nrun, cube, n_dims, inpar, fixedpar, outpar, lnlike, Naccept) printPoint4MCMC(Chisq, CurChisq, MinChisq, AccRat, FlagTuneR, kcovar) # save the last point CurObs[-1] = mult saveCube(CurObs, data_file, file_path, str(Naccept), True)
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