def __init_spline(self, knots, coeffs, deg, units=None): knots = interpret_quantity(knots, expect_sequence=True) self._state_attrs.extend(['knots', 'coeffs', 'deg']) self.kind = 'spline' if isunitless(knots): knots = ureg.Quantity(knots, units) elif units is not None: units = ureg.Unit(units) assert knots.dimensionality == units.dimensionality knots = knots.to(units) self.units = str(knots.units) self.knots = knots self.coeffs = coeffs self.deg = deg def llh(x): x = self.__strip(self.__convert(x)) return splev(x, tck=(self.__strip(self.knots), coeffs, deg), ext=2) self.llh = llh self.max_at = fminbound( func=self.__attach_units_to_args(self.chi2), x1=np.min(self.__strip(self.knots)), x2=np.max(self.__strip(self.knots)), ) if self.units is not None: self.max_at = self.max_at * ureg(self.units) self.max_at_str = self.__stringify(self.max_at) self.valid_range = (np.min(self.knots) * ureg(self.units), np.max(self.knots) * ureg(self.units)) self._str = lambda s: 'spline prior: deg=%d, valid in [%s, %s]%s; max at %s%s' \ %(self.deg, self.__stringify(np.min(self.knots)), self.__stringify(np.max(self.knots)), self.units_str, self.max_at_str, self.units_str)
def parse_fit_config(fit_cfg): """Perform sanity checks on and parse fit configuration file. Parameters ---------- fit_cfg : str path to a fit configuration file Returns ------- fit_cfg : PISAConfigParser parsed fit configuration sys_list : list of str parsed names of systematic parameters units_list : list of str units corresponding to each discrete systematic combine_regex : list of str each string is a regular expression for combining pipeline outputs; see :func:`pisa.core.map.MapSet.combine_regex` for details. """ fit_cfg = from_file(fit_cfg) no_ws_section_map = {s.strip(): s for s in fit_cfg.sections()} if GENERAL_SECTION_NAME not in no_ws_section_map.values(): raise KeyError('Fit config is missing the "%s" section!' % GENERAL_SECTION_NAME) general_section = fit_cfg[GENERAL_SECTION_NAME] if SYS_LIST_OPTION not in general_section: raise KeyError( "Fit config has to specify systematic parameters as" ' "%s" option in "%s" section (comma-separated list of names).' % (SYS_LIST_OPTION, GENERAL_SECTION_NAME)) sys_list = [s.strip() for s in general_section[SYS_LIST_OPTION].split(",")] if UNITS_OPTION in general_section: units_list = [] units_specs = (general_section[UNITS_OPTION].replace( UNITS_SPECIFIER, "").split(",")) for units_spec in units_specs: # Make sure units are interpret-able by Pint try: ureg.Unit(units_spec) except: logging.error( 'Unit "%s" specified by "%s" option in "general" section is not' "interpret-able by Pint", units_spec, UNITS_OPTION, ) raise units_list.append(units_spec) else: units_list = ["dimensionless" for s in sys_list] logging.warn( "No %s option found in %s section; assuming systematic parameters are" " dimensionless", UNITS_OPTION, GENERAL_SECTION_NAME, ) if len(units_list) != len(sys_list): raise ValueError( '{} units specified by "{}" option but {} systematics specified by "{}"' "option; must be same number of each.".format( len(units_list), UNITS_OPTION, len(sys_list), SYS_LIST_OPTION)) logging.info( "Found systematic parameters %s", ["{} ({})".format(s, u) for s, u in zip(sys_list, units_list)], ) combine_regex = general_section.get(COMBINE_REGEX_OPTION, None) if combine_regex: try: combine_regex = literal_eval(combine_regex) except (SyntaxError, ValueError): logging.warn( 'Deprecated syntax for "combine_re" (make into a Python-evaluatable' "sequence of strings instead) :: combine_regex = %s", combine_regex, ) combine_regex = [r.strip() for r in combine_regex.split(",")] if APPLY_ALL_SECTION_NAME in no_ws_section_map: apply_all_section = fit_cfg[no_ws_section_map[APPLY_ALL_SECTION_NAME]] for no_ws_sname, sname in no_ws_section_map.items(): if not (no_ws_sname.startswith(NOMINAL_SET_PFX) or no_ws_sname.startswith(SYS_SET_PFX)): continue sys_set_section = fit_cfg[sname] for option, val in apply_all_section.items(): sys_set_section[option] = val return fit_cfg, sys_list, units_list, combine_regex
def __init__( self, fit_results_file, data=None, params=None, input_names=None, output_names=None, debug_mode=None, error_method=None, input_specs=None, calc_specs=None, output_specs=None, links=None, ): # -- Read fit_results_file and extract necessary info -- # fit_results = from_file(fit_results_file) # handle backwards compatibility for old style fit results files if "hyperplanes" in fit_results: using_old_fit_file = False elif "sys_list" in fit_results: using_old_fit_file = True else: raise ValueError("Unrecognised format for input fit file") # get list of systematic parameter names fitted; need to conserve order here! if using_old_fit_file: fit_param_names = fit_results["sys_list"] else: fit_param_names = fit_results["param_names"] if "param_units" in fit_results: fit_param_units = fit_results["param_units"] else: fit_param_units = ["dimensionless" for _ in fit_param_names] fit_param_units = [ureg.Unit(u) for u in fit_param_units] # Perfer to have the actual binning, so we can compare bin edges to # "reasonable" precision to make sure the hyperplane fits are applicable to the # current binning. # # If there is no binning in the hyperplane fit results file, look for a hash # value; barring that, just ensure that the dimensionality & number of bins # match. binning_spec = fit_results.get("binning", None) if binning_spec is not None: fit_binning = MultiDimBinning(**binning_spec) else: fit_binning = None if fit_binning is not None: fit_binning_hash = fit_binning.hash else: fit_binning_hash = fit_results.get("binning_hash", None) if fit_binning_hash is None: logging.warn("Cannot determine the hash of the binning employed" " for the hyperplane fits. Correct application of" " fits is not guaranteed!") # -- Expected input / output names -- # input_names = () output_names = () # -- Which keys are added or altered for the outputs during `apply` -- # input_calc_keys = () output_calc_keys = ("hyperplane_scalefactors", ) if error_method == "sumw2": output_apply_keys = ("weights", "errors") input_apply_keys = output_apply_keys else: output_apply_keys = ("weights", ) input_apply_keys = output_apply_keys # -- Initialize base class -- # super(pi_hyperplanes, self).__init__( data=data, params=params, expected_params=fit_param_names, input_names=input_names, output_names=output_names, debug_mode=debug_mode, error_method=error_method, input_specs=input_specs, calc_specs=calc_specs, output_specs=output_specs, input_calc_keys=input_calc_keys, output_calc_keys=output_calc_keys, input_apply_keys=input_apply_keys, output_apply_keys=output_apply_keys, ) # -- Only allowed/implemented modes -- # assert self.input_mode is not None assert self.calc_mode == "binned" assert self.output_mode is not None self.links = ast.literal_eval(links) # -- Add attrs to `self` specific to `pi_hyperplanes` -- # self.fit_results_file = fit_results_file """str : path to hyperplane fit results file""" self.using_old_fit_file = using_old_fit_file """bool : whether the hyperplane fit file is in the "old" format""" self.fit_results = fit_results """OrderedDict : parsed hyperplane fit file""" self.fit_param_names = fit_param_names """list : param names used in hyperplane fit, in order they appear in file""" self.fit_param_units = fit_param_units """list : param untis used in hyperplane fit, in order they appear in file""" self.fit_binning = fit_binning """MultiDimBinning : binning used for hyperplane fits; one hyperplane per bin""" self.fit_binning_hash = fit_binning_hash """str : hash of the binning used for hyperplane fits"""
def __init__( self, fit_results_file, data=None, params=None, input_names=None, output_names=None, debug_mode=None, error_method=None, input_specs=None, calc_specs=None, output_specs=None, links=None, ): # -- Read fit_results_file and extract necessary info -- # if fit_results_file.endswith('.csv'): # in this case those are datarelease files form = 'datarelease' import pandas as pd fit_results = {} fit_results['nue_cc+nuebar_cc'] = pd.read_csv( fit_results_file.replace('*', 'nue_cc')) fit_results['numu_cc+numubar_cc'] = pd.read_csv( fit_results_file.replace('*', 'numu_cc')) fit_results['nutau_cc+nutaubar_cc'] = pd.read_csv( fit_results_file.replace('*', 'nutau_cc')) fit_results['nu_nc+nubar_nc'] = pd.read_csv( fit_results_file.replace('*', 'all_nc')) fit_param_names = [ a for a in fit_results['nu_nc+nubar_nc'].columns if a not in ['pid', 'reco_energy', 'reco_coszen', 'offset'] ] fit_binning = calc_specs else: fit_results = from_file(fit_results_file) # handle backwards compatibility for old style fit results files if "hyperplanes" in fit_results: form = 'linear' elif "sys_list" in fit_results: form = 'legacy' else: raise ValueError("Unrecognised format for input fit file") # get list of systematic parameter names fitted; need to conserve order here! if form == 'legacy': fit_param_names = fit_results["sys_list"] else: fit_param_names = fit_results["param_names"] # Perfer to have the actual binning, so we can compare bin edges to # "reasonable" precision to make sure the hyperplane fits are applicable to the # current binning. # # If there is no binning in the hyperplane fit results file, look for a hash # value; barring that, just ensure that the dimensionality & number of bins # match. binning_spec = fit_results.get("binning", None) if binning_spec is not None: fit_binning = MultiDimBinning(**binning_spec) else: fit_binning = None if "param_units" in fit_results: fit_param_units = fit_results["param_units"] else: fit_param_units = ["dimensionless" for _ in fit_param_names] fit_param_units = [ureg.Unit(u) for u in fit_param_units] if fit_binning is not None: fit_binning_hash = fit_binning.hash else: fit_binning_hash = fit_results.get("binning_hash", None) if fit_binning_hash is None: logging.warning("Cannot determine the hash of the binning employed" " for the hyperplane fits. Correct application of" " fits is not guaranteed!") # -- Expected input / output names -- # input_names = () output_names = () # -- Which keys are added or altered for the outputs during `apply` -- # input_calc_keys = () output_calc_keys = ("hyperplane_scalefactors", ) if error_method == "sumw2": output_apply_keys = ("weights", "errors") input_apply_keys = output_apply_keys else: output_apply_keys = ("weights", ) input_apply_keys = output_apply_keys # -- Initialize base class -- # super().__init__( data=data, params=params, expected_params=fit_param_names, input_names=input_names, output_names=output_names, debug_mode=debug_mode, error_method=error_method, input_specs=input_specs, calc_specs=calc_specs, output_specs=output_specs, input_calc_keys=input_calc_keys, output_calc_keys=output_calc_keys, input_apply_keys=input_apply_keys, output_apply_keys=output_apply_keys, ) # -- Only allowed/implemented modes -- # assert self.input_mode is not None assert self.calc_mode == "binned" assert self.output_mode is not None self.links = ast.literal_eval(links) # -- Add attrs to `self` specific to `pi_hyperplanes` -- # self.fit_results_file = fit_results_file """str : path to hyperplane fit results file""" self.fit_results = fit_results """OrderedDict : parsed hyperplane fit file""" self.fit_param_names = fit_param_names """list : param names used in hyperplane fit, in order they appear in file""" self.fit_param_units = fit_param_units """list : param untis used in hyperplane fit, in order they appear in file""" self.fit_binning = fit_binning """MultiDimBinning : binning used for hyperplane fits; one hyperplane per bin""" self.fit_binning_hash = fit_binning_hash """str : hash of the binning used for hyperplane fits""" self.form = form """str : format of input file"""