aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--__init__.py0
-rwxr-xr-xchainer_plot.py271
-rwxr-xr-xfr.py73
-rw-r--r--utils/enums.py8
-rw-r--r--utils/mcmc.py13
-rw-r--r--utils/misc.py44
-rw-r--r--utils/plot.py167
7 files changed, 245 insertions, 331 deletions
diff --git a/__init__.py b/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/__init__.py
+++ /dev/null
diff --git a/chainer_plot.py b/chainer_plot.py
deleted file mode 100755
index 3facb30..0000000
--- a/chainer_plot.py
+++ /dev/null
@@ -1,271 +0,0 @@
-#! /usr/bin/env python
-"""
-From an MCMC chains file, make a triangle plot.
-"""
-
-from __future__ import absolute_import, division
-
-import sys, os
-import errno
-
-import numpy as np
-import matplotlib as mpl
-mpl.use('Agg')
-from matplotlib import rc, rcParams
-
-import getdist
-from getdist import plots
-from getdist import mcsamples
-
-from utils.fr import angles_to_u, angles_to_fr
-
-rc('text', usetex=False)
-rc('font', **{'family':'serif', 'serif':['Computer Modern'], 'size':18})
-cols = ['#29A2C6','#FF6D31','#FFCB18','#73B66B','#EF597B', '#333333']
-
-font = {'family' : 'serif',
- 'weight' : 'bold',
- 'size' : 18}
-
-
-def plot(infile, angles, outfile, measured_ratio, sigma_ratio, fix_sfr,
- fix_mixing, fix_scale, source_ratio, scale, dimension, energy, scale_bounds):
- """Make the triangle plot"""
- if not angles:
- if fix_mixing:
- labels = [r'{\rm log}_{10}\Lambda', r'\phi_e', r'\phi_\mu', r'\phi_\tau']
- elif fix_sfr:
- if fix_scale:
- labels = [r'\mid \tilde{U}_{e1} \mid', r'\mid \tilde{U}_{e2} \mid', r'\mid \tilde{U}_{e3} \mid', \
- r'\mid \tilde{U}_{\mu1} \mid', r'\mid \tilde{U}_{\mu2} \mid', r'\mid \tilde{U}_{\mu3} \mid', \
- r'\mid \tilde{U}_{\tau1} \mid', r'\mid \tilde{U}_{\tau2} \mid', r'\mid \tilde{U}_{\tau3} \mid']
- else:
- labels = [r'\mid \tilde{U}_{e1} \mid', r'\mid \tilde{U}_{e2} \mid', r'\mid \tilde{U}_{e3} \mid', \
- r'\mid \tilde{U}_{\mu1} \mid', r'\mid \tilde{U}_{\mu2} \mid', r'\mid \tilde{U}_{\mu3} \mid', \
- r'\mid \tilde{U}_{\tau1} \mid', r'\mid \tilde{U}_{\tau2} \mid', r'\mid \tilde{U}_{\tau3} \mid', \
- r'{\rm log}_{10}(\Lambda)']
- else:
- if fix_scale:
- labels = [r'\mid \tilde{U}_{e1} \mid', r'\mid \tilde{U}_{e2} \mid', r'\mid \tilde{U}_{e3} \mid', \
- r'\mid \tilde{U}_{\mu1} \mid', r'\mid \tilde{U}_{\mu2} \mid', r'\mid \tilde{U}_{\mu3} \mid', \
- r'\mid \tilde{U}_{\tau1} \mid', r'\mid \tilde{U}_{\tau2} \mid', r'\mid \tilde{U}_{\tau3} \mid', \
- r'{\rm log}_{10}\Lambda', r'\phi_e', r'\phi_\mu', r'\phi_\tau']
- else:
- labels = [r'\mid \tilde{U}_{e1} \mid', r'\mid \tilde{U}_{e2} \mid', r'\mid \tilde{U}_{e3} \mid', \
- r'\mid \tilde{U}_{\mu1} \mid', r'\mid \tilde{U}_{\mu2} \mid', r'\mid \tilde{U}_{\mu3} \mid', \
- r'\mid \tilde{U}_{\tau1} \mid', r'\mid \tilde{U}_{\tau2} \mid', r'\mid \tilde{U}_{\tau3} \mid', \
- r'\phi_e', r'\phi_\mu', r'\phi_\tau']
- else:
- if fix_sfr:
- if fix_mixing:
- assert 0
- labels=[r'\tilde{s}_{12}^2', r'{\rm log}_{10}\Lambda']
- elif fix_scale:
- labels=[r'\tilde{s}_{12}^2', r'\tilde{c}_{13}^4',
- r'\tilde{s}_{23}^2', r'\tilde{\delta_{CP}}']
- else:
- labels=[r'\tilde{s}_{12}^2', r'\tilde{c}_{13}^4',
- r'\tilde{s}_{23}^2', r'\tilde{\delta_{CP}}',
- r'{\rm log}_{10}\Lambda']
- else:
- if fix_mixing:
- labels=[r'{\rm log}_{10}\Lambda', r'sin^4(\phi)', r'cos(2\psi)']
- elif fix_scale:
- labels=[r'\tilde{s}_{12}^2', r'\tilde{c}_{13}^4',
- r'\tilde{s}_{23}^2', r'\tilde{\delta_{CP}}',
- r'sin^4(\phi)', r'cos(2\psi)']
- else:
- labels=[r'\tilde{s}_{12}^2', r'\tilde{c}_{13}^4',
- r'\tilde{s}_{23}^2', r'\tilde{\delta_{CP}}',
- r'{\rm log}_{10}\Lambda', r'sin^4(\phi)', r'cos(2\psi)']
- labels = [r'convNorm', r'promptNorm', 'muonNorm', 'astroNorm', 'astroDeltaGamma'] + labels
- print 'labels', labels
-
- if not fix_scale:
- s2 = np.log10(scale_bounds)
-
- if not angles:
- if fix_mixing:
- ranges = [s2, (0, 1), (0, 1), (0, 1)]
- elif fix_sfr:
- if fix_scale:
- ranges = [(0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1)]
- else:
- ranges = [(0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), s2]
- else:
- if fix_scale:
- ranges = [(0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1)]
- else:
- ranges = [(0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), (0, 1), s2, (0, 1), (0, 1), (0, 1)]
- else:
- if fix_sfr:
- if fix_mixing:
- ranges = [(0, 1), s2]
- elif fix_scale:
- ranges = [(0, 1), (0, 1), (0, 1), (0, 2*np.pi)]
- else:
- ranges = [(0, 1), (0, 1), (0, 1), (0, 2*np.pi), s2]
- else:
- if fix_mixing:
- ranges = [s2, (0, 1), (-1, 1)]
- elif fix_scale:
- ranges = [(0, 1), (0, 1), (0, 1), (0, 2*np.pi), (0, 1), (-1, 1)]
- else:
- ranges = [(0, 1), (0, 1), (0, 1), (0, 2*np.pi), s2, (0, 1), (-1, 1)]
- ranges = [(0, 5), (0, 5), (0, 5), (0, 5), (0, 5)] + ranges
- print 'ranges', ranges
-
- def flat_angles_to_u(x):
- return abs(angles_to_u(x)).astype(np.float32).flatten().tolist()
-
- raw = np.load(infile)
- print 'raw.shape', raw.shape
- if not angles:
- nuisance, raw = raw[:,5:], raw[:,-5:]
- if fix_mixing:
- fr_elements = np.array(map(angles_to_fr, raw[:,-2:]))
- sc_elements = raw[:,:-2]
- Tchain = np.column_stack([sc_elements, fr_elements])
- elif fix_sfr:
- if fix_scale:
- Tchain = np.array(map(flat_angles_to_u, raw))
- else:
- sc_elements = raw[:,-1:]
- m_elements = np.array(map(flat_angles_to_u, raw[:,:-1]))
- Tchain = np.column_stack([m_elements, sc_elements])
- else:
- if fix_scale:
- fr_elements = np.array(map(angles_to_fr, raw[:,-2:]))
- m_elements = np.array(map(flat_angles_to_u, raw[:,:-2]))
- Tchain = np.column_stack([m_elements, fr_elements])
- else:
- fr_elements = np.array(map(angles_to_fr, raw[:,-2:]))
- sc_elements = raw[:,-3:-2]
- m_elements = np.array(map(flat_angles_to_u, raw[:,:-3]))
- Tchain = np.column_stack([m_elements, sc_elements, fr_elements])
- Tchain = np.column_stack([nuisance, Tchain])
- else:
- Tchain = raw
- print 'Tchain.shape', Tchain.shape
-
- if fix_sfr:
- if fix_scale:
- label = 'Source flavour ratio = [{0:.2f}, {1:.2f}, {2:.2f}]\nIC observed flavour ratio = [{3:.2f}, {4:.2f}, {5:.2f}]\nSigma = {6:.3f}\nDimension = {7}\nEnergy = {8} GeV\nScale = {9}'.format(
- source_ratio[0], source_ratio[1], source_ratio[2],
- measured_ratio[0], measured_ratio[1], measured_ratio[2], sigma_ratio,
- dimension, int(energy), scale
- )
- else:
- label = 'Source flavour ratio = [{0:.2f}, {1:.2f}, {2:.2f}]\nIC observed flavour ratio = [{3:.2f}, {4:.2f}, {5:.2f}]\nSigma = {6:.3f}\nDimension = {7}\nEnergy = {8} GeV'.format(
- source_ratio[0], source_ratio[1], source_ratio[2],
- measured_ratio[0], measured_ratio[1], measured_ratio[2], sigma_ratio,
- dimension, int(energy)
- )
- else:
- if fix_scale:
- label = 'IC observed flavour ratio = [{0:.2f}, {1:.2f}, {2:.2f}]\nSigma = {3:.3f}\nDimension = {4}\nEnergy = {5} GeV\nScale = {6}'.format(
- measured_ratio[0], measured_ratio[1], measured_ratio[2], sigma_ratio,
- dimension, int(energy), scale
- )
- else:
- label = 'IC observed flavour ratio = [{0:.2f}, {1:.2f}, {2:.2f}]\nSigma = {3:.3f}\nDimension = {4}\nEnergy = {5} GeV'.format(
- measured_ratio[0], measured_ratio[1], measured_ratio[2], sigma_ratio,
- dimension, int(energy)
- )
-
- Tsample = mcsamples.MCSamples(
- samples=Tchain, labels=labels, ranges=ranges
- )
-
- Tsample.updateSettings({'contours': [0.90, 0.99]})
- Tsample.num_bins_2D=500
- Tsample.fine_bins_2D=500
- Tsample.smooth_scale_2D=0.03
-
- g = plots.getSubplotPlotter()
- g.settings.num_plot_contours = 2
- g.settings.axes_fontsize = 10
- g.settings.figure_legend_frame = False
- g.triangle_plot(
- [Tsample], filled=True,
- )
- if fix_mixing and fix_sfr:
- mpl.pyplot.figtext(0.4, 0.7, label, fontsize=4)
- else:
- mpl.pyplot.figtext(0.5, 0.7, label, fontsize=15)
- print 'outfile = {0}'.format(outfile)
- try:
- os.makedirs(outfile[:-len(os.path.basename(outfile))])
- except OSError as exc: # Python >2.5
- if exc.errno == errno.EEXIST and os.path.isdir(outfile[:-len(os.path.basename(outfile))]):
- pass
- else:
- raise
- g.export(outfile)
-
-
-def parse_args():
- """Parse command line arguments"""
- parser = argparse.ArgumentParser(description=__doc__)
- parser.add_argument(
- '--infile', type=str, required=True,
- help='Path to MCMC chains'
- )
- parser.add_argument(
- '--angles', default=False, action='store_true',
- help='Plot in terms of mixing angles'
- )
- parser.add_argument(
- '--outfile', type=str, default='./untitled.pdf',
- help='Path to output plot'
- )
- parser.add_argument(
- '--bestfit-ratio', type=int, nargs=3, required=False,
- help='Set the bestfit flavour ratio'
- )
- parser.add_argument(
- '--sigma-ratio', type=float, required=False,
- help='Set the 1 sigma for the flavour ratio'
- )
- parser.add_argument(
- '--fix-sfr', action='store_true',
- help='Fix the source flavour ratio'
- )
- parser.add_argument(
- '--fix-mixing', action='store_true',
- help='Fix the new physics mixing values to a single term, s_12^2'
- )
- parser.add_argument(
- '--source-ratio', type=int, nargs=3, default=[2, 1, 0],
- help='Set the source flavour ratio for the case when you want to fix it'
- )
- parser.add_argument(
- '--scale', type=float, required=False,
- help='Fix the scale to this value'
- )
- parser.add_argument(
- '--dimension', type=int, default=3, help='Dimension'
- )
- parser.add_argument(
- '--energy', type=float, default=1000, help='Energy'
- )
- parser.add_argument(
- '--scale-bounds', type=float, nargs=2,
- help='Upper and lower limits to plot the new physics scale'
- )
- args = parser.parse_args()
- return args
-
-
-def main():
- args = vars(parse_args())
- plot(**args)
-
- print "DONE!"
-
-
-main.__doc__ = __doc__
-
-
-if __name__ == '__main__':
- main()
diff --git a/fr.py b/fr.py
index b92f87f..3e9581e 100755
--- a/fr.py
+++ b/fr.py
@@ -17,23 +17,24 @@ import numpy as np
from utils import mcmc as mcmc_utils
from utils import misc as misc_utils
+from utils.enums import ParamTag
from utils.fr import MASS_EIGENVALUES, normalise_fr
from utils.gf import gf_argparse
from utils.misc import Param, ParamSet
-
-import chainer_plot
+from utils.plot import plot_argparse, chainer_plot
def define_nuisance():
"""Define the nuisance parameters to scan over with default values,
ranges and sigma.
"""
+ tag = ParamTag.NUISANCE
nuisance = ParamSet(
- Param(name='convNorm' , value=1. , ranges=[0., 5.], std=0.3),
- Param(name='promptNorm' , value=0. , ranges=[0., 5.], std=0.05),
- Param(name='muonNorm' , value=1. , ranges=[0., 5.], std=0.1),
- Param(name='astroNorm' , value=1. , ranges=[0., 5.], std=0.1),
- Param(name='astroDeltaGamma', value=2. , ranges=[0., 5.], std=0.1)
+ Param(name='convNorm' , value=1. , ranges=[0., 5.], std=0.3 , tag=tag),
+ Param(name='promptNorm' , value=0. , ranges=[0., 5.], std=0.05, tag=tag),
+ Param(name='muonNorm' , value=1. , ranges=[0., 5.], std=0.1 , tag=tag),
+ Param(name='astroNorm' , value=1. , ranges=[0., 5.], std=0.1 , tag=tag),
+ Param(name='astroDeltaGamma', value=2. , ranges=[0., 5.], std=0.1 , tag=tag)
)
return nuisance
@@ -63,22 +64,25 @@ def get_paramsets(args):
mcmc_paramset = []
if not args.fix_mixing:
+ tag = ParamTag.MMANGLES
mcmc_paramset.extend([
- Param(name='s_12^2', value=0.5, ranges=[0., 1.], std=0.2, tex=r'\tilde{s}_{12}^2'),
- Param(name='c_13^4', value=0.5, ranges=[0., 1.], std=0.2, tex=r'\tilde{c}_{13}^4'),
- Param(name='s_23^2', value=0.5, ranges=[0., 1.], std=0.2, tex=r'\tilde{s}_{23}^4'),
- Param(name='dcp', value=np.pi, ranges=[0., 2*np.pi], std=0.2, tex=r'\tilde{\delta_{CP}}')
+ Param(name='s_12^2', value=0.5, ranges=[0., 1.], std=0.2, tex=r'\tilde{s}_{12}^2', tag=tag),
+ Param(name='c_13^4', value=0.5, ranges=[0., 1.], std=0.2, tex=r'\tilde{c}_{13}^4', tag=tag),
+ Param(name='s_23^2', value=0.5, ranges=[0., 1.], std=0.2, tex=r'\tilde{s}_{23}^4', tag=tag),
+ Param(name='dcp', value=np.pi, ranges=[0., 2*np.pi], std=0.2, tex=r'\tilde{\delta_{CP}}', tag=tag)
])
if not args.fix_scale:
logLam, scale_region = np.log10(args.scale), np.log10(args.scale_region)
lL_range = (logLam-scale_region, logLam+scale_region)
+ tag = ParamTag.SCALE
mcmc_paramset.append(
- Param(name='logLam', value=logLam, ranges=lL_range, std=3, tex=r'{\rm log}_{10}\Lambda')
+ Param(name='logLam', value=logLam, ranges=lL_range, std=3, tex=r'{\rm log}_{10}\Lambda', tag=tag)
)
if not args.fix_source_ratio:
+ tag = ParamTag.SRCANGLES
mcmc_paramset.extend([
- Param(name='s_phi4', value=0.5, ranges=[0., 1.], std=0.2, tex=r'sin^4(\phi)'),
- Param(name='c_2psi', value=0.5, ranges=[0., 1.], std=0.2, tex=r'cos(2\psi)')
+ Param(name='s_phi4', value=0.5, ranges=[0., 1.], std=0.2, tex=r'sin^4(\phi)', tag=tag),
+ Param(name='c_2psi', value=0.5, ranges=[0., 1.], std=0.2, tex=r'cos(2\psi)', tag=tag)
])
mcmc_paramset = ParamSet(nuisance_paramset.params + mcmc_paramset)
return nuisance_paramset, mcmc_paramset
@@ -162,9 +166,10 @@ def parse_args():
'--outfile', type=str, default='./untitled',
help='Path to output chains'
)
+ mcmc_utils.mcmc_argparse(parser)
nuisance_argparse(parser)
gf_argparse(parser)
- mcmc_utils.mcmc_argparse(parser)
+ plot_argparse(parser)
return parser.parse_args()
@@ -206,38 +211,14 @@ def main():
)
mcmc_utils.save_chains(samples, outfile)
- scale_bounds = (args.scale/args.scale_region, args.scale*args.scale_region)
print "Making triangle plots"
- chainer_plot.plot(
- infile = outfile+'.npy',
- angles = True,
- outfile = outfile[:5]+outfile[5:].replace('data', 'plots')+'_angles.pdf',
- measured_ratio = args.measured_ratio,
- sigma_ratio = args.sigma_ratio,
- fix_sfr = args.fix_source_ratio,
- fix_mixing = args.fix_mixing,
- fix_scale = args.fix_scale,
- source_ratio = args.source_ratio,
- scale = args.scale,
- dimension = args.dimension,
- energy = args.energy,
- scale_bounds = scale_bounds,
- )
- # chainer_plot.plot(
- # infile=outfile+'.npy',
- # angles=False,
- # outfile=outfile[:5]+outfile[5:].replace('data', 'plots')+'.pdf',
- # measured_ratio=args.measured_ratio,
- # sigma_ratio=args.sigma_ratio,
- # fix_sfr=args.fix_source_ratio,
- # fix_mixing=args.fix_mixing,
- # fix_scale=FIX_SCALE,
- # source_ratio=args.source_ratio,
- # scale=args.scale,
- # dimension=args.dimension,
- # energy=args.energy,
- # scale_bounds=scale_bounds,
- # )
+ chainer_plot(
+ infile = outfile+'.npy',
+ outfile = outfile[:5]+outfile[5:].replace('data', 'plots'),
+ outformat = ['pdf'],
+ args = args,
+ mcmc_paramset = mcmc_paramset
+ )
print "DONE!"
diff --git a/utils/enums.py b/utils/enums.py
index 31885de..e154d0f 100644
--- a/utils/enums.py
+++ b/utils/enums.py
@@ -40,6 +40,14 @@ class Likelihood(Enum):
GOLEMFIT = 3
+class ParamTag(Enum):
+ NUISANCE = 1
+ MMANGLES = 2
+ SCALE = 3
+ SRCANGLES = 4
+ NONE = 5
+
+
class Priors(Enum):
UNIFORM = 1
LOGUNIFORM = 2
diff --git a/utils/mcmc.py b/utils/mcmc.py
index d91764f..aebe12f 100644
--- a/utils/mcmc.py
+++ b/utils/mcmc.py
@@ -9,9 +9,6 @@ Useful functions to use an MCMC for the BSM flavour ratio analysis
from __future__ import absolute_import, division
-import os
-import errno
-
import argparse
from functools import partial
@@ -23,7 +20,7 @@ from scipy.stats import multivariate_normal
from utils import fr as fr_utils
from utils.enums import Likelihood
-from utils.misc import enum_keys, enum_parse, parse_bool
+from utils.misc import enum_keys, enum_parse, make_dir, parse_bool
def lnprior(theta, paramset):
@@ -115,13 +112,7 @@ def save_chains(chains, outfile):
Output file location of chains
"""
- try:
- os.makedirs(outfile[:-len(os.path.basename(outfile))])
- except OSError as exc: # Python >2.5
- if exc.errno == errno.EEXIST and os.path.isdir(outfile[:-len(os.path.basename(outfile))]):
- pass
- else:
- raise
+ make_dir(outfile)
print 'Saving chains to location {0}'.format(outfile+'.npy')
np.save(outfile+'.npy', chains)
diff --git a/utils/misc.py b/utils/misc.py
index 5c3eb2e..c54d25c 100644
--- a/utils/misc.py
+++ b/utils/misc.py
@@ -16,21 +16,23 @@ import multiprocessing
import numpy as np
-from utils.enums import Likelihood
+from utils.enums import Likelihood, ParamTag
class Param(object):
"""Parameter class to store parameters.
"""
- def __init__(self, name, value, ranges, std=None, tex=None):
+ def __init__(self, name, value, ranges, std=None, tex=None, tag=None):
self._ranges = None
self._tex = None
+ self._tag = None
self.name = name
self.value = value
self.ranges = ranges
self.std = std
self.tex = tex
+ self.tag = tag
@property
def ranges(self):
@@ -42,12 +44,23 @@ class Param(object):
@property
def tex(self):
- return r'{0}'.format(self.tex)
+ return r'{0}'.format(self._tex)
@tex.setter
def tex(self, t):
self._tex = t if t is not None else r'{\rm %s}' % self.name
+ @property
+ def tag(self):
+ return self._tag
+
+ @tex.setter
+ def tag(self, t):
+ if t is None: self._tag = ParamTag.NONE
+ else:
+ assert t in ParamTag
+ self._tag = t
+
class ParamSet(Sequence):
"""Container class for a set of parameters.
@@ -105,6 +118,10 @@ class ParamSet(Sequence):
return tuple([obj.name for obj in self._params])
@property
+ def labels(self):
+ return tuple([obj.tex for obj in self._params])
+
+ @property
def values(self):
return tuple([obj.value for obj in self._params])
@@ -117,12 +134,23 @@ class ParamSet(Sequence):
return tuple([obj.std for obj in self._params])
@property
+ def tags(self):
+ return tuple([obj.tag for obj in self._params])
+
+ @property
def params(self):
return self._params
def to_dict(self):
return {obj.name: obj.value for obj in self._params}
+ def from_tag(self, tag):
+ return tuple([obj for obj in self._params if obj.tag is tag])
+
+ def idx_from_tag(self, tag):
+ return tuple([idx for idx, obj in enumerate(self._params)
+ if obj.tag is tag])
+
def gen_outfile_name(args):
"""Generate a name for the output file based on the input args.
@@ -222,6 +250,16 @@ def enum_parse(s, c):
return c[s.upper()]
+def make_dir(outfile):
+ try:
+ os.makedirs(outfile[:-len(os.path.basename(outfile))])
+ except OSError as exc: # Python >2.5
+ if exc.errno == errno.EEXIST and os.path.isdir(outfile[:-len(os.path.basename(outfile))]):
+ pass
+ else:
+ raise
+
+
def thread_type(t):
if t.lower() == 'max':
return multiprocessing.cpu_count()
diff --git a/utils/plot.py b/utils/plot.py
new file mode 100644
index 0000000..fb90b3e
--- /dev/null
+++ b/utils/plot.py
@@ -0,0 +1,167 @@
+# author : S. Mandalia
+# s.p.mandalia@qmul.ac.uk
+#
+# date : March 19, 2018
+
+"""
+Plotting functions for the BSM flavour ratio analysis
+"""
+
+from __future__ import absolute_import, division
+
+import argparse
+
+import numpy as np
+import matplotlib as mpl
+mpl.use('Agg')
+from matplotlib import rc
+
+import getdist
+from getdist import plots
+from getdist import mcsamples
+
+from utils import misc as misc_utils
+from utils.enums import ParamTag
+from utils.fr import angles_to_u, angles_to_fr
+
+rc('text', usetex=False)
+rc('font', **{'family':'serif', 'serif':['Computer Modern'], 'size':18})
+
+
+def plot_argparse(parser):
+ """Arguments for plotting."""
+ parser.add_argument(
+ '--plot-angles', type=misc_utils.parse_bool, default='True',
+ help='Plot MCMC triangle in the angles space'
+ )
+ parser.add_argument(
+ '--plot-elements', type=misc_utils.parse_bool, default='False',
+ help='Plot MCMC triangle in the mixing elements space'
+ )
+
+
+def flat_angles_to_u(x):
+ """Convert from angles to mixing elements."""
+ return abs(angles_to_u(x)).astype(np.float32).flatten().tolist()
+
+
+def plot_Tchain(Tchain, axes_labels, ranges):
+ """Plot the Tchain using getdist."""
+ Tsample = mcsamples.MCSamples(
+ samples=Tchain, labels=axes_labels, ranges=ranges
+ )
+
+ Tsample.updateSettings({'contours': [0.90, 0.99]})
+ Tsample.num_bins_2D=500
+ Tsample.fine_bins_2D=500
+ Tsample.smooth_scale_2D=0.03
+
+ g = plots.getSubplotPlotter()
+ g.settings.num_plot_contours = 2
+ g.settings.axes_fontsize = 10
+ g.settings.figure_legend_frame = False
+ g.triangle_plot(
+ [Tsample], filled=True,
+ )
+ return g
+
+
+def gen_figtext(args):
+ """Generate the figure text."""
+ mr1, mr2, mr3 = args.measured_ratio
+ if args.fix_source_ratio:
+ sr1, sr2, sr3 = args.source_ratio
+ if args.fix_scale:
+ return 'Source flavour ratio = [{0:.2f}, {1:.2f}, {2:.2f}]\nIC ' \
+ 'observed flavour ratio = [{3:.2f}, {4:.2f}, ' \
+ '{5:.2f}]\nSigma = {6:.3f}\nDimension = {7}\nEnergy = ' \
+ '{8} GeV\nScale = {9}'.format(
+ sr1, sr2, sr3, mr1, mr2, mr3, args.sigma_ratio,
+ args.dimension, int(args.energy), args.scale
+ )
+ else:
+ return 'Source flavour ratio = [{0:.2f}, {1:.2f}, {2:.2f}]\nIC ' \
+ 'observed flavour ratio = [{3:.2f}, {4:.2f}, ' \
+ '{5:.2f}]\nSigma = {6:.3f}\nDimension = {7}\nEnergy = {8} ' \
+ 'GeV'.format(
+ sr1, sr3, sr2, mr1, mr2, mr3, args.sigma_ratio,
+ args.dimension, int(args.energy)
+ )
+ else:
+ if args.fix_scale:
+ return 'IC observed flavour ratio = [{0:.2f}, {1:.2f}, ' \
+ '{2:.2f}]\nSigma = {3:.3f}\nDimension = {4}\nEnergy = {5} ' \
+ 'GeV\nScale = {6}'.format(
+ mr1, mr2, mr3, args.sigma_ratio, args.dimension,
+ int(args.energy), args.scale
+ )
+ else:
+ return 'IC observed flavour ratio = [{0:.2f}, {1:.2f}, ' \
+ '{2:.2f}]\nSigma = {3:.3f}\nDimension = {4}\nEnergy = {5} ' \
+ 'GeV'.format(
+ mr1, mr2, mr3, args.sigma_ratio, args.dimension,
+ int(args.energy)
+ )
+
+def chainer_plot(infile, outfile, outformat, args, mcmc_paramset):
+ """Make the triangle plot."""
+ if not args.plot_angles and not args.plot_elements:
+ return
+
+ raw = np.load(infile)
+ print 'raw.shape', raw.shape
+
+ misc_utils.make_dir(outfile)
+ fig_text = gen_figtext(args)
+
+ axes_labels = mcmc_paramset.labels
+ ranges = mcmc_paramset.ranges
+
+ if args.plot_angles:
+ Tchain = raw
+ g = plot_Tchain(Tchain, axes_labels, ranges)
+
+ if args.fix_mixing and args.fix_source_ratio:
+ mpl.pyplot.figtext(0.4, 0.7, fig_text, fontsize=4)
+ else:
+ mpl.pyplot.figtext(0.5, 0.7, fig_text, fontsize=15)
+ for of in outformat:
+ g.export(outfile+'_angles.'+of)
+
+ if args.plot_elements:
+ nu_index = mcmc_paramset.idx_from_tag(ParamTag.NUISANCE)
+ fr_index = mcmc_paramset.idx_from_tag(ParamTag.MMANGLES)
+ sc_index = mcmc_paramset.idx_from_tag(ParamTag.SCALE)
+ sr_index = mcmc_paramset.idx_from_tag(ParamTag.SRCANGLES)
+
+ nu_elements = raw[:,nu_index]
+ fr_elements = np.array(map(angles_to_fr, raw[:,fr_index]))
+ sc_elements = raw[:,sc_index]
+ sr_elements = np.array(map(flat_angles_to_u, raw[:,sr_index]))
+ Tchain = np.column_stack(
+ [nu_elements, fr_elements, sc_elements, sr_elements]
+ )
+
+ trns_ranges = ranges[nu_index,]
+ trns_axes_labels = axes_labels[nu_index,]
+ if not args.fix_mixing:
+ trns_axes_labels += \
+ [r'\mid \tilde{U}_{e1} \mid' , r'\mid \tilde{U}_{e2} \mid' , r'\mid \tilde{U}_{e3} \mid' , \
+ r'\mid \tilde{U}_{\mu1} \mid' , r'\mid \tilde{U}_{\mu2} \mid' , r'\mid \tilde{U}_{\mu3} \mid' , \
+ r'\mid \tilde{U}_{\tau1} \mid' , r'\mid \tilde{U}_{\tau2} \mid' , r'\mid \tilde{U}_{\tau3} \mid']
+ trns_ranges += [(0, 1)] * 9
+ if not args.fix_scale:
+ trns_axes_labels += [axes_labels[sc_index]]
+ trns_ranges += [ranges[sc_index]]
+ if not args.fix_source_ratio:
+ trns_axes_labels += [r'\phi_e', r'\phi_\mu', r'\phi_\tau']
+ trns_ranges += [(0, 1)] * 3
+
+ g = plot_Tchain(Tchain, trns_axes_labels, trns_ranges)
+
+ if args.fix_mixing and args.fix_source_ratio:
+ mpl.pyplot.figtext(0.4, 0.7, fig_text, fontsize=4)
+ else:
+ mpl.pyplot.figtext(0.5, 0.7, fig_text, fontsize=15)
+ for of in outformat:
+ g.export(outfile+'_angles.'+of)