|
9 | 9 |
|
10 | 10 |
|
11 | 11 | def solve_for_calibration_parameters(Io, Is):
|
| 12 | + """ |
| 13 | + Solves for the calibration parameters given the reference |
| 14 | + measurements. |
| 15 | +
|
| 16 | + See https://doi.org/10.1016/S0921-4526(00)00823-1. |
| 17 | + """ |
12 | 18 | Iopp, Iopa, Ioap, Ioaa = Io
|
13 | 19 | Ipp, Ipa, Iap, Iaa = Is
|
14 | 20 |
|
@@ -53,51 +59,11 @@ def solve_for_calibration_parameters(Io, Is):
|
53 | 59 | return I0 / 4, Pp, Pa, Ap, Aa, Rspp, Rsaa
|
54 | 60 |
|
55 | 61 |
|
56 |
| -def generate_valid_calibration_parameters(): |
57 |
| - I0 = np.random.random() |
58 |
| - Pp = np.random.random() |
59 |
| - Pa = -np.random.random() |
60 |
| - Ap = np.random.random() |
61 |
| - Aa = -np.random.random() |
62 |
| - Rspp = np.random.random() |
63 |
| - Rsaa = Rspp * np.random.random() |
64 |
| - return tuple(map(sc.scalar, (I0, Pp, Pa, Ap, Aa, Rspp, Rsaa))) |
65 |
| - |
66 |
| - |
67 |
| -def intensity_from_parameters(I0, Pp, Pa, Ap, Aa, Rpp, Rpa, Rap, Raa): |
68 |
| - return ( |
69 |
| - I0 |
70 |
| - * ( |
71 |
| - Rpp * (1 + Ap) * (1 + Pp) |
72 |
| - + Rpa * (1 - Ap) * (1 + Pp) |
73 |
| - + Rap * (1 + Ap) * (1 - Pp) |
74 |
| - + Raa * (1 - Ap) * (1 - Pp) |
75 |
| - ), |
76 |
| - I0 |
77 |
| - * ( |
78 |
| - Rpp * (1 + Aa) * (1 + Pp) |
79 |
| - + Rpa * (1 - Aa) * (1 + Pp) |
80 |
| - + Rap * (1 + Aa) * (1 - Pp) |
81 |
| - + Raa * (1 - Aa) * (1 - Pp) |
82 |
| - ), |
83 |
| - I0 |
84 |
| - * ( |
85 |
| - Rpp * (1 + Ap) * (1 + Pa) |
86 |
| - + Rpa * (1 - Ap) * (1 + Pa) |
87 |
| - + Rap * (1 + Ap) * (1 - Pa) |
88 |
| - + Raa * (1 - Ap) * (1 - Pa) |
89 |
| - ), |
90 |
| - I0 |
91 |
| - * ( |
92 |
| - Rpp * (1 + Aa) * (1 + Pa) |
93 |
| - + Rpa * (1 - Aa) * (1 + Pa) |
94 |
| - + Rap * (1 + Aa) * (1 - Pa) |
95 |
| - + Raa * (1 - Aa) * (1 - Pa) |
96 |
| - ), |
97 |
| - ) |
98 |
| - |
99 |
| - |
100 | 62 | def correction_matrix(Pp, Pa, Ap, Aa):
|
| 63 | + """ |
| 64 | + Defines the linear relationship between measured intensity |
| 65 | + and reflectivity. |
| 66 | + """ |
101 | 67 | return [
|
102 | 68 | [
|
103 | 69 | (1 + Pp) * (1 + Ap),
|
@@ -126,48 +92,68 @@ def correction_matrix(Pp, Pa, Ap, Aa):
|
126 | 92 | ]
|
127 | 93 |
|
128 | 94 |
|
129 |
| -def compute_calibration_factors(Io, Is): |
| 95 | +def calibration_factors_from_reference_measurements(Io, Is): |
| 96 | + """ |
| 97 | + Computes the polarization instrument parameters from |
| 98 | + the calibration measurements on the non-magnetic reference |
| 99 | + and the calibration measurements on the magnetic reference. |
| 100 | + """ |
130 | 101 | I0, Pp, Pa, Ap, Aa, _, _ = solve_for_calibration_parameters(Io, Is)
|
131 | 102 | return I0, correction_matrix(Pp, Pa, Ap, Aa)
|
132 | 103 |
|
133 | 104 |
|
| 105 | +def _linsolve(A, b): |
| 106 | + x = np.linalg.solve( |
| 107 | + np.stack([np.stack(row, -1) for row in A], -2), |
| 108 | + np.stack(b, -1)[..., None], |
| 109 | + )[..., 0] |
| 110 | + return np.moveaxis(x, -1, 0) |
| 111 | + |
| 112 | + |
134 | 113 | def linsolve(A, b):
|
135 |
| - return np.linalg.solve( |
136 |
| - np.stack([[a.values for a in row] for row in A]), |
137 |
| - np.stack([bi.values for bi in b], axis=-1), |
| 114 | + x = _linsolve( |
| 115 | + [[a.values for a in row] for row in A], |
| 116 | + [bi.values for bi in b], |
138 | 117 | )
|
| 118 | + return [sc.array(dims=b[0].dims, values=xi) for xi in x] |
139 | 119 |
|
140 | 120 |
|
141 |
| -def computer_reflectivity_calibrate_on_q( |
| 121 | +def compute_reflectivity_calibrate_on_q( |
142 | 122 | reference_supermirror,
|
143 | 123 | reference_polarized_supermirror,
|
144 | 124 | sample,
|
145 | 125 | qbins,
|
146 | 126 | ):
|
| 127 | + """Reduces reference and sample to Q before applying |
| 128 | + the polarization correction and normalization.""" |
147 | 129 | reference_supermirror = [
|
148 | 130 | reduce_from_lz_to_q(i, qbins) for i in reference_supermirror
|
149 | 131 | ]
|
150 | 132 | reference_polarized_supermirror = [
|
151 | 133 | reduce_from_lz_to_q(i, qbins) for i in reference_polarized_supermirror
|
152 | 134 | ]
|
153 |
| - sample = [reduce_from_events_to_q(i, qbins) for i in sample] |
154 |
| - I0, C = compute_calibration_factors( |
| 135 | + I0, C = calibration_factors_from_reference_measurements( |
155 | 136 | reference_supermirror, reference_polarized_supermirror
|
156 | 137 | )
|
157 |
| - return [i / I0 for i in linsolve(C, sample)] |
| 138 | + sample = [reduce_from_events_to_q(i, qbins) for i in sample] |
| 139 | + sample = linsolve(C, sample) |
| 140 | + return [i / I0 for i in sample] |
158 | 141 |
|
159 | 142 |
|
160 |
| -def computer_reflectivity_calibrate_on_lz( |
| 143 | +def compute_reflectivity_calibrate_on_lz( |
161 | 144 | reference_supermirror,
|
162 | 145 | reference_polarized_supermirror,
|
163 | 146 | sample,
|
164 | 147 | wbins,
|
165 | 148 | qbins,
|
166 | 149 | ):
|
167 |
| - sample = reduce_from_events_to_lz(sample, wbins) |
168 |
| - I0, C = compute_calibration_factors( |
| 150 | + """Applied the polarization correction on the wavelength-z grid |
| 151 | + then reduces to Q to apply the normalization.""" |
| 152 | + sample = [reduce_from_events_to_lz(s, wbins) for s in sample] |
| 153 | + I0, C = calibration_factors_from_reference_measurements( |
169 | 154 | reference_supermirror, reference_polarized_supermirror
|
170 | 155 | )
|
171 | 156 | sample = linsolve(C, sample)
|
| 157 | + sample = [reduce_from_lz_to_q(s, qbins) for s in sample] |
172 | 158 | I0 = reduce_from_lz_to_q(I0, qbins)
|
173 |
| - return [i / I0 for i in reduce_from_lz_to_q(sample, qbins)] |
| 159 | + return [i / I0 for i in sample] |
0 commit comments