def prior_from_config(cp, prior_section='prior'): """Loads a prior distribution from the given config file. Parameters ---------- cp : pycbc.workflow.WorkflowConfigParser The config file to read. sections : list of str, optional The sections to retrieve the prior from. If ``None`` (the default), will look in sections starting with 'prior'. Returns ------- distributions.JointDistribution The prior distribution. """ # Read variable and static parameters from the config file variable_params, _ = distributions.read_params_from_config( cp, prior_section=prior_section, vargs_section='variable_params', sargs_section='static_params') # Read constraints to apply to priors from the config file constraints = distributions.read_constraints_from_config(cp) # Get PyCBC distribution instances for each variable parameter in the # config file dists = distributions.read_distributions_from_config(cp, prior_section) # construct class that will return draws from the prior return distributions.JointDistribution(variable_params, *dists, **{"constraints": constraints})
def setUp(self): # set random seed numpy.random.seed(1024) # path to example configuration file for testing config_path = "/".join([os.path.dirname(os.path.realpath(__file__)), "../examples/distributions/example.ini"]) # get a set of simulated command line options for # configuration file reading class Arguments(object): config_overrides = [] config_files = [config_path] self.opts = Arguments() # read configuration files self.cp = WorkflowConfigParser.from_cli(self.opts) args = distributions.read_args_from_config(self.cp) self.variable_args, self.static_args, self.contraints = args # read distributions self.dists = distributions.read_distributions_from_config(self.cp) # check that all distriubtions will be tested for dname, dclass in distributions.distribs.iteritems(): if (not numpy.any([isinstance(dist, dclass) for dist in self.dists]) and dname not in EXCLUDE_DIST_NAMES): raise ValueError("There is no test for {}".format(dname))
def prior_from_config(cp, variable_params, prior_section, constraint_section): """Gets arguments and keyword arguments from a config file. Parameters ---------- cp : WorkflowConfigParser Config file parser to read. variable_params : list List of of model parameter names. prior_section : str Section to read prior(s) from. constraint_section : str Section to read constraint(s) from. Returns ------- pycbc.distributions.JointDistribution The prior. """ # get prior distribution for each variable parameter logging.info("Setting up priors for each parameter") dists = distributions.read_distributions_from_config(cp, prior_section) constraints = distributions.read_constraints_from_config( cp, constraint_section) return distributions.JointDistribution(variable_params, *dists, constraints=constraints)
def __init__(self, config_file, random_seed): # Fix the seed for the random number generator np.random.seed(random_seed) # Read in the configuration file using a WorkflowConfigParser. # Note that the argument `configFiles` has to be a list here, # so we need to wrap the `config_file` argument accordingly... config_file = WorkflowConfigParser(configFiles=[config_file]) # Extract variable arguments and constraints # We don't need the static_args here, hence they do not get amended. self.var_args, _ = read_params_from_config(config_file) self.constraints = read_constraints_from_config(config_file) # Extract distributions dist = read_distributions_from_config(config_file) # Extract transformations self.trans = read_transforms_from_config(config_file) # Set up a joint distribution to sample from self.pval = JointDistribution(self.var_args, *dist, **{'constraints': self.constraints})
def prior_from_config(cp, prior_section='prior'): """Loads a prior distribution from the given config file. Parameters ---------- cp : pycbc.workflow.WorkflowConfigParser The config file to read. sections : list of str, optional The sections to retrieve the prior from. If ``None`` (the default), will look in sections starting with 'prior'. Returns ------- distributions.JointDistribution The prior distribution. """ # Read variable and static parameters from the config file variable_params, _ = distributions.read_params_from_config( cp, prior_section=prior_section, vargs_section='variable_params', sargs_section='static_params') # Read constraints to apply to priors from the config file constraints = distributions.read_constraints_from_config(cp) # Get PyCBC distribution instances for each variable parameter in the # config file dists = distributions.read_distributions_from_config(cp, prior_section) # construct class that will return draws from the prior return distributions.JointDistribution(variable_params, *dists, **{"constraints": constraints})
def setUp(self): # set random seed numpy.random.seed(1024) # path to example configuration file for testing config_path = "/".join([os.path.dirname(os.path.realpath(__file__)), "../examples/distributions/example.ini"]) # get a set of simulated command line options for # configuration file reading class Arguments(object): config_overrides = [] config_delete = [] config_files = [config_path] self.opts = Arguments() # read configuration files self.cp = WorkflowConfigParser.from_cli(self.opts) self.variable_args, self.static_args = \ distributions.read_params_from_config(self.cp) self.constraints = distributions.read_constraints_from_config(self.cp) # read distributions self.dists = distributions.read_distributions_from_config(self.cp) # check that all distriubtions will be tested for dname in distributions.distribs: dclass = distributions.distribs[dname] if (not numpy.any([isinstance(dist, dclass) for dist in self.dists]) and dname not in EXCLUDE_DIST_NAMES): raise ValueError("There is no test for {}".format(dname))
def initial_dist_from_config(cp, variable_params): r"""Loads a distribution for the sampler start from the given config file. A distribution will only be loaded if the config file has a [initial-\*] section(s). Parameters ---------- cp : Config parser The config parser to try to load from. variable_params : list of str The variable parameters for the distribution. Returns ------- JointDistribution or None : The initial distribution. If no [initial-\*] section found in the config file, will just return None. """ if len(cp.get_subsections("initial")): logging.info("Using a different distribution for the starting points " "than the prior.") initial_dists = distributions.read_distributions_from_config( cp, section="initial") constraints = distributions.read_constraints_from_config( cp, constraint_section="initial_constraint") init_dist = distributions.JointDistribution( variable_params, *initial_dists, **{"constraints": constraints}) else: init_dist = None return init_dist
def initial_dist_from_config(cp, variable_params): r"""Loads a distribution for the sampler start from the given config file. A distribution will only be loaded if the config file has a [initial-\*] section(s). Parameters ---------- cp : Config parser The config parser to try to load from. variable_params : list of str The variable parameters for the distribution. Returns ------- JointDistribution or None : The initial distribution. If no [initial-\*] section found in the config file, will just return None. """ if len(cp.get_subsections("initial")): logging.info("Using a different distribution for the starting points " "than the prior.") initial_dists = distributions.read_distributions_from_config( cp, section="initial") constraints = distributions.read_constraints_from_config( cp, constraint_section="initial_constraint") init_dist = distributions.JointDistribution( variable_params, *initial_dists, **{"constraints": constraints}) else: init_dist = None return init_dist
def __init__( self, config_files: Union[List[Union[str, os.PathLike]], Union[str, os.PathLike]], seed: Optional[int] = None, ): """Class to generate gravitational waveform parameters using PyCBC workflow and distribution packages. """ if seed is not None: raise NotImplementedError( "Reproducible random seed not yet implemented.") self.config_files = config_files if isinstance( config_files, list) else [config_files] self.config_parser = WorkflowConfigParser( configFiles=self.config_files) self.parameters, self.static_args = read_params_from_config( self.config_parser) self.constraints = read_constraints_from_config(self.config_parser) self.transforms = read_transforms_from_config(self.config_parser) self.distribution = JointDistribution( self.parameters, *read_distributions_from_config(self.config_parser), **{'constraints': self.constraints}) # ensure statistics match output of self.parameters self.statistics = compute_parameter_statistics({ parameter: self.distribution.bounds[parameter] for parameter in self.parameters })
def prior_from_config(cp, variable_params, prior_section, constraint_section): """Gets arguments and keyword arguments from a config file. Parameters ---------- cp : WorkflowConfigParser Config file parser to read. variable_params : list List of of model parameter names. prior_section : str Section to read prior(s) from. constraint_section : str Section to read constraint(s) from. Returns ------- pycbc.distributions.JointDistribution The prior. """ # get prior distribution for each variable parameter logging.info("Setting up priors for each parameter") dists = distributions.read_distributions_from_config(cp, prior_section) constraints = distributions.read_constraints_from_config( cp, constraint_section) return distributions.JointDistribution(variable_params, *dists, constraints=constraints)
def __init__(self, config_file, seed=0): numpy.random.seed(seed) config_file = WorkflowConfigParser(config_file, None) var_args, self.static, constraints = read_args_from_config(config_file) dist = read_distributions_from_config(config_file) self.trans = read_transforms_from_config(config_file) self.pval = JointDistribution(var_args, *dist, **{"constraints": constraints})
def from_config(cls, cp, section, tag): """ Return instance based on config file Return a new instance based on the config file. This will draw from a single distribution section provided in the config file and apply a single transformation section if desired. If a transformation is applied, an inverse mapping is also provided for use in the config file. """ from pycbc.distributions import read_distributions_from_config from pycbc.transforms import (read_transforms_from_config, apply_transforms, BaseTransform) from pycbc.transforms import transforms as global_transforms params = tag.split(VARARGS_DELIM) subname = cp.get_opt_tag(section, 'subname', tag) size = cp.get_opt_tag(section, 'sample-size', tag) distsec = '{}_sample'.format(subname) dist = read_distributions_from_config(cp, section=distsec) if len(dist) > 1: raise ValueError("Fixed sample distrubtion only supports a single" " distribution to sample from.") logging.info('Drawing samples for fixed sample distribution:%s', params) samples = dist[0].rvs(size=int(float(size))) samples = {p: samples[p] for p in samples.dtype.names} transec = '{}_transform'.format(subname) trans = read_transforms_from_config(cp, section=transec) if len(trans) > 0: trans = trans[0] samples = apply_transforms(samples, [trans]) p1 = samples[params[0]] # We have transformed parameters, so automatically provide the # inverse transform for use in passing to waveform approximants class Thook(BaseTransform): name = subname _inputs = trans.outputs _outputs = trans.inputs p1name = params[0] sort = p1.argsort() p1sorted = p1[sort] def transform(self, maps): idx = numpy.searchsorted(self.p1sorted, maps[self.p1name]) out = {p: samples[p][self.sort[idx]] for p in self.outputs} return self.format_output(maps, out) global_transforms[Thook.name] = Thook return cls(params, samples)
def from_config(cls, cp, data=None, delta_f=None, delta_t=None, gates=None, recalibration=None, **kwargs): """Initializes an instance of this class from the given config file. Parameters ---------- cp : WorkflowConfigParser Config file parser to read. data : dict A dictionary of data, in which the keys are the detector names and the values are the data. This is not retrieved from the config file, and so must be provided. delta_f : float The frequency spacing of the data; needed for waveform generation. delta_t : float The time spacing of the data; needed for time-domain waveform generators. recalibration : dict of pycbc.calibration.Recalibrate, optional Dictionary of detectors -> recalibration class instances for recalibrating data. gates : dict of tuples, optional Dictionary of detectors -> tuples of specifying gate times. The sort of thing returned by `pycbc.gate.gates_from_cli`. \**kwargs : All additional keyword arguments are passed to the class. Any provided keyword will over ride what is in the config file. """ prior_section = "marginalized_prior" args = cls._init_args_from_config(cp) marg_prior = read_distributions_from_config(cp, prior_section) if len(marg_prior) == 0: raise AttributeError("No priors are specified for the " "marginalization. Please specify this in a " "section in the config file with heading " "{}-variable".format(prior_section)) params = [i.params[0] for i in marg_prior] marg_args = [k for k, v in args.items() if "_marginalization" in k] if len(marg_args) != len(params): raise ValueError("There is not a prior for each keyword argument") kwargs['marg_prior'] = marg_prior for i in params: kwargs[i + "_marginalization"] = True args.update(kwargs) variable_params = args['variable_params'] args["data"] = data try: static_params = args['static_params'] except KeyError: static_params = {} # set up waveform generator try: approximant = static_params['approximant'] except KeyError: raise ValueError("no approximant provided in the static args") generator_function = generator.select_waveform_generator(approximant) waveform_generator = generator.FDomainDetFrameGenerator( generator_function, epoch=data.values()[0].start_time, variable_args=variable_params, detectors=data.keys(), delta_f=delta_f, delta_t=delta_t, recalib=recalibration, gates=gates, **static_params) args['waveform_generator'] = waveform_generator args["f_lower"] = static_params["f_lower"] return cls(**args)
def draw_samples_from_config(path, num=1, seed=150914): r""" Generate sampling points from a standalone .ini file. Parameters ---------- path : str The path to the .ini file. num : int The number of samples. seed: int The random seed for sampling. Returns -------- samples : pycbc.io.record.FieldArray The parameter values and names of sample(s). Examples -------- Draw a sample from the distribution defined in the .ini file: >>> import numpy as np >>> from pycbc.distributions.utils import draw_samples_from_config >>> # A path to the .ini file. >>> CONFIG_PATH = "./pycbc_bbh_prior.ini" >>> random_seed = np.random.randint(low=0, high=2**32-1) >>> sample = draw_samples_from_config( >>> path=CONFIG_PATH, num=1, seed=random_seed) >>> # Print all parameters. >>> print(sample.fieldnames) >>> print(sample) >>> # Print a certain parameter, for example 'mass1'. >>> print(sample[0]['mass1']) """ np.random.seed(seed) # Initialise InterpolatingConfigParser class. config_parser = InterpolatingConfigParser() # Read the file file = open(path, 'r') config_parser.read_file(file) file.close() # Get the vairable arguments from the .ini file. variable_args, _ = distributions.read_params_from_config( config_parser, prior_section='prior', vargs_section='variable_params') constraints = distributions.read_constraints_from_config(config_parser) if any(config_parser.get_subsections('waveform_transforms')): waveform_transforms = transforms.read_transforms_from_config( config_parser, 'waveform_transforms') else: waveform_transforms = None # Get prior distribution for each variable parameter. dists = distributions.read_distributions_from_config(config_parser) # Construct class that will draw the samples. randomsampler = distributions.JointDistribution( variable_args, *dists, **{"constraints": constraints}) # Draw samples from prior distribution. samples = randomsampler.rvs(size=int(num)) # Apply parameter transformation. if waveform_transforms is not None: samples = transforms.apply_transforms(samples, waveform_transforms) else: pass return samples
def from_config(cls, cp, data=None, delta_f=None, delta_t=None, gates=None, recalibration=None, **kwargs): """Initializes an instance of this class from the given config file. Parameters ---------- cp : WorkflowConfigParser Config file parser to read. data : dict A dictionary of data, in which the keys are the detector names and the values are the data. This is not retrieved from the config file, and so must be provided. delta_f : float The frequency spacing of the data; needed for waveform generation. delta_t : float The time spacing of the data; needed for time-domain waveform generators. recalibration : dict of pycbc.calibration.Recalibrate, optional Dictionary of detectors -> recalibration class instances for recalibrating data. gates : dict of tuples, optional Dictionary of detectors -> tuples of specifying gate times. The sort of thing returned by `pycbc.gate.gates_from_cli`. \**kwargs : All additional keyword arguments are passed to the class. Any provided keyword will over ride what is in the config file. """ prior_section = "marginalized_prior" args = cls._init_args_from_config(cp) marg_prior = read_distributions_from_config(cp, prior_section) if len(marg_prior) == 0: raise AttributeError("No priors are specified for the " "marginalization. Please specify this in a " "section in the config file with heading " "{}-variable".format(prior_section)) params = [i.params[0] for i in marg_prior] marg_args = [k for k, v in args.items() if "_marginalization" in k] if len(marg_args) != len(params): raise ValueError("There is not a prior for each keyword argument") kwargs['marg_prior'] = marg_prior for i in params: kwargs[i+"_marginalization"] = True args.update(kwargs) variable_params = args['variable_params'] args["data"] = data try: static_params = args['static_params'] except KeyError: static_params = {} # set up waveform generator try: approximant = static_params['approximant'] except KeyError: raise ValueError("no approximant provided in the static args") generator_function = generator.select_waveform_generator(approximant) waveform_generator = generator.FDomainDetFrameGenerator( generator_function, epoch=data.values()[0].start_time, variable_args=variable_params, detectors=data.keys(), delta_f=delta_f, delta_t=delta_t, recalib=recalibration, gates=gates, **static_params) args['waveform_generator'] = waveform_generator args["f_lower"] = static_params["f_lower"] return cls(**args)