diff options
| -rw-r--r-- | .gitignore | 6 | ||||
| -rw-r--r-- | __init__.py | 0 | ||||
| -rwxr-xr-x | chainer_plot.py | 265 | ||||
| -rwxr-xr-x | mcmc_scan.py | 563 | ||||
| -rw-r--r-- | nufit_u.txt | 14 | ||||
| -rw-r--r-- | plot_llh/LVCPT.py | 431 | ||||
| -rw-r--r-- | plot_llh/MinimalTools.py | 166 | ||||
| -rw-r--r-- | plot_llh/PhysConst.py | 390 | ||||
| -rw-r--r-- | plot_llh/make_plots.py | 117 | ||||
| -rw-r--r-- | plot_llh/mcmc_scan.py | 174 | ||||
| -rw-r--r-- | submitter/make_dag.py | 100 | ||||
| -rw-r--r-- | submitter/submit.sub | 37 |
12 files changed, 2263 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..546aa78 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*.npy +nohup.out +*.pyc +*.nfs* +plots/ +*.pdf diff --git a/__init__.py b/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/__init__.py diff --git a/chainer_plot.py b/chainer_plot.py new file mode 100755 index 0000000..26dc164 --- /dev/null +++ b/chainer_plot.py @@ -0,0 +1,265 @@ +#! /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 + +import mcmc_scan + +rc('text', usetex=True) +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)'] + print 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)] + + def flat_angles_to_u(x): + return abs(mcmc_scan.angles_to_u(x)).astype(np.float32).flatten().tolist() + + raw = np.load(infile) + print 'raw.shape', raw.shape + if not angles: + if fix_mixing: + fr_elements = np.array(map(mcmc_scan.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(mcmc_scan.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(mcmc_scan.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]) + else: + Tchain = raw + + 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/mcmc_scan.py b/mcmc_scan.py new file mode 100755 index 0000000..f79e2af --- /dev/null +++ b/mcmc_scan.py @@ -0,0 +1,563 @@ +#! /usr/bin/env python +""" +From a gaussian likelihood run an MCMC scan to find the posteriors +""" + +from __future__ import absolute_import, division + +import os, sys +import errno + +import argparse +import multiprocessing + +import numpy as np +from scipy.stats import multivariate_normal +from scipy import linalg + +import emcee +import tqdm + +import chainer_plot + + +RUN_SCAN = True + +FIX_MIXING = False +FIX_SFR = True +SOURCE_FR = [1, 2, 0] +FIX_SCALE = True + +DIMENSION = 3 +ENERGY = 1000000 # GeV +MEASURED_FR = [1, 1, 1] +SIGMA = 0.001 +SCALE_RATIO = 100. +MASS_EIGENVALUES = [7.40E-23, 2.515E-21] +# MASS_EIGENVALUES = [7.40E-100, 2.515E-100] +FLAT = False + +CHANGE_MASS = False +if CHANGE_MASS: + SCALE = 1E-27 +else: + SCALE = np.power(10, np.round(np.log10(MASS_EIGENVALUES[1]/ENERGY)) - np.log10(ENERGY**(DIMENSION-3))) +SCALE2_BOUNDS = (SCALE*1E-10, SCALE*1E10) + + +def test_uni(x): + """Test the unitarity of a matrix.""" + # print 'Unitarity test:\n{0}'.format(abs(np.dot(x, x.conj().T))) + return abs(np.dot(x, x.conj().T)) + + +def angles_to_fr(angles): + sphi4, c2psi = angles + + psi = (0.5)*np.arccos(c2psi) + + sphi2 = np.sqrt(sphi4) + cphi2 = 1. - sphi2 + spsi2 = np.sin(psi)**2 + cspi2 = 1. - spsi2 + + x = sphi2*cspi2 + y = sphi2*spsi2 + z = cphi2 + return x, y, z + + +def angles_to_u(angles): + s12_2, c13_4, s23_2, dcp = angles + dcp = np.complex128(dcp) + + c12_2 = 1. - s12_2 + c13_2 = np.sqrt(c13_4) + s13_2 = 1. - c13_2 + c23_2 = 1. - s23_2 + + t12 = np.arcsin(np.sqrt(s12_2)) + t13 = np.arccos(np.sqrt(c13_2)) + t23 = np.arcsin(np.sqrt(s23_2)) + + c12 = np.cos(t12) + s12 = np.sin(t12) + c13 = np.cos(t13) + s13 = np.sin(t13) + c23 = np.cos(t23) + s23 = np.sin(t23) + + p1 = np.array([[1 , 0 , 0] , [0 , c23 , s23] , [0 , -s23 , c23]] , dtype=np.complex128) + p2 = np.array([[c13 , 0 , s13*np.exp(-1j*dcp)] , [0 , 1 , 0] , [-s13*np.exp(1j*dcp) , 0 , c13]] , dtype=np.complex128) + p3 = np.array([[c12 , s12 , 0] , [-s12 , c12 , 0] , [0 , 0 , 1]] , dtype=np.complex128) + + u = np.dot(np.dot(p1, p2), p3) + return u + + +def cardano_eqn(ham): + """Diagonalise the effective Hamiltonian 3x3 matrix into the form + h_{eff} = UE_{eff}U^{dagger} using the procedure in PRD91, 052003 (2015) + """ + a = -np.trace(ham) + b = (0.5) * ((np.trace(ham))**2 - np.trace(np.dot(ham, ham))) + c = -linalg.det(ham) + + Q = (1/9.) * (a**2 - 3*b) + R = (1/54.) * (2*a**3 - 9*a*b + 27*c) + theta = np.arccos(R / np.sqrt(Q**3)) + + E1 = -2 * np.sqrt(Q) * np.cos(theta/3.) - (1/3.)*a + E2 = -2 * np.sqrt(Q) * np.cos((theta - 2.*np.pi)/3.) - (1/3.)*a + E3 = -2 * np.sqrt(Q) * np.cos((theta + 2.*np.pi)/3.) - (1/3.)*a + + A1 = ham[1][2] * (ham[0][0] - E1) - ham[1][0]*ham[0][2] + A2 = ham[1][2] * (ham[0][0] - E2) - ham[1][0]*ham[0][2] + A3 = ham[1][2] * (ham[0][0] - E3) - ham[1][0]*ham[0][2] + + B1 = ham[2][0] * (ham[1][1] - E1) - ham[2][1]*ham[1][0] + B2 = ham[2][0] * (ham[1][1] - E2) - ham[2][1]*ham[1][0] + B3 = ham[2][0] * (ham[1][1] - E3) - ham[2][1]*ham[1][0] + + C1 = ham[1][0] * (ham[2][2] - E1) - ham[1][2]*ham[2][0] + C2 = ham[1][0] * (ham[2][2] - E2) - ham[1][2]*ham[2][0] + C3 = ham[1][0] * (ham[2][2] - E3) - ham[1][2]*ham[2][0] + + N1 = np.sqrt(abs(A1*B1)**2 + abs(A1*C1)**2 + abs(B1*C1)**2) + N2 = np.sqrt(abs(A2*B2)**2 + abs(A2*C2)**2 + abs(B2*C2)**2) + N3 = np.sqrt(abs(A3*B3)**2 + abs(A3*C3)**2 + abs(B3*C3)**2) + + mm = np.array([ + [np.conjugate(B1)*C1 / N1, np.conjugate(B2)*C2 / N2, np.conjugate(B3)*C3 / N3], + [A1*C1 / N1, A2*C2 / N2, A3*C3 / N3], + [A1*B1 / N1, A2*B2 / N2, A3*B3 / N3] + ]) + return mm + + +# s_12^2, c_13^4, s_23^2, dcp +NUFIT_U = angles_to_u((0.307, (1-0.02195)**2, 0.565, 3.97935)) + + +def params_to_BSMu(theta): + if FIX_MIXING: + s12_2, c13_4, s23_2, dcp, sc2 = 0.5, 1.0-1E-6, 0.5, 0., theta + elif FIX_SCALE: + s12_2, c13_4, s23_2, dcp = theta + sc2 = np.log10(SCALE) + else: + s12_2, c13_4, s23_2, dcp, sc2 = theta + sc2 = np.power(10., sc2) + sc1 = sc2 / SCALE_RATIO + + 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)) + + new_physics_u = angles_to_u((s12_2, c13_4, s23_2, dcp)) + scale_matrix = np.array( + [[0, 0, 0], [0, sc1, 0], [0, 0, sc2]] + ) + bsm_term = (ENERGY**(DIMENSION-3)) * np.dot(new_physics_u, np.dot(scale_matrix, new_physics_u.conj().T)) + + bsm_ham = sm_ham + bsm_term + + eg_vector = cardano_eqn(bsm_ham) + tu = test_uni(eg_vector) + if not abs(np.trace(tu) - 3.) < 1e-5 or not abs(np.sum(tu) - 3.) < 1e-5: + raise AssertionError('Matrix is not unitary!\neg_vector\n{0}\ntest u\n{1}'.format(eg_vector, tu)) + return eg_vector + + +def u_to_fr(initial_fr, matrix): + """Compute the observed flavour ratio assuming decoherence.""" + # TODO(shivesh): energy dependence + composition = np.einsum( + 'ai, bi, a -> b', abs(matrix)**2, abs(matrix)**2, initial_fr + ) + ratio = composition / np.sum(initial_fr) + return ratio + + +def triangle_llh(theta): + """-Log likelihood function for a given theta.""" + if FIX_SFR: + fr1, fr2, fr3 = SOURCE_FR + u = params_to_BSMu(theta) + else: + fr1, fr2, fr3 = angles_to_fr(theta[-2:]) + u = params_to_BSMu(theta[:-2]) + + fr = u_to_fr((fr1, fr2, fr3), u) + fr_bf = MEASURED_FR + cov_fr = np.identity(3) * SIGMA + if FLAT: + return 10. + else: + return np.log(multivariate_normal.pdf(fr, mean=fr_bf, cov=cov_fr)) + + +def lnprior(theta): + """Priors on theta.""" + if FIX_SFR: + if FIX_MIXING: + s12_2, sc2 = theta + elif FIX_SCALE: + s12_2, c13_4, s23_2, dcp = theta + else: + s12_2, c13_4, s23_2, dcp, sc2 = theta + else: + if FIX_MIXING: + sc2, sphi4, c2psi = theta + elif FIX_SCALE: + s12_2, c13_4, s23_2, dcp, sphi4, c2psi = theta + else: + s12_2, c13_4, s23_2, dcp, sc2, sphi4, c2psi = theta + if not FIX_SCALE: + sc2 = np.power(10., sc2) + + if not FIX_SFR: + # Flavour ratio bounds + if 0. <= sphi4 <= 1.0 and -1.0 <= c2psi <= 1.0: + pass + else: return -np.inf + + # Mixing angle bounds + if not FIX_MIXING: + if 0. <= s12_2 <= 1. and 0. <= c13_4 <= 1. and 0. <= s23_2 <= 1. \ + and 0. <= dcp <= 2*np.pi: + pass + else: return -np.inf + + # Scale bounds + if not FIX_SCALE: + if SCALE2_BOUNDS[0] <= sc2 <= SCALE2_BOUNDS[1]: + pass + else: return -np.inf + + return 0. + + +def lnprob(theta): + """Prob function for mcmc.""" + lp = lnprior(theta) + if not np.isfinite(lp): + return -np.inf + return lp + triangle_llh(theta) + + +def parse_args(): + """Parse command line arguments""" + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument( + '--measured-ratio', type=int, nargs=3, default=[1, 1, 1], + help='Set the central value for the measured flavour ratio at IceCube' + ) + parser.add_argument( + '--sigma-ratio', type=float, default=0.01, + help='Set the 1 sigma for the measured flavour ratio' + ) + parser.add_argument( + '--fix-source-ratio', type=str, default='False', + help='Fix the source flavour ratio' + ) + 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( + '--fix-mixing', type=str, default='False', + help='Fix all mixing parameters except one' + ) + parser.add_argument( + '--fix-scale', type=str, default='False', + help='Fix the new physics scale' + ) + parser.add_argument( + '--scale', type=float, default=1e-30, + help='Set the new physics scale' + ) + parser.add_argument( + '--dimension', type=int, default=3, + help='Set the new physics dimension to consider' + ) + parser.add_argument( + '--energy', type=float, default=1000, + help='Set the energy scale' + ) + parser.add_argument( + '--flat-llh', type=str, default='False', + help='Run with a flat likelihood' + ) + parser.add_argument( + '--burnin', type=int, default=100, + help='Amount to burnin' + ) + parser.add_argument( + '--nwalkers', type=int, default=100, + help='Number of walkers' + ) + parser.add_argument( + '--nsteps', type=int, default=2000, + help='Number of steps to run' + ) + parser.add_argument( + '--seed', type=int, default=99, + help='Set the random seed value' + ) + parser.add_argument( + '--outfile', type=str, default='./untitled', + help='Path to output chains' + ) + args = parser.parse_args() + return args + + +def main(): + args = parse_args() + + np.random.seed(args.seed) + + global DIMENSION + global ENERGY + global MEASURED_FR + global SIGMA + global FLAT + global FIX_SFR + global SOURCE_FR + global FIX_MIXING + global FIX_SCALE + global SCALE + global SCALE2_BOUNDS + + DIMENSION = args.dimension + ENERGY = args.energy + + MEASURED_FR = np.array(args.measured_ratio) / float(np.sum(args.measured_ratio)) + SIGMA = args.sigma_ratio + + if args.flat_llh.lower() == 'true': + FLAT = True + elif args.flat_llh.lower() == 'false': + FLAT = False + else: + raise ValueError + + if args.fix_source_ratio.lower() == 'true': + FIX_SFR = True + elif args.fix_source_ratio.lower() == 'false': + FIX_SFR = False + else: + raise ValueError + + if args.fix_mixing.lower() == 'true': + FIX_MIXING = True + elif args.fix_mixing.lower() == 'false': + FIX_MIXING = False + else: + raise ValueError + + if args.fix_scale.lower() == 'true': + FIX_SCALE = True + elif args.fix_scale.lower() == 'false': + FIX_SCALE = False + else: + raise ValueError + + if FIX_SFR: + SOURCE_FR = np.array(args.source_ratio) / float(np.sum(args.source_ratio)) + + if FIX_SCALE: + SCALE = args.scale + else: + if CHANGE_MASS: + SCALE = 1E-27 + else: + SCALE = np.power(10, np.round(np.log10(MASS_EIGENVALUES[1]/ENERGY)) - np.log10(ENERGY**(DIMENSION-3))) + + if FIX_MIXING and FIX_SFR: + raise NotImplementedError('Fixed mixing and sfr not implemented') + if FIX_MIXING and FIX_SCALE: + raise NotImplementedError('Fixed mixing and scale not implemented') + + SCALE2_BOUNDS = (SCALE*1E-10, SCALE*1E10) + + print 'RUN_SCAN = {0}'.format(RUN_SCAN) + print 'MEASURED_FR = {0}'.format(MEASURED_FR) + print 'SIGMA = {0}'.format(SIGMA) + print 'FLAT = {0}'.format(FLAT) + print 'ENERGY = {0}'.format(ENERGY) + print 'DIMENSION = {0}'.format(DIMENSION) + print 'SCALE2_BOUNDS = {0}'.format(SCALE2_BOUNDS) + print 'FIX_SFR = {0}'.format(FIX_SFR) + if FIX_SFR: + print 'SOURCE_FR = {0}'.format(SOURCE_FR) + print 'FIX_MIXING = {0}'.format(FIX_MIXING) + print 'FIX_SCALE = {0}'.format(FIX_SCALE) + if FIX_SCALE: + print 'SCALE = {0}'.format(SCALE) + + if FIX_SFR: + if FIX_MIXING: + ndim = 2 + elif FIX_SCALE: + ndim = 4 + else: + ndim = 5 + else: + if FIX_MIXING: + ndim = 3 + elif FIX_SCALE: + ndim = 6 + else: + ndim = 7 + nwalkers = args.nwalkers + ntemps = 1 + burnin = args.burnin + betas = np.array([1e0, 1e-1, 1e-2, 1e-3, 1e-4]) + s2 = np.average(np.log10(SCALE2_BOUNDS)) + if FIX_SFR: + if FIX_MIXING: + p0_base = [0.5, s2] + p0_std = [0.2, 3] + elif FIX_SCALE: + p0_base = [0.5, 0.5, 0.5, np.pi] + p0_std = [0.2, 0.2, 0.2, 0.2] + else: + p0_base = [0.5, 0.5, 0.5, np.pi, s2] + p0_std = [0.2, 0.2, 0.2, 0.2, 3] + else: + if FIX_MIXING: + p0_base = [s2, 0.5, 0.0] + p0_std = [3, 0.2, 0.2] + elif FIX_SCALE: + p0_base = [0.5, 0.5, 0.5, np.pi, 0.5, 0.0] + p0_std = [0.2, 0.2, 0.2, 0.2, 0.2, 0.2] + else: + p0_base = [0.5, 0.5, 0.5, np.pi, s2, 0.5, 0.0] + p0_std = [0.2, 0.2, 0.2, 0.2, 3, 0.2, 0.2] + + print 'p0_base', p0_base + print 'p0_std', p0_std + p0 = np.random.normal(p0_base, p0_std, size=[ntemps, nwalkers, ndim]) + print map(lnprior, p0[0]) + + if RUN_SCAN: + # threads = multiprocessing.cpu_count() + threads = 1 + sampler = emcee.PTSampler( + ntemps, nwalkers, ndim, triangle_llh, lnprior, threads=threads + ) + + if RUN_SCAN: + print "Running burn-in" + for result in tqdm.tqdm(sampler.sample(p0, iterations=burnin), total=burnin): + pos, prob, state = result + sampler.reset() + print "Finished burn-in" + + nsteps = args.nsteps + + print "Running" + for _ in tqdm.tqdm(sampler.sample(pos, iterations=nsteps), total=nsteps): + pass + print "Finished" + + if FIX_SFR: + if FIX_MIXING: + outfile = args.outfile+'_{0:03d}_{1:03d}_{2:03d}_{3:04d}_sfr_{4:03d}_{5:03d}_{6:03d}_DIM{7}_fix_mixing'.format( + int(MEASURED_FR[0]*100), int(MEASURED_FR[1]*100), int(MEASURED_FR[2]*100), int(SIGMA*1000), + int(SOURCE_FR[0]*100), int(SOURCE_FR[1]*100), int(SOURCE_FR[2]*100), DIMENSION + ) + elif FIX_SCALE: + outfile = args.outfile+'_{0:03d}_{1:03d}_{2:03d}_{3:04d}_sfr_{4:03d}_{5:03d}_{6:03d}_DIM{7}_fixed_scale_{8}'.format( + int(MEASURED_FR[0]*100), int(MEASURED_FR[1]*100), int(MEASURED_FR[2]*100), int(SIGMA*1000), + int(SOURCE_FR[0]*100), int(SOURCE_FR[1]*100), int(SOURCE_FR[2]*100), DIMENSION, SCALE + ) + else: + outfile = args.outfile+'_{0:03d}_{1:03d}_{2:03d}_{3:04d}_sfr_{4:03d}_{5:03d}_{6:03d}_DIM{7}_single_scale'.format( + int(MEASURED_FR[0]*100), int(MEASURED_FR[1]*100), int(MEASURED_FR[2]*100), int(SIGMA*1000), + int(SOURCE_FR[0]*100), int(SOURCE_FR[1]*100), int(SOURCE_FR[2]*100), DIMENSION + ) + else: + if FIX_MIXING: + outfile = args.outfile+'_{0:03d}_{1:03d}_{2:03d}_{3:04d}_DIM{4}_fix_mixing'.format( + int(MEASURED_FR[0]*100), int(MEASURED_FR[1]*100), int(MEASURED_FR[2]*100), + int(SIGMA*1000), DIMENSION + ) + elif FIX_SCALE: + outfile = args.outfile+'_{0:03d}_{1:03d}_{2:03d}_{3:04d}_DIM{4}_fixed_scale_{5}'.format( + int(MEASURED_FR[0]*100), int(MEASURED_FR[1]*100), int(MEASURED_FR[2]*100), + int(SIGMA*1000), DIMENSION, SCALE + ) + else: + outfile = args.outfile+'_{0:03d}_{1:03d}_{2:03d}_{3:04d}_DIM{4}'.format( + int(MEASURED_FR[0]*100), int(MEASURED_FR[1]*100), int(MEASURED_FR[2]*100), + int(SIGMA*1000), DIMENSION + ) + + if RUN_SCAN: + samples = sampler.chain[0, :, :, :].reshape((-1, ndim)) + print 'acceptance fraction', sampler.acceptance_fraction + print 'sum of acceptance fraction', np.sum(sampler.acceptance_fraction) + print 'np.unique(samples[:,0]).shape', np.unique(samples[:,0]).shape + + try: + print 'autocorrelation', sampler.acor + except: + print 'WARNING : NEED TO RUN MORE SAMPLES FOR FILE ' + outfile + + if FLAT: + outfile += '_flat' + + if RUN_SCAN: + 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 + np.save(outfile+'.npy', samples) + + # print "Making triangle plots" + # chainer_plot.plot( + # infile=outfile+'.npy', + # angles=True, + # outfile=outfile[:5]+outfile[5:].replace('data', 'plots')+'_angles.pdf', + # measured_ratio=MEASURED_FR, + # sigma_ratio=SIGMA, + # fix_sfr=FIX_SFR, + # fix_mixing=FIX_MIXING, + # fix_scale=FIX_SCALE, + # source_ratio=SOURCE_FR, + # scale=SCALE, + # dimension=DIMENSION, + # energy=ENERGY, + # scale_bounds=SCALE2_BOUNDS, + # ) + # chainer_plot.plot( + # infile=outfile+'.npy', + # angles=False, + # outfile=outfile[:5]+outfile[5:].replace('data', 'plots')+'.pdf', + # measured_ratio=MEASURED_FR, + # sigma_ratio=SIGMA, + # fix_sfr=FIX_SFR, + # fix_mixing=FIX_MIXING, + # fix_scale=FIX_SCALE, + # source_ratio=SOURCE_FR, + # scale=SCALE, + # dimension=DIMENSION, + # energy=ENERGY, + # scale_bounds=SCALE2_BOUNDS, + # ) + print "DONE!" + + +main.__doc__ = __doc__ + + +if __name__ == '__main__': + main() + diff --git a/nufit_u.txt b/nufit_u.txt new file mode 100644 index 0000000..a9c9cb2 --- /dev/null +++ b/nufit_u.txt @@ -0,0 +1,14 @@ + +[[ 0.73544986+0.j 0.48950332+0.j -0.31349347+0.34816928j] + [-0.16927408+0.2178619j 0.67961271+0.14500529j 0.66406513+0.j ] + [ 0.58860262+0.19116206j -0.51117311+0.12723432j 0.58268130+0.j ]] + +abs: +[[ 0.82327921 0.54796108 0.14815532] + [ 0.31112912 0.59211521 0.74336952] + [ 0.47477365 0.5908792 0.65226662]] + +M +[[0, 0, 0 ], + [0, 7.40E-23, 0 ], + [0, 0, 2.515E-21]] diff --git a/plot_llh/LVCPT.py b/plot_llh/LVCPT.py new file mode 100644 index 0000000..f5b02e6 --- /dev/null +++ b/plot_llh/LVCPT.py @@ -0,0 +1,431 @@ + +# coding: utf-8 + +## The Theory + +import numpy +import MinimalTools as MT +import PhysConst as PC +import numpy as np +import matplotlib.pyplot as plt +import matplotlib.collections as mco +import matplotlib as mpl +import scipy.interpolate as interpolate +import scipy.integrate as integrate +import scipy as sp +from numpy import linalg as LA + +use_cython = False + +if use_cython: + import cython.cLVCPT as clv + +mpl.rc('font', family='serif', size=20) + +pc = PC.PhysicsConstants() + +degree = np.pi/180.0 +pc.th12 = 33.36*degree#33.48*degree +pc.th23 = 45.*degree#42.3*degree +pc.th13 = 8.66*degree#8.5*degree +pc.delta1 = 0.0#300.0*degree#306.*degree # perhaps better just set to 0. +pc.dm21sq = 7.5e-5 +pc.dm31sq = 2.47e-3#2.457e-3 +pc.Refresh() + +MT.calcU(pc) +DELTAM2 = MT.flavorM2(pc) + +def Hamiltonian(Enu, LVATERM = np.zeros((3,3), dtype=numpy.complex), + LVCTERM = np.zeros((3,3), dtype=numpy.complex)): + return DELTAM2/(2.0*Enu) + LVATERM + Enu*LVCTERM + +def OscProbFromMixingMatrix(alpha, beta, MixMatrix): + return sum([(np.absolute(MixMatrix[i][alpha])*np.absolute(MixMatrix[i][beta]))**2 for i in range(pc.numneu)] ) + #return sum([(np.absolute(MixMatrix[i][alpha]))**2*(np.absolute(MixMatrix[i][beta]))**2 for i in range(pc.numneu)] ) + #prob = 0.0; + #for i in range(pc.numneu) : + # prob += (np.absolute(MixMatrix[i][alpha]))**2*(np.absolute(MixMatrix[i][beta]))**2 + #return prob + +def OscProb(alpha, Enu, LVATERM = np.zeros((3,3), dtype=numpy.complex), + LVCTERM = np.zeros((3,3), dtype=numpy.complex)): + eigvals, eigvec = MT.eigenvectors(Hamiltonian(Enu, LVATERM=LVATERM, LVCTERM=LVCTERM)) + #print eigvec.dtype + if use_cython: + return [ clv.OscProbFromMixingMatrix(alpha,beta,eigvec) for beta in range(pc.numneu)] + else: + return [ OscProbFromMixingMatrix(alpha,beta,eigvec) for beta in range(pc.numneu)] + +def FlavorRatio(initial_flavor_ratio, Enu, LVATERM = np.zeros((3,3), dtype=numpy.complex), + LVCTERM = np.zeros((3,3), dtype=numpy.complex)): + final_flavor_ratio = [0.0]*pc.numneu + osc_prob_array = [OscProb(beta,Enu,LVATERM=LVATERM,LVCTERM=LVCTERM) for beta in range(pc.numneu)] + + for alpha in range(pc.numneu): + for beta,phi in enumerate(initial_flavor_ratio): + final_flavor_ratio[alpha] += osc_prob_array[beta][alpha]*phi + return final_flavor_ratio + +def RRR(initial_flavor_ratio, Enu, LVATERM = np.zeros((3,3), dtype=numpy.complex), + LVCTERM = np.zeros((3,3), dtype=numpy.complex)): + ffr = FlavorRatio(initial_flavor_ratio,Enu,LVATERM=LVATERM,LVCTERM=LVCTERM) + return ffr[1]/ffr[0] +def SSS(initial_flavor_ratio, Enu, LVATERM = np.zeros((3,3), dtype=numpy.complex), + LVCTERM = np.zeros((3,3), dtype=numpy.complex)): + ffr = FlavorRatio(initial_flavor_ratio,Enu,LVATERM=LVATERM,LVCTERM=LVCTERM) + return ffr[2]/ffr[1] + +def PointToList(p1,p2): + return [[p1[0],p2[0]],[p1[1],p2[1]]] + +def PointFromFlavor(origin,scale,flavor_ratio_list): + nu_e_vec = np.array([1.,0.])*scale + nu_mu_vec = np.array([1./2.,np.sqrt(3.)/2.])*scale + nu_tau_vec = np.array([-1./2.,np.sqrt(3.)/2.])*scale + fpos = origin + flavor_ratio_list[0]*nu_e_vec + flavor_ratio_list[1]*nu_mu_vec + return [fpos[0],fpos[1]] + +def MakeFlavorTriangle(list_of_flavor_ratios, scale = 8, + p = np.array([0.,0.]), save_file = False, PlotPoints = False, PlotTrayectories = False, figure = None, alpha = 1.0, + filename = "triangle",icolor = "green", icolormap = "Greens", divisions = 5, initial_flavor_ratio = [1,0,0], + term = "a", subdivisions = False, triangle_collection = None, color_scale = "lin", return_fig = True, addtext = "", + add_default_text = True, ilw = 1., slw = 0.75, output_format = "eps", inner_line_color = "k", plot_color_bar = False): + # i will be nice ... + list_of_flavor_ratios = np.array(list_of_flavor_ratios) + + if figure == None: + fig = plt.figure(figsize=(scale,scale), frameon = False) + else: + fig = figure + + ax = fig.add_axes([0, 0, 1, 1]) + ax.axis('off') + + # delete extra lines + frame = plt.gca() + frame.axes.get_xaxis().set_visible(False) + frame.axes.get_yaxis().set_visible(False) + + s0 = np.array([1.,0.])*scale + s1 = np.array([1./2.,np.sqrt(3.)/2.])*scale + s2 = np.array([1./2.,-np.sqrt(3.)/2.])*scale + + # make triangle outer frame + + plt.plot(*PointToList(p, p+s0), color = "k", lw = 4) + plt.plot(*PointToList(p, p+s1), color = "k", lw = 2) + plt.plot(*PointToList(p+s0, p+s1), color = "k", lw = 2) + + # put outer triangle labels + + # ax.text((p+s0*0.5+s0*0.025)[0], (p+s0*0.5-np.array([0,0.15*scale]))[1],r"$\alpha^{\oplus}_{e}$", + # horizontalalignment="center",fontsize = 50, zorder = 10) + # ax.text((p+s1*0.5-0.2*s0)[0], (p+s1*0.5+0.1*s0)[1]+scale*0.1,r"$\alpha^{\oplus}_{\tau}$", + # horizontalalignment="center",fontsize = 50, zorder = 10, rotation = 60.) + # ax.text((p+s1*0.5 + 0.7*s0)[0], (p+s1*0.5 + 0.6*s0)[1]+0.05*scale,r"$\alpha^{\oplus}_{\mu}$", + # horizontalalignment="center",fontsize = 50, zorder = 10, rotation = -60) + + ax.text((p+s0*0.5+s0*0.025)[0], (p+s0*0.5-np.array([0,0.15*scale]))[1],r"$f_{e,\oplus}$", + horizontalalignment="center",fontsize = 50, zorder = 10) + ax.text((p+s1*0.5-0.2*s0)[0], (p+s1*0.5+0.1*s0)[1]+scale*0.1,r"$f_{\tau, \oplus}$", + horizontalalignment="center",fontsize = 50, zorder = 10, rotation = 60.) + ax.text((p+s1*0.5 + 0.7*s0)[0], (p+s1*0.5 + 0.6*s0)[1]+0.05*scale,r"$f_{\mu, \oplus}$", + horizontalalignment="center",fontsize = 50, zorder = 10, rotation = -60) + + # construct triangle grid + fsl = 35 + for i in range(divisions+1): + subsize = 1./float(divisions) + + ax.text((p+s0*subsize*float(i))[0], (p+s0*subsize*float(i)-np.array([0,0.05*scale]))[1],str(i*subsize), + horizontalalignment="center",fontsize = fsl) + plt.plot(*PointToList(p+s0*subsize*float(i), p+s1+s2*subsize*float(i)), color = inner_line_color, lw = ilw, ls = "dashed", zorder = -1) + ax.text((p+s1-s1*subsize*float(i)-np.array([0.06*scale,0.0]))[0], (p+s1-s1*subsize*float(i))[1],str(i*subsize), + horizontalalignment="center",fontsize = fsl) + plt.plot(*PointToList(p+s0*subsize*float(divisions-i), p+s1-s1*subsize*float(i)), color = inner_line_color, lw = ilw, ls = "dashed", zorder = -1) + + ax.text((p+s1+s2*subsize*float(i)+np.array([0.05*scale,0.0]))[0], (p+s1+s2*subsize*float(i))[1],str((divisions-i)*subsize), + horizontalalignment="center",fontsize = fsl) + plt.plot(*PointToList(p+s1*subsize*float(divisions-i), p+s1+s2*subsize*float(i)), color = inner_line_color, lw = ilw, ls = "dashed", zorder = -1) + + if subdivisions and i < divisions: + plt.plot(*PointToList(p+s0*subsize*float(i+0.5), p+s1+s2*subsize*float(i+0.5)), color = inner_line_color, lw = slw, ls = "dotted", zorder = -1) + if subdivisions and i > 0: + plt.plot(*PointToList(p+s0*subsize*float(divisions-(i-0.5)), p+s1-s1*subsize*float(i-0.5)), color = inner_line_color, lw = slw, ls = "dotted", zorder = -1) + plt.plot(*PointToList(p+s1*subsize*float(divisions-(i-0.5)), p+s1+s2*subsize*float(i-0.5)), color = inner_line_color, lw = slw, ls = "dotted", zorder = -1) + + + # plot triangle collection + if (triangle_collection != None): + # get total number of points + total_points = float(sum([ triangle.number_of_points for triangle in triangle_collection])) + max_points = float(max([ triangle.number_of_points for triangle in triangle_collection])) + color_map = plt.get_cmap(icolormap) + for triangle in triangle_collection: + if triangle.number_of_points > 0: + xx,yy = zip(*triangle.coordinates) + if color_scale == "lin": + plt.fill(xx,yy,lw = 0., zorder = -0.8, color = color_map(0.75), alpha = np.sqrt(float(triangle.number_of_points)/max_points)) + #plt.fill(xx,yy,lw = 0., zorder = -0.8, color = color_map(float(triangle.number_of_points)/max_points), alpha = alpha) + elif color_scale == "log": + plt.fill(xx,yy,lw = 0., zorder = -0.8, color = color_map(0.75), alpha = (np.log10(float(triangle.number_of_points))/np.log10(max_points))) + #plt.fill(xx,yy,lw = 0., zorder = -0.8, color = color_map(0.7), alpha = (np.log10(float(triangle.number_of_points))/np.log10(max_points))**(2./3.)) + #plt.fill(xx,yy,lw = 0., zorder = -0.8, color = color_map(np.log10(float(triangle.number_of_points))/np.log10(max_points)), alpha = alpha) + #plt.fill(xx,yy,lw = 0., zorder = -0.8, color = color_map(np.log10(float(triangle.number_of_points)))) + else : + raise NameError('Error. Love CA.') + + if(plot_color_bar): + # the color bar magic + # location set on 0 to 1 scales. + left = 0.1 + bottom = -0.25 + width = 0.8 + height = 0.025 + cbaxes = fig.add_axes([left,bottom,width,height]) + if color_scale == "lin": + norm = mpl.colors.Normalize(vmin = 0., vmax = max_points) + elif color_scale == "log": + norm = mpl.colors.Normalize(vmin = 0., vmax = 1.0) + else : + raise NameError('Error. Love CA.') + mpl.rcParams.update({'font.size': 10}) + triangle_colorbar = mpl.colorbar.ColorbarBase(cbaxes, cmap = color_map, norm = norm, + orientation = "horizontal", spacing = "proportional", + # ) + format ='%.0e') + cbaxes.set_xlabel("Likelihood", fontsize = 12) + + # plot flavor ratio points + if PlotTrayectories : + if len(list_of_flavor_ratios.shape) == 3 : + for flavor_ratio_l in list_of_flavor_ratios: + flv_ratio_coords = map(lambda f:PointFromFlavor(p,scale,np.array(f)),flavor_ratio_l) + xc, yc = zip(*flv_ratio_coords) + plt.plot(xc,yc, color = icolor, + ms = 10, linewidth = 4, zorder = 0) + elif len(list_of_flavor_ratios.shape) == 2 : + flv_ratio_coords = map(lambda f:PointFromFlavor(p,scale,np.array(f)),list_of_flavor_ratios) + xc, yc = zip(*flv_ratio_coords) + + plt.plot(xc,yc, color = icolor, + ms = 10, linewidth = 4, zorder = 0) + else: + raise NameError('Check your input flavor list array and the joined flag. Love CA.') + elif PlotPoints: + if len(list_of_flavor_ratios.shape) !=2 : + print len(list_of_flavor_ratios.shape) + raise NameError('Check your input flavor list array and the joined flag. Love CA.') + for i,flavor_ratio in enumerate(list_of_flavor_ratios): + if len(icolor) != len(list_of_flavor_ratios): + icolor_ = icolor + else: + icolor_ = icolor[i] + plt.plot(*PointFromFlavor(p,scale,np.array(flavor_ratio)), color = icolor_, + marker = 'o', ms = 10, linewidth = 0, + markeredgecolor=None,markeredgewidth=0.1, zorder = 1000) + + # put back color scale axis + if add_default_text: + ax.text((s0/5.+0.9*s1)[0],(s0/5.+0.9*s1)[1], + "LV "+term+"-term scan with\n $\ \phi_e:\ \phi_\\mu:\ \phi_\\tau = "+str(initial_flavor_ratio[0])+":\ "+str(initial_flavor_ratio[1])+":\ "+str(initial_flavor_ratio[2])+"$"+" \n "+addtext, + fontsize = 20) + + if(save_file): + # save figure + plt.savefig("./plots/"+filename+"."+output_format, dpi = 600, bbox_inches='tight') + else: + # show figure + plt.show() + if return_fig: + return fig + + +def s_bario(p,p0,p1,p2): + return (p0[1]*p2[0] - p0[0]*p2[1] + (p2[1] - p0[1])*p[0] + (p0[0] - p2[0])*p[1]) + +def t_bario(p,p0,p1,p2): + return (p0[0]*p1[1] - p0[1]*p1[0] + (p0[1] - p1[1])*p[0] + (p1[0] - p0[0])*p[1]) + +def IsInTriangle(p,p0,p1,p2,area): + s = s_bario(p,p0,p1,p2) + t = t_bario(p,p0,p1,p2) + #print s,t,2.0*area - s - t + return s >= -1.e-15 and t >= -1.0e-15 and s+t <= 2.0*area + + +class Triangle: + coordinates = [] + area = 0.0 + number_of_points = 0.0 + n_t = 0 + i = 0 + j = 0 + orientation = "" + + def IsPointIn(self,point): + p0 = self.coordinates[0] + p1 = self.coordinates[1] + p2 = self.coordinates[2] + return IsInTriangle(point,p0,p1,p2,self.area) + + +def GenerateTriangles(scale, divisions, p = np.array([0.,0.])): + s0 = np.array([1.,0.])*scale/float(divisions) + s1 = np.array([1./2.,np.sqrt(3.)/2.])*scale/float(divisions) + s2 = np.array([1./2.,-np.sqrt(3.)/2.])*scale/float(divisions) + + area = np.sqrt(3)*(LA.norm(s0)/2.0)**2 + + n_t = 0 + + triangle_collection = [] + for i in range(divisions): + for j in range(divisions-i): + lower_triangle = Triangle() + + p0_l = p + i*s0 + j*s1 + p1_l = p0_l + s0 + p2_l = p0_l + s1 + + lower_triangle.coordinates = [p0_l,p1_l,p2_l] + lower_triangle.n_t = n_t + lower_triangle.i = i + lower_triangle.j = j + lower_triangle.orientation = "L" + lower_triangle.area = area + + n_t += 1 + # append to triangle collection + triangle_collection.append(lower_triangle) + + upper_triangle = Triangle() + + p0_u = p2_l + p1_u = p1_l + p2_u = p1_l + s1 + + upper_triangle.coordinates = [p0_u,p1_u,p2_u] + upper_triangle.n_t = n_t + upper_triangle.i = i + upper_triangle.j = j + upper_triangle.orientation = "U" + upper_triangle.area = area + + n_t += 1 + # append to triangle collection + triangle_collection.append(upper_triangle) + return triangle_collection + +def AddPointToTriangleCollectionLegacy(flavor_ratio, triangle_collection, + p = np.array([0.,0.]), scale = 8, divisions = 10): + point = PointFromFlavor(p,scale,np.array(flavor_ratio)) + electron = 0; tau = 2; + # the silly way + for triangle in triangle_collection: + if(triangle.IsPointIn(point)): + triangle.number_of_points += 1. + +def AddPointToTriangleCollection(flavor_ratio, triangle_collection, + p = np.array([0.,0.]), scale = 8, divisions = 10): + point = PointFromFlavor(p,scale,np.array(flavor_ratio)) + electron = 0; muon = 1; tau = 2; + # the smart way + u_i = int(flavor_ratio[electron]*float(divisions)) + u_j = int(flavor_ratio[muon]*float(divisions)) + index = u_i*(2*divisions-u_i+1) + 2*u_j + if triangle_collection[index].IsPointIn(point): + triangle_collection[index].number_of_points += 1. + else: + triangle_collection[index+1].number_of_points += 1. +# legacy + #elif triangle_collection[index+1].IsPointIn(point): + # triangle_collection[index+1].number_of_points += 1. + #else: + # print "Math error." + # print point, "\n",u_i, u_j, "\n", triangle_collection[index].coordinates, "\n", triangle_collection[index+1].coordinates + # raise NameError("Error triangle location math") + +class AnarchySampling: + def __init__(self, n_sample, LV_scale_1, LV_scale_2, term): + self.n_sample = n_sample + self.th12_sample = np.arcsin(np.sqrt(np.random.uniform(0.,1., size=n_sample))) + self.th13_sample = np.arccos(np.sqrt(np.sqrt(np.random.uniform(0.,1., size=n_sample)))) + self.th23_sample = np.arcsin(np.sqrt(np.random.uniform(0.,1., size=n_sample))) + self.delta_sample = np.random.uniform(0.,2.*np.pi, size=n_sample) + + self.LV_scale_1 = LV_scale_1 + self.LV_scale_2 = LV_scale_2 + + self.term = term + +def GenerateFlavorRatioPoints(Initial_Flavor_Ratio, SamplingObject, gamma = 2.0, + Log10Emax = 7., Log10Emin = 4.0, Epoints = 30, + save_list = False, save_avg = True): + flavor_tray_list = [] + flavor_avg_list = [] + + # energy things + + Erange = np.logspace(Log10Emin,Log10Emax,Epoints) # in GeV + Emin = Erange[0] + Emax = Erange[-1] + + if gamma == 1 or gamma == 1.0: + spectral_normalization = np.log(Emax)-np.log(Emin) + else: + spectral_normalization = (Emax**(1.-gamma) - Emin**(1.-gamma))/(1.-gamma) + + spectral_function = lambda Enu: Enu**(-gamma)/spectral_normalization + + # loop over random parameters + for i in range(SamplingObject.n_sample): + lv_term = MT.LVP() + + lv_term.th12 = SamplingObject.th12_sample[i] + lv_term.th13 = SamplingObject.th13_sample[i] + lv_term.th23 = SamplingObject.th23_sample[i] + lv_term.delta1 = SamplingObject.delta_sample[i] + + lv_term.LVS21 = SamplingObject.LV_scale_1 + lv_term.LVS31 = SamplingObject.LV_scale_2 + + lv_term.Refresh() + + LVTERM = MT.LVTerm(lv_term); + + if SamplingObject.term == "a": + flavor_ratio_list = np.array(map(lambda Enu : FlavorRatio(Initial_Flavor_Ratio, Enu*pc.GeV, LVATERM = LVTERM), Erange)) + elif SamplingObject.term == "c": + flavor_ratio_list = np.array(map(lambda Enu : FlavorRatio(Initial_Flavor_Ratio, Enu*pc.GeV, LVCTERM = LVTERM), Erange)) + else : + raise NameError('Only a or c term.'+ str(term)) + + if save_avg: + if Epoints != 1: + flavor_avg = [0.]*lv_term.numneu + for alpha in range(lv_term.numneu): + #inter = interpolate.interp1d(Erange,flavor_ratio_list[:,alpha]) + inter = interpolate.UnivariateSpline(Erange,flavor_ratio_list[:,alpha]) + flavor_avg[alpha] = integrate.quad(lambda Enu : inter(Enu)*spectral_function(Enu), + Emin,Emax, limit = 75, epsrel = 1e-2, epsabs = 1.0e-2)[0] + #flavor_avg[alpha] = integrate.quadrature(lambda Enu : inter(Enu)*spectral_function(Enu), + # Emin,Emax, maxiter = 75, rtol = 1e-3, tol = 1.e-3)[0] + flavor_avg_list.append(flavor_avg) + else: + flavor_avg = flavor_ratio_list[0] + flavor_avg_list.append(flavor_avg) + + if save_list: + flavor_tray_list.append(flavor_ratio_list) + + if save_list and save_avg: + return flavor_tray_list, flavor_avg_list + elif save_list: + return flavor_tray_list + elif save_avg: + return flavor_avg_list + else : + print "Math is broken." + return None diff --git a/plot_llh/MinimalTools.py b/plot_llh/MinimalTools.py new file mode 100644 index 0000000..4ae8360 --- /dev/null +++ b/plot_llh/MinimalTools.py @@ -0,0 +1,166 @@ +import numpy as np +from PhysConst import PhysicsConstants + +def eigenvectors(M): + """ Calculates the eigenvectors and eigenvalues ordered by eigenvalue size + + @type M : matrix + @param M : matrix M + + @rtype : list + @return : [eigenvalues list, eigenvector list] + """ + D,V = np.linalg.eig(M) + DV = [] + VT = V.T + for i,eigenvalue in enumerate(D): + DV.append([eigenvalue,VT[i]]) + + DV = sorted(DV,key = lambda x : x[0].real)#np.abs(x[0].real)) + + V2 = [] + D2 = [] + for e in DV: + V2.append(e[1]) + D2.append(e[0]) + return D2,V2 + +# General Rotation Matrix +def R(i,j,cp,param): + """ Rotation Matrix + Calculates the R_ij rotations. Also incorporates CP-phases when necesary. + @type i : int + @param i : i-column. + @type j : int + @param j : j-row. + @type cp : int + @param cp : if cp = 0 : no CP-phase. else CP-phase = CP_array[cp] + + @rtype : numpy.array + @return : returns the R_ij rotation matrix. + """ + # if cp = 0 -> no complex phase + # R_ij, i<j + if(j<i): + # no funny business + l = i + i = j + j = l + + # rotation matrix generator + R = np.zeros([param.numneu,param.numneu],complex) + # diagonal terms + for k in np.arange(0,param.numneu,1): + if(k != i-1 and k != j-1): + R[k,k] = 1.0 + else : + R[k,k] = param.c[i,j] + # non-diagonal terms + if(cp != 0): + sd = np.sin(param.dcp[cp]) + cd = np.cos(param.dcp[cp]) + faseCP = complex(cd,sd) + else: + faseCP = complex(1.0,0.0) + + R[i-1,j-1] = param.s[i,j]*faseCP.conjugate() + R[j-1,i-1] = -param.s[i,j]*faseCP + return R + +def calcU(param): + """ Defining the mixing matrix parametrization. + @type param : PhysicsConstants + @param param : set of physical parameters to be used. + + @rtype : None + @return : Sets mixing matrix. + """ + if(param.numneu == 2): + return self.R(1,2,0,param) + elif(param.numneu == 3): + return np.dot(R(2,3,0,param),np.dot(R(1,3,1,param),R(1,2,0,param))) + elif(param.numneu == 4): + return np.dot(R(3,4,0,param),np.dot(R(2,4,2,param),np.dot(R(1,4,0,param),np.dot(R(2,3,0,param),np.dot(R(1,3,1,param),R(1,2,0,param)))))) + elif(param.numneu == 5): + return np.dot(R(4,5,0,param),np.dot(R(3,5,0,param),np.dot(R(2,5,0,param),np.dot(R(1,5,3,param),np.dot(R(3,4,0,param),np.dot(R(2,4,0,param),np.dot(R(1,4,2,param),np.dot(R(2,3,0,param),np.dot(R(1,3,1,param),R(1,2,0,param)))))))))) + elif(param.numneu == 6): + # 3+3 twin-sterile-neutrino model + return np.dot(R(3,6,0,param),np.dot(R(2,5,0,param),np.dot(R(1,4,0,param),np.dot(R(2,3,0,param),np.dot(R(1,3,1,param),R(1,2,0,param)))))) + else: + print "Sorry, too many neutrinos. Not yet implemented! =(." + quit() + + # antineutrino case + if param.neutype == "antineutrino" : + return self.U.conjugate() + + + +def massM2(param): + """ Mass term in the neutrino mass basis. + + @type param : PhysicsConstants + @param param : set of physical parameters to be used. + + @rtype : numpy array + @return : mass matrix in mass basis. + """ + M2 = np.zeros([param.numneu,param.numneu],complex) + for k in np.arange(1,param.numneu,1): + M2[k,k] = param.dmsq[k+1] + return M2 + +def flavorM2(param): + """ Mass term in the neutrino flavor basis. + + @type param : PhysicsConstants + @param param : set of physical parameters to be used. + + @rtype : numpy array + @return : mass matrix in flavor basis. + """ + U = calcU(param) + return np.dot(U,np.dot(massM2(param),U.conjugate().T)) + +class LVP(PhysicsConstants): + def __init__(self): + super(LVP,self).__init__() + self.th12 = 0.0 + self.th13 = 0.0 + self.th23 = 0.0 + self.delta1 = 0.0 + self.deltaCP = 0.0 + super(LVP,self).Refresh() + + # LVS + self.LVS21 = 0.0 # + self.LVS31 = 0.0 # + self.LVS41 = 0.0 # + self.LVS51 = 0.0 # + self.LVS61 = 0.0 # + # SQUARED MASS DIFFERENCE MATRIX + self.LVS = np.zeros([self.numneumax+2],float) + self.LVS[2] = self.LVS21 + self.LVS[3] = self.LVS31 + self.LVS[4] = self.LVS41 + self.LVS[5] = self.LVS51 + self.LVS[6] = self.LVS61 + + def Refresh(self): + super(LVP,self).Refresh() + LVS = self.LVS + LVS[2] = self.LVS21 + LVS[3] = self.LVS31 + LVS[4] = self.LVS41 + LVS[5] = self.LVS51 + LVS[6] = self.LVS61 + +def DiagonalMatrixLV(param): + DD = np.zeros([param.numneu,param.numneu],complex) + for k in np.arange(1,param.numneu,1): + DD[k,k] = param.LVS[k+1] + return DD + +def LVTerm(LVparam): + U = calcU(LVparam) + return np.dot(U,np.dot(DiagonalMatrixLV(LVparam),U.conjugate().T)) diff --git a/plot_llh/PhysConst.py b/plot_llh/PhysConst.py new file mode 100644 index 0000000..89a0be0 --- /dev/null +++ b/plot_llh/PhysConst.py @@ -0,0 +1,390 @@ +""" +Author : C.A. Arguelles +Date : 10/MAY/2011 + +Contains Physics constants and global variables. + +Log : +- Modified on 23/ABR/2012 by C.Arguelles + + Changed the definition of PhysicsConstants to + include an __init__ to separate the class global + properties from its instances. +""" + +# python standard modules +import numpy as np + +class PhysicsConstants(object): + + def __init__(self): + ## PHYSICS CONSTANTS + #=========================================================================== + # NAME + #=========================================================================== + + self.name = "STD" # Default values + self.linestyle = "solid" # Default linestyle in plots + self.markerstyle = "*" # Default marker style + self.colorstyle = "red" # Default color style + self.savefilename = "output.dat" # Default color style + + #=============================================================================== + # ## MATH + #=============================================================================== + self.PI=3.14159265 # Pi + self.PIby2=1.5707963268 # Pi/2 + self.sqr2=1.4142135624 # Sqrt[2] + self.ln2 = np.log(2.0) + + #=============================================================================== + # ## EARTH + #=============================================================================== + self.EARTHRADIUS = 6371.0 # [km] Earth radius + #=============================================================================== + # ## SUN + #=============================================================================== + self.SUNRADIUS = 109*self.EARTHRADIUS # [km] Sun radius + + #=============================================================================== + # # PHYSICAL CONSTANTS + #=============================================================================== + self.GF = 1.16639e-23 # [eV^-2] Fermi Constant + self.Na = 6.0221415e+23 # [mol cm^-3] Avogadro Number + self.sw_sq = 0.2312 # [dimensionless] sin(th_weinberg) ^2 + self.G = 6.67300e-11 # [m^3 kg^-1 s^-2] + self.alpha = 1.0/137.0 # [dimensionless] fine-structure constant + + #=============================================================================== + # ## UNIT CONVERSION FACTORS + #=============================================================================== + # Energy + self.TeV = 1.0e12 # [eV/TeV] + self.GeV = 1.0e9 # [eV/GeV] + self.MeV = 1.0e6 # [eV/MeV] + self.keV = 1.0e3 # [eV/keV] + self.Joule = 1/1.60225e-19 # [eV/J] + # Mass + self.kg = 5.62e35 # [eV/kg] + self.gr = 1e-3*self.kg # [eV/g] + # Time + self.sec = 1.523e15 # [eV^-1/s] + self.hour = 3600.0*self.sec # [eV^-1/h] + self.day = 24.0*self.hour # [eV^-1/d] + self.year = 365.0*self.day # [eV^-1/yr] + self.yearstosec = self.sec/self.year # [s/yr] + # Distance + self.meter = 5.076e6 # [eV^-1/m] + self.cm = 1.0e-2*self.meter # [eV^-1/cm] + self.km = 1.0e3*self.meter # [eV^-1/km] + self.fermi = 1.0e-15*self.meter # [eV^-1/fm] + self.angstrom = 1.0e-10*self.meter # [eV^-1/A] + self.AU = 149.60e9*self.meter # [eV^-1/AU] + self.parsec = 3.08568025e16*self.meter# [eV^-1/parsec] + # Integrated Luminocity # review + self.picobarn = 1.0e-36*self.cm**2 # [eV^-2/pb] + self.femtobarn = 1.0e-39*self.cm**2 # [eV^-2/fb] + # Presure + self.Pascal = self.Joule/self.meter**3 # [eV^4/Pa] + self.hPascal = 100.0*self.Pascal # [eV^4/hPa] + self.atm = 101325.0*self.Pascal # [eV^4/atm] + self.psi = 6893.0*self.Pascal # [eV^4/psi] + # Temperature + self.kelvin = 1/1.1604505e4 # [eV/K] + # Angle + self.degree = self.PI/180.0 # [rad/degree] + # magnetic field + self.T = 0.000692445 # [eV^2/T] + + # old notation + self.cm3toev3 = 7.68351405e-15 # cm^3-> ev^3 + self.KmtoEv =5.0677288532e+9 # km -> eV + self.yearstosec = 31536.0e3 # years -> sec + + #=============================================================================== + # ## NEUTRINO OSCILLATION PARAMETERS ## + #=============================================================================== + + self.numneu = 3 # number of neutrinos + self.numneumax = 6 # maximum neutrino number + self.neutype = 'neutrino' + #neutype = 'antineutrino' + + # values updated according to 1209.3023 Table 1 FreeFluxes + RSBL + + # MIXING ANGLES + + self.th12 = 0.579639 + self.th13 = 0.150098 + self.th23 = self.PIby2/2.0 + self.th14 = 0.0 + self.th24 = 0.0 + self.th34 = 0.0 + self.th15 = 0.0 + self.th25 = 0.0 + self.th35 = 0.0 + self.th45 = 0.0 + self.th16 = 0.0 + self.th26 = 0.0 + self.th36 = 0.0 + self.th46 = 0.0 + self.th56 = 0.0 + + # mixing angles matrix array + self.th = np.zeros([self.numneumax+1,self.numneumax+1],float) + self.th[1,2] = self.th12 + self.th[1,3] = self.th13 + self.th[2,3] = self.th23 + self.th[1,4] = self.th14 + self.th[2,4] = self.th24 + self.th[3,4] = self.th34 + self.th[1,5] = self.th15 + self.th[2,5] = self.th25 + self.th[3,5] = self.th35 + self.th[4,5] = self.th45 + self.th[1,6] = self.th16 + self.th[2,6] = self.th26 + self.th[3,6] = self.th36 + self.th[4,6] = self.th46 + self.th[5,6] = self.th56 + + self.s12 = np.sin(self.th12) + self.c12 = np.cos(self.th12) + self.s13 = np.sin(self.th13) + self.c13 = np.cos(self.th13) + self.s23 = np.sin(self.th23) + self.c23 = np.cos(self.th23) + self.s14 = np.sin(self.th14) + self.c14 = np.cos(self.th14) + self.s24 = np.sin(self.th24) + self.c24 = np.cos(self.th24) + self.s34 = np.sin(self.th34) + self.c34 = np.cos(self.th34) + self.s15 = np.sin(self.th15) + self.c15 = np.cos(self.th15) + self.s25 = np.sin(self.th25) + self.c25 = np.cos(self.th25) + self.s35 = np.sin(self.th35) + self.c35 = np.cos(self.th35) + self.s45 = np.sin(self.th45) + self.c45 = np.cos(self.th45) + self.s16 = np.sin(self.th16) + self.c16 = np.cos(self.th16) + self.s26 = np.sin(self.th26) + self.c26 = np.cos(self.th26) + self.s36 = np.sin(self.th36) + self.c36 = np.cos(self.th36) + self.s46 = np.sin(self.th46) + self.c46 = np.cos(self.th46) + self.s56 = np.sin(self.th56) + self.c56 = np.cos(self.th56) + + # cos(th_ij) matrix array + self.c = np.zeros([self.numneumax+1,self.numneumax+1],float) + self.c[1,2] = self.c12 + self.c[1,3] = self.c13 + self.c[1,4] = self.c14 + self.c[2,3] = self.c23 + self.c[2,4] = self.c24 + self.c[3,4] = self.c34 + self.c[1,5] = self.c15 + self.c[2,5] = self.c25 + self.c[3,5] = self.c35 + self.c[4,5] = self.c45 + self.c[1,6] = self.c16 + self.c[2,6] = self.c26 + self.c[3,6] = self.c36 + self.c[4,6] = self.c46 + self.c[5,6] = self.c56 + + # sin(th_ij) matrix array + self.s = np.zeros([self.numneumax+1,self.numneumax+1],float) + self.s[1,2] = self.s12 + self.s[1,3] = self.s13 + self.s[1,4] = self.s14 + self.s[2,3] = self.s23 + self.s[2,4] = self.s24 + self.s[3,4] = self.s34 + self.s[1,5] = self.s15 + self.s[2,5] = self.s25 + self.s[3,5] = self.s35 + self.s[4,5] = self.s45 + self.s[1,6] = self.s16 + self.s[2,6] = self.s26 + self.s[3,6] = self.s36 + self.s[4,6] = self.s46 + self.s[5,6] = self.s56 + + # CP PHASES + #self.delta21=3.3e-5 + #self.delta32=3.1e-3 + #self.delta31=self.delta32+self.delta21 + #self.deltaCP=self.PIby2 + + # CP Phases + self.deltaCP = 5.235987 + self.delta1 = self.deltaCP + self.delta2 = 0.0 + self.delta3 = 0.0 + + # d-CP phases + self.dcp = np.zeros([self.numneumax-2+1],complex) + self.dcp[0] = 1.0 + self.dcp[1] = self.delta1 + self.dcp[2] = self.delta2 + self.dcp[3] = self.delta3 + + # SQUARED MASS DIFFERENCE + self.dm21sq = 7.50e-5 # [eV^2] + self.dm31sq = 2.47e-3 # [eV^2] + self.dm32sq = -2.43e-3 # [eV^2] + # STERILE + self.dm41sq = 0.0 # [eV^2] + self.dm51sq = 0.0 # [eV^2] + self.dm61sq = 0.0 # [eV^2] + # SQUARED MASS DIFFERENCE MATRIX + self.dmsq = np.zeros([self.numneumax+2],float) + self.dmsq[2] = self.dm21sq + self.dmsq[3] = self.dm31sq + self.dmsq[4] = self.dm41sq + self.dmsq[5] = self.dm51sq + self.dmsq[6] = self.dm61sq + + self.dm2 = np.zeros([self.numneumax+1,self.numneumax+1],float) + self.dm2[1,2] = self.dm21sq + self.dm2[1,3] = self.dm31sq + self.dm2[2,3] = self.dm32sq + self.dm2[1,4] = self.dm41sq + self.dm2[1,5] = self.dm51sq + self.dm2[1,6] = self.dm61sq + + # MIXING MATRIX + self.U = None + + #=============================================================================== + # # PARTICLE MASSES + #=============================================================================== + self.muon_mass = 0.10565 # [GeV] + self.neutron_mass = 0.939565 # [GeV] + self.proton_mass = 0.938272 # [GeV] + self.electron_mass = 0.510998910e-3 # [GeV] + + self.atomic_mass_unit = 1.660538e-24 # [g] + + ## names + self.electron = 0 + self.muon = 1 + self.tau = 2 + self.sterile1 = 3 + self.sterile2 = 4 + self.sterile3 = 5 + + #=============================================================================== + # REFRESH + #=============================================================================== + + def Refresh(self): + # Refresh angles + self.s12 = np.sin(self.th12) + self.c12 = np.cos(self.th12) + self.s13 = np.sin(self.th13) + self.c13 = np.cos(self.th13) + self.s23 = np.sin(self.th23) + self.c23 = np.cos(self.th23) + self.s14 = np.sin(self.th14) + self.c14 = np.cos(self.th14) + self.s24 = np.sin(self.th24) + self.c24 = np.cos(self.th24) + self.s34 = np.sin(self.th34) + self.c34 = np.cos(self.th34) + self.s15 = np.sin(self.th15) + self.c15 = np.cos(self.th15) + self.s25 = np.sin(self.th25) + self.c25 = np.cos(self.th25) + self.s35 = np.sin(self.th35) + self.c35 = np.cos(self.th35) + self.s45 = np.sin(self.th45) + self.c45 = np.cos(self.th45) + self.s16 = np.sin(self.th16) + self.c16 = np.cos(self.th16) + self.s26 = np.sin(self.th26) + self.c26 = np.cos(self.th26) + self.s36 = np.sin(self.th36) + self.c36 = np.cos(self.th36) + self.s46 = np.sin(self.th46) + self.c46 = np.cos(self.th46) + self.s56 = np.sin(self.th56) + self.c56 = np.cos(self.th56) + + th = self.th + th[1,2] = self.th12 + th[1,3] = self.th13 + th[2,3] = self.th23 + th[1,4] = self.th14 + th[2,4] = self.th24 + th[3,4] = self.th34 + th[1,5] = self.th15 + th[2,5] = self.th25 + th[3,5] = self.th35 + th[4,5] = self.th45 + th[1,6] = self.th16 + th[2,6] = self.th26 + th[3,6] = self.th36 + th[4,6] = self.th46 + th[5,6] = self.th56 + # Refresh cos(th_ij) + c = self.c + c[1,2] = self.c12 + c[1,3] = self.c13 + c[1,4] = self.c14 + c[2,3] = self.c23 + c[2,4] = self.c24 + c[3,4] = self.c34 + c[1,5] = self.c15 + c[2,5] = self.c25 + c[3,5] = self.c35 + c[4,5] = self.c45 + c[1,6] = self.c16 + c[2,6] = self.c26 + c[3,6] = self.c36 + c[4,6] = self.c46 + c[5,6] = self.c56 + # Refresh sin(th_ij) + s = self.s + self.s[1,2] = self.s12 + self.s[1,3] = self.s13 + self.s[1,4] = self.s14 + self.s[2,3] = self.s23 + self.s[2,4] = self.s24 + self.s[3,4] = self.s34 + self.s[1,5] = self.s15 + self.s[2,5] = self.s25 + self.s[3,5] = self.s35 + self.s[4,5] = self.s45 + self.s[1,6] = self.s16 + self.s[2,6] = self.s26 + self.s[3,6] = self.s36 + self.s[4,6] = self.s46 + self.s[5,6] = self.s56 + # Refresh CP-Phases + dcp = self.dcp + dcp[0] = 1.0 + dcp[1] = self.delta1 + dcp[2] = self.delta2 + dcp[3] = self.delta3 + #dcp[4] = self.delta2 + # Refresh Square mass differences + dmsq = self.dmsq + dmsq[2] = self.dm21sq + dmsq[3] = self.dm31sq + dmsq[4] = self.dm41sq + dmsq[5] = self.dm51sq + dmsq[6] = self.dm61sq + + dm2 = self.dm2 + dm2[1,2] = self.dm21sq + dm2[1,3] = self.dm31sq + dm2[2,3] = self.dm32sq + dm2[1,4] = self.dm41sq + dm2[1,5] = self.dm51sq + dm2[1,6] = self.dm61sq + diff --git a/plot_llh/make_plots.py b/plot_llh/make_plots.py new file mode 100644 index 0000000..9216396 --- /dev/null +++ b/plot_llh/make_plots.py @@ -0,0 +1,117 @@ +#!/usr/bin/python + +import sys +sys.path.append('/Users/Teps/Theory') +#import header as h +#sys.path.append('/Users/Teps/Theory/HESE') +#import anarchy_header as ah +sys.path.append('/Users/Teps/Theory/HESE/Carlos') +import matplotlib as mpl +import matplotlib.pyplot as plt +from matplotlib import rc, rcParams +import MinimalTools as MT +import PhysConst as PC +import LVCPT as LVCPT +import numpy as np + +import sys,os + +rc('text', usetex=True) +rc('font', **{'family':'serif', 'serif':['Computer Modern'], 'size':18}) +cols = ['#29A2C6','#FF6D31','#FFCB18','#73B66B','#EF597B', '#333333'] + +font = {'family' : 'serif', + 'weight' : 'bold', + 'size' : 18} + +if len(sys.argv)< 2: + print sys.argv + print "Usage: make_plots.py input_filepath." + exit(1) + +#colors_schemes = ["Greens","Reds","Blues","PuRd","summer"] +colors_schemes = ["Greens","Reds","Blues","spring","summer"] +#colors_schemes = ["Greens","Reds","Blues","cool","summer"] +#colors_schemes = ["Greens","Reds","Blues","PuRd","summer"] +#colors_schemes = ["Blues","Greens","Reds","PuRd","summer"] +#colors_schemes = ["Greys","Greens","Reds","PuRd","summer"] +#colors_schemes = ["Greys","Greys","Greys","Greys","summer"] +#colors_schemes = ["PuRd","summer"] +output_format = "pdf" + +# if True then will plot all files in the same figure +use_same_canvas = True +figure = None + +for i in range(len(sys.argv)-1): + infile = sys.argv[i+1] + print "Load data: " + str(infile) + if infile[-3:] == 'txt': + flavor_list = np.genfromtxt(infile) + else: + flavor_list = np.load(infile) + if len(flavor_list[~np.isfinite(flavor_list)]) != 0: + fl = [] + for x in flavor_list: + if np.sum(~np.isfinite(x)) == 0: + fl.append(x.tolist()) + flavor_list = np.array(fl) + print flavor_list + print "Done loading data" + + if not use_same_canvas : + filename = "triangle_plot_"+os.path.splitext(sys.argv[i+1])[0] + else : + filename = "triangle_plot" + + # plots scale and diviions + scale = 8 + divisions = 40 + + print "Begin making plot ..." + triangle_collection = LVCPT.GenerateTriangles(scale,divisions*2) + map(lambda f : LVCPT.AddPointToTriangleCollection(f,triangle_collection, scale = scale, divisions = divisions*2),flavor_list) + + if use_same_canvas: + figure = LVCPT.MakeFlavorTriangle(flavor_list, divisions = 5, save_file=True, + filename = filename + "_hist", icolor = "g", icolormap = colors_schemes[i], + triangle_collection=triangle_collection, figure = figure, alpha = 0.8, + initial_flavor_ratio = [0,1,0], subdivisions = True, color_scale = "lin", + output_format = output_format, inner_line_color ="silver",add_default_text = False, + plot_color_bar =True) + + else: + figure = LVCPT.MakeFlavorTriangle(flavor_list, divisions = 5, save_file=True, + filename = filename + "_hist", icolor = "g", icolormap = colors_schemes[i], + triangle_collection=triangle_collection, alpha = 0.8, + initial_flavor_ratio = [0,1,0], subdivisions = True, color_scale = "lin", + output_format = output_format, inner_line_color = "silver",add_default_text = False, + plot_color_bar =True) + + print "Done making plot: " + filename + "_hist."+output_format + +ax = figure.get_axes()[0] +#ax.plot(6.5-0.35,5.5+0.3+0.35,"o", color = "grey", ms = 10, markeredgewidth = 0.1, alpha = 0.9) +#ax.text(6.7-0.35,5.44+0.3+0.35,r"$(1-x:x:0)$", fontsize = 16) +#ax.axvline(x = 7.9) +fsz = 32 +ax.plot(6.5-0.1,5.5+0.3+0.35+0.2+0.2,"o", color = "gold", ms = 25, markeredgewidth = 0.1, alpha = 0.9) +ax.text(6.7-0.1,5.44+0.3+0.35+0.2+0.2,r"$(1:2:0)$", fontsize = fsz) + +ax.plot(6.5-0.1,5.5+0.35+0.2,"o", color = "#2B653E", ms = 25, markeredgewidth = 0.1, alpha = 0.9) +ax.text(6.7-0.1,5.44+0.35+0.2,r"$(1:0:0)$", fontsize = fsz) + +ax.plot(6.5-0.1,5.5-0.3+0.35-0.2+0.2,"o", color = "#CA323D", ms = 25, markeredgewidth = 0.1, alpha = 0.9) +ax.text(6.7-0.1,5.44-0.3+0.35-0.2+0.2,r"$(0:1:0)$", fontsize = fsz) + +ax.plot(6.5-0.1,5.5-0.3+0.35-0.3-0.4+0.2,"o", color = "#2D4676", ms = 25, markeredgewidth = 0.1, alpha = 0.9) +ax.text(6.7-0.1,5.44-0.3+0.35-0.3-0.4+0.2,r"$(0:0:1)$", fontsize = fsz) + +plt.savefig("./plots/"+filename+"."+output_format, dpi = 600, bbox_inches='tight') + +exit(1) + +##os.system("cd plots") +##os.system("gs triangle_plot_hist.eps") +##os.system("cd ..") + diff --git a/plot_llh/mcmc_scan.py b/plot_llh/mcmc_scan.py new file mode 100644 index 0000000..455d5dd --- /dev/null +++ b/plot_llh/mcmc_scan.py @@ -0,0 +1,174 @@ +#! /usr/bin/env python +""" +Sample points from a gaussian likelihood +""" + +from __future__ import absolute_import, division + +import sys + +import argparse +import multiprocessing + +import numpy as np +from scipy.stats import multivariate_normal + +import emcee +import tqdm + +MEASURED_FR = [1, 1, 1] +SIGMA = 0.001 + + +def angles_to_fr(angles): + sphi4, c2psi = angles + + psi = (0.5)*np.arccos(c2psi) + + sphi2 = np.sqrt(sphi4) + cphi2 = 1. - sphi2 + spsi2 = np.sin(psi)**2 + cspi2 = 1. - spsi2 + + x = sphi2*cspi2 + y = sphi2*spsi2 + z = cphi2 + return x, y, z + + +def triangle_llh(theta): + """-Log likelihood function for a given theta.""" + fr = angles_to_fr(theta) + fr_bf = MEASURED_FR + cov_fr = np.identity(3) * SIGMA + return np.log(multivariate_normal.pdf(fr, mean=fr_bf, cov=cov_fr)) + + +def lnprior(theta): + """Priors on theta.""" + sphi4, c2psi = theta + + # Flavour ratio bounds + if 0. <= sphi4 <= 1.0 and -1.0 <= c2psi <= 1.0: + pass + else: return -np.inf + + return 0. + + +def lnprob(theta): + """Prob function for mcmc.""" + lp = lnprior(theta) + if not np.isfinite(lp): + return -np.inf + return lp + triangle_llh(theta) + + +def parse_args(): + """Parse command line arguments""" + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument( + '--measured-ratio', type=int, nargs=3, default=[1, 1, 1], + help='Set the central value for the measured flavour ratio at IceCube' + ) + parser.add_argument( + '--sigma-ratio', type=float, default=0.01, + help='Set the 1 sigma for the measured flavour ratio' + ) + parser.add_argument( + '--burnin', type=int, default=100, + help='Amount to burnin' + ) + parser.add_argument( + '--nwalkers', type=int, default=100, + help='Number of walkers' + ) + parser.add_argument( + '--nsteps', type=int, default=2000, + help='Number of steps to run' + ) + parser.add_argument( + '--seed', type=int, default=99, + help='Set the random seed value' + ) + parser.add_argument( + '--outfile', type=str, default='./untitled', + help='Path to output chains' + ) + args = parser.parse_args() + return args + + +def main(): + args = parse_args() + + np.random.seed(args.seed) + + global MEASURED_FR + global SIGMA + + MEASURED_FR = np.array(args.measured_ratio) / float(np.sum(args.measured_ratio)) + SIGMA = args.sigma_ratio + + print 'MEASURED_FR = {0}'.format(MEASURED_FR) + print 'SIGMA = {0}'.format(SIGMA) + + ndim = 2 + nwalkers = args.nwalkers + ntemps = 1 + burnin = args.burnin + betas = np.array([1e0, 1e-1, 1e-2, 1e-3, 1e-4]) + p0_base = [0.5, 0.5] + p0_std = [.2, 0.2] + + print 'p0_base', p0_base + print 'p0_std', p0_std + p0 = np.random.normal(p0_base, p0_std, size=[ntemps, nwalkers, ndim]) + print map(lnprior, p0[0]) + + # threads = multiprocessing.cpu_count() + threads = 1 + sampler = emcee.PTSampler( + ntemps, nwalkers, ndim, triangle_llh, lnprior, threads=threads + ) + + print "Running burn-in" + for result in tqdm.tqdm(sampler.sample(p0, iterations=burnin), total=burnin): + pos, prob, state = result + sampler.reset() + print "Finished burn-in" + + nsteps = args.nsteps + + print "Running" + for _ in tqdm.tqdm(sampler.sample(pos, iterations=nsteps), total=nsteps): + pass + print "Finished" + + outfile = args.outfile+'_{0:03d}_{1:03d}_{2:03d}_{3:.1E}'.format( + int(MEASURED_FR[0]*100), int(MEASURED_FR[1]*100), int(MEASURED_FR[2]*100), SIGMA + ) + + samples = sampler.chain[0, :, :, :].reshape((-1, ndim)) + print 'acceptance fraction', sampler.acceptance_fraction + print 'sum of acceptance fraction', np.sum(sampler.acceptance_fraction) + print 'np.unique(samples[:,0]).shape', np.unique(samples[:,0]).shape + + try: + print 'autocorrelation', sampler.acor + except: + print 'WARNING : NEED TO RUN MORE SAMPLES FOR FILE ' + outfile + print 'outfile = ', outfile + + fr_samples = np.array(map(angles_to_fr, samples)) + np.save(outfile+'.npy', fr_samples) + + print "DONE!" + + +main.__doc__ = __doc__ + + +if __name__ == '__main__': + main() + diff --git a/submitter/make_dag.py b/submitter/make_dag.py new file mode 100644 index 0000000..10381f6 --- /dev/null +++ b/submitter/make_dag.py @@ -0,0 +1,100 @@ +#! /usr/bin/env python + +import numpy as np + +a_fr = (1, 2, 0) +b_fr = (1, 0, 0) +c_fr = (0, 1, 0) +d_fr = (0, 0, 1) +e_fr = (1, 1, 1) +f_fr = (2, 1, 0) +g_fr = (1, 1, 0) + +full_scan_mfr = [ + (1, 1, 1), (1, 1, 0) +] + +fix_sfr_mfr = [ + (1, 1, 1, 1, 0, 0), + (1, 1, 1, 0, 1, 0), + (1, 1, 1, 0, 0, 1), + (1, 1, 1, 1, 2, 0), + (1, 1, 0, 0, 1, 0), + (1, 1, 0, 1, 2, 0), + (1, 1, 0, 1, 0, 0), + (1, 0, 0, 1, 0, 0), + (0, 1, 0, 0, 1, 0), + (1, 2, 0, 0, 1, 0), + (1, 2, 0, 1, 2, 0) +] + +sigmas = ['0.1', '0.01'] +dimensions = [6] +energy = [1e4, 1e6, 1e7] +flat = False +burnin = 1000 +nwalkers = 200 +nsteps = 10000 +scales = "1E-20 1E-30" + +outfile = 'dagman_FR.submit' +condor_script = '/home/smandalia/Documents/flavour_ratio/submitter/submit.sub' + +with open(outfile, 'w') as f: + job_number = 1 + for dim in dimensions: + print 'dimension', dim + for en in energy: + print 'energy {0:.0E}'.format(en) + + outchain_head = '/data/user/smandalia/flavour_ratio/data/DIM{0}/{1:.0E}'.format(dim, en) + + for sig in sigmas: + print 'sigma', sig + for frs in fix_sfr_mfr: + print frs + outchains = outchain_head + '/fix_ifr/{0}/mcmc_chain'.format(str(sig).replace('.', '_')) + f.write('JOB\tjob{0}\t{1}\n'.format(job_number, condor_script)) + f.write('VARS\tjob{0}\tmr0="{1}"\n'.format(job_number, frs[0])) + f.write('VARS\tjob{0}\tmr1="{1}"\n'.format(job_number, frs[1])) + f.write('VARS\tjob{0}\tmr2="{1}"\n'.format(job_number, frs[2])) + f.write('VARS\tjob{0}\tsigma="{1}"\n'.format(job_number, sig)) + f.write('VARS\tjob{0}\tfix_source_ratio="{1}"\n'.format(job_number, 'True')) + f.write('VARS\tjob{0}\tsr0="{1}"\n'.format(job_number, frs[3])) + f.write('VARS\tjob{0}\tsr1="{1}"\n'.format(job_number, frs[4])) + f.write('VARS\tjob{0}\tsr2="{1}"\n'.format(job_number, frs[5])) + f.write('VARS\tjob{0}\tfix_scale="{1}"\n'.format(job_number, 'False')) + f.write('VARS\tjob{0}\tscale="{1}"\n'.format(job_number, 0)) + f.write('VARS\tjob{0}\tdimension="{1}"\n'.format(job_number, dim)) + f.write('VARS\tjob{0}\tenergy="{1}"\n'.format(job_number, en)) + f.write('VARS\tjob{0}\tflat_llh="{1}"\n'.format(job_number, flat)) + f.write('VARS\tjob{0}\tburnin="{1}"\n'.format(job_number, burnin)) + f.write('VARS\tjob{0}\tnwalkers="{1}"\n'.format(job_number, nwalkers)) + f.write('VARS\tjob{0}\tnsteps="{1}"\n'.format(job_number, nsteps)) + f.write('VARS\tjob{0}\toutfile="{1}"\n'.format(job_number, outchains)) + f.write('VARS\tjob{0}\tfix_mixing="{1}"\n'.format(job_number, 'False')) + job_number += 1 + + for frs in full_scan_mfr: + print frs + outchains = outchain_head + '/full_scan/{0}/mcmc_chain'.format(str(sig).replace('.', '_')) + f.write('JOB\tjob{0}\t{1}\n'.format(job_number, condor_script)) + f.write('VARS\tjob{0}\tmr0="{1}"\n'.format(job_number, frs[0])) + f.write('VARS\tjob{0}\tmr1="{1}"\n'.format(job_number, frs[1])) + f.write('VARS\tjob{0}\tmr2="{1}"\n'.format(job_number, frs[2])) + f.write('VARS\tjob{0}\tsigma="{1}"\n'.format(job_number, sig)) + f.write('VARS\tjob{0}\tfix_source_ratio="{1}"\n'.format(job_number, 'False')) + f.write('VARS\tjob{0}\tsr0="{1}"\n'.format(job_number, 0)) + f.write('VARS\tjob{0}\tsr1="{1}"\n'.format(job_number, 0)) + f.write('VARS\tjob{0}\tsr2="{1}"\n'.format(job_number, 0)) + f.write('VARS\tjob{0}\tfix_scale="{1}"\n'.format(job_number, 'False')) + f.write('VARS\tjob{0}\tscale="{1}"\n'.format(job_number, 0)) + f.write('VARS\tjob{0}\tdimension="{1}"\n'.format(job_number, dim)) + f.write('VARS\tjob{0}\tenergy="{1}"\n'.format(job_number, en)) + f.write('VARS\tjob{0}\tflat_llh="{1}"\n'.format(job_number, flat)) + f.write('VARS\tjob{0}\tburnin="{1}"\n'.format(job_number, burnin)) + f.write('VARS\tjob{0}\tnwalkers="{1}"\n'.format(job_number, nwalkers)) + f.write('VARS\tjob{0}\tnsteps="{1}"\n'.format(job_number, nsteps)) + f.write('VARS\tjob{0}\toutfile="{1}"\n'.format(job_number, outchains)) + f.write('VARS\tjob{0}\tfix_mixing="{1}"\n'.format(job_number, 'False')) + job_number += 1 diff --git a/submitter/submit.sub b/submitter/submit.sub new file mode 100644 index 0000000..9e21fc5 --- /dev/null +++ b/submitter/submit.sub @@ -0,0 +1,37 @@ +Executable = /home/smandalia/Documents/flavour_ratio/mcmc_scan.py +Arguments = --measured-ratio $(mr0) $(mr1) $(mr2) --sigma-ratio $(sigma) --fix-source-ratio $(fix_source_ratio) --source-ratio $(sr0) $(sr1) $(sr2) --fix-scale $(fix_scale) --scale $(scale) --dimension $(dimension) --energy $(energy) --flat-llh $(flat_llh) --burnin $(burnin) --nwalkers $(nwalkers) --nsteps $(nsteps) --seed 24 --outfile $(outfile) --fix-mixing $(fix_mixing) + +# All logs will go to a single file +log = /home/smandalia/Documents/flavour_ratio/submitter/logs/job_$(Cluster).log +output = /home/smandalia/Documents/flavour_ratio/submitter/logs/job_$(Cluster).out +error = /home/smandalia/Documents/flavour_ratio/submitter/logs/job_$(Cluster).err + +getenv = True +# environment = "X509_USER_PROXY=x509up_u14830" + +# Stage user cert to the node (Gridftp-Users is already on CVMFS) +# transfer_input_files = /tmp/x509up_u14830 + +# but do not try to copy outputs back (see: https://htcondor-wiki.cs.wisc.edu/index.cgi/tktview?tn=3081) +# +TransferOutput="" + +request_memory = 1GB +request_cpus = 1 + +Universe = vanilla +Notification = never + +# run on both SL5 and 6 +# +WantRHEL6 = True +# +WantSLC6 = False + +# # run on OSG +# +WantGlidein = True + +# +TransferOutput="" + +# Requirements = IS_GLIDEIN && HAS_CVMFS_icecube_opensciencegrid_org && (OpSysAndVer =?= "CentOS6" || OpSysAndVer =?= "RedHat6" || OpSysAndVer =?= "SL6") +# Requirements = IS_GLIDEIN + +# GO! +queue |
