aboutsummaryrefslogtreecommitdiffstats
path: root/utils
diff options
context:
space:
mode:
authorshivesh <s.p.mandalia@qmul.ac.uk>2018-04-24 11:22:19 -0500
committershivesh <s.p.mandalia@qmul.ac.uk>2018-04-24 11:22:19 -0500
commitcfe60732b09544e304e66129383ceaf92ac8cdff (patch)
treecccf10230c86f293e540a3b158df52acd332114d /utils
parent2ca0c5597590e2043bd280dd8aee3d9d09bae29a (diff)
downloadGolemFlavor-cfe60732b09544e304e66129383ceaf92ac8cdff.tar.gz
GolemFlavor-cfe60732b09544e304e66129383ceaf92ac8cdff.zip
Tue Apr 24 11:22:19 CDT 2018
Diffstat (limited to 'utils')
-rw-r--r--utils/enums.py21
-rw-r--r--utils/fr.py17
-rw-r--r--utils/gf.py31
-rw-r--r--utils/likelihood.py38
-rw-r--r--utils/mcmc.py4
-rw-r--r--utils/multinest.py28
-rw-r--r--utils/param.py56
-rw-r--r--utils/plot.py25
8 files changed, 160 insertions, 60 deletions
diff --git a/utils/enums.py b/utils/enums.py
index 359e104..8a9e868 100644
--- a/utils/enums.py
+++ b/utils/enums.py
@@ -21,11 +21,6 @@ class EnergyDependance(Enum):
SPECTRAL = 2
-class FitPriorsCateg(Enum):
- DEFAULT = 1
- XS = 2
-
-
class Likelihood(Enum):
FLAT = 1
GAUSSIAN = 2
@@ -35,11 +30,17 @@ class Likelihood(Enum):
class ParamTag(Enum):
NUISANCE = 1
- MMANGLES = 2
- SCALE = 3
- SRCANGLES = 4
- BESTFIT = 5
- NONE = 6
+ SM_ANGLES = 2
+ MMANGLES = 3
+ SCALE = 4
+ SRCANGLES = 5
+ BESTFIT = 6
+ NONE = 7
+
+
+class PriorsCateg(Enum):
+ UNIFORM = 1
+ GAUSSIAN = 2
class MCMCSeedType(Enum):
diff --git a/utils/fr.py b/utils/fr.py
index 6a405a7..342a848 100644
--- a/utils/fr.py
+++ b/utils/fr.py
@@ -198,17 +198,18 @@ def normalise_fr(fr):
return np.array(fr) / float(np.sum(fr))
-def estimate_scale(args, mass_eigenvalues=MASS_EIGENVALUES):
+def estimate_scale(args):
"""Estimate the scale at which new physics will enter."""
+ m_eign = args.m3x_2
if args.energy_dependance is EnergyDependance.MONO:
scale = np.power(
- 10, np.round(np.log10(MASS_EIGENVALUES[1]/args.energy)) - \
+ 10, np.round(np.log10(m_eign/args.energy)) - \
np.log10(args.energy**(args.dimension-3))
)
elif args.energy_dependance is EnergyDependance.SPECTRAL:
scale = np.power(
10, np.round(
- np.log10(MASS_EIGENVALUES[1]/np.power(10, np.average(np.log10(args.binning)))) \
+ np.log10(m_eign/np.power(10, np.average(np.log10(args.binning)))) \
- np.log10(np.power(10, np.average(np.log10(args.binning)))**(args.dimension-3))
)
)
@@ -297,7 +298,7 @@ NUFIT_U = angles_to_u((0.307, (1-0.02195)**2, 0.565, 3.97935))
def params_to_BSMu(theta, dim, energy, mass_eigenvalues=MASS_EIGENVALUES,
- nufit_u=NUFIT_U, no_bsm=False, fix_mixing=False,
+ sm_u=NUFIT_U, no_bsm=False, fix_mixing=False,
fix_mixing_almost=False, fix_scale=False, scale=None,
check_uni=True, epsilon=1e-9):
"""Construct the BSM mixing matrix from the BSM parameters.
@@ -316,8 +317,8 @@ def params_to_BSMu(theta, dim, energy, mass_eigenvalues=MASS_EIGENVALUES,
mass_eigenvalues : list, length = 2
SM mass eigenvalues
- nufit_u : numpy ndarray, dimension 3
- SM NuFIT mixing matrix
+ sm_u : numpy ndarray, dimension 3
+ SM mixing matrix
no_bsm : bool
Turn off BSM behaviour
@@ -350,7 +351,7 @@ def params_to_BSMu(theta, dim, energy, mass_eigenvalues=MASS_EIGENVALUES,
[-0.32561308 -3.95946524e-01j, 0.64294909 -2.23453580e-01j, 0.03700830 +5.22032403e-01j]])
"""
- if np.shape(nufit_u) != (3, 3):
+ if np.shape(sm_u) != (3, 3):
raise ValueError(
'Input matrix should be a square and dimension 3, '
'got\n{0}'.format(ham)
@@ -377,7 +378,7 @@ def params_to_BSMu(theta, dim, energy, mass_eigenvalues=MASS_EIGENVALUES,
mass_matrix = np.array(
[[0, 0, 0], [0, mass_eigenvalues[0], 0], [0, 0, mass_eigenvalues[1]]]
)
- sm_ham = (1./(2*energy))*np.dot(nufit_u, np.dot(mass_matrix, nufit_u.conj().T))
+ sm_ham = (1./(2*energy))*np.dot(sm_u, np.dot(mass_matrix, sm_u.conj().T))
if no_bsm:
eg_vector = cardano_eqn(sm_ham)
else:
diff --git a/utils/gf.py b/utils/gf.py
index 20afc75..59d1033 100644
--- a/utils/gf.py
+++ b/utils/gf.py
@@ -18,6 +18,37 @@ from utils.enums import DataType, SteeringCateg
from utils.misc import enum_parse, thread_factors
+def fit_flags(llh_paramset):
+ default_flags = {
+ # False means it's not fixed in minimization
+ 'astroFlavorAngle1' : True,
+ 'astroFlavorAngle2' : True,
+ 'astroENorm' : True,
+ 'astroMuNorm' : True,
+ 'astroTauNorm' : True,
+ 'convNorm' : True,
+ 'promptNorm' : True,
+ 'muonNorm' : True,
+ 'astroNorm' : True,
+ 'astroParticleBalance' : True,
+ 'astroDeltaGamma' : True,
+ 'cutoffEnergy' : True,
+ 'CRDeltaGamma' : True,
+ 'piKRatio' : True,
+ 'NeutrinoAntineutrinoRatio' : True,
+ 'darkNorm' : True,
+ 'domEfficiency' : True,
+ 'holeiceForward' : True,
+ 'anisotropyScale' : True,
+ 'astroNormSec' : True,
+ 'astroDeltaGammaSec' : True
+ }
+ flags = gf.FitParametersFlag()
+ for param in llh_paramset:
+ flags.__setattr__(param.name, False)
+ return flags
+
+
def steering_params(args):
steering_categ = args.ast
params = gf.SteeringParams()
diff --git a/utils/likelihood.py b/utils/likelihood.py
index 1981c72..04828e8 100644
--- a/utils/likelihood.py
+++ b/utils/likelihood.py
@@ -18,16 +18,21 @@ import GolemFitPy as gf
from utils import fr as fr_utils
from utils import gf as gf_utils
-from utils.enums import EnergyDependance, Likelihood, ParamTag
+from utils.enums import EnergyDependance, Likelihood, ParamTag, PriorsCateg
from utils.misc import enum_parse
-def gaussian_llh(fr, fr_bf, sigma):
+def multi_gaussian(fr, fr_bf, sigma):
"""Multivariate gaussian likelihood."""
cov_fr = np.identity(3) * sigma
return np.log(multivariate_normal.pdf(fr, mean=fr_bf, cov=cov_fr))
+def log_gaussian(x, mu, sig):
+ """Log gaussian for one dimension."""
+ return np.log((1./np.sqrt(2*np.pi*sig**2))*np.exp(-((x-mu)**2)/(2*sig**2)))
+
+
def likelihood_argparse(parser):
parser.add_argument(
'--likelihood', default='gaussian', type=partial(enum_parse, c=Likelihood),
@@ -41,16 +46,25 @@ def likelihood_argparse(parser):
def lnprior(theta, paramset):
"""Priors on theta."""
+ for idx, param in enumerate(paramset):
+ param.value = theta[idx]
ranges = paramset.ranges
for value, range in zip(theta, ranges):
if range[0] <= value <= range[1]:
pass
else: return -np.inf
- return 0.
+
+ prior = 0
+ for param in paramset:
+ if param.prior is PriorsCateg.GAUSSIAN:
+ prior += log_gaussian(
+ param.nominal_value, param.value, param.std
+ )
+ return prior
def triangle_llh(theta, args, asimov_paramset, llh_paramset, fitter):
- """-Log likelihood function for a given theta."""
+ """Log likelihood function for a given theta."""
if len(theta) != len(llh_paramset):
raise AssertionError(
'Length of MCMC scan is not the same as the input '
@@ -89,11 +103,21 @@ def triangle_llh(theta, args, asimov_paramset, llh_paramset, fitter):
[ParamTag.SCALE, ParamTag.MMANGLES], values=True
)
+ m_eig_names = ['m21_2', 'm3x_2']
+ mass_eigenvalues = [x.value for x in llh_paramset if x.name in m_eig_names]
+
+ ma_names = ['s_12_2', 'c_13_4', 's_23_2', 'dcp']
+ sm_u = fr_utils.angles_to_u(
+ [x.value for x in llh_paramset if x.name in ma_names]
+ )
+
if args.energy_dependance is EnergyDependance.MONO:
u = fr_utils.params_to_BSMu(
theta = bsm_angles,
dim = args.dimension,
energy = args.energy,
+ mass_eigenvalues = mass_eigenvalues,
+ sm_u = sm_u,
no_bsm = args.no_bsm,
fix_mixing = args.fix_mixing,
fix_mixing_almost = args.fix_mixing_almost,
@@ -108,6 +132,8 @@ def triangle_llh(theta, args, asimov_paramset, llh_paramset, fitter):
theta = bsm_angles,
dim = args.dimension,
energy = args.energy,
+ mass_eigenvalues = mass_eigenvalues,
+ sm_u = sm_u,
no_bsm = args.no_bsm,
fix_mixing = args.fix_mixing,
fix_mixing_almost = args.fix_mixing_almost,
@@ -130,14 +156,14 @@ def triangle_llh(theta, args, asimov_paramset, llh_paramset, fitter):
return 1.
elif args.likelihood is Likelihood.GAUSSIAN:
fr_bf = args.measured_ratio
- return gaussian_llh(fr, fr_bf, args.sigma_ratio)
+ return multi_gaussian(fr, fr_bf, args.sigma_ratio)
elif args.likelihood is Likelihood.GOLEMFIT:
return gf_utils.get_llh(fitter, hypo_paramset)
elif args.likelihood is Likelihood.GF_FREQ:
return gf_utils.get_llh_freq(fitter, hypo_paramset)
-def ln_prob(theta, args, fitter, asimov_paramset, llh_paramset):
+def ln_prob(theta, args, asimov_paramset, llh_paramset, fitter):
lp = lnprior(theta, paramset=llh_paramset)
if not np.isfinite(lp):
return -np.inf
diff --git a/utils/mcmc.py b/utils/mcmc.py
index 97b77dd..fa044ea 100644
--- a/utils/mcmc.py
+++ b/utils/mcmc.py
@@ -72,11 +72,11 @@ def mcmc_argparse(parser):
help='Type of distrbution to make the initial MCMC seed'
)
parser.add_argument(
- '--plot-angles', type=misc_utils.parse_bool, default='True',
+ '--plot-angles', type=parse_bool, default='True',
help='Plot MCMC triangle in the angles space'
)
parser.add_argument(
- '--plot-elements', type=misc_utils.parse_bool, default='False',
+ '--plot-elements', type=parse_bool, default='False',
help='Plot MCMC triangle in the mixing elements space'
)
diff --git a/utils/multinest.py b/utils/multinest.py
index 3a7ab2d..426a951 100644
--- a/utils/multinest.py
+++ b/utils/multinest.py
@@ -15,13 +15,27 @@ import numpy as np
from pymultinest import analyse, run
-from utils.likelihood import triangle_llh
+from utils import likelihood
from utils.misc import make_dir, parse_bool
-def CubePrior(cube, ndim, n_params):
- # default are uniform priors
- return ;
+def CubePrior(cube, ndim, n_params, mn_paramset):
+ if ndim != len(mn_paramset):
+ raise AssertionError(
+ 'Length of MultiNest scan paramset is not the same as the input '
+ 'params\ncube={0}\nmn_paramset]{1}'.format(cube, mn_paramset)
+ )
+ pranges = mn_paramset.seeds
+ for i in xrange(ndim):
+ mn_paramset[i].value = (pranges[i][1]-pranges[i][0])*cube[i] + pranges[i][0]
+ prior = 0
+ for parm in mn_paramset:
+ if parm.prior is PriorsCateg.GAUSSIAN:
+ prior_penatly += multivariate_normal(
+ parm.nominal_value, mean=parm.value, cov=parm.std
+ )
+ print 'prior', prior
+ return prior
def lnProb(cube, ndim, n_params, mn_paramset, llh_paramset, asimov_paramset,
@@ -38,7 +52,7 @@ def lnProb(cube, ndim, n_params, mn_paramset, llh_paramset, asimov_paramset,
llh_paramset[pm].value = mn_paramset[pm].value
theta = llh_paramset.values
# print 'llh_paramset', llh_paramset
- return triangle_llh(
+ return likelihood.ln_prob(
theta=theta,
args=args,
asimov_paramset=asimov_paramset,
@@ -72,10 +86,6 @@ def mn_argparse(parser):
'--mn-output', type=str, default='./mnrun/',
help='Folder to store MultiNest evaluations'
)
- parser.add_argument(
- '--plot-multinest', type=parse_bool, default='False',
- help='Plot MultiNest evidence'
- )
def mn_evidence(mn_paramset, llh_paramset, asimov_paramset, args, fitter):
diff --git a/utils/param.py b/utils/param.py
index bf230df..13f1a63 100644
--- a/utils/param.py
+++ b/utils/param.py
@@ -12,17 +12,20 @@ from __future__ import absolute_import, division
import sys
from collections import Sequence
+from copy import deepcopy
import numpy as np
from utils.plot import get_units
from utils.fr import fr_to_angles
-from utils.enums import Likelihood, ParamTag
+from utils.enums import Likelihood, ParamTag, PriorsCateg
class Param(object):
"""Parameter class to store parameters."""
- def __init__(self, name, value, ranges, seed=None, std=None, tex=None, tag=None):
+ def __init__(self, name, value, ranges, prior=None, seed=None, std=None,
+ tex=None, tag=None):
+ self._prior = None
self._seed = None
self._ranges = None
self._tex = None
@@ -30,8 +33,10 @@ class Param(object):
self.name = name
self.value = value
- self.seed = seed
+ self.nominal_value = deepcopy(value)
+ self.prior = prior
self.ranges = ranges
+ self.seed = seed
self.std = std
self.tex = tex
self.tag = tag
@@ -45,6 +50,18 @@ class Param(object):
self._ranges = [val for val in values]
@property
+ def prior(self):
+ return self._prior
+
+ @prior.setter
+ def prior(self, value):
+ if value is None:
+ self._prior = PriorsCateg.UNIFORM
+ else:
+ assert value in PriorsCateg
+ self._prior = value
+
+ @property
def seed(self):
if self._seed is None: return self.ranges
return tuple(self._seed)
@@ -146,6 +163,10 @@ class ParamSet(Sequence):
return tuple([obj.value for obj in self._params])
@property
+ def nominal_values(self):
+ return tuple([obj.nominal_value for obj in self._params])
+
+ @property
def seeds(self):
return tuple([obj.seed for obj in self._params])
@@ -185,18 +206,22 @@ class ParamSet(Sequence):
return ParamSet([io[1] for io in ps])
-def get_paramsets(args):
+def get_paramsets(args, nuisance_paramset):
"""Make the paramsets for generating the Asmimov MC sample and also running
the MCMC.
"""
asimov_paramset = []
llh_paramset = []
- if args.likelihood == Likelihood.GOLEMFIT:
- nuisance_paramset = define_nuisance()
- asimov_paramset.extend(nuisance_paramset.params)
- llh_paramset.extend(nuisance_paramset.params)
- for parm in nuisance_paramset:
- parm.value = args.__getattribute__(parm.name)
+
+ llh_paramset.extend(
+ [x for x in nuisance_paramset.from_tag(ParamTag.SM_ANGLES)]
+ )
+ if args.likelihood is Likelihood.GOLEMFIT:
+ gf_nuisance = [x for x in nuisance_paramset.from_tag(ParamTag.NUISANCE)]
+ asimov_paramset.extend(gf_nuisance)
+ llh_paramset.extend(gf_nuisance)
+ for parm in llh_paramset:
+ parm.value = args.__getattribute__(parm.name)
tag = ParamTag.BESTFIT
flavour_angles = fr_to_angles(args.measured_ratio)
asimov_paramset.extend([
@@ -207,17 +232,16 @@ def get_paramsets(args):
if not args.fix_mixing and not args.fix_mixing_almost:
tag = ParamTag.MMANGLES
- e = 1e-10
llh_paramset.extend([
- Param(name='s_12^2', value=0.5, ranges=[0.+e, 1.-e], std=0.2, tex=r'\tilde{s}_{12}^2', tag=tag),
- Param(name='c_13^4', value=0.5, ranges=[0.+e, 1.-e], std=0.2, tex=r'\tilde{c}_{13}^4', tag=tag),
- Param(name='s_23^2', value=0.5, ranges=[0.+e, 1.-e], std=0.2, tex=r'\tilde{s}_{23}^4', tag=tag),
- Param(name='dcp', value=np.pi, ranges=[0.+e, 2*np.pi-e], std=0.2, tex=r'\tilde{\delta_{CP}}', tag=tag)
+ Param(name='np_s_12^2', value=0.5, ranges=[0., 1.], std=0.2, tex=r'\tilde{s}_{12}^2', tag=tag),
+ Param(name='np_c_13^4', value=0.5, ranges=[0., 1.], std=0.2, tex=r'\tilde{c}_{13}^4', tag=tag),
+ Param(name='np_s_23^2', value=0.5, ranges=[0., 1.], std=0.2, tex=r'\tilde{s}_{23}^4', tag=tag),
+ Param(name='np_dcp', value=np.pi, ranges=[0., 2*np.pi], std=0.2, tex=r'\tilde{\delta_{CP}}', tag=tag)
])
if args.fix_mixing_almost:
tag = ParamTag.MMANGLES
llh_paramset.extend([
- Param(name='s_23^2', value=0.5, ranges=[0., 1.], std=0.2, tex=r'\tilde{s}_{23}^4', tag=tag)
+ Param(name='np_s_23^2', value=0.5, ranges=[0., 1.], std=0.2, tex=r'\tilde{s}_{23}^4', tag=tag)
])
if not args.fix_scale:
tag = ParamTag.SCALE
diff --git a/utils/plot.py b/utils/plot.py
index 66c888c..6ae8dc2 100644
--- a/utils/plot.py
+++ b/utils/plot.py
@@ -24,7 +24,7 @@ from getdist import plots
from getdist import mcsamples
from utils import misc as misc_utils
-from utils.enums import EnergyDependance, Likelihood, ParamTag
+from utils.enums import EnergyDependance, Likelihood, ParamTag, StatCateg
from utils.fr import angles_to_u, angles_to_fr
rc('text', usetex=False)
@@ -231,25 +231,32 @@ def chainer_plot(infile, outfile, outformat, args, llh_paramset):
g.export(outfile+'_elements.'+of)
-def plot_multinest(data, outfile, outformat, args, scale_param, label=None):
- """Make MultiNest factor plot."""
+def plot_statistic(data, outfile, outformat, args, scale_param, label=None):
+ """Make MultiNest factor or LLH value plot."""
print "Making MultiNest Factor plot"
fig_text = gen_figtext(args)
if label is not None: fig_text += '\n' + label
print 'data.shape', data.shape
- scales, evidences = data.T
- min_idx = np.argmin(scales)
- null = evidences[min_idx]
-
- reduced_ev = -(evidences - null)
+ scales, statistic = data.T
+ if args.stat_method is StatCateg.BAYESIAN:
+ min_idx = np.argmin(scales)
+ null = statistic[min_idx]
+ reduced_ev = -(statistic - null)
+ elif args.stat_method is StatCateg.FREQUENTIST:
+ min_idx = np.argmin(statistic)
+ null = statistic[min_idx]
+ reduced_ev = 2*(statistic - null)
fig = plt.figure(figsize=(7, 5))
ax = fig.add_subplot(111)
ax.set_xlim(scale_param.ranges)
ax.set_xlabel('$'+scale_param.tex+'$')
- ax.set_ylabel(r'Bayes Factor')
+ if args.stat_method is StatCateg.BAYESIAN:
+ ax.set_ylabel(r'Bayes Factor')
+ elif args.stat_method is StatCateg.FREQUENTIST:
+ ax.set_ylabel(r'$\Delta {\rm LLH}$')
ax.plot(scales, reduced_ev)