def compile_2nd_matrix_pseudo_ellipse_torsionless(matrix, Rx2_eigen, theta_x, theta_y): """Generate the 2nd degree Frame Order matrix for the torsionless pseudo-ellipse. @param matrix: The Frame Order matrix, 2nd degree to be populated. @type matrix: numpy 9D, rank-2 array @param Rx2_eigen: The Kronecker product of the eigenframe rotation matrix with itself. @type Rx2_eigen: numpy 9D, rank-2 array @param theta_x: The cone opening angle along x. @type theta_x: float @param theta_y: The cone opening angle along y. @type theta_y: float """ # The rigid case. if theta_x == 0.0: # Set up the matrix as the identity. matrix[:] = 0.0 for i in range(len(matrix)): matrix[i, i] = 1.0 # Rotate and return the frame order matrix. return rotate_daeg(matrix, Rx2_eigen) # The surface area normalisation factor. fact = 6.0 * pec(theta_x, theta_y) fact2 = 0.5 * fact # Invert. if fact == 0.0: fact = 1e100 fact2 = 1e100 else: fact = 1.0 / fact fact2 = 1.0 / fact2 # Diagonal. matrix[0, 0] = fact2 * (3.0*pi + quad(part_int_daeg2_pseudo_ellipse_torsionless_00, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[1, 1] = fact * (2.0*pi + quad(part_int_daeg2_pseudo_ellipse_torsionless_11, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[2, 2] = fact * (5.0*pi - quad(part_int_daeg2_pseudo_ellipse_torsionless_22, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[3, 3] = matrix[1, 1] matrix[4, 4] = fact2 * (3.0*pi + quad(part_int_daeg2_pseudo_ellipse_torsionless_44, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[5, 5] = fact * (5.0*pi - quad(part_int_daeg2_pseudo_ellipse_torsionless_55, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[6, 6] = matrix[2, 2] matrix[7, 7] = matrix[5, 5] matrix[8, 8] = fact2 * (2.0*pi - quad(part_int_daeg2_pseudo_ellipse_torsionless_88, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) # Off diagonal set 1. matrix[0, 4] = matrix[4, 0] = fact2 * (pi + quad(part_int_daeg2_pseudo_ellipse_torsionless_04, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[0, 8] = matrix[8, 0] = fact2 * (2.0*pi + quad(part_int_daeg2_pseudo_ellipse_torsionless_08, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[4, 8] = matrix[8, 4] = fact2 * (2.0*pi + quad(part_int_daeg2_pseudo_ellipse_torsionless_48, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) # Off diagonal set 2. matrix[1, 3] = matrix[3, 1] = matrix[0, 4] matrix[2, 6] = matrix[6, 2] = -matrix[0, 8] matrix[5, 7] = matrix[7, 5] = -matrix[4, 8] # Rotate and return the frame order matrix. return rotate_daeg(matrix, Rx2_eigen)
def compile_1st_matrix_pseudo_ellipse(matrix, R_eigen, theta_x, theta_y, sigma_max): """Generate the 1st degree Frame Order matrix for the pseudo-ellipse. @param matrix: The Frame Order matrix, 1st degree to be populated. @type matrix: numpy 3D, rank-2 array @param R_eigen: The eigenframe rotation matrix. @type R_eigen: numpy 3D, rank-2 array @param theta_x: The cone opening angle along x. @type theta_x: float @param theta_y: The cone opening angle along y. @type theta_y: float @param sigma_max: The maximum torsion angle. @type sigma_max: float """ # The surface area normalisation factor. fact = 2.0 * pec(theta_x, theta_y) # Invert. if fact == 0.0: fact = 1e100 else: fact = 1.0 / fact # Sinc value. sinc_smax = sinc(sigma_max/pi) # Numerical integration of phi of each element. matrix[0, 0] = fact * sinc_smax * (2.0*pi + quad(part_int_daeg1_pseudo_ellipse_00, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[1, 1] = fact * sinc_smax * (2.0*pi + quad(part_int_daeg1_pseudo_ellipse_11, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[2, 2] = fact * quad(part_int_daeg1_pseudo_ellipse_22, -pi, pi, args=(theta_x, theta_y), full_output=1)[0] # Rotate and return the frame order matrix. return rotate_daeg(matrix, R_eigen)
def compile_1st_matrix_iso_cone(matrix, R_eigen, cone_theta, sigma_max): """Generate the 1st degree Frame Order matrix for the isotropic cone. @param matrix: The Frame Order matrix, 1st degree to be populated. @type matrix: numpy 3D, rank-2 array @param R_eigen: The eigenframe rotation matrix. @type R_eigen: numpy 3D, rank-2 array @param cone_theta: The cone opening angle. @type cone_theta: float @param sigma_max: The maximum torsion angle. @type sigma_max: float """ # Zeros. matrix[:] = 0.0 # Pre-calculate trig values. sinc_sigma_max = sinc(sigma_max/pi) cos_theta = cos(cone_theta) # Diagonal values. matrix[0, 0] = sinc_sigma_max * (cos_theta + 3.0) matrix[1, 1] = matrix[0, 0] matrix[2, 2] = 2.0*cos_theta + 2.0 # Rotate and return the frame order matrix. return 0.25 * rotate_daeg(matrix, R_eigen)
def compile_2nd_matrix_pseudo_ellipse_free_rotor(matrix, Rx2_eigen, theta_x, theta_y): """Generate the 2nd degree Frame Order matrix for the free rotor pseudo-ellipse. @param matrix: The Frame Order matrix, 2nd degree to be populated. @type matrix: numpy 9D, rank-2 array @param Rx2_eigen: The Kronecker product of the eigenframe rotation matrix with itself. @type Rx2_eigen: numpy 9D, rank-2 array @param theta_x: The cone opening angle along x. @type theta_x: float @param theta_y: The cone opening angle along y. @type theta_y: float """ # The surface area normalisation factor. fact = 1.0 / (6.0 * pec(theta_x, theta_y)) # Diagonal. matrix[0, 0] = fact * (4.0*pi - quad(part_int_daeg2_pseudo_ellipse_free_rotor_00, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[1, 1] = matrix[3, 3] = fact * 3.0/2.0 * quad(part_int_daeg2_pseudo_ellipse_free_rotor_11, -pi, pi, args=(theta_x, theta_y), full_output=1)[0] matrix[4, 4] = fact * (4.0*pi - quad(part_int_daeg2_pseudo_ellipse_free_rotor_44, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[8, 8] = fact * (4.0*pi - 2.0*quad(part_int_daeg2_pseudo_ellipse_free_rotor_88, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) # Off diagonal set 1. matrix[0, 4] = matrix[0, 0] matrix[4, 0] = matrix[4, 4] matrix[0, 8] = fact * (4.0*pi + quad(part_int_daeg2_pseudo_ellipse_free_rotor_08, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[8, 0] = fact * (4.0*pi + quad(part_int_daeg2_pseudo_ellipse_free_rotor_80, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[4, 8] = fact * (4.0*pi + quad(part_int_daeg2_pseudo_ellipse_free_rotor_48, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[8, 4] = matrix[8, 0] # Off diagonal set 2. matrix[1, 3] = matrix[3, 1] = -matrix[1, 1] # Rotate and return the frame order matrix. return rotate_daeg(matrix, Rx2_eigen)
def compile_1st_matrix_pseudo_ellipse_free_rotor(matrix, R_eigen, theta_x, theta_y): """Generate the 1st degree Frame Order matrix for the free rotor pseudo-ellipse. @param matrix: The Frame Order matrix, 1st degree to be populated. @type matrix: numpy 3D, rank-2 array @param R_eigen: The eigenframe rotation matrix. @type R_eigen: numpy 3D, rank-2 array @param theta_x: The cone opening angle along x. @type theta_x: float @param theta_y: The cone opening angle along y. @type theta_y: float """ # The surface area normalisation factor. fact = 2.0 * pec(theta_x, theta_y) # Invert. if fact == 0.0: fact = 1e100 else: fact = 1.0 / fact # Numerical integration of phi of each element. matrix[2, 2] = fact * quad(part_int_daeg1_pseudo_ellipse_free_rotor_22, -pi, pi, args=(theta_x, theta_y), full_output=1)[0] # Rotate and return the frame order matrix. return rotate_daeg(matrix, R_eigen)
def compile_2nd_matrix_free_rotor(matrix, Rx2_eigen): """Generate the rotated 2nd degree Frame Order matrix for the free rotor model. The rotor axis is assumed to be parallel to the z-axis in the eigenframe. @param matrix: The Frame Order matrix, 2nd degree to be populated. @type matrix: numpy 9D, rank-2 array @param Rx2_eigen: The Kronecker product of the eigenframe rotation matrix with itself. @type Rx2_eigen: numpy 9D, rank-2 array """ # Zeros. matrix[:] = 0.0 # Diagonal. matrix[0, 0] = 0.5 matrix[1, 1] = 0.5 matrix[3, 3] = 0.5 matrix[4, 4] = 0.5 matrix[8, 8] = 1 # Off diagonal set 1. matrix[0, 4] = matrix[4, 0] = 0.5 # Off diagonal set 2. matrix[1, 3] = matrix[3, 1] = -0.5 # Rotate and return the frame order matrix. return rotate_daeg(matrix, Rx2_eigen)
def compile_2nd_matrix_pseudo_ellipse(matrix, Rx2_eigen, theta_x, theta_y, sigma_max): """Generate the 2nd degree Frame Order matrix for the pseudo-ellipse. @param matrix: The Frame Order matrix, 2nd degree to be populated. @type matrix: numpy 9D, rank-2 array @param Rx2_eigen: The Kronecker product of the eigenframe rotation matrix with itself. @type Rx2_eigen: numpy 9D, rank-2 array @param theta_x: The cone opening angle along x. @type theta_x: float @param theta_y: The cone opening angle along y. @type theta_y: float @param sigma_max: The maximum torsion angle. @type sigma_max: float """ # The surface area normalisation factor. fact = 12.0 * pec(theta_x, theta_y) # Invert. if fact == 0.0: fact = 1e100 else: fact = 1.0 / fact # Sigma_max part. if sigma_max == 0.0: fact2 = 1e100 else: fact2 = fact / (2.0 * sigma_max) # Diagonal. matrix[0, 0] = fact * (4.0*pi*(sinc(2.0*sigma_max/pi) + 2.0) + quad(part_int_daeg2_pseudo_ellipse_00, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0]) matrix[1, 1] = fact * (4.0*pi*sinc(2.0*sigma_max/pi) + quad(part_int_daeg2_pseudo_ellipse_11, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0]) matrix[2, 2] = fact * 2.0*sinc(sigma_max/pi) * (5.0*pi - quad(part_int_daeg2_pseudo_ellipse_22, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0]) matrix[3, 3] = matrix[1, 1] matrix[4, 4] = fact * (4.0*pi*(sinc(2.0*sigma_max/pi) + 2.0) + quad(part_int_daeg2_pseudo_ellipse_44, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0]) matrix[5, 5] = fact * 2.0*sinc(sigma_max/pi) * (5.0*pi - quad(part_int_daeg2_pseudo_ellipse_55, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0]) matrix[6, 6] = matrix[2, 2] matrix[7, 7] = matrix[5, 5] matrix[8, 8] = 4.0 * fact * (2.0*pi - quad(part_int_daeg2_pseudo_ellipse_88, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0]) # Off diagonal set 1. matrix[0, 4] = fact * (4.0*pi*(2.0 - sinc(2.0*sigma_max/pi)) + quad(part_int_daeg2_pseudo_ellipse_04, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0]) matrix[4, 0] = fact * (4.0*pi*(2.0 - sinc(2.0*sigma_max/pi)) + quad(part_int_daeg2_pseudo_ellipse_40, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0]) matrix[0, 8] = 4.0 * fact * (2.0*pi - quad(part_int_daeg2_pseudo_ellipse_08, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0]) matrix[8, 0] = fact * (8.0*pi + quad(part_int_daeg2_pseudo_ellipse_80, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0]) matrix[4, 8] = 4.0 * fact * (2.0*pi - quad(part_int_daeg2_pseudo_ellipse_48, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0]) matrix[8, 4] = fact * (8.0*pi - quad(part_int_daeg2_pseudo_ellipse_84, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0]) # Off diagonal set 2. matrix[1, 3] = matrix[3, 1] = fact * (4.0*pi*sinc(2.0*sigma_max/pi) + quad(part_int_daeg2_pseudo_ellipse_13, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0]) matrix[2, 6] = matrix[6, 2] = -fact * 4.0 * sinc(sigma_max/pi) * (2.0*pi + quad(part_int_daeg2_pseudo_ellipse_26, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0]) matrix[5, 7] = matrix[7, 5] = -fact * 4.0 * sinc(sigma_max/pi) * (2.0*pi + quad(part_int_daeg2_pseudo_ellipse_57, -pi, pi, args=(theta_x, theta_y, sigma_max), full_output=1)[0]) # Rotate and return the frame order matrix. return rotate_daeg(matrix, Rx2_eigen)
def compile_2nd_matrix_double_rotor(matrix, Rx2_eigen, smax1, smax2): """Generate the rotated 2nd degree Frame Order matrix for the double rotor model. The cone axis is assumed to be parallel to the z-axis in the eigenframe. @param matrix: The Frame Order matrix, 2nd degree to be populated. @type matrix: numpy 9D, rank-2 array @param Rx2_eigen: The Kronecker product of the eigenframe rotation matrix with itself. @type Rx2_eigen: numpy 9D, rank-2 array @param smax1: The maximum torsion angle for the first rotor. @type smax1: float @param smax2: The maximum torsion angle for the second rotor. @type smax2: float """ # Zeros. matrix[:] = 0.0 # Repetitive trig calculations. sinc_smax1 = sinc(smax1 / pi) sinc_2smax1 = sinc(2.0 * smax1 / pi) sinc_2smax1p1 = sinc_2smax1 + 1.0 sinc_2smax1n1 = sinc_2smax1 - 1.0 sinc_smax2 = sinc(smax2 / pi) sinc_2smax2 = sinc(2.0 * smax2 / pi) sinc_2smax2p1 = sinc_2smax2 + 1.0 sinc_2smax2n1 = sinc_2smax2 - 1.0 # Diagonal. matrix[0, 0] = sinc_2smax1 + 1.0 matrix[1, 1] = 2.0 * sinc_smax1 * sinc_smax2 matrix[2, 2] = sinc_smax2 * sinc_2smax1p1 matrix[3, 3] = matrix[1, 1] matrix[4, 4] = sinc_2smax2p1 matrix[5, 5] = sinc_smax1 * sinc_2smax2p1 matrix[6, 6] = matrix[2, 2] matrix[7, 7] = matrix[5, 5] matrix[8, 8] = 0.5 * sinc_2smax1p1 * sinc_2smax2p1 # Off diagonal set 1. matrix[4, 0] = 0.5 * sinc_2smax1n1 * sinc_2smax2n1 matrix[0, 8] = -sinc_2smax1n1 matrix[8, 0] = -0.5 * sinc_2smax1n1 * sinc_2smax2p1 matrix[4, 8] = -0.5 * sinc_2smax1p1 * sinc_2smax2n1 matrix[8, 4] = -sinc_2smax2n1 # Off diagonal set 2. matrix[2, 6] = matrix[6, 2] = sinc_smax2 * sinc_2smax1n1 matrix[5, 7] = matrix[7, 5] = sinc_smax1 * sinc_2smax2n1 # Divide by 2. multiply(0.5, matrix, matrix) # Rotate and return the frame order matrix. return rotate_daeg(matrix, Rx2_eigen)
def compile_2nd_matrix_double_rotor(matrix, Rx2_eigen, smax1, smax2): """Generate the rotated 2nd degree Frame Order matrix for the double rotor model. The cone axis is assumed to be parallel to the z-axis in the eigenframe. @param matrix: The Frame Order matrix, 2nd degree to be populated. @type matrix: numpy 9D, rank-2 array @param Rx2_eigen: The Kronecker product of the eigenframe rotation matrix with itself. @type Rx2_eigen: numpy 9D, rank-2 array @param smax1: The maximum torsion angle for the first rotor. @type smax1: float @param smax2: The maximum torsion angle for the second rotor. @type smax2: float """ # Zeros. matrix[:] = 0.0 # Repetitive trig calculations. sinc_smax1 = sinc(smax1/pi) sinc_2smax1 = sinc(2.0*smax1/pi) sinc_2smax1p1 = sinc_2smax1 + 1.0 sinc_2smax1n1 = sinc_2smax1 - 1.0 sinc_smax2 = sinc(smax2/pi) sinc_2smax2 = sinc(2.0*smax2/pi) sinc_2smax2p1 = sinc_2smax2 + 1.0 sinc_2smax2n1 = sinc_2smax2 - 1.0 # Diagonal. matrix[0, 0] = sinc_2smax1 + 1.0 matrix[1, 1] = 2.0 * sinc_smax1 * sinc_smax2 matrix[2, 2] = sinc_smax2 * sinc_2smax1p1 matrix[3, 3] = matrix[1, 1] matrix[4, 4] = sinc_2smax2p1 matrix[5, 5] = sinc_smax1 * sinc_2smax2p1 matrix[6, 6] = matrix[2, 2] matrix[7, 7] = matrix[5, 5] matrix[8, 8] = 0.5 * sinc_2smax1p1 * sinc_2smax2p1 # Off diagonal set 1. matrix[4, 0] = 0.5 * sinc_2smax1n1 * sinc_2smax2n1 matrix[0, 8] = -sinc_2smax1n1 matrix[8, 0] = -0.5 * sinc_2smax1n1 * sinc_2smax2p1 matrix[4, 8] = -0.5 * sinc_2smax1p1 * sinc_2smax2n1 matrix[8, 4] = -sinc_2smax2n1 # Off diagonal set 2. matrix[2, 6] = matrix[6, 2] = sinc_smax2 * sinc_2smax1n1 matrix[5, 7] = matrix[7, 5] = sinc_smax1 * sinc_2smax2n1 # Divide by 2. multiply(0.5, matrix, matrix) # Rotate and return the frame order matrix. return rotate_daeg(matrix, Rx2_eigen)
def compile_2nd_matrix_iso_cone(matrix, Rx2_eigen, cone_theta, sigma_max): """Generate the rotated 2nd degree Frame Order matrix for the isotropic cone. The cone axis is assumed to be parallel to the z-axis in the eigenframe. @param matrix: The Frame Order matrix, 2nd degree to be populated. @type matrix: numpy 9D, rank-2 array @param Rx2_eigen: The Kronecker product of the eigenframe rotation matrix with itself. @type Rx2_eigen: numpy 9D, rank-2 array @param cone_theta: The cone opening angle. @type cone_theta: float @param sigma_max: The maximum torsion angle. @type sigma_max: float """ # Zeros. matrix[:] = 0.0 # Repetitive trig calculations. sinc_smax = sinc(sigma_max/pi) sinc_2smax = sinc(2.0*sigma_max/pi) cos_tmax = cos(cone_theta) cos_tmax2 = cos_tmax**2 # Larger factors. fact_sinc_2smax = sinc_2smax*(cos_tmax2 + 4.0*cos_tmax + 7.0) / 24.0 fact_cos_tmax2 = (cos_tmax2 + cos_tmax + 4.0) / 12.0 fact_cos_tmax = (cos_tmax + 1.0) / 4.0 # Diagonal. matrix[0, 0] = fact_sinc_2smax + fact_cos_tmax2 matrix[1, 1] = fact_sinc_2smax + fact_cos_tmax matrix[2, 2] = sinc_smax * (2.0*cos_tmax2 + 5.0*cos_tmax + 5.0) / 12.0 matrix[3, 3] = matrix[1, 1] matrix[4, 4] = matrix[0, 0] matrix[5, 5] = matrix[2, 2] matrix[6, 6] = matrix[2, 2] matrix[7, 7] = matrix[2, 2] matrix[8, 8] = (cos_tmax2 + cos_tmax + 1.0) / 3.0 # Off diagonal set 1. matrix[0, 4] = matrix[4, 0] = -fact_sinc_2smax + fact_cos_tmax2 matrix[0, 8] = matrix[8, 0] = -(cos_tmax2 + cos_tmax - 2.0) / 6.0 matrix[4, 8] = matrix[8, 4] = matrix[0, 8] # Off diagonal set 2. matrix[1, 3] = matrix[3, 1] = fact_sinc_2smax - fact_cos_tmax matrix[2, 6] = matrix[6, 2] = sinc_smax * (cos_tmax2 + cos_tmax - 2.0) / 6.0 matrix[5, 7] = matrix[7, 5] = matrix[2, 6] # Rotate and return the frame order matrix. return rotate_daeg(matrix, Rx2_eigen)
def compile_1st_matrix_pseudo_ellipse(matrix, R_eigen, theta_x, theta_y, sigma_max): """Generate the 1st degree Frame Order matrix for the pseudo-ellipse. @param matrix: The Frame Order matrix, 1st degree to be populated. @type matrix: numpy 3D, rank-2 array @param R_eigen: The eigenframe rotation matrix. @type R_eigen: numpy 3D, rank-2 array @param theta_x: The cone opening angle along x. @type theta_x: float @param theta_y: The cone opening angle along y. @type theta_y: float @param sigma_max: The maximum torsion angle. @type sigma_max: float """ # The surface area normalisation factor. fact = 2.0 * pec(theta_x, theta_y) # Invert. if fact == 0.0: fact = 1e100 else: fact = 1.0 / fact # Sinc value. sinc_smax = sinc(sigma_max / pi) # Numerical integration of phi of each element. matrix[0, 0] = fact * sinc_smax * (2.0 * pi + quad(part_int_daeg1_pseudo_ellipse_00, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[1, 1] = fact * sinc_smax * (2.0 * pi + quad(part_int_daeg1_pseudo_ellipse_11, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[2, 2] = fact * quad(part_int_daeg1_pseudo_ellipse_22, -pi, pi, args=(theta_x, theta_y), full_output=1)[0] # Rotate and return the frame order matrix. return rotate_daeg(matrix, R_eigen)
def compile_2nd_matrix_pseudo_ellipse_free_rotor(matrix, Rx2_eigen, theta_x, theta_y): """Generate the 2nd degree Frame Order matrix for the free rotor pseudo-ellipse. @param matrix: The Frame Order matrix, 2nd degree to be populated. @type matrix: numpy 9D, rank-2 array @param Rx2_eigen: The Kronecker product of the eigenframe rotation matrix with itself. @type Rx2_eigen: numpy 9D, rank-2 array @param theta_x: The cone opening angle along x. @type theta_x: float @param theta_y: The cone opening angle along y. @type theta_y: float """ # The surface area normalisation factor. fact3 = 3.0 * pec(theta_x, theta_y) fact4 = 4.0 * pec(theta_x, theta_y) fact6 = 6.0 * pec(theta_x, theta_y) # Invert. if fact3 == 0.0: fact3 = 1e100 fact4 = 1e100 fact6 = 1e100 else: fact3 = 1.0 / fact3 fact4 = 1.0 / fact4 fact6 = 1.0 / fact6 # Diagonal. matrix[0, 0] = fact6 * (4.0*pi - quad(part_int_daeg2_pseudo_ellipse_free_rotor_00, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[1, 1] = matrix[3, 3] = fact4 * quad(part_int_daeg2_pseudo_ellipse_free_rotor_11, -pi, pi, args=(theta_x, theta_y), full_output=1)[0] matrix[4, 4] = fact6 * (4.0*pi - quad(part_int_daeg2_pseudo_ellipse_free_rotor_44, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[8, 8] = fact3 * (2.0*pi - quad(part_int_daeg2_pseudo_ellipse_free_rotor_88, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) # Off diagonal set 1. matrix[0, 4] = matrix[0, 0] matrix[4, 0] = matrix[4, 4] matrix[0, 8] = fact3 * (2.0*pi + quad(part_int_daeg2_pseudo_ellipse_free_rotor_08, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[8, 0] = fact6 * (4.0*pi + quad(part_int_daeg2_pseudo_ellipse_free_rotor_80, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[4, 8] = fact3 * (2.0*pi + quad(part_int_daeg2_pseudo_ellipse_free_rotor_48, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[8, 4] = matrix[8, 0] # Off diagonal set 2. matrix[1, 3] = matrix[3, 1] = -matrix[1, 1] # Rotate and return the frame order matrix. return rotate_daeg(matrix, Rx2_eigen)
def compile_2nd_matrix_iso_cone_torsionless(matrix, Rx2_eigen, cone_theta): """Generate the rotated 2nd degree Frame Order matrix for the torsionless isotropic cone. The cone axis is assumed to be parallel to the z-axis in the eigenframe. @param matrix: The Frame Order matrix, 2nd degree to be populated. @type matrix: numpy 9D, rank-2 array @param Rx2_eigen: The Kronecker product of the eigenframe rotation matrix with itself. @type Rx2_eigen: numpy 9D, rank-2 array @param cone_theta: The cone opening angle. @type cone_theta: float """ # Zeros. for i in range(9): for j in range(9): matrix[i, j] = 0.0 # Repetitive trig calculations. cos_tmax = cos(cone_theta) cos_tmax2 = cos_tmax**2 # Diagonal. matrix[0, 0] = (3.0*cos_tmax2 + 6.0*cos_tmax + 15.0) / 24.0 matrix[1, 1] = (cos_tmax2 + 10.0*cos_tmax + 13.0) / 24.0 matrix[2, 2] = (4.0*cos_tmax2 + 10.0*cos_tmax + 10.0) / 24.0 matrix[3, 3] = matrix[1, 1] matrix[4, 4] = matrix[0, 0] matrix[5, 5] = matrix[2, 2] matrix[6, 6] = matrix[2, 2] matrix[7, 7] = matrix[2, 2] matrix[8, 8] = (cos_tmax2 + cos_tmax + 1.0) / 3.0 # Off diagonal set 1. matrix[0, 4] = matrix[4, 0] = (cos_tmax2 - 2.0*cos_tmax + 1.0) / 24.0 matrix[0, 8] = matrix[8, 0] = -(cos_tmax2 + cos_tmax - 2.0) / 6.0 matrix[4, 8] = matrix[8, 4] = matrix[0, 8] # Off diagonal set 2. matrix[1, 3] = matrix[3, 1] = matrix[0, 4] matrix[2, 6] = matrix[6, 2] = -matrix[0, 8] matrix[5, 7] = matrix[7, 5] = -matrix[0, 8] # Rotate and return the frame order matrix. return rotate_daeg(matrix, Rx2_eigen)
def compile_1st_matrix_free_rotor(matrix, R_eigen): """Generate the 1st degree Frame Order matrix for the free rotor model. @param matrix: The Frame Order matrix, 1st degree to be populated. @type matrix: numpy 3D, rank-2 array @param R_eigen: The eigenframe rotation matrix. @type R_eigen: numpy 3D, rank-2 array """ # Zeros. matrix[:] = 0.0 # The single value. matrix[2, 2] = 1.0 # Rotate and return the frame order matrix. return rotate_daeg(matrix, R_eigen)
def compile_2nd_matrix_iso_cone_torsionless(matrix, Rx2_eigen, cone_theta): """Generate the rotated 2nd degree Frame Order matrix for the torsionless isotropic cone. The cone axis is assumed to be parallel to the z-axis in the eigenframe. @param matrix: The Frame Order matrix, 2nd degree to be populated. @type matrix: numpy 9D, rank-2 array @param Rx2_eigen: The Kronecker product of the eigenframe rotation matrix with itself. @type Rx2_eigen: numpy 9D, rank-2 array @param cone_theta: The cone opening angle. @type cone_theta: float """ # Zeros. matrix[:] = 0.0 # Repetitive trig calculations. cos_tmax = cos(cone_theta) cos_tmax2 = cos_tmax**2 # Diagonal. matrix[0, 0] = (3.0 * cos_tmax2 + 6.0 * cos_tmax + 15.0) / 24.0 matrix[1, 1] = (cos_tmax2 + 10.0 * cos_tmax + 13.0) / 24.0 matrix[2, 2] = (4.0 * cos_tmax2 + 10.0 * cos_tmax + 10.0) / 24.0 matrix[3, 3] = matrix[1, 1] matrix[4, 4] = matrix[0, 0] matrix[5, 5] = matrix[2, 2] matrix[6, 6] = matrix[2, 2] matrix[7, 7] = matrix[2, 2] matrix[8, 8] = (cos_tmax2 + cos_tmax + 1.0) / 3.0 # Off diagonal set 1. matrix[0, 4] = matrix[4, 0] = (cos_tmax2 - 2.0 * cos_tmax + 1.0) / 24.0 matrix[0, 8] = matrix[8, 0] = -(cos_tmax2 + cos_tmax - 2.0) / 6.0 matrix[4, 8] = matrix[8, 4] = matrix[0, 8] # Off diagonal set 2. matrix[1, 3] = matrix[3, 1] = matrix[0, 4] matrix[2, 6] = matrix[6, 2] = -matrix[0, 8] matrix[5, 7] = matrix[7, 5] = -matrix[0, 8] # Rotate and return the frame order matrix. return rotate_daeg(matrix, Rx2_eigen)
def compile_1st_matrix_iso_cone_free_rotor(matrix, R_eigen, tmax): """Generate the 1st degree Frame Order matrix for the free rotor isotropic cone. @param matrix: The Frame Order matrix, 1st degree to be populated. @type matrix: numpy 3D, rank-2 array @param R_eigen: The eigenframe rotation matrix. @type R_eigen: numpy 3D, rank-2 array @param tmax: The cone opening angle. @type tmax: float """ # Zeros. matrix[:] = 0.0 # Diagonal values. matrix[2, 2] = cos(tmax) + 1.0 # Rotate and return the frame order matrix. return 0.5 * rotate_daeg(matrix, R_eigen)
def compile_2nd_matrix_rotor(matrix, Rx2_eigen, smax): """Generate the rotated 2nd degree Frame Order matrix for the rotor model. The cone axis is assumed to be parallel to the z-axis in the eigenframe. @param matrix: The Frame Order matrix, 2nd degree to be populated. @type matrix: numpy 9D, rank-2 array @param Rx2_eigen: The Kronecker product of the eigenframe rotation matrix with itself. @type Rx2_eigen: numpy 9D, rank-2 array @param smax: The maximum torsion angle. @type smax: float """ # Zeros. for i in range(9): for j in range(9): matrix[i, j] = 0.0 # Repetitive trig calculations. sinc_smax = sinc(smax/pi) sinc_2smax = sinc(2.0*smax/pi) # Diagonal. matrix[0, 0] = (sinc_2smax + 1.0) / 2.0 matrix[1, 1] = matrix[0, 0] matrix[2, 2] = sinc_smax matrix[3, 3] = matrix[0, 0] matrix[4, 4] = matrix[0, 0] matrix[5, 5] = matrix[2, 2] matrix[6, 6] = matrix[2, 2] matrix[7, 7] = matrix[2, 2] matrix[8, 8] = 1.0 # Off diagonal set 1. matrix[0, 4] = matrix[4, 0] = -(sinc_2smax - 1.0) / 2.0 # Off diagonal set 2. matrix[1, 3] = matrix[3, 1] = -matrix[0, 4] # Rotate and return the frame order matrix. return rotate_daeg(matrix, Rx2_eigen)
def compile_2nd_matrix_iso_cone(matrix, Rx2_eigen, cone_theta, sigma_max): """Generate the rotated 2nd degree Frame Order matrix for the isotropic cone. The cone axis is assumed to be parallel to the z-axis in the eigenframe. @param matrix: The Frame Order matrix, 2nd degree to be populated. @type matrix: numpy 9D, rank-2 array @param Rx2_eigen: The Kronecker product of the eigenframe rotation matrix with itself. @type Rx2_eigen: numpy 9D, rank-2 array @param cone_theta: The cone opening angle. @type cone_theta: float @param sigma_max: The maximum torsion angle. @type sigma_max: float """ # Populate the Frame Order matrix in the eigenframe. populate_2nd_eigenframe_iso_cone(matrix, cone_theta, sigma_max) # Rotate and return the frame order matrix. return rotate_daeg(matrix, Rx2_eigen)
def compile_2nd_matrix_rotor(matrix, Rx2_eigen, smax): """Generate the rotated 2nd degree Frame Order matrix for the rotor model. The cone axis is assumed to be parallel to the z-axis in the eigenframe. @param matrix: The Frame Order matrix, 2nd degree to be populated. @type matrix: numpy 9D, rank-2 array @param Rx2_eigen: The Kronecker product of the eigenframe rotation matrix with itself. @type Rx2_eigen: numpy 9D, rank-2 array @param smax: The maximum torsion angle. @type smax: float """ # Zeros. matrix[:] = 0.0 # Repetitive trig calculations. sinc_smax = sinc(smax / pi) sinc_2smax = sinc(2.0 * smax / pi) # Diagonal. matrix[0, 0] = (sinc_2smax + 1.0) / 2.0 matrix[1, 1] = matrix[0, 0] matrix[2, 2] = sinc_smax matrix[3, 3] = matrix[0, 0] matrix[4, 4] = matrix[0, 0] matrix[5, 5] = matrix[2, 2] matrix[6, 6] = matrix[2, 2] matrix[7, 7] = matrix[2, 2] matrix[8, 8] = 1.0 # Off diagonal set 1. matrix[0, 4] = matrix[4, 0] = -(sinc_2smax - 1.0) / 2.0 # Off diagonal set 2. matrix[1, 3] = matrix[3, 1] = -matrix[0, 4] # Rotate and return the frame order matrix. return rotate_daeg(matrix, Rx2_eigen)
def compile_2nd_matrix_iso_cone_free_rotor(matrix, Rx2_eigen, s1): """Generate the rotated 2nd degree Frame Order matrix for the free rotor isotropic cone. The cone axis is assumed to be parallel to the z-axis in the eigenframe. In this model, the three order parameters are defined as:: S1 = S2, S3 = 0 @param matrix: The Frame Order matrix, 2nd degree to be populated. @type matrix: numpy 9D, rank-2 array @param Rx2_eigen: The Kronecker product of the eigenframe rotation matrix with itself. @type Rx2_eigen: numpy 9D, rank-2 array @param s1: The cone order parameter. @type s1: float """ # Populate the Frame Order matrix in the eigenframe. populate_2nd_eigenframe_iso_cone_free_rotor(matrix, s1) # Rotate and return the frame order matrix. return rotate_daeg(matrix, Rx2_eigen)
def compile_1st_matrix_rotor(matrix, R_eigen, sigma_max): """Generate the 1st degree Frame Order matrix for the rotor model. @param matrix: The Frame Order matrix, 1st degree to be populated. @type matrix: numpy 3D, rank-2 array @param R_eigen: The eigenframe rotation matrix. @type R_eigen: numpy 3D, rank-2 array @param sigma_max: The maximum torsion angle. @type sigma_max: float """ # Zeros. matrix[:] = 0.0 # The sinc value. val = sinc(sigma_max / pi) # Diagonal values. matrix[0, 0] = val matrix[1, 1] = val matrix[2, 2] = 1.0 # Rotate and return the frame order matrix. return rotate_daeg(matrix, R_eigen)
def compile_1st_matrix_double_rotor(matrix, R_eigen, smax1, smax2): """Generate the 1st degree Frame Order matrix for the double rotor model. @param matrix: The Frame Order matrix, 1st degree to be populated. @type matrix: numpy 3D, rank-2 array @param R_eigen: The eigenframe rotation matrix. @type R_eigen: numpy 3D, rank-2 array @param smax1: The maximum torsion angle for the first rotor. @type smax1: float @param smax2: The maximum torsion angle for the second rotor. @type smax2: float """ # Repetitive trig calculations. sinc_smax1 = sinc(smax1 / pi) sinc_smax2 = sinc(smax2 / pi) # Numerical integration of phi of each element. matrix[0, 0] = sinc_smax1 matrix[1, 1] = sinc_smax2 matrix[2, 2] = sinc_smax1 * sinc_smax2 # Rotate and return the frame order matrix. return rotate_daeg(matrix, R_eigen)
def compile_2nd_matrix_iso_cone_free_rotor(matrix, Rx2_eigen, tmax): """Generate the rotated 2nd degree Frame Order matrix for the free rotor isotropic cone. The cone axis is assumed to be parallel to the z-axis in the eigenframe. @param matrix: The Frame Order matrix, 2nd degree to be populated. @type matrix: numpy 9D, rank-2 array @param Rx2_eigen: The Kronecker product of the eigenframe rotation matrix with itself. @type Rx2_eigen: numpy 9D, rank-2 array @param tmax: The cone opening angle. @type tmax: float """ # Zeros. matrix[:] = 0.0 # Repetitive trig calculations. cos_tmax = cos(tmax) cos_tmax2 = cos_tmax**2 # Diagonal. matrix[0, 0] = matrix[4, 4] = (cos_tmax2 + cos_tmax + 4.0) / 12.0 matrix[1, 1] = matrix[3, 3] = (cos_tmax + 1.0) / 4.0 matrix[8, 8] = (cos_tmax2 + cos_tmax + 1.0) / 3.0 # Off diagonal set 1. matrix[0, 4] = matrix[4, 0] = matrix[0, 0] matrix[0, 8] = matrix[8, 0] = -(cos_tmax2 + cos_tmax - 2.0) / 6.0 matrix[4, 8] = matrix[8, 4] = matrix[0, 8] # Off diagonal set 2. matrix[1, 3] = matrix[3, 1] = -matrix[1, 1] # Rotate and return the frame order matrix. return rotate_daeg(matrix, Rx2_eigen)
def compile_1st_matrix_rotor(matrix, R_eigen, sigma_max): """Generate the 1st degree Frame Order matrix for the rotor model. @param matrix: The Frame Order matrix, 1st degree to be populated. @type matrix: numpy 3D, rank-2 array @param R_eigen: The eigenframe rotation matrix. @type R_eigen: numpy 3D, rank-2 array @param sigma_max: The maximum torsion angle. @type sigma_max: float """ # Zeros. matrix[:] = 0.0 # The sinc value. val = sinc(sigma_max/pi) # Diagonal values. matrix[0, 0] = val matrix[1, 1] = val matrix[2, 2] = 1.0 # Rotate and return the frame order matrix. return rotate_daeg(matrix, R_eigen)
def compile_1st_matrix_double_rotor(matrix, R_eigen, smax1, smax2): """Generate the 1st degree Frame Order matrix for the double rotor model. @param matrix: The Frame Order matrix, 1st degree to be populated. @type matrix: numpy 3D, rank-2 array @param R_eigen: The eigenframe rotation matrix. @type R_eigen: numpy 3D, rank-2 array @param smax1: The maximum torsion angle for the first rotor. @type smax1: float @param smax2: The maximum torsion angle for the second rotor. @type smax2: float """ # Repetitive trig calculations. sinc_smax1 = sinc(smax1/pi) sinc_smax2 = sinc(smax2/pi) # Numerical integration of phi of each element. matrix[0, 0] = sinc_smax1 matrix[1, 1] = sinc_smax2 matrix[2, 2] = sinc_smax1 * sinc_smax2 # Rotate and return the frame order matrix. return rotate_daeg(matrix, R_eigen)
def compile_2nd_matrix_pseudo_ellipse_torsionless(matrix, Rx2_eigen, theta_x, theta_y): """Generate the 2nd degree Frame Order matrix for the torsionless pseudo-ellipse. @param matrix: The Frame Order matrix, 2nd degree to be populated. @type matrix: numpy 9D, rank-2 array @param Rx2_eigen: The Kronecker product of the eigenframe rotation matrix with itself. @type Rx2_eigen: numpy 9D, rank-2 array @param theta_x: The cone opening angle along x. @type theta_x: float @param theta_y: The cone opening angle along y. @type theta_y: float """ # The rigid case. if theta_x == 0.0: # Set up the matrix as the identity. matrix[:] = 0.0 for i in range(len(matrix)): matrix[i, i] = 1.0 # Rotate and return the frame order matrix. return rotate_daeg(matrix, Rx2_eigen) # The surface area normalisation factor. fact = 6.0 * pec(theta_x, theta_y) fact2 = 0.5 * fact # Invert. if fact == 0.0: fact = 1e100 fact2 = 1e100 else: fact = 1.0 / fact fact2 = 1.0 / fact2 # Diagonal. matrix[0, 0] = fact2 * (3.0 * pi + quad(part_int_daeg2_pseudo_ellipse_torsionless_00, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[1, 1] = fact * (2.0 * pi + quad(part_int_daeg2_pseudo_ellipse_torsionless_11, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[2, 2] = fact * (5.0 * pi - quad(part_int_daeg2_pseudo_ellipse_torsionless_22, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[3, 3] = matrix[1, 1] matrix[4, 4] = fact2 * (3.0 * pi + quad(part_int_daeg2_pseudo_ellipse_torsionless_44, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[5, 5] = fact * (5.0 * pi - quad(part_int_daeg2_pseudo_ellipse_torsionless_55, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[6, 6] = matrix[2, 2] matrix[7, 7] = matrix[5, 5] matrix[8, 8] = fact2 * (2.0 * pi - quad(part_int_daeg2_pseudo_ellipse_torsionless_88, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) # Off diagonal set 1. matrix[0, 4] = matrix[ 4, 0] = fact2 * (pi + quad(part_int_daeg2_pseudo_ellipse_torsionless_04, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[0, 8] = matrix[8, 0] = fact2 * ( 2.0 * pi + quad(part_int_daeg2_pseudo_ellipse_torsionless_08, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[4, 8] = matrix[8, 4] = fact2 * ( 2.0 * pi + quad(part_int_daeg2_pseudo_ellipse_torsionless_48, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) # Off diagonal set 2. matrix[1, 3] = matrix[3, 1] = matrix[0, 4] matrix[2, 6] = matrix[6, 2] = -matrix[0, 8] matrix[5, 7] = matrix[7, 5] = -matrix[4, 8] # Rotate and return the frame order matrix. return rotate_daeg(matrix, Rx2_eigen)
def compile_2nd_matrix_pseudo_ellipse(matrix, Rx2_eigen, theta_x, theta_y, sigma_max): """Generate the 2nd degree Frame Order matrix for the pseudo-ellipse. @param matrix: The Frame Order matrix, 2nd degree to be populated. @type matrix: numpy 9D, rank-2 array @param Rx2_eigen: The Kronecker product of the eigenframe rotation matrix with itself. @type Rx2_eigen: numpy 9D, rank-2 array @param theta_x: The cone opening angle along x. @type theta_x: float @param theta_y: The cone opening angle along y. @type theta_y: float @param sigma_max: The maximum torsion angle. @type sigma_max: float """ # The rigid case. if theta_x == 0.0 and sigma_max == 0.0: # Set up the matrix as the identity. matrix[:] = 0.0 for i in range(len(matrix)): matrix[i, i] = 1.0 # Rotate and return the frame order matrix. return rotate_daeg(matrix, Rx2_eigen) # The surface area normalisation factor. fact = 12.0 * pec(theta_x, theta_y) # Invert. if fact == 0.0: fact = 1e100 else: fact = 1.0 / fact # Repetitive calculations. sinc_smax = sinc(sigma_max / pi) sinc_2smax = sinc(2.0 * sigma_max / pi) # Diagonal. matrix[0, 0] = fact * (4.0 * pi * (sinc_2smax + 2.0) + quad(part_int_daeg2_pseudo_ellipse_00, -pi, pi, args=(theta_x, theta_y, sinc_2smax), full_output=1)[0]) matrix[1, 1] = fact * (4.0 * pi * sinc_2smax + quad(part_int_daeg2_pseudo_ellipse_11, -pi, pi, args=(theta_x, theta_y, sinc_2smax), full_output=1)[0]) matrix[2, 2] = fact * 2.0 * sinc_smax * ( 5.0 * pi - quad(part_int_daeg2_pseudo_ellipse_22, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[3, 3] = matrix[1, 1] matrix[4, 4] = fact * (4.0 * pi * (sinc_2smax + 2.0) + quad(part_int_daeg2_pseudo_ellipse_44, -pi, pi, args=(theta_x, theta_y, sinc_2smax), full_output=1)[0]) matrix[5, 5] = fact * 2.0 * sinc_smax * ( 5.0 * pi - quad(part_int_daeg2_pseudo_ellipse_55, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[6, 6] = matrix[2, 2] matrix[7, 7] = matrix[5, 5] matrix[8, 8] = 4.0 * fact * (2.0 * pi - quad(part_int_daeg2_pseudo_ellipse_88, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) # Off diagonal set 1. matrix[0, 4] = fact * (4.0 * pi * (2.0 - sinc_2smax) + quad(part_int_daeg2_pseudo_ellipse_04, -pi, pi, args=(theta_x, theta_y, sinc_2smax), full_output=1)[0]) matrix[4, 0] = fact * (4.0 * pi * (2.0 - sinc_2smax) + quad(part_int_daeg2_pseudo_ellipse_40, -pi, pi, args=(theta_x, theta_y, sinc_2smax), full_output=1)[0]) matrix[0, 8] = 4.0 * fact * (2.0 * pi - quad(part_int_daeg2_pseudo_ellipse_08, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[8, 0] = fact * (8.0 * pi + quad(part_int_daeg2_pseudo_ellipse_80, -pi, pi, args=(theta_x, theta_y, sinc_2smax), full_output=1)[0]) matrix[4, 8] = 4.0 * fact * (2.0 * pi - quad(part_int_daeg2_pseudo_ellipse_48, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[8, 4] = fact * (8.0 * pi - quad(part_int_daeg2_pseudo_ellipse_84, -pi, pi, args=(theta_x, theta_y, sinc_2smax), full_output=1)[0]) # Off diagonal set 2. matrix[1, 3] = matrix[3, 1] = fact * (4.0 * pi * sinc_2smax + quad(part_int_daeg2_pseudo_ellipse_13, -pi, pi, args=(theta_x, theta_y, sinc_2smax), full_output=1)[0]) matrix[2, 6] = matrix[6, 2] = -fact * 4.0 * sinc_smax * ( 2.0 * pi + quad(part_int_daeg2_pseudo_ellipse_26, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) matrix[5, 7] = matrix[7, 5] = -fact * 4.0 * sinc_smax * ( 2.0 * pi + quad(part_int_daeg2_pseudo_ellipse_57, -pi, pi, args=(theta_x, theta_y), full_output=1)[0]) # Rotate and return the frame order matrix. return rotate_daeg(matrix, Rx2_eigen)