aboutsummaryrefslogtreecommitdiffstats
path: root/plot_llh/MinimalTools.py
blob: 4ae8360645c4fa681321eaa5482ba960b4569bdf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
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))