Coverage for src/susi/model/susi_mm_sunrise_telescope.py: 22%
60 statements
« prev ^ index » next coverage.py v7.5.0, created at 2025-06-13 14:15 +0000
« prev ^ index » next coverage.py v7.5.0, created at 2025-06-13 14:15 +0000
1# -*- coding: utf-8 -*-
2import sys
3import logging
4from os import path
5import numpy as np
6from .susi_mm import susi_mmirr
8__author__ = "Francisco Iglesias and Alex Feller"
9__copyright__ = "Copyright 2020, Max Planck Institute for Solar System Research"
10__version__ = "0.01"
11__maintainer__ = "Francisco Iglesias"
12__email__ = "franciscoaiglesias@gmail.com"
15def get_mirror_par(name, wl):
16 """
17 Return the specified mirror properties for the desired wavelength.
18 """
19 # ; n, k refractive index
20 # ; psi, delta ellipsometric parameters [deg]
21 # ; rp, rs intensity reflectivities
22 # ; name Name of the component (used for e.g. results reports)
23 # ; p1, p2 Optical properties
24 # ; In refractive-index mode (ellips = 0, see below) p1 and p2
25 # ; represent the components n - i*k of the complex refractive index
26 # ; In ellipsometric mode (ellips = 1, see below) p1 and p2
27 # ; represent the ellipsometric parameters psi and delta [deg]
28 # ; AOI Angle of incidence [deg]
29 # ; AOR Angle of rotation [deg]; for mirrors
30 # ; For a mirror, this denotes the angle between Stokes +Q and the
31 # ; plane of incidence. For Stokes +Q perpendicular to the plane of
32 # ; incidence, AOR = 0 deg.
33 # ; For a waveplate, AOR = 0 deg means that the optical axes are aligned
34 # ; with the Stokes +Q direction.
35 # ; For a polarizer, AOR = 0 deg means that the transmission axis is aligned
36 # ; with Stokes +Q.
38 # Mirror properties at 314 nm ??
39 # Mirror parameters for diff angles of incidence (AOI). Used in various modules below
40 # AOI = 45 deg
41 rp45 = 0.8766
42 rs45 = 0.9274
43 delta45 = 146.86 # original in Alex's model is 146.86
44 psi45 = np.arctan(np.sqrt(rp45 / rs45)) * 180.0 / np.pi
45 # AOI = 0 deg
46 rp0 = 0.8985
47 rs0 = rp0
48 delta0 = 180.0
49 psi0 = 45.0
50 # Values for unity Mueller matrix (mirror not active)
51 rpu = 1.0
52 rsu = 1.0
53 deltau = 180.0
54 psiu = 45.0
56 if name == 'M1':
57 return {'p1': psi0, 'p2': delta0, 'rp': rp0, 'rs': rs0, 'ellips': 1, 'AOI': 0.0, 'AOR': 0.0}
58 elif name == 'M2':
59 return {'p1': psi0, 'p2': delta0, 'rp': rp0, 'rs': rs0, 'ellips': 1, 'AOI': 0.0, 'AOR': 0.0}
60 elif name == 'M3':
61 return {'p1': psi45, 'p2': delta45, 'rp': rp45, 'rs': rs45, 'ellips': 1, 'AOI': 45.0, 'AOR': 90.0}
62 elif name == 'M4':
63 return {'p1': psi45, 'p2': delta45, 'rp': rp45, 'rs': rs45, 'ellips': 1, 'AOI': 45.0, 'AOR': 90.0}
64 else:
65 logging.error(f'Mirror name {name} not found')
66 return None
69def telescope_mm(wl, norm=True, f1=False, m1_only=False):
70 """ "
71 Returns a scalar Mueller matrix of Sunrise III telescope_mm for the desired wavelength.
72 This includes M1,M2,M3 and M4 mirrors.
73 norm: If True, the Mueller matrix is normalized to element 0,0
74 f1: If True, then the matrix from focus F1 is returned (M1 is not included)
75 """
76 # Mirrors constants. Taken from external_libs/idl_susi_1D_pol_model/config_igl.pro
78 # M1
79 par = get_mirror_par('M1', wl)
80 mm_telescope = susi_mmirr(
81 par['p1'], par['p2'], par['AOI'], par['AOR'], np.mean([par['rp'], par['rs']]), par['ellips']
82 )
83 if not m1_only:
84 # M2
85 par = get_mirror_par('M2', wl)
86 mm_mirror = susi_mmirr(
87 par['p1'], par['p2'], par['AOI'], par['AOR'], np.mean([par['rp'], par['rs']]), par['ellips']
88 )
89 if f1:
90 mm_telescope = mm_mirror
91 else:
92 mm_telescope = np.matmul(mm_mirror, mm_telescope)
93 # M3
94 par = get_mirror_par('M3', wl)
95 mm_mirror = susi_mmirr(
96 par['p1'], par['p2'], par['AOI'], par['AOR'], np.mean([par['rp'], par['rs']]), par['ellips']
97 )
98 mm_telescope = np.matmul(mm_mirror, mm_telescope)
99 # M4
100 par = get_mirror_par('M4', wl)
101 mm_mirror = susi_mmirr(
102 par['p1'], par['p2'], par['AOI'], par['AOR'], np.mean([par['rp'], par['rs']]), par['ellips']
103 )
104 mm_telescope = np.matmul(mm_mirror, mm_telescope)
106 if norm:
107 return mm_telescope / mm_telescope[0, 0]
108 else:
109 return mm_telescope
112if __name__ == '__main__':
113 sys.path.append(path.dirname(path.dirname(path.abspath(__file__))))
114 wl = 314.0 # nm
115 mm = np.array2string(telescope_mm(wl, f1=True), precision=6, suppress_small=True, separator=',')
116 print(f'Mueller matrix for Sunrise III F1 at {wl} nm:\n{mm}')
117 mm = np.array2string(telescope_mm(wl), precision=6, suppress_small=True, separator=',')
118 print(f'Mueller matrix for Sunrise III Telescope at {wl} nm:\n{mm}')
119 mm = np.array2string(telescope_mm(wl, m1_only=True), precision=6, suppress_small=True, separator=',')
120 print(f'Mueller matrix for Sunrise III M1 at {wl} nm:\n{mm}')