def main(args): no_plots = False chain_root = args.chain_root if args.ini_file is None and chain_root is None: doError('Must give either a .ini file of parameters or a chain file root name. Run "GetDist.py -h" for help.') if not '.ini' in args.ini_file and chain_root is None: # use default settings acting on chain_root, no plots chain_root = args.ini_file args.ini_file = getdist.default_getdist_settings no_plots = True if not os.path.isfile(args.ini_file): doError('Parameter file does not exist: ' + args.ini_file) if chain_root and chain_root.endswith('.txt'): chain_root = chain_root[:-4] # Input parameters ini = IniFile(args.ini_file) # File root if chain_root is not None: in_root = chain_root else: in_root = ini.params['file_root'] if not in_root: doError('Chain Root file name not given ') rootname = os.path.basename(in_root) if args.ignore_rows is not None: ignorerows = args.ignore_rows else: ignorerows = ini.float('ignore_rows', 0.0) samples_are_chains = ini.bool('samples_are_chains', True) paramnames = ini.string('parameter_names', '') # Create instance of MCSamples mc = MCSamples(in_root, files_are_chains=samples_are_chains, paramNamesFile=paramnames) mc.initParameters(ini) if ini.bool('adjust_priors', False) or ini.bool('map_params', False): doError( 'To adjust priors or define new parameters, use a separate python script; see the python getdist docs for examples') plot_ext = ini.string('plot_ext', 'py') finish_run_command = ini.string('finish_run_command', '') no_plots = ini.bool('no_plots', no_plots) plots_only = ini.bool('plots_only', False) no_tests = plots_only or ini.bool('no_tests', False) thin_factor = ini.int('thin_factor', 0) thin_cool = ini.float('thin_cool', 1.0) make_single_samples = ini.bool('make_single_samples', False) single_thin = ini.int('single_thin', 1) cool = ini.float('cool', 1.0) chain_exclude = ini.int_list('exclude_chain') shade_meanlikes = ini.bool('shade_meanlikes', False) plot_meanlikes = ini.bool('plot_meanlikes', False) dumpNDbins = ini.bool('dump_ND_bins', False) out_dir = ini.string('out_dir', './') if out_dir: if not os.path.isdir(out_dir): os.mkdir(out_dir) print('producing files in directory ', out_dir) mc.out_dir = out_dir out_root = ini.string('out_root', '') if out_root: rootname = out_root print('producing files with with root ', out_root) mc.rootname = rootname rootdirname = os.path.join(out_dir, rootname) mc.rootdirname = rootdirname if 'do_minimal_1d_intervals' in ini.params: doError('do_minimal_1d_intervals no longer used; set credible_interval_threshold instead') line = ini.string('PCA_params', '') if line.lower() == 'all': PCA_params = mc.paramNames.list() else: PCA_params = line.split() PCA_num = ini.int('PCA_num', len(PCA_params)) if PCA_num != 0: if PCA_num < 2: doError('Can only do PCA for 2 or more parameters') PCA_func = ini.string('PCA_func', '') # Characters representing functional mapping if PCA_func == '': PCA_func = ['N'] * PCA_num # No mapping PCA_NormParam = ini.string('PCA_normparam', '') or None make_scatter_samples = ini.bool('make_scatter_samples', False) # ============================================================================== first_chain = ini.int('first_chain', 0) last_chain = ini.int('chain_num', -1) # -1 means keep reading until one not found # Chain files chain_files = chains.chainFiles(in_root, first_chain=first_chain, last_chain=last_chain, chain_exclude=chain_exclude) mc.loadChains(in_root, chain_files) mc.removeBurnFraction(ignorerows) mc.deleteFixedParams() mc.makeSingle() def filterParList(namestring, num=None): if not namestring.strip(): pars = mc.paramNames.list() else: pars = [] for name in namestring.split(): if '?' in name or '*' in name: pars += mc.paramNames.getMatches(name, strings=True) elif mc.paramNames.parWithName(name): pars.append(name) if num is not None and len(pars) != num: print('%iD plot has missing parameter or wrong number of parameters: %s' % (num, pars)) pars = None return pars if cool != 1: print('Cooling chains by ', cool) mc.cool(cool) mc.updateBaseStatistics() if not no_tests: mc.getConvergeTests(mc.converge_test_limit, writeDataToFile=True, feedback=True) mc.writeCovMatrix() mc.writeCorrelationMatrix() # Output thinned data if requested # Must do this with unsorted output if thin_factor != 0: thin_ix = mc.thin_indices(thin_factor) filename = rootdirname + '_thin.txt' mc.writeThinData(filename, thin_ix, thin_cool) print(mc.getNumSampleSummaryText().strip()) if mc.likeStats: print(mc.likeStats.likeSummary().strip()) if PCA_num > 0 and not plots_only: mc.PCA(PCA_params, PCA_func, PCA_NormParam, writeDataToFile=True) if not no_plots or dumpNDbins: # set plot_data_dir before we generate the 1D densities below plot_data_dir = ini.string('plot_data_dir', default='', allowEmpty=True) if plot_data_dir and not os.path.isdir(plot_data_dir): os.mkdir(plot_data_dir) else: plot_data_dir = None mc.plot_data_dir = plot_data_dir # Do 1D bins mc._setDensitiesandMarge1D(writeDataToFile=not no_plots and plot_data_dir, meanlikes=plot_meanlikes) if not no_plots: # Output files for 1D plots print('Calculating plot data...') plotparams = [] line = ini.string('plot_params', '') if line not in ['', '0']: plotparams = filterParList(line) line = ini.string('plot_2D_param', '').strip() plot_2D_param = None if line and line != '0': plot_2D_param = line cust2DPlots = [] if not plot_2D_param: # Use custom array of specific plots num_cust2D_plots = ini.int('plot_2D_num', 0) for i in range(1, num_cust2D_plots + 1): line = ini.string('plot' + str(i)) pars = filterParList(line, 2) if pars is not None: cust2DPlots.append(pars) else: num_cust2D_plots -= 1 triangle_params = [] triangle_plot = ini.bool('triangle_plot', False) if triangle_plot: line = ini.string('triangle_params', '') triangle_params = filterParList(line) triangle_num = len(triangle_params) triangle_plot = triangle_num > 1 num_3D_plots = ini.int('num_3D_plots', 0) plot_3D = [] for ix in range(1, num_3D_plots + 1): line = ini.string('3D_plot' + str(ix)) pars = filterParList(line, 3) if pars is not None: plot_3D.append(pars) else: num_3D_plots -= 1 # Produce file of weight-1 samples if requested if (num_3D_plots and not make_single_samples or make_scatter_samples) and not no_plots: make_single_samples = True single_thin = max(1, int(round(mc.norm / mc.max_mult)) // mc.max_scatter_points) if plot_data_dir: if make_single_samples: filename = os.path.join(plot_data_dir, rootname.strip() + '_single.txt') mc.makeSingleSamples(filename, single_thin) # Write paramNames file mc.getParamNames().saveAsText(os.path.join(plot_data_dir, rootname + '.paramnames')) mc.getBounds().saveToFile(os.path.join(plot_data_dir, rootname + '.bounds')) make_plots = ini.bool('make_plots', False) done2D = {} filename = rootdirname + '.' + plot_ext mc.writeScriptPlots1D(filename, plotparams) if make_plots: runScript(filename) # Do 2D bins if plot_2D_param == 'corr': # In this case output the most correlated variable combinations print('...doing 2D plots for most correlated variables') cust2DPlots = mc.getCorrelatedVariable2DPlots() plot_2D_param = None elif plot_2D_param: mc.paramNames.parWithName(plot_2D_param, error=True) # just check if cust2DPlots or plot_2D_param: print('...producing 2D plots') filename = rootdirname + '_2D.' + plot_ext done2D = mc.writeScriptPlots2D(filename, plot_2D_param, cust2DPlots, writeDataToFile=plot_data_dir, shade_meanlikes=shade_meanlikes) if make_plots: runScript(filename) if triangle_plot: # Add the off-diagonal 2D plots print('...producing triangle plot') filename = rootdirname + '_tri.' + plot_ext mc.writeScriptPlotsTri(filename, triangle_params) for i, p2 in enumerate(triangle_params): for p1 in triangle_params[i + 1:]: if not done2D.get((p1, p2)) and plot_data_dir: mc.get2DDensityGridData(p1, p2, writeDataToFile=True, meanlikes=shade_meanlikes) if make_plots: runScript(filename) # Do 3D plots (i.e. 2D scatter plots with coloured points) if num_3D_plots: print('...producing ', num_3D_plots, '2D colored scatter plots') filename = rootdirname + '_3D.' + plot_ext mc.writeScriptPlots3D(filename, plot_3D) if make_plots: runScript(filename) if not plots_only: # Write out stats marginalized mc.getMargeStats().saveAsText(rootdirname + '.margestats') # Limits from global likelihood if mc.loglikes is not None: mc.getLikeStats().saveAsText(rootdirname + '.likestats') if dumpNDbins: num_bins_ND = ini.int('num_bins_ND', 10) line = ini.string('ND_params','') if line not in ["",'0']: ND_params = filterParList(line) print(ND_params) ND_dim=len(ND_params) print(ND_dim) mc.getRawNDDensityGridData(ND_params, writeDataToFile=True, meanlikes=shade_meanlikes) # System command if finish_run_command: finish_run_command = finish_run_command.replace('%ROOTNAME%', rootname) finish_run_command = finish_run_command.replace('%PLOTDIR%', plot_data_dir) finish_run_command = finish_run_command.replace('%PLOTROOT%', os.path.join(plot_data_dir, rootname)) os.system(finish_run_command)
def parameter_diff_chain(chain_1, chain_2, boost=1): """ Compute the chain of the parameter differences between the two input chains. The parameters of the difference chain are related to the parameters of the input chains, :math:`\\theta_1` and :math:`\\theta_2` by: .. math:: \\Delta \\theta \\equiv \\theta_1 - \\theta_2 This function only returns the differences for the parameters that are common to both chains. This function preserves the chain separation (if any) so that the convergence of the difference chain can be tested. This function does not assume Gaussianity of the chain. This functions does assume that the parameter determinations from the two chains (i.e. the underlying data sets) are uncorrelated. Do not use this function for chains that are correlated. :param chain_1: :class:`~getdist.mcsamples.MCSamples` first input chain with :math:`n_1` samples :param chain_2: :class:`~getdist.mcsamples.MCSamples` second input chain with :math:`n_2` samples :param boost: (optional) boost the number of samples in the difference chain. By default the length of the difference chain will be the length of the longest chain. Given two chains the full difference chain can contain :math:`n_1\\times n_2` samples but this is usually prohibitive for realistic chains. The boost parameters wil increase the number of samples to be :math:`{\\rm boost}\\times {\\rm max}(n_1,n_2)`. Default boost parameter is one. If boost is None the full difference chain is going to be computed (and will likely require a lot of memory and time). :return: :class:`~getdist.mcsamples.MCSamples` the instance with the parameter difference chain. """ # check input: if boost is not None: if boost < 1: raise ValueError('Minimum boost is 1\n Input value is ', boost) # test for type, this function assumes that we are working with MCSamples: if not isinstance(chain_1, MCSamples): raise TypeError('Input chain_1 is not of MCSamples type.') if not isinstance(chain_2, MCSamples): raise TypeError('Input chain_2 is not of MCSamples type.') # get the parameter names: param_names_1 = chain_1.getParamNames().list() param_names_2 = chain_2.getParamNames().list() # get the common names: param_names = [_p for _p in param_names_1 if _p in param_names_2] num_params = len(param_names) if num_params == 0: raise ValueError('There are no shared parameters to difference') # get the names and labels: diff_param_names = ['delta_' + name for name in param_names] diff_param_labels = [ '\\Delta ' + name.label for name in chain_1.getParamNames().parsWithNames(param_names) ] # get parameter indexes: indexes_1 = [chain_1.index[name] for name in param_names] indexes_2 = [chain_2.index[name] for name in param_names] # get separate chains: if not hasattr(chain_1, 'chain_offsets'): _chains_1 = [chain_1] else: _chains_1 = chain_1.getSeparateChains() if not hasattr(chain_2, 'chain_offsets'): _chains_2 = [chain_2] else: _chains_2 = chain_2.getSeparateChains() # set the boost: if chain_1.sampler == 'nested' \ or chain_2.sampler == 'nested' or boost is None: chain_boost = max(len(_chains_1), len(_chains_2)) sample_boost = None else: chain_boost = min(boost, max(len(_chains_1), len(_chains_2))) sample_boost = boost # get the combinations: if len(_chains_1) > len(_chains_2): temp_ind = np.indices((len(_chains_2), len(_chains_1))) else: temp_ind = np.indices((len(_chains_1), len(_chains_2))) ind1 = np.concatenate([ np.diagonal(temp_ind, offset=i, axis1=1, axis2=2)[0] for i in range(chain_boost) ]) ind2 = np.concatenate([ np.diagonal(temp_ind, offset=i, axis1=1, axis2=2)[1] for i in range(chain_boost) ]) chains_combinations = [[_chains_1[i], _chains_2[j]] for i, j in zip(ind1, ind2)] # compute the parameter difference samples: diff_chain_samples = [ parameter_diff_weighted_samples(samp1, samp2, boost=sample_boost, indexes_1=indexes_1, indexes_2=indexes_2) for samp1, samp2 in chains_combinations ] # create the samples: diff_samples = MCSamples(names=diff_param_names, labels=diff_param_labels) diff_samples.chains = diff_chain_samples diff_samples.makeSingle() # get the ranges: _ranges = {} for name, _min, _max in zip(diff_param_names, np.amin(diff_samples.samples, axis=0), np.amax(diff_samples.samples, axis=0)): _ranges[name] = [_min, _max] diff_samples.setRanges(_ranges) # initialize other things: if chain_1.name_tag is not None and chain_2.name_tag is not None: diff_samples.name_tag = chain_1.name_tag + '_diff_' + chain_2.name_tag # set distinction between base and derived parameters: _temp = diff_samples.getParamNames().list() _temp_paramnames = chain_1.getParamNames() for _nam in diff_samples.getParamNames().parsWithNames(_temp): _temp_name = _nam.name.replace('delta_', '', 1) _nam.isDerived = _temp_paramnames.parWithName(_temp_name).isDerived # update and compute everything: diff_samples.updateBaseStatistics() diff_samples.deleteFixedParams() # return diff_samples
def main(args): no_plots = False chain_root = args.chain_root if args.ini_file is None and chain_root is None: doError('Must give either a .ini file of parameters or a chain file root name. Run "GetDist.py -h" for help.') if not ".ini" in args.ini_file and chain_root is None: # use default settings acting on chain_root, no plots chain_root = args.ini_file args.ini_file = getdist.default_getdist_settings no_plots = True if not os.path.isfile(args.ini_file): doError("Parameter file does not exist: " + args.ini_file) if chain_root and chain_root.endswith(".txt"): chain_root = chain_root[:-4] # Input parameters ini = IniFile(args.ini_file) # File root if chain_root is not None: in_root = chain_root else: in_root = ini.params["file_root"] if not in_root: doError("Chain Root file name not given ") rootname = os.path.basename(in_root) if args.ignore_rows is not None: ignorerows = args.ignore_rows else: ignorerows = ini.float("ignore_rows", 0.0) samples_are_chains = ini.bool("samples_are_chains", True) # Create instance of MCSamples mc = MCSamples(in_root, files_are_chains=samples_are_chains) mc.initParameters(ini) if ini.bool("adjust_priors", False) or ini.bool("map_params", False): doError( "To adjust priors or define new parameters, use a separate python script; see the python getdist docs for examples" ) plot_ext = ini.string("plot_ext", "py") finish_run_command = ini.string("finish_run_command", "") no_plots = ini.bool("no_plots", no_plots) plots_only = ini.bool("plots_only", False) no_tests = plots_only or ini.bool("no_tests", False) thin_factor = ini.int("thin_factor", 0) thin_cool = ini.float("thin_cool", 1.0) make_single_samples = ini.bool("make_single_samples", False) single_thin = ini.int("single_thin", 1) cool = ini.float("cool", 1.0) chain_exclude = ini.int_list("exclude_chain") shade_meanlikes = ini.bool("shade_meanlikes", False) plot_meanlikes = ini.bool("plot_meanlikes", False) out_dir = ini.string("out_dir", "./") if out_dir: if not os.path.isdir(out_dir): os.mkdir(out_dir) print("producing files in directory ", out_dir) mc.out_dir = out_dir out_root = ini.string("out_root", "") if out_root: rootname = out_root print("producing files with with root ", out_root) mc.rootname = rootname rootdirname = os.path.join(out_dir, rootname) mc.rootdirname = rootdirname if "do_minimal_1d_intervals" in ini.params: doError("do_minimal_1d_intervals no longer used; set credible_interval_threshold instead") line = ini.string("PCA_params", "") if line.lower() == "all": PCA_params = mc.paramNames.list() else: PCA_params = line.split() PCA_num = ini.int("PCA_num", len(PCA_params)) if PCA_num != 0: if PCA_num < 2: doError("Can only do PCA for 2 or more parameters") PCA_func = ini.string("PCA_func", "") # Characters representing functional mapping if PCA_func == "": PCA_func = ["N"] * PCA_num # No mapping PCA_NormParam = ini.string("PCA_normparam", "") or None make_scatter_samples = ini.bool("make_scatter_samples", False) # ============================================================================== first_chain = ini.int("first_chain", 0) last_chain = ini.int("chain_num", -1) # -1 means keep reading until one not found # Chain files chain_files = chains.chainFiles( in_root, first_chain=first_chain, last_chain=last_chain, chain_exclude=chain_exclude ) mc.loadChains(in_root, chain_files) mc.removeBurnFraction(ignorerows) mc.deleteFixedParams() mc.makeSingle() def filterParList(namestring, num=None): if not namestring.strip(): pars = mc.paramNames.list() else: pars = [] for name in namestring.split(): if "?" in name or "*" in name: pars += mc.paramNames.getMatches(name, strings=True) elif mc.paramNames.parWithName(name): pars.append(name) if num is not None and len(pars) != num: raise Exception("%iD plot has missing parameter or wrong number of parameters: %s" % (num, pars)) return pars if cool != 1: print("Cooling chains by ", cool) mc.cool(cool) mc.updateBaseStatistics() if not no_tests: mc.getConvergeTests(mc.converge_test_limit, writeDataToFile=True, feedback=True) mc.writeCovMatrix() mc.writeCorrelationMatrix() # Output thinned data if requested # Must do this with unsorted output if thin_factor != 0: thin_ix = mc.thin_indices(thin_factor) filename = rootdirname + "_thin.txt" mc.writeThinData(filename, thin_ix, thin_cool) print(mc.getNumSampleSummaryText().strip()) if mc.likeStats: print(mc.likeStats.likeSummary().strip()) if PCA_num > 0 and not plots_only: mc.PCA(PCA_params, PCA_func, PCA_NormParam, writeDataToFile=True) if not no_plots: # set plot_data_dir before we generate the 1D densities below plot_data_dir = ini.string("plot_data_dir", default="", allowEmpty=True) if plot_data_dir and not os.path.isdir(plot_data_dir): os.mkdir(plot_data_dir) else: plot_data_dir = None mc.plot_data_dir = plot_data_dir # Do 1D bins mc._setDensitiesandMarge1D(writeDataToFile=not no_plots and plot_data_dir, meanlikes=plot_meanlikes) if not no_plots: # Output files for 1D plots print("Calculating plot data...") plotparams = [] line = ini.string("plot_params", "") if line not in ["", "0"]: plotparams = filterParList(line) line = ini.string("plot_2D_param", "").strip() plot_2D_param = None if line and line != "0": plot_2D_param = line cust2DPlots = [] if not plot_2D_param: # Use custom array of specific plots num_cust2D_plots = ini.int("plot_2D_num", 0) for i in range(1, num_cust2D_plots + 1): line = ini.string("plot" + str(i)) pars = filterParList(line, 2) cust2DPlots.append(pars) triangle_params = [] triangle_plot = ini.bool("triangle_plot", False) if triangle_plot: line = ini.string("triangle_params", "") triangle_params = filterParList(line) triangle_num = len(triangle_params) triangle_plot = triangle_num > 1 num_3D_plots = ini.int("num_3D_plots", 0) plot_3D = [] for ix in range(1, num_3D_plots + 1): line = ini.string("3D_plot" + str(ix)) plot_3D.append(filterParList(line, 3)) # Produce file of weight-1 samples if requested if (num_3D_plots and not make_single_samples or make_scatter_samples) and not no_plots: make_single_samples = True single_thin = max(1, int(round(mc.norm / mc.max_mult)) // mc.max_scatter_points) if plot_data_dir: if make_single_samples: filename = os.path.join(plot_data_dir, rootname.strip() + "_single.txt") mc.makeSingleSamples(filename, single_thin) # Write paramNames file mc.getParamNames().saveAsText(os.path.join(plot_data_dir, rootname + ".paramnames")) mc.getBounds().saveToFile(os.path.join(plot_data_dir, rootname + ".bounds")) make_plots = ini.bool("make_plots", False) done2D = {} filename = rootdirname + "." + plot_ext mc.writeScriptPlots1D(filename, plotparams) if make_plots: runScript(filename) # Do 2D bins if plot_2D_param == "corr": # In this case output the most correlated variable combinations print("...doing 2D plots for most correlated variables") cust2DPlots = mc.getCorrelatedVariable2DPlots() plot_2D_param = None elif plot_2D_param: mc.paramNames.parWithName(plot_2D_param, error=True) # just check if cust2DPlots or plot_2D_param: print("...producing 2D plots") filename = rootdirname + "_2D." + plot_ext done2D = mc.writeScriptPlots2D( filename, plot_2D_param, cust2DPlots, writeDataToFile=plot_data_dir, shade_meanlikes=shade_meanlikes ) if make_plots: runScript(filename) if triangle_plot: # Add the off-diagonal 2D plots print("...producing triangle plot") filename = rootdirname + "_tri." + plot_ext mc.writeScriptPlotsTri(filename, triangle_params) for i, p2 in enumerate(triangle_params): for p1 in triangle_params[i + 1 :]: if not done2D.get((p1, p2)) and plot_data_dir: mc.get2DDensityGridData(p1, p2, writeDataToFile=True, meanlikes=shade_meanlikes) if make_plots: runScript(filename) # Do 3D plots (i.e. 2D scatter plots with coloured points) if num_3D_plots: print("...producing ", num_3D_plots, "2D colored scatter plots") filename = rootdirname + "_3D." + plot_ext mc.writeScriptPlots3D(filename, plot_3D) if make_plots: runScript(filename) if not plots_only: # Write out stats marginalized mc.getMargeStats().saveAsText(rootdirname + ".margestats") # Limits from global likelihood if mc.loglikes is not None: mc.getLikeStats().saveAsText(rootdirname + ".likestats") # System command if finish_run_command: finish_run_command = finish_run_command.replace("%ROOTNAME%", rootname) finish_run_command = finish_run_command.replace("%PLOTDIR%", plot_data_dir) finish_run_command = finish_run_command.replace("%PLOTROOT%", os.path.join(plot_data_dir, rootname)) os.system(finish_run_command)