lidar_correction_ghk.py

changeset 40
676673dd931d
parent 37
9d15b4fca316
child 41
0f37e20f12c5
equal deleted inserted replaced
37:9d15b4fca316 40:676673dd931d
1 # -*- coding: utf-8 -*-
2 """
3 Copyright 2016, 2019 Volker Freudenthaler
4
5 Licensed under the EUPL, Version 1.1 only (the "Licence").
6
7 You may not use this work except in compliance with the Licence.
8 A copy of the licence is distributed with the code. Alternatively, you may obtain
9 a copy of the Licence at:
10
11 https://joinup.ec.europa.eu/community/eupl/og_page/eupl
12
13 Unless required by applicable law or agreed to in writing, software distributed
14 under the Licence is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS
15 OF ANY KIND, either express or implied. See the Licence for the specific language governing
16 permissions and limitations under the Licence.
17
18 Equation reference: http://www.atmos-meas-tech-discuss.net/amt-2015-338/amt-2015-338.pdf
19 With equations code from Appendix C
20 Python 3.7, seaborn 0.9.0
21
22 Code description:
23
24 From measured lidar signals we cannot directly determine the desired backscatter coefficient (F11) and the linear depolarization ratio (LDR)
25 because of the cross talk between the channles and systematic errors of a lidar system.
26 http://www.atmos-meas-tech-discuss.net/amt-2015-338/amt-2015-338.pdf provides an analytical model for the description of these errors,
27 with which the measured signals can be corrected.
28 This code simulates the lidar measurements with "assumed true" model parameters from an input file, and calculates the correction parameters (G,H, and K).
29 The "assumed true" system parameters are the ones we think are the right ones, but in reality these parameters probably deviate from the assumed truth due to
30 uncertainties. The uncertainties of the "assumed true" parameters can be described in the input file. Then this code calculates the lidar signals and the
31 gain ratio eta* with all possible combinations of "errors", which represents the distribution of "possibly real" signals, and "corrects" them with the "assumed true"
32 GHK parameters (GT0, GR0, HT0, HR0, and K0) to derive finally the distributions of "possibly real" linear depolarization ratios (LDRcorr),
33 which are plotted for five different input linear depolarization ratios (LDRtrue). The red bars in the plots represent the input values of LDRtrue.
34 A complication arises from the fact that the correction parameter K = eta*/eta (Eq. 83) can depend on the LDR during the calibration measurement, i.e. LDRcal or aCal
35 in the code (see e.g. Eqs. (103), (115), and (141); mind the mistake in Eq. (116)). Therefor values of K for LDRcal = 0.004, 0.2, and 0.45 are calculated for
36 "assumed true" system parameters and printed in the output file behind the GH parameters. The full impact of the LDRcal dependent K can be considered in the error
37 calculation by specifying a range of possible LDRcal values in the input file. For the real calibration measurements a calibration range with low or no aerosol
38 content should be chosen, and the default in the input file is a range of LDRcal between 0.004 and 0.014 (i.e. 0.009 +-0.005).
39
40 Tip: In case you run the code with Spyder, all output text and plots can be displayed together in an IPython console, which can be saved as an html file.
41
42 Ver. 0.9.8: - for details, see "Improvements_of_lidar_correction_ghk_ver.0.9.8_190124.pdf"
43 - correct calculation of Eta for cleaned anaylsers considering the combined transmission Eta = (TaT* TiT)(1 + cos2RotaT * DaT * DiT) and (TaR * TiR)(1 + cos2RotaR * DaR * DiR) according to the papers supplement Eqs. (S.10.10.1) ff
44 - ND-filters can be added for the calibration measurements in the transmitted (TCalT) and the reflected path (TCalR) in order to include their uncertainties in the error calculation.
45 - includes the simulation of signal noise
46 """
47 # Comment: The code might works with Python 2.7 with the help of following line, which enables Python2 to correctly interpret the Python 3 print statements.
48 from __future__ import print_function
49 # !/usr/bin/env python3
50
51 import os
52 import sys
53
54 import numpy as np
55
56 # Comment: the seaborn library makes nicer plots, but the code works also without it.
57 try:
58 import seaborn as sns
59
60 sns_loaded = True
61 except ImportError:
62 sns_loaded = False
63
64 import matplotlib.pyplot as plt
65 # from time import clock # python 2
66 from timeit import default_timer as clock
67
68 # from matplotlib.backends.backend_pdf import PdfPages
69 # pdffile = '{}.pdf'.format('path')
70 # pp = PdfPages(pdffile)
71 ## pp.savefig can be called multiple times to save to multiple pages
72 # pp.savefig()
73 # pp.close()
74
75 from contextlib import contextmanager
76
77 @contextmanager
78 def redirect_stdout(new_target):
79 old_target, sys.stdout = sys.stdout, new_target # replace sys.stdout
80 try:
81 yield new_target # run some code with the replaced stdout
82 finally:
83 sys.stdout.flush()
84 sys.stdout = old_target # restore to the previous value
85
86 '''
87 real_raw_input = vars(__builtins__).get('raw_input',input)
88 '''
89 try:
90 import __builtin__
91
92 input = getattr(__builtin__, 'raw_input')
93 except (ImportError, AttributeError):
94 pass
95
96 from distutils.util import strtobool
97
98
99 def user_yes_no_query(question):
100 sys.stdout.write('%s [y/n]\n' % question)
101 while True:
102 try:
103 return strtobool(input().lower())
104 except ValueError:
105 sys.stdout.write('Please respond with \'y\' or \'n\'.\n')
106
107
108 # if user_yes_no_query('want to exit?') == 1: sys.exit()
109
110 abspath = os.path.abspath(__file__)
111 dname = os.path.dirname(abspath)
112 fname = os.path.basename(abspath)
113 os.chdir(dname)
114
115 # PrintToOutputFile = True
116
117 sqr05 = 0.5 ** 0.5
118
119 # ---- Initial definition of variables; the actual values will be read in with exec(open('./optic_input.py').read()) below
120 # Do you want to calculate the errors? If not, just the GHK-parameters are determined.
121 ScriptVersion = "0.9.8d"
122 Error_Calc = True
123 LID = "internal"
124 EID = "internal"
125 # --- IL Laser IL and +-Uncertainty
126 DOLP, dDOLP, nDOLP = 0.995, 0.005, 1 # degree of linear polarization; default 1
127 RotL, dRotL, nRotL = 0.0, 0.0, 1 # alpha; rotation of laser polarization in degrees; default 0
128 # IL = 1e5 #photons in the laser beam, including detection efficiency of the telescope, atmodspheric and r^2 attenuation
129 # --- ME Emitter and +-Uncertainty
130 DiE, dDiE, nDiE = 0., 0.00, 1 # Diattenuation
131 TiE = 1. # Unpolarized transmittance
132 RetE, dRetE, nRetE = 0., 180.0, 0 # Retardance in degrees
133 RotE, dRotE, nRotE = 0., 0.0, 0 # beta: Rotation of optical element in degrees
134 # --- MO Receiver Optics including telescope
135 DiO, dDiO, nDiO = -0.055, 0.003, 1
136 TiO = 0.9
137 RetO, dRetO, nRetO = 0., 180.0, 2
138 RotO, dRotO, nRotO = 0., 0.1, 1 # gamma
139 # --- PBS MT transmitting path defined with (TS,TP); and +-Uncertainty
140 TP, dTP, nTP = 0.98, 0.02, 1
141 TS, dTS, nTS = 0.001, 0.001, 1
142 TiT = 0.5 * (TP + TS)
143 DiT = (TP - TS) / (TP + TS)
144 # PolFilter
145 RetT, dRetT, nRetT = 0., 180., 0
146 ERaT, dERaT, nERaT = 0.001, 0.001, 1
147 RotaT, dRotaT, nRotaT = 0., 3., 1
148 DaT = (1 - ERaT) / (1 + ERaT)
149 TaT = 0.5 * (1 + ERaT)
150 # --- PBS MR reflecting path defined with (RS,RP); and +-Uncertainty
151 RS_RP_depend_on_TS_TP = False
152 if (RS_RP_depend_on_TS_TP):
153 RP, dRP, nRP = 1 - TP, 0.00, 0
154 RS, dRS, nRS = 1 - TS, 0.00, 0
155 else:
156 RP, dRP, nRP = 0.05, 0.01, 1
157 RS, dRS, nRS = 0.98, 0.01, 1
158 TiR = 0.5 * (RP + RS)
159 DiR = (RP - RS) / (RP + RS)
160 # PolFilter
161 RetR, dRetR, nRetR = 0., 180., 0
162 ERaR, dERaR, nERaR = 0.001, 0.001, 1
163 RotaR, dRotaR, nRotaR = 90., 3., 1
164 DaR = (1 - ERaR) / (1 + ERaR)
165 TaR = 0.5 * (1 + ERaR)
166
167 # +++ Orientation of the PBS with respect to the reference plane (see Polarisation-orientation.png and Polarisation-orientation-2.png in /system_settings)
168 # Y = +1: polarisation in reference plane is finally transmitted,
169 # Y = -1: polarisation in reference plane is finally reflected.
170 Y = 1.
171
172 # Calibrator = type defined by matrix values
173 LocC = 4 # location of calibrator: behind laser = 1; behind emitter = 2; before receiver = 3; before PBS = 4
174
175 # --- Additional attenuation (transmission of the ND-filter) during the calibration
176 TCalT, dTCalT, nTCalT = 1, 0, 0 # transmitting path; error calc not working yet
177 TCalR, dTCalR, nTCalR = 1, 0, 0 # reflecting path; error calc not working yet
178
179 # *** signal noise error calculation
180 # --- number of photon counts in the signal summed up in the calibration range during the calibration measurements
181 NCalT = 1e6 # default 1e6, assumed the same in +45° and -45° signals
182 NCalR = 1e6 # default 1e6, assumed the same in +45° and -45° signals
183 NILfac = 200 # duration of standard (0°) measurement relative to calibration measurements
184 nNCal = 0 # error nNCal: one-sigma in steps to left and right for calibration signals
185 nNI = 0 # error nNI: one-sigma in steps to left and right for 0° signals
186 IoutTp0, IoutTp, dIoutTp0 = 0.5, 0.5, 0
187 IoutTm0, IoutTm, dIoutTm0 = 0.5, 0.5, 0
188 IoutRp0, IoutRp, dIoutRp0 = 0.5, 0.5, 0
189 IoutRm0, IoutRm, dIoutRm0 = 0.5, 0.5, 0
190 It0, It, dIt0 = 1 , 1, 0
191 Ir0, Ir, dTr0 = 1 , 1, 0
192 CalcFrom0deg = True
193
194 TypeC = 3 # linear polarizer calibrator
195 # example with extinction ratio 0.001
196 DiC, dDiC, nDiC = 1.0, 0., 0 # ideal 1.0
197 TiC = 0.5 # ideal 0.5
198 RetC, dRetC, nRetC = 0., 0., 0
199 RotC, dRotC, nRotC = 0.0, 0.1, 0 # constant calibrator offset epsilon
200 RotationErrorEpsilonForNormalMeasurements = False # is in general False for TypeC == 3 calibrator
201
202 # Rotation error without calibrator: if False, then epsilon = 0 for normal measurements
203 RotationErrorEpsilonForNormalMeasurements = True
204 # BSR backscatter ratio
205 # BSR, dBSR, nBSR = 10, 0.05, 1
206 BSR = np.zeros(5)
207 BSR = [1.1, 2, 5, 10, 50]
208 # theoretical molecular LDR LDRm
209 LDRm, dLDRm, nLDRm = 0.004, 0.001, 1
210 # LDRCal assumed atmospheric linear depolarization ratio during the calibration measurements (first guess)
211 LDRCal0, dLDRCal, nLDRCal = 0.25, 0.04, 1
212 LDRCal = LDRCal0
213 # measured LDRm will be corrected with calculated parameters
214 LDRmeas = 0.015
215 # LDRtrue for simulation of measurement => LDRsim
216 LDRtrue = 0.5
217 LDRtrue2 = 0.004
218 LDRunCorr = 1
219 # Initialize other values to 0
220 ER, nER, dER = 0.001, 0, 0.001
221 K = 0.
222 Km = 0.
223 Kp = 0.
224 LDRcorr = 0.
225 Eta = 0.
226 Ir = 0.
227 It = 0.
228 h = 1.
229
230 Loc = ['', 'behind laser', 'behind emitter', 'before receiver', 'before PBS']
231 Type = ['', 'mechanical rotator', 'hwp rotator', 'linear polarizer', 'qwp rotator', 'circular polarizer',
232 'real HWP +-22.5°']
233 dY = ['reflected channel', '', 'transmitted channel']
234 bPlotEtax = False
235
236 # end of initial definition of variables
237 # *******************************************************************************************************************************
238
239 # --- Read actual lidar system parameters from optic_input.py (must be in the programs sub-directory 'system_settings')
240 #InputFile = 'optic_input_example_lidar_2.py'
241 #InputFile = 'optic_input_example_lidar_3.py'
242 #InputFile = 'optic_input_example_lidar_4.py'
243 #InputFile = 'optic_input_example_lidar_5.py'
244 InputFile = 'optic_input_example_lidar.py'
245
246 '''
247 print("From ", dname)
248 print("Running ", fname)
249 print("Reading input file ", InputFile, " for")
250 '''
251 input_path = os.path.join('.', 'system_settings', InputFile)
252 # this works with Python 2 and 3!
253 exec (open(input_path).read(), globals())
254 # end of read actual system parameters
255
256
257 # --- Manual Parameter Change ---
258 # (use for quick parameter changes without changing the input file )
259 # DiO = 0.
260 # LDRtrue = 0.45
261 # LDRtrue2 = 0.004
262 # Y = -1
263 # LocC = 4 #location of calibrator: 1 = behind laser; 2 = behind emitter; 3 = before receiver; 4 = before PBS
264 ##TypeC = 6 Don't change the TypeC here
265 # RotationErrorEpsilonForNormalMeasurements = True
266 # LDRCal = 0.25
267 ## --- Errors
268 DOLP0, dDOLP, nDOLP = DOLP, dDOLP, nDOLP
269 RotL0, dRotL, nRotL = RotL, dRotL, nRotL
270
271 DiE0, dDiE, nDiE = DiE, dDiE, nDiE
272 RetE0, dRetE, nRetE = RetE, dRetE, nRetE
273 RotE0, dRotE, nRotE = RotE, dRotE, nRotE
274
275 DiO0, dDiO, nDiO = DiO, dDiO, nDiO
276 RetO0, dRetO, nRetO = RetO, dRetO, nRetO
277 RotO0, dRotO, nRotO = RotO, dRotO, nRotO
278
279 DiC0, dDiC, nDiC = DiC, dDiC, nDiC
280 RetC0, dRetC, nRetC = RetC, dRetC, nRetC
281 RotC0, dRotC, nRotC = RotC, dRotC, nRotC
282
283 TP0, dTP, nTP = TP, dTP, nTP
284 TS0, dTS, nTS = TS, dTS, nTS
285 RetT0, dRetT, nRetT = RetT, dRetT, nRetT
286
287 ERaT0, dERaT, nERaT = ERaT, dERaT, nERaT
288 RotaT0, dRotaT, nRotaT = RotaT, dRotaT, nRotaT
289
290 RP0, dRP, nRP = RP, dRP, nRP
291 RS0, dRS, nRS = RS, dRS, nRS
292 RetR0, dRetR, nRetR = RetR, dRetR, nRetR
293
294 ERaR0, dERaR, nERaR = ERaR, dERaR, nERaR
295 RotaR0, dRotaR, nRotaR = RotaR, dRotaR, nRotaR
296
297 LDRCal0, dLDRCal, nLDRCal = LDRCal, dLDRCal, nLDRCal
298
299 # BSR0, dBSR, nBSR = BSR, dBSR, nBSR
300 LDRm0, dLDRm, nLDRm = LDRm, dLDRm, nLDRm
301 # ---------- End of manual parameter change
302
303 RotL, RotE, RetE, DiE, RotO, RetO, DiO, RotC, RetC, DiC = RotL0, RotE0, RetE0, DiE0, RotO0, RetO0, DiO0, RotC0, RetC0, DiC0
304 TP, TS, RP, RS, ERaT, RotaT, RetT, ERaR, RotaR, RetR = TP0, TS0, RP0, RS0, ERaT0, RotaT0, RetT0, ERaR0, RotaR0, RetR0
305 LDRCal = LDRCal0
306 DTa0, TTa0, DRa0, TRa0, LDRsimx, LDRCorr = 0, 0, 0, 0, 0, 0
307 TCalT0, TCalR0 = TCalT, TCalR
308
309 TiT = 0.5 * (TP + TS)
310 DiT = (TP - TS) / (TP + TS)
311 ZiT = (1. - DiT ** 2) ** 0.5
312 TiR = 0.5 * (RP + RS)
313 DiR = (RP - RS) / (RP + RS)
314 ZiR = (1. - DiR ** 2) ** 0.5
315
316 C2aT = np.cos(np.deg2rad(2 * RotaT))
317 C2aR = np.cos(np.deg2rad(2 * RotaR))
318 ATPT = (1 + C2aT * DaT * DiT)
319 ARPT = (1 + C2aR * DaR * DiR)
320 TTa = TiT * TaT * ATPT # unpolarized transmission
321 TRa = TiR * TaR * ARPT # unpolarized transmission
322 Eta0 = TRa / TTa
323 # --- this subroutine is for the calculation of the PLDR from LDR, BSR, and LDRm -----------------------------------------------------
324 def CalcPLDR(LDR, BSR, LDRm):
325 PLDR = (BSR * (1. + LDRm) * LDR - LDRm * (1. + LDR)) / (BSR * (1. + LDRm) - (1. + LDR))
326 return (PLDR)
327 # --- this subroutine is for the calculation with certain fixed parameters -----------------------------------------------------
328 def Calc(TCalT, TCalR, NCalT, NCalR, DOLP, RotL, RotE, RetE, DiE, RotO, RetO, DiO,
329 RotC, RetC, DiC, TP, TS, RP, RS,
330 ERaT, RotaT, RetT, ERaR, RotaR, RetR, LDRCal):
331 # ---- Do the calculations of bra-ket vectors
332 h = -1. if TypeC == 2 else 1
333 # from input file: assumed LDRCal for calibration measurements
334 aCal = (1. - LDRCal) / (1 + LDRCal)
335 # from input file: measured LDRm and true LDRtrue, LDRtrue2 =>
336 # ameas = (1.-LDRmeas)/(1+LDRmeas)
337 atrue = (1. - LDRtrue) / (1 + LDRtrue)
338 # atrue2 = (1.-LDRtrue2)/(1+LDRtrue2)
339
340 # angles of emitter and laser and calibrator and receiver optics
341 # RotL = alpha, RotE = beta, RotO = gamma, RotC = epsilon
342 S2a = np.sin(2 * np.deg2rad(RotL))
343 C2a = np.cos(2 * np.deg2rad(RotL))
344 S2b = np.sin(2 * np.deg2rad(RotE))
345 C2b = np.cos(2 * np.deg2rad(RotE))
346 S2ab = np.sin(np.deg2rad(2 * RotL - 2 * RotE))
347 C2ab = np.cos(np.deg2rad(2 * RotL - 2 * RotE))
348 S2g = np.sin(np.deg2rad(2 * RotO))
349 C2g = np.cos(np.deg2rad(2 * RotO))
350
351 # Laser with Degree of linear polarization DOLP
352 IinL = 1.
353 QinL = DOLP
354 UinL = 0.
355 VinL = (1. - DOLP ** 2) ** 0.5
356
357 # Stokes Input Vector rotation Eq. E.4
358 A = C2a * QinL - S2a * UinL
359 B = S2a * QinL + C2a * UinL
360 # Stokes Input Vector rotation Eq. E.9
361 C = C2ab * QinL - S2ab * UinL
362 D = S2ab * QinL + C2ab * UinL
363
364 # emitter optics
365 CosE = np.cos(np.deg2rad(RetE))
366 SinE = np.sin(np.deg2rad(RetE))
367 ZiE = (1. - DiE ** 2) ** 0.5
368 WiE = (1. - ZiE * CosE)
369
370 # Stokes Input Vector after emitter optics equivalent to Eq. E.9 with already rotated input vector from Eq. E.4
371 # b = beta
372 IinE = (IinL + DiE * C)
373 QinE = (C2b * DiE * IinL + A + S2b * (WiE * D - ZiE * SinE * VinL))
374 UinE = (S2b * DiE * IinL + B - C2b * (WiE * D - ZiE * SinE * VinL))
375 VinE = (-ZiE * SinE * D + ZiE * CosE * VinL)
376
377 # Stokes Input Vector before receiver optics Eq. E.19 (after atmosphere F)
378 IinF = IinE
379 QinF = aCal * QinE
380 UinF = -aCal * UinE
381 VinF = (1. - 2. * aCal) * VinE
382
383 # receiver optics
384 CosO = np.cos(np.deg2rad(RetO))
385 SinO = np.sin(np.deg2rad(RetO))
386 ZiO = (1. - DiO ** 2) ** 0.5
387 WiO = (1. - ZiO * CosO)
388
389 # calibrator
390 CosC = np.cos(np.deg2rad(RetC))
391 SinC = np.sin(np.deg2rad(RetC))
392 ZiC = (1. - DiC ** 2) ** 0.5
393 WiC = (1. - ZiC * CosC)
394
395 # Stokes Input Vector before the polarising beam splitter Eq. E.31
396 A = C2g * QinE - S2g * UinE
397 B = S2g * QinE + C2g * UinE
398
399 IinP = (IinE + DiO * aCal * A)
400 QinP = (C2g * DiO * IinE + aCal * QinE - S2g * (WiO * aCal * B + ZiO * SinO * (1 - 2 * aCal) * VinE))
401 UinP = (S2g * DiO * IinE - aCal * UinE + C2g * (WiO * aCal * B + ZiO * SinO * (1 - 2 * aCal) * VinE))
402 VinP = (ZiO * SinO * aCal * B + ZiO * CosO * (1 - 2 * aCal) * VinE)
403
404 # -------------------------
405 # F11 assuemd to be = 1 => measured: F11m = IinP / IinE with atrue
406 # F11sim = TiO*(IinE + DiO*atrue*A)/IinE
407 # -------------------------
408
409 # analyser
410 if (RS_RP_depend_on_TS_TP):
411 RS = 1 - TS
412 RP = 1 - TP
413
414 TiT = 0.5 * (TP + TS)
415 DiT = (TP - TS) / (TP + TS)
416 ZiT = (1. - DiT ** 2) ** 0.5
417 TiR = 0.5 * (RP + RS)
418 DiR = (RP - RS) / (RP + RS)
419 ZiR = (1. - DiR ** 2) ** 0.5
420 CosT = np.cos(np.deg2rad(RetT))
421 SinT = np.sin(np.deg2rad(RetT))
422 CosR = np.cos(np.deg2rad(RetR))
423 SinR = np.sin(np.deg2rad(RetR))
424
425 DaT = (1 - ERaT) / (1 + ERaT)
426 DaR = (1 - ERaR) / (1 + ERaR)
427 TaT = 0.5 * (1 + ERaT)
428 TaR = 0.5 * (1 + ERaR)
429
430 S2aT = np.sin(np.deg2rad(h * 2 * RotaT))
431 C2aT = np.cos(np.deg2rad(2 * RotaT))
432 S2aR = np.sin(np.deg2rad(h * 2 * RotaR))
433 C2aR = np.cos(np.deg2rad(2 * RotaR))
434
435 # Analyzer As before the PBS Eq. D.5; combined PBS and cleaning pol-filter
436 ATPT = (1 + C2aT * DaT * DiT) # unpolarized transmission correction
437 TTa = TiT * TaT * ATPT # unpolarized transmission
438 ATP1 = 1
439 ATP2 = Y * (DiT + C2aT * DaT) / ATPT
440 ATP3 = Y * S2aT * DaT * ZiT * CosT / ATPT
441 ATP4 = S2aT * DaT * ZiT * SinT / ATPT
442 ATP = np.array([ATP1, ATP2, ATP3, ATP4])
443 DTa = ATP2 * Y
444
445 ARPT = (1 + C2aR * DaR * DiR) # unpolarized transmission correction
446 TRa = TiR * TaR * ARPT # unpolarized transmission
447 ARP1 = 1
448 ARP2 = Y * (DiR + C2aR * DaR) / ARPT
449 ARP3 = Y * S2aR * DaR * ZiR * CosR / ARPT
450 ARP4 = S2aR * DaR * ZiR * SinR / ARPT
451 ARP = np.array([ARP1, ARP2, ARP3, ARP4])
452 DRa = ARP2 * Y
453
454
455 # ---- Calculate signals and correction parameters for diffeent locations and calibrators
456 if LocC == 4: # Calibrator before the PBS
457 # print("Calibrator location not implemented yet")
458
459 # S2ge = np.sin(np.deg2rad(2*RotO + h*2*RotC))
460 # C2ge = np.cos(np.deg2rad(2*RotO + h*2*RotC))
461 S2e = np.sin(np.deg2rad(h * 2 * RotC))
462 C2e = np.cos(np.deg2rad(2 * RotC))
463 # rotated AinP by epsilon Eq. C.3
464 ATP2e = C2e * ATP2 + S2e * ATP3
465 ATP3e = C2e * ATP3 - S2e * ATP2
466 ARP2e = C2e * ARP2 + S2e * ARP3
467 ARP3e = C2e * ARP3 - S2e * ARP2
468 ATPe = np.array([ATP1, ATP2e, ATP3e, ATP4])
469 ARPe = np.array([ARP1, ARP2e, ARP3e, ARP4])
470 # Stokes Input Vector before the polarising beam splitter Eq. E.31
471 A = C2g * QinE - S2g * UinE
472 B = S2g * QinE + C2g * UinE
473 # C = (WiO*aCal*B + ZiO*SinO*(1-2*aCal)*VinE)
474 Co = ZiO * SinO * VinE
475 Ca = (WiO * B - 2 * ZiO * SinO * VinE)
476 # C = Co + aCal*Ca
477 # IinP = (IinE + DiO*aCal*A)
478 # QinP = (C2g*DiO*IinE + aCal*QinE - S2g*C)
479 # UinP = (S2g*DiO*IinE - aCal*UinE + C2g*C)
480 # VinP = (ZiO*SinO*aCal*B + ZiO*CosO*(1-2*aCal)*VinE)
481 IinPo = IinE
482 QinPo = (C2g * DiO * IinE - S2g * Co)
483 UinPo = (S2g * DiO * IinE + C2g * Co)
484 VinPo = ZiO * CosO * VinE
485
486 IinPa = DiO * A
487 QinPa = QinE - S2g * Ca
488 UinPa = -UinE + C2g * Ca
489 VinPa = ZiO * (SinO * B - 2 * CosO * VinE)
490
491 IinP = IinPo + aCal * IinPa
492 QinP = QinPo + aCal * QinPa
493 UinP = UinPo + aCal * UinPa
494 VinP = VinPo + aCal * VinPa
495 # Stokes Input Vector before the polarising beam splitter rotated by epsilon Eq. C.3
496 # QinPe = C2e*QinP + S2e*UinP
497 # UinPe = C2e*UinP - S2e*QinP
498 QinPoe = C2e * QinPo + S2e * UinPo
499 UinPoe = C2e * UinPo - S2e * QinPo
500 QinPae = C2e * QinPa + S2e * UinPa
501 UinPae = C2e * UinPa - S2e * QinPa
502 QinPe = C2e * QinP + S2e * UinP
503 UinPe = C2e * UinP - S2e * QinP
504
505 # Calibration signals and Calibration correction K from measurements with LDRCal / aCal
506 if (TypeC == 2) or (TypeC == 1): # rotator calibration Eq. C.4
507 # parameters for calibration with aCal
508 AT = ATP1 * IinP + h * ATP4 * VinP
509 BT = ATP3e * QinP - h * ATP2e * UinP
510 AR = ARP1 * IinP + h * ARP4 * VinP
511 BR = ARP3e * QinP - h * ARP2e * UinP
512 # Correction parameters for normal measurements; they are independent of LDR
513 if (not RotationErrorEpsilonForNormalMeasurements): # calibrator taken out
514 IS1 = np.array([IinPo, QinPo, UinPo, VinPo])
515 IS2 = np.array([IinPa, QinPa, UinPa, VinPa])
516 GT = np.dot(ATP, IS1)
517 GR = np.dot(ARP, IS1)
518 HT = np.dot(ATP, IS2)
519 HR = np.dot(ARP, IS2)
520 else:
521 IS1 = np.array([IinPo, QinPo, UinPo, VinPo])
522 IS2 = np.array([IinPa, QinPa, UinPa, VinPa])
523 GT = np.dot(ATPe, IS1)
524 GR = np.dot(ARPe, IS1)
525 HT = np.dot(ATPe, IS2)
526 HR = np.dot(ARPe, IS2)
527 elif (TypeC == 3) or (TypeC == 4): # linear polariser calibration Eq. C.5
528 # parameters for calibration with aCal
529 AT = ATP1 * IinP + ATP3e * UinPe + ZiC * CosC * (ATP2e * QinPe + ATP4 * VinP)
530 BT = DiC * (ATP1 * UinPe + ATP3e * IinP) - ZiC * SinC * (ATP2e * VinP - ATP4 * QinPe)
531 AR = ARP1 * IinP + ARP3e * UinPe + ZiC * CosC * (ARP2e * QinPe + ARP4 * VinP)
532 BR = DiC * (ARP1 * UinPe + ARP3e * IinP) - ZiC * SinC * (ARP2e * VinP - ARP4 * QinPe)
533 # Correction parameters for normal measurements; they are independent of LDR
534 if (not RotationErrorEpsilonForNormalMeasurements): # calibrator taken out
535 IS1 = np.array([IinPo, QinPo, UinPo, VinPo])
536 IS2 = np.array([IinPa, QinPa, UinPa, VinPa])
537 GT = np.dot(ATP, IS1)
538 GR = np.dot(ARP, IS1)
539 HT = np.dot(ATP, IS2)
540 HR = np.dot(ARP, IS2)
541 else:
542 IS1e = np.array([IinPo + DiC * QinPoe, DiC * IinPo + QinPoe, ZiC * (CosC * UinPoe + SinC * VinPo),
543 -ZiC * (SinC * UinPoe - CosC * VinPo)])
544 IS2e = np.array([IinPa + DiC * QinPae, DiC * IinPa + QinPae, ZiC * (CosC * UinPae + SinC * VinPa),
545 -ZiC * (SinC * UinPae - CosC * VinPa)])
546 GT = np.dot(ATPe, IS1e)
547 GR = np.dot(ARPe, IS1e)
548 HT = np.dot(ATPe, IS2e)
549 HR = np.dot(ARPe, IS2e)
550 elif (TypeC == 6): # diattenuator calibration +-22.5° rotated_diattenuator_X22x5deg.odt
551 # parameters for calibration with aCal
552 AT = ATP1 * IinP + sqr05 * DiC * (ATP1 * QinPe + ATP2e * IinP) + (1 - 0.5 * WiC) * (
553 ATP2e * QinPe + ATP3e * UinPe) + ZiC * (sqr05 * SinC * (ATP3e * VinP - ATP4 * UinPe) + ATP4 * CosC * VinP)
554 BT = sqr05 * DiC * (ATP1 * UinPe + ATP3e * IinP) + 0.5 * WiC * (
555 ATP2e * UinPe + ATP3e * QinPe) - sqr05 * ZiC * SinC * (ATP2e * VinP - ATP4 * QinPe)
556 AR = ARP1 * IinP + sqr05 * DiC * (ARP1 * QinPe + ARP2e * IinP) + (1 - 0.5 * WiC) * (
557 ARP2e * QinPe + ARP3e * UinPe) + ZiC * (sqr05 * SinC * (ARP3e * VinP - ARP4 * UinPe) + ARP4 * CosC * VinP)
558 BR = sqr05 * DiC * (ARP1 * UinPe + ARP3e * IinP) + 0.5 * WiC * (
559 ARP2e * UinPe + ARP3e * QinPe) - sqr05 * ZiC * SinC * (ARP2e * VinP - ARP4 * QinPe)
560 # Correction parameters for normal measurements; they are independent of LDR
561 if (not RotationErrorEpsilonForNormalMeasurements): # calibrator taken out
562 IS1 = np.array([IinPo, QinPo, UinPo, VinPo])
563 IS2 = np.array([IinPa, QinPa, UinPa, VinPa])
564 GT = np.dot(ATP, IS1)
565 GR = np.dot(ARP, IS1)
566 HT = np.dot(ATP, IS2)
567 HR = np.dot(ARP, IS2)
568 else:
569 IS1e = np.array([IinPo + DiC * QinPoe, DiC * IinPo + QinPoe, ZiC * (CosC * UinPoe + SinC * VinPo),
570 -ZiC * (SinC * UinPoe - CosC * VinPo)])
571 IS2e = np.array([IinPa + DiC * QinPae, DiC * IinPa + QinPae, ZiC * (CosC * UinPae + SinC * VinPa),
572 -ZiC * (SinC * UinPae - CosC * VinPa)])
573 GT = np.dot(ATPe, IS1e)
574 GR = np.dot(ARPe, IS1e)
575 HT = np.dot(ATPe, IS2e)
576 HR = np.dot(ARPe, IS2e)
577 else:
578 print("Calibrator not implemented yet")
579 sys.exit()
580
581 elif LocC == 3: # C before receiver optics Eq.57
582
583 # S2ge = np.sin(np.deg2rad(2*RotO - 2*RotC))
584 # C2ge = np.cos(np.deg2rad(2*RotO - 2*RotC))
585 S2e = np.sin(np.deg2rad(2 * RotC))
586 C2e = np.cos(np.deg2rad(2 * RotC))
587
588 # As with C before the receiver optics (rotated_diattenuator_X22x5deg.odt)
589 AF1 = np.array([1, C2g * DiO, S2g * DiO, 0])
590 AF2 = np.array([C2g * DiO, 1 - S2g ** 2 * WiO, S2g * C2g * WiO, -S2g * ZiO * SinO])
591 AF3 = np.array([S2g * DiO, S2g * C2g * WiO, 1 - C2g ** 2 * WiO, C2g * ZiO * SinO])
592 AF4 = np.array([0, S2g * SinO, -C2g * SinO, CosO])
593
594 ATF = (ATP1 * AF1 + ATP2 * AF2 + ATP3 * AF3 + ATP4 * AF4)
595 ARF = (ARP1 * AF1 + ARP2 * AF2 + ARP3 * AF3 + ARP4 * AF4)
596 ATF2 = ATF[1]
597 ATF3 = ATF[2]
598 ARF2 = ARF[1]
599 ARF3 = ARF[2]
600
601 # rotated AinF by epsilon
602 ATF1 = ATF[0]
603 ATF4 = ATF[3]
604 ATF2e = C2e * ATF[1] + S2e * ATF[2]
605 ATF3e = C2e * ATF[2] - S2e * ATF[1]
606 ARF1 = ARF[0]
607 ARF4 = ARF[3]
608 ARF2e = C2e * ARF[1] + S2e * ARF[2]
609 ARF3e = C2e * ARF[2] - S2e * ARF[1]
610
611 ATFe = np.array([ATF1, ATF2e, ATF3e, ATF4])
612 ARFe = np.array([ARF1, ARF2e, ARF3e, ARF4])
613
614 QinEe = C2e * QinE + S2e * UinE
615 UinEe = C2e * UinE - S2e * QinE
616
617 # Stokes Input Vector before receiver optics Eq. E.19 (after atmosphere F)
618 IinF = IinE
619 QinF = aCal * QinE
620 UinF = -aCal * UinE
621 VinF = (1. - 2. * aCal) * VinE
622
623 IinFo = IinE
624 QinFo = 0.
625 UinFo = 0.
626 VinFo = VinE
627
628 IinFa = 0.
629 QinFa = QinE
630 UinFa = -UinE
631 VinFa = -2. * VinE
632
633 # Stokes Input Vector before receiver optics rotated by epsilon Eq. C.3
634 QinFe = C2e * QinF + S2e * UinF
635 UinFe = C2e * UinF - S2e * QinF
636 QinFoe = C2e * QinFo + S2e * UinFo
637 UinFoe = C2e * UinFo - S2e * QinFo
638 QinFae = C2e * QinFa + S2e * UinFa
639 UinFae = C2e * UinFa - S2e * QinFa
640
641 # Calibration signals and Calibration correction K from measurements with LDRCal / aCal
642 if (TypeC == 2) or (TypeC == 1): # rotator calibration Eq. C.4
643 # parameters for calibration with aCal
644 AT = ATF1 * IinF + ATF4 * h * VinF
645 BT = ATF3e * QinF - ATF2e * h * UinF
646 AR = ARF1 * IinF + ARF4 * h * VinF
647 BR = ARF3e * QinF - ARF2e * h * UinF
648 # Correction parameters for normal measurements; they are independent of LDR
649 if (not RotationErrorEpsilonForNormalMeasurements):
650 GT = ATF1 * IinE + ATF4 * VinE
651 GR = ARF1 * IinE + ARF4 * VinE
652 HT = ATF2 * QinE - ATF3 * UinE - ATF4 * 2 * VinE
653 HR = ARF2 * QinE - ARF3 * UinE - ARF4 * 2 * VinE
654 else:
655 GT = ATF1 * IinE + ATF4 * h * VinE
656 GR = ARF1 * IinE + ARF4 * h * VinE
657 HT = ATF2e * QinE - ATF3e * h * UinE - ATF4 * h * 2 * VinE
658 HR = ARF2e * QinE - ARF3e * h * UinE - ARF4 * h * 2 * VinE
659 elif (TypeC == 3) or (TypeC == 4): # linear polariser calibration Eq. C.5
660 # p = +45°, m = -45°
661 IF1e = np.array([IinF, ZiC * CosC * QinFe, UinFe, ZiC * CosC * VinF])
662 IF2e = np.array([DiC * UinFe, -ZiC * SinC * VinF, DiC * IinF, ZiC * SinC * QinFe])
663 AT = np.dot(ATFe, IF1e)
664 AR = np.dot(ARFe, IF1e)
665 BT = np.dot(ATFe, IF2e)
666 BR = np.dot(ARFe, IF2e)
667
668 # Correction parameters for normal measurements; they are independent of LDR --- the same as for TypeC = 6
669 if (not RotationErrorEpsilonForNormalMeasurements): # calibrator taken out
670 IS1 = np.array([IinE, 0, 0, VinE])
671 IS2 = np.array([0, QinE, -UinE, -2 * VinE])
672 GT = np.dot(ATF, IS1)
673 GR = np.dot(ARF, IS1)
674 HT = np.dot(ATF, IS2)
675 HR = np.dot(ARF, IS2)
676 else:
677 IS1e = np.array([IinFo + DiC * QinFoe, DiC * IinFo + QinFoe, ZiC * (CosC * UinFoe + SinC * VinFo),
678 -ZiC * (SinC * UinFoe - CosC * VinFo)])
679 IS2e = np.array([IinFa + DiC * QinFae, DiC * IinFa + QinFae, ZiC * (CosC * UinFae + SinC * VinFa),
680 -ZiC * (SinC * UinFae - CosC * VinFa)])
681 GT = np.dot(ATFe, IS1e)
682 GR = np.dot(ARFe, IS1e)
683 HT = np.dot(ATFe, IS2e)
684 HR = np.dot(ARFe, IS2e)
685
686 elif (TypeC == 6): # diattenuator calibration +-22.5° rotated_diattenuator_X22x5deg.odt
687 # parameters for calibration with aCal
688 IF1e = np.array([IinF + sqr05 * DiC * QinFe, sqr05 * DiC * IinF + (1 - 0.5 * WiC) * QinFe,
689 (1 - 0.5 * WiC) * UinFe + sqr05 * ZiC * SinC * VinF,
690 -sqr05 * ZiC * SinC * UinFe + ZiC * CosC * VinF])
691 IF2e = np.array([sqr05 * DiC * UinFe, 0.5 * WiC * UinFe - sqr05 * ZiC * SinC * VinF,
692 sqr05 * DiC * IinF + 0.5 * WiC * QinFe, sqr05 * ZiC * SinC * QinFe])
693 AT = np.dot(ATFe, IF1e)
694 AR = np.dot(ARFe, IF1e)
695 BT = np.dot(ATFe, IF2e)
696 BR = np.dot(ARFe, IF2e)
697
698 # Correction parameters for normal measurements; they are independent of LDR
699 if (not RotationErrorEpsilonForNormalMeasurements): # calibrator taken out
700 # IS1 = np.array([IinE,0,0,VinE])
701 # IS2 = np.array([0,QinE,-UinE,-2*VinE])
702 IS1 = np.array([IinFo, 0, 0, VinFo])
703 IS2 = np.array([0, QinFa, UinFa, VinFa])
704 GT = np.dot(ATF, IS1)
705 GR = np.dot(ARF, IS1)
706 HT = np.dot(ATF, IS2)
707 HR = np.dot(ARF, IS2)
708 else:
709 IS1e = np.array([IinFo + DiC * QinFoe, DiC * IinFo + QinFoe, ZiC * (CosC * UinFoe + SinC * VinFo),
710 -ZiC * (SinC * UinFoe - CosC * VinFo)])
711 IS2e = np.array([IinFa + DiC * QinFae, DiC * IinFa + QinFae, ZiC * (CosC * UinFae + SinC * VinFa),
712 -ZiC * (SinC * UinFae - CosC * VinFa)])
713 # IS1e = np.array([IinFo,0,0,VinFo])
714 # IS2e = np.array([0,QinFae,UinFae,VinFa])
715 GT = np.dot(ATFe, IS1e)
716 GR = np.dot(ARFe, IS1e)
717 HT = np.dot(ATFe, IS2e)
718 HR = np.dot(ARFe, IS2e)
719
720 else:
721 print('Calibrator not implemented yet')
722 sys.exit()
723
724 elif LocC == 2: # C behind emitter optics Eq.57 -------------------------------------------------------
725 # print("Calibrator location not implemented yet")
726 S2e = np.sin(np.deg2rad(2 * RotC))
727 C2e = np.cos(np.deg2rad(2 * RotC))
728
729 # AS with C before the receiver optics (see document rotated_diattenuator_X22x5deg.odt)
730 AF1 = np.array([1, C2g * DiO, S2g * DiO, 0])
731 AF2 = np.array([C2g * DiO, 1 - S2g ** 2 * WiO, S2g * C2g * WiO, -S2g * ZiO * SinO])
732 AF3 = np.array([S2g * DiO, S2g * C2g * WiO, 1 - C2g ** 2 * WiO, C2g * ZiO * SinO])
733 AF4 = np.array([0, S2g * SinO, -C2g * SinO, CosO])
734
735 ATF = (ATP1 * AF1 + ATP2 * AF2 + ATP3 * AF3 + ATP4 * AF4)
736 ARF = (ARP1 * AF1 + ARP2 * AF2 + ARP3 * AF3 + ARP4 * AF4)
737 ATF1 = ATF[0]
738 ATF2 = ATF[1]
739 ATF3 = ATF[2]
740 ATF4 = ATF[3]
741 ARF1 = ARF[0]
742 ARF2 = ARF[1]
743 ARF3 = ARF[2]
744 ARF4 = ARF[3]
745
746 # AS with C behind the emitter
747 # terms without aCal
748 ATE1o, ARE1o = ATF1, ARF1
749 ATE2o, ARE2o = 0., 0.
750 ATE3o, ARE3o = 0., 0.
751 ATE4o, ARE4o = ATF4, ARF4
752 # terms with aCal
753 ATE1a, ARE1a = 0., 0.
754 ATE2a, ARE2a = ATF2, ARF2
755 ATE3a, ARE3a = -ATF3, -ARF3
756 ATE4a, ARE4a = -2 * ATF4, -2 * ARF4
757 # rotated AinEa by epsilon
758 ATE2ae = C2e * ATF2 + S2e * ATF3
759 ATE3ae = -S2e * ATF2 - C2e * ATF3
760 ARE2ae = C2e * ARF2 + S2e * ARF3
761 ARE3ae = -S2e * ARF2 - C2e * ARF3
762
763 ATE1 = ATE1o
764 ATE2e = aCal * ATE2ae
765 ATE3e = aCal * ATE3ae
766 ATE4 = (1 - 2 * aCal) * ATF4
767 ARE1 = ARE1o
768 ARE2e = aCal * ARE2ae
769 ARE3e = aCal * ARE3ae
770 ARE4 = (1 - 2 * aCal) * ARF4
771
772 # rotated IinE
773 QinEe = C2e * QinE + S2e * UinE
774 UinEe = C2e * UinE - S2e * QinE
775
776 # Calibration signals and Calibration correction K from measurements with LDRCal / aCal
777 if (TypeC == 2) or (TypeC == 1): # +++++++++ rotator calibration Eq. C.4
778 AT = ATE1o * IinE + (ATE4o + aCal * ATE4a) * h * VinE
779 BT = aCal * (ATE3ae * QinEe - ATE2ae * h * UinEe)
780 AR = ARE1o * IinE + (ARE4o + aCal * ARE4a) * h * VinE
781 BR = aCal * (ARE3ae * QinEe - ARE2ae * h * UinEe)
782
783 # Correction parameters for normal measurements; they are independent of LDR
784 if (not RotationErrorEpsilonForNormalMeasurements):
785 # Stokes Input Vector before receiver optics Eq. E.19 (after atmosphere F)
786 GT = ATE1o * IinE + ATE4o * h * VinE
787 GR = ARE1o * IinE + ARE4o * h * VinE
788 HT = ATE2a * QinE + ATE3a * h * UinEe + ATE4a * h * VinE
789 HR = ARE2a * QinE + ARE3a * h * UinEe + ARE4a * h * VinE
790 else:
791 GT = ATE1o * IinE + ATE4o * h * VinE
792 GR = ARE1o * IinE + ARE4o * h * VinE
793 HT = ATE2ae * QinE + ATE3ae * h * UinEe + ATE4a * h * VinE
794 HR = ARE2ae * QinE + ARE3ae * h * UinEe + ARE4a * h * VinE
795
796 elif (TypeC == 3) or (TypeC == 4): # +++++++++ linear polariser calibration Eq. C.5
797 # p = +45°, m = -45°
798 AT = ATE1 * IinE + ZiC * CosC * (ATE2e * QinEe + ATE4 * VinE) + ATE3e * UinEe
799 BT = DiC * (ATE1 * UinEe + ATE3e * IinE) + ZiC * SinC * (ATE4 * QinEe - ATE2e * VinE)
800 AR = ARE1 * IinE + ZiC * CosC * (ARE2e * QinEe + ARE4 * VinE) + ARE3e * UinEe
801 BR = DiC * (ARE1 * UinEe + ARE3e * IinE) + ZiC * SinC * (ARE4 * QinEe - ARE2e * VinE)
802
803 # Correction parameters for normal measurements; they are independent of LDR
804 if (not RotationErrorEpsilonForNormalMeasurements):
805 # Stokes Input Vector before receiver optics Eq. E.19 (after atmosphere F)
806 GT = ATE1o * IinE + ATE4o * VinE
807 GR = ARE1o * IinE + ARE4o * VinE
808 HT = ATE2a * QinE + ATE3a * UinE + ATE4a * VinE
809 HR = ARE2a * QinE + ARE3a * UinE + ARE4a * VinE
810 else:
811 D = IinE + DiC * QinEe
812 A = DiC * IinE + QinEe
813 B = ZiC * (CosC * UinEe + SinC * VinE)
814 C = -ZiC * (SinC * UinEe - CosC * VinE)
815 GT = ATE1o * D + ATE4o * C
816 GR = ARE1o * D + ARE4o * C
817 HT = ATE2a * A + ATE3a * B + ATE4a * C
818 HR = ARE2a * A + ARE3a * B + ARE4a * C
819
820 elif (TypeC == 6): # real HWP calibration +-22.5° rotated_diattenuator_X22x5deg.odt
821 # p = +22.5°, m = -22.5°
822 IE1e = np.array([IinE + sqr05 * DiC * QinEe, sqr05 * DiC * IinE + (1 - 0.5 * WiC) * QinEe,
823 (1 - 0.5 * WiC) * UinEe + sqr05 * ZiC * SinC * VinE,
824 -sqr05 * ZiC * SinC * UinEe + ZiC * CosC * VinE])
825 IE2e = np.array([sqr05 * DiC * UinEe, 0.5 * WiC * UinEe - sqr05 * ZiC * SinC * VinE,
826 sqr05 * DiC * IinE + 0.5 * WiC * QinEe, sqr05 * ZiC * SinC * QinEe])
827 ATEe = np.array([ATE1, ATE2e, ATE3e, ATE4])
828 AREe = np.array([ARE1, ARE2e, ARE3e, ARE4])
829 AT = np.dot(ATEe, IE1e)
830 AR = np.dot(AREe, IE1e)
831 BT = np.dot(ATEe, IE2e)
832 BR = np.dot(AREe, IE2e)
833
834 # Correction parameters for normal measurements; they are independent of LDR
835 if (not RotationErrorEpsilonForNormalMeasurements): # calibrator taken out
836 GT = ATE1o * IinE + ATE4o * VinE
837 GR = ARE1o * IinE + ARE4o * VinE
838 HT = ATE2a * QinE + ATE3a * UinE + ATE4a * VinE
839 HR = ARE2a * QinE + ARE3a * UinE + ARE4a * VinE
840 else:
841 D = IinE + DiC * QinEe
842 A = DiC * IinE + QinEe
843 B = ZiC * (CosC * UinEe + SinC * VinE)
844 C = -ZiC * (SinC * UinEe - CosC * VinE)
845 GT = ATE1o * D + ATE4o * C
846 GR = ARE1o * D + ARE4o * C
847 HT = ATE2a * A + ATE3a * B + ATE4a * C
848 HR = ARE2a * A + ARE3a * B + ARE4a * C
849
850 else:
851 print('Calibrator not implemented yet')
852 sys.exit()
853
854 else:
855 print("Calibrator location not implemented yet")
856 sys.exit()
857
858 # Determination of the correction K of the calibration factor.
859 IoutTp = TTa * TiC * TiO * TiE * (AT + BT)
860 IoutTm = TTa * TiC * TiO * TiE * (AT - BT)
861 IoutRp = TRa * TiC * TiO * TiE * (AR + BR)
862 IoutRm = TRa * TiC * TiO * TiE * (AR - BR)
863 # --- Results and Corrections; electronic etaR and etaT are assumed to be 1
864 Etapx = IoutRp / IoutTp
865 Etamx = IoutRm / IoutTm
866 Etax = (Etapx * Etamx) ** 0.5
867
868 Eta = (TRa / TTa) # = TRa / TTa; Eta = Eta*/K Eq. 84 => K = Eta* / Eta; equation corrected according to the papers supplement Eqs. (S.10.10.1) ff
869 K = Etax / Eta
870
871 # For comparison with Volkers Libreoffice Müller Matrix spreadsheet
872 # Eta_test_p = (IoutRp/IoutTp)
873 # Eta_test_m = (IoutRm/IoutTm)
874 # Eta_test = (Eta_test_p*Eta_test_m)**0.5
875
876 # ----- random error calculation ----------
877 # noise must be calculated with the photon counts of measured signals;
878 # relative standard deviation of calibration signals with LDRcal; assumed to be statisitcally independent
879 # normalised noise errors
880 if (CalcFrom0deg):
881 dIoutTp = (NCalT * IoutTp) ** -0.5
882 dIoutTm = (NCalT * IoutTm) ** -0.5
883 dIoutRp = (NCalR * IoutRp) ** -0.5
884 dIoutRm = (NCalR * IoutRm) ** -0.5
885 else:
886 dIoutTp = (NCalT ** -0.5)
887 dIoutTm = (NCalT ** -0.5)
888 dIoutRp = (NCalR ** -0.5)
889 dIoutRm = (NCalR ** -0.5)
890 # Forward simulated 0°-signals with LDRCal with atrue; from input file
891
892 It = TTa * TiO * TiE * (GT + atrue * HT)
893 Ir = TRa * TiO * TiE * (GR + atrue * HR)
894 # relative standard deviation of standard signals with LDRmeas; assumed to be statisitcally independent
895 if (CalcFrom0deg):
896 dIt = ((NCalT * It / IoutTp * NILfac / TCalT) ** -0.5)
897 dIr = ((NCalR * Ir / IoutRp * NILfac / TCalR) ** -0.5)
898 else:
899 dIt = ((NCalT * 2 * NILfac / TCalT ) ** -0.5) * It
900 dIr = ((NCalR * 2 * NILfac / TCalR) ** -0.5) * Ir
901
902 # ----- Forward simulated LDRsim = 1/Eta*Ir/It # simulated LDR* with Y from input file
903 LDRsim = Ir / It # simulated uncorrected LDR with Y from input file
904 # Corrected LDRsimCorr from forward simulated LDRsim (atrue)
905 # LDRsimCorr = (1./Eta*LDRsim*(GT+HT)-(GR+HR))/((GR-HR)-1./Eta*LDRsim*(GT-HT))
906 '''
907 if ((Y == -1.) and (abs(RotL0) < 45)) or ((Y == +1.) and (abs(RotL0) > 45)):
908 LDRsimx = 1. / LDRsim / Etax
909 else:
910 LDRsimx = LDRsim / Etax
911 '''
912 LDRsimx = LDRsim
913
914 # The following is correct without doubt
915 # LDRCorr = (LDRsim/(Etax/K)*(GT+HT)-(GR+HR))/((GR-HR)-LDRsim/(Etax/K)*(GT-HT))
916
917 # The following is a test whether the equations for calibration Etax and normal signal (GHK, LDRsim) are consistent
918 LDRCorr = (LDRsim / (Etax / K) * (GT + HT) - (GR + HR)) / ((GR - HR) - LDRsim / (Etax / K) * (GT - HT))
919 # here we could also use Eta instead of Etax / K => how to test whether Etax is correct? => comparison with MüllerMatrix simulation!
920 # Without any correction: only measured It, Ir, EtaX are used
921 LDRunCorr = (LDRsim / Etax * (GT / abs(GT) + HT / abs(HT)) - (GR / abs(GR) + HR / abs(HR))) / ((GR / abs(GR) - HR / abs(HR)) - LDRsim / Etax * (GT / abs(GT) - HT / abs(HT)))
922
923 #LDRCorr = LDRsimx # for test only
924
925 F11sim = 1 / (TiO * TiE) * ((HR * Eta * It - HT * Ir) / (HR * GT - HT * GR)) # IL = 1, Etat = Etar = 1 ; AMT Eq.64; what is Etax/K? => see about 20 lines above: = Eta
926
927 return (IoutTp, IoutTm, IoutRp, IoutRm, It, Ir, dIoutTp, dIoutTm, dIoutRp, dIoutRm, dIt, dIr,
928 GT, HT, GR, HR, K, Eta, LDRsimx, LDRCorr, DTa, DRa, TTa, TRa, F11sim, LDRunCorr)
929
930
931
932 # *******************************************************************************************************************************
933
934 # --- CALC with assumed true parameters from the input file
935 IoutTp0, IoutTm0, IoutRp0, IoutRm0, It0, Ir0, dIoutTp0, dIoutTm0, dIoutRp0, dIoutRm0, dIt0, dIr0, \
936 GT0, HT0, GR0, HR0, K0, Eta0, LDRsimx, LDRCorr, DTa0, DRa0, TTa0, TRa0, F11sim0, LDRunCorr = \
937 Calc(TCalT, TCalR, NCalT, NCalR, DOLP0, RotL0, RotE0, RetE0, DiE0,
938 RotO0, RetO0, DiO0, RotC0, RetC0, DiC0, TP0, TS0, RP0, RS0,
939 ERaT0, RotaT0, RetT0, ERaR0, RotaR0, RetR0, LDRCal0)
940 Etax0 = K0 * Eta0
941 # --- Print parameters to console and output file
942 with open('output_files\\' + LID + '-' + InputFile[0:-3] + '-GHK.dat', 'w') as f:
943 with redirect_stdout(f):
944 print("From folder", dname)
945 print("Running prog", fname)
946 print("Version", ScriptVersion)
947 print("Reading input file ", InputFile) # , " for Lidar system :", EID, ", ", LID)
948 print("for Lidar system: ", EID, ", ", LID)
949 # --- Print iput information*********************************
950 print(" --- Input parameters: value ±error / ±steps ----------------------")
951 print("{0:5}{1:5} {2:6.4f}±{3:7.4f}/{4:2d}; {5:8} {6:8.4f}±{7:7.4f}/{8:2d}".format(
952 "Laser: ", "DOLP =", DOLP0, dDOLP, nDOLP," Rotation alpha = ", RotL0, dRotL, nRotL))
953 print(" Diatt., Tunpol, Retard., Rotation (deg)")
954 print("{0:12} {1:7.4f}±{2:7.4f}/{8:2d}, {3:7.4f}, {4:3.0f}±{5:3.0f}/{9:2d}, {6:7.4f}±{7:7.4f}/{10:2d}".format(
955 "Emitter ", DiE0, dDiE, TiE, RetE0, dRetE, RotE0, dRotE, nDiE, nRetE, nRotE))
956 print("{0:12} {1:7.4f}±{2:7.4f}/{8:2d}, {3:7.4f}, {4:3.0f}±{5:3.0f}/{9:2d}, {6:7.4f}±{7:7.4f}/{10:2d}".format(
957 "Receiver ", DiO0, dDiO, TiO, RetO0, dRetO, RotO0, dRotO, nDiO, nRetO, nRotO))
958 print("{0:12} {1:7.4f}±{2:7.4f}/{8:2d}, {3:7.4f}, {4:3.0f}±{5:3.0f}/{9:2d}, {6:7.4f}±{7:7.4f}/{10:2d}".format(
959 "Calibrator ", DiC0, dDiC, TiC, RetC0, dRetC, RotC0, dRotC, nDiC, nRetC, nRotC))
960 print("{0:12}".format(" --- Pol.-filter ---"))
961 print("{0:12}{1:7.4f}±{2:7.4f}/{3:2d}, {4:7.4f}±{5:7.4f}/{6:2d}".format(
962 "ERT, RotT :", ERaT0, dERaT, nERaT, RotaT0, dRotaT, nRotaT))
963 print("{0:12}{1:7.4f}±{2:7.4f}/{3:2d}, {4:7.4f}±{5:7.4f}/{6:2d}".format(
964 "ERR, RotR :", ERaR0, dERaR, nERaR, RotaR0, dRotaR, nRotaR))
965 print("{0:12}".format(" --- PBS ---"))
966 print("{0:12}{1:7.4f}±{2:7.4f}/{3:2d}, {4:7.4f}±{5:7.4f}/{6:2d}".format(
967 "TP,TS :", TP0, dTP, nTP, TS0, dTS, nTS))
968 print("{0:12}{1:7.4f}±{2:7.4f}/{3:2d}, {4:7.4f}±{5:7.4f}/{6:2d}".format(
969 "RP,RS :", RP0, dRP, nRP, RS0, dRS, nRS))
970 print("{0:12}{1:7.4f},{2:7.4f}, {3:7.4f},{4:7.4f}, {5:1.0f}".format(
971 "DT,TT,DR,TR,Y :", DiT, TiT, DiR, TiR, Y))
972 print("{0:12}".format(" --- Combined PBS + Pol.-filter ---"))
973 print("{0:12}{1:7.4f},{2:7.4f}, {3:7.4f},{4:7.4f}".format(
974 "DT,TT,DR,TR :", DTa0, TTa0, DRa0, TRa0))
975 print("{0:26}: {1:6.3f}± {2:5.3f}/{3:2d}".format(
976 "LDRCal during calibration in calibration range", LDRCal0, dLDRCal, nLDRCal))
977 print("{0:12}".format(" --- Additional ND filter attenuation (transmission) during the calibration ---"))
978 print("{0:12}{1:7.4f}±{2:7.4f}/{3:2d}, {4:7.4f}±{5:7.4f}/{6:2d}".format(
979 "TCalT,TCalR :", TCalT0, dTCalT, nTCalT, TCalR0, dTCalR, nTCalR))
980 print()
981 print("Rotation Error Epsilon For Normal Measurements = ", RotationErrorEpsilonForNormalMeasurements)
982 print(Type[TypeC], Loc[LocC])
983 print("Parallel signal detected in", dY[int(Y + 1)])
984 print("RS_RP_depend_on_TS_TP = ", RS_RP_depend_on_TS_TP)
985 # end of print actual system parameters
986 # ******************************************************************************
987
988 # print()
989 # print(" --- LDRCal during calibration | simulated and corrected LDRs -------------")
990 # print("{0:8} |{1:8}->{2:8},{3:9}->{4:9} |{5:8}->{6:8}".format(" LDRCal"," LDRtrue", " LDRsim"," LDRtrue2", " LDRsim2", " LDRmeas", " LDRcorr"))
991 # print("{0:8.5f} |{1:8.5f}->{2:8.5f},{3:9.5f}->{4:9.5f} |{5:8.5f}->{6:8.5f}".format(LDRCal, LDRtrue, LDRsim, LDRtrue2, LDRsim2, LDRmeas, LDRCorr))
992 # print("{0:8} |{1:8}->{2:8}->{3:8}".format(" LDRCal"," LDRtrue", " LDRsimx", " LDRcorr"))
993 # print("{0:6.3f}±{1:5.3f}/{2:2d}|{3:8.5f}->{4:8.5f}->{5:8.5f}".format(LDRCal0, dLDRCal, nLDRCal, LDRtrue, LDRsimx, LDRCorr))
994 # print("{0:8} |{1:8}->{2:8}->{3:8}".format(" LDRCal"," LDRtrue", " LDRsimx", " LDRcorr"))
995 # print(" --- LDRCal during calibration")
996
997 # print("{0:8}={1:8.5f};{2:8}={3:8.5f}".format(" IinP",IinP," F11sim",F11sim))
998 print()
999
1000 K0List = np.zeros(6)
1001 LDRsimxList = np.zeros(6)
1002 LDRCalList = 0.004, 0.02, 0.1, 0.2, 0.3, 0.45
1003 # The loop over LDRCalList is ony for checking whether and how much the LDR depends on the LDRCal during calibration and whether the corrections work.
1004 # Still with assumed true parameters in input file
1005
1006 facIt = NCalT / TCalT0 * NILfac
1007 facIr = NCalR / TCalR0 * NILfac
1008 print("IoutTp, IoutTm, IoutRp, IoutRm, It , Ir , dIoutTp, dIoutTm, dIoutRp, dIoutRm, dIt, dIr")
1009
1010 for i, LDRCal in enumerate(LDRCalList):
1011 IoutTp, IoutTm, IoutRp, IoutRm, It, Ir, dIoutTp, dIoutTm, dIoutRp, dIoutRm, dIt, dIr, \
1012 GT0, HT0, GR0, HR0, K0, Eta0, LDRsimx, LDRCorr, DTa0, DRa0, TTa0, TRa0, F11sim0, LDRunCorr = \
1013 Calc(TCalT0, TCalR0, NCalT, NCalR, DOLP0, RotL0, RotE0, RetE0, DiE0,
1014 RotO0, RetO0, DiO0, RotC0, RetC0, DiC0, TP0, TS0, RP0, RS0,
1015 ERaT0, RotaT0, RetT0, ERaR0, RotaR0, RetR0, LDRCal)
1016 K0List[i] = K0
1017 LDRsimxList[i] = LDRsimx
1018
1019 # check error signals
1020 # print( "{:0.4f}, {:0.4f}, {:0.4f}, {:0.4f}, {:0.4f}, {:0.4f}, {:0.4f}, {:0.4f}, {:0.4f}, {:0.4f}, {:0.4f}, {:0.4f}"
1021 # .format(IoutTp * NCalT, IoutTm * NCalT, IoutRp * NCalR, IoutRm * NCalR, It * facIt, Ir * facIr, dIoutTp, dIoutTm, dIoutRp, dIoutRm, dIt, dIr))
1022 #print( "{:0.4f}, {:0.4f}, {:0.4f}, {:0.4f}, {:0.4f}, {:0.4f}, {:0.4f}, {:0.4f}, {:0.4f}, {:0.4f}, {:0.4f}, {:0.4f}".format(IoutTp, IoutTm, IoutRp, IoutRm, It, Ir, dIoutTp, dIoutTm, dIoutRp, dIoutRm, dIt, dIr))
1023 # end check error signals
1024 print('===========================================================================================================')
1025 print("{0:8},{1:8},{2:8},{3:8},{4:9},{5:8},{6:9},{7:9},{8:9},{9:9}".format(
1026 " GR", " GT", " HR", " HT", " K(0.004)", " K(0.02)", " K(0.1)", " K(0.2)", " K(0.3)", " K(0.45)"))
1027 print("{0:8.5f},{1:8.5f},{2:8.5f},{3:8.5f},{4:9.5f},{5:9.5f},{6:9.5f},{7:9.5f},{8:9.5f},{9:9.5f}".format(
1028 GR0, GT0, HR0, HT0, K0List[0], K0List[1], K0List[2], K0List[3], K0List[4], K0List[5]))
1029 print('===========================================================================================================')
1030 print()
1031 print("Errors from neglecting GHK corrections and/or calibration:")
1032 print("{0:>10},{1:>10},{2:>10},{3:>10},{4:>10},{5:>10}".format(
1033 "LDRtrue", "LDRunCorr", "1/LDRunCorr", "LDRsimx", "1/LDRsimx", "LDRCorr"))
1034
1035 #LDRtrueList = 0.004, 0.02, 0.2, 0.45
1036 aF11sim0 = np.zeros(5)
1037 LDRrange = np.zeros(5)
1038 LDRrange = [0.004, 0.02, 0.1, 0.3, 0.45] # list
1039
1040 # The loop over LDRtrueList is only for checking how much the uncorrected LDRsimx deviates from LDRtrue ... and whether the corrections work.
1041 # LDRsimx = LDRsim = Ir / It or 1/LDRsim
1042 # Still with assumed true parameters in input file
1043 for i, LDRtrue in enumerate(LDRrange):
1044 #for LDRtrue in LDRrange:
1045 IoutTp, IoutTm, IoutRp, IoutRm, It, Ir, dIoutTp, dIoutTm, dIoutRp, dIoutRm, dIt, dIr, \
1046 GT0, HT0, GR0, HR0, K0, Eta0, LDRsimx, LDRCorr, DTa0, DRa0, TTa0, TRa0, F11sim0, LDRunCorr = \
1047 Calc(TCalT0, TCalR0, NCalT, NCalR, DOLP0, RotL0, RotE0, RetE0, DiE0,
1048 RotO0, RetO0, DiO0, RotC0, RetC0, DiC0, TP0, TS0, RP0, RS0,
1049 ERaT0, RotaT0, RetT0, ERaR0, RotaR0, RetR0, LDRCal0)
1050 print("{0:10.5f},{1:10.5f},{2:10.5f},{3:10.5f},{4:10.5f},{5:10.5f}".format(LDRtrue, LDRunCorr, 1/LDRunCorr, LDRsimx, 1/LDRsimx, LDRCorr))
1051 aF11sim0[i] = F11sim0
1052 # the assumed true aF11sim0 results will be used below to calc the deviation from the real signals
1053 print("LDRsimx = LDR of the nominal system directly from measured signals without calibration and GHK-corrections")
1054 print("LDRunCorr = LDR of the nominal system directly from measured signals with calibration but without GHK-corrections; electronic amplifications = 1 assumed")
1055 print("LDRCorr = LDR calibrated and GHK-corrected")
1056 print()
1057 print("Errors from signal noise:")
1058 print("Signal counts: NCalT, NCalR, NILfac, nNCal, nNI = {0:10.0f},{1:10.0f},{2:3.0f},{3:2.0f},{4:2.0f}".format(
1059 NCalT, NCalR, NILfac, nNCal, nNI))
1060
1061 '''# das muß wieder weg
1062 print("IoutTp, IoutTm, IoutRp, IoutRm, It , Ir , dIoutTp, dIoutTm, dIoutRp, dIoutRm, dIt, dIr")
1063 LDRCal = 0.01
1064 for i, LDRtrue in enumerate(LDRrange):
1065 IoutTp, IoutTm, IoutRp, IoutRm, It, Ir, dIoutTp, dIoutTm, dIoutRp, dIoutRm, dIt, dIr, \
1066 GT0, HT0, GR0, HR0, K0, Eta0, LDRsimx, LDRCorr, DTa0, DRa0, TTa0, TRa0, F11sim0, LDRunCorr = \
1067 Calc(TCalT0, TCalR0, NCalT, NCalR, DOLP0, RotL0, RotE0, RetE0, DiE0,
1068 RotO0, RetO0, DiO0, RotC0, RetC0, DiC0, TP0, TS0, RP0, RS0,
1069 ERaT0, RotaT0, RetT0, ERaR0, RotaR0, RetR0, LDRCal0)
1070 print( "{:0.4f}, {:0.4f}, {:0.4f}, {:0.4f}, {:0.4f}, {:0.4f}, {:0.4f}, {:0.4f}, {:0.4f}, {:0.4f}, {:0.4f}, {:0.4f}".format(
1071 IoutTp * NCalT, IoutTm * NCalT, IoutRp * NCalR, IoutRm * NCalR, It * facIt, Ir * facIr,
1072 dIoutTp, dIoutTm, dIoutRp, dIoutRm, dIt, dIr))
1073 aF11sim0[i] = F11sim0
1074 # the assumed true aF11sim0 results will be used below to calc the deviation from the real signals
1075 # bis hierher weg
1076 '''
1077
1078 file = open('output_files\\' + LID + '-' + InputFile[0:-3] + '-GHK.dat', 'r')
1079 print(file.read())
1080 file.close()
1081
1082 '''
1083 if(PrintToOutputFile):
1084 f = open('output_ver7.dat', 'w')
1085 old_target = sys.stdout
1086 sys.stdout = f
1087
1088 print("something")
1089
1090 if(PrintToOutputFile):
1091 sys.stdout.flush()
1092 f.close
1093 sys.stdout = old_target
1094 '''
1095 if (Error_Calc):
1096 # --- CALC again assumed truth with LDRCal0 and with assumed true parameters in input file to reset all 0-values
1097 IoutTp0, IoutTm0, IoutRp0, IoutRm0, It0, Ir0, dIoutTp0, dIoutTm0, dIoutRp0, dIoutRm0, dIt0, dIr0, \
1098 GT0, HT0, GR0, HR0, K0, Eta0, LDRsimx, LDRCorr, DTa0, DRa0, TTa0, TRa0, F11sim0, LDRunCorr = \
1099 Calc(TCalT0, TCalR0, NCalT, NCalR, DOLP0, RotL0, RotE0, RetE0, DiE0,
1100 RotO0, RetO0, DiO0, RotC0, RetC0, DiC0, TP0, TS0, RP0, RS0,
1101 ERaT0, RotaT0, RetT0, ERaR0, RotaR0, RetR0, LDRCal0)
1102 Etax0 = K0 * Eta0
1103 # --- Start Error calculation with variable parameters ------------------------------------------------------------------
1104 # error nNCal: one-sigma in steps to left and right for calibration signals
1105 # error nNI: one-sigma in steps to left and right for 0° signals
1106
1107 iN = -1
1108 N = ((nTCalT * 2 + 1) * (nTCalR * 2 + 1) *
1109 (nNCal * 2 + 1) ** 4 * (nNI * 2 + 1) ** 2 *
1110 (nDOLP * 2 + 1) * (nRotL * 2 + 1) *
1111 (nRotE * 2 + 1) * (nRetE * 2 + 1) * (nDiE * 2 + 1) *
1112 (nRotO * 2 + 1) * (nRetO * 2 + 1) * (nDiO * 2 + 1) *
1113 (nRotC * 2 + 1) * (nRetC * 2 + 1) * (nDiC * 2 + 1) *
1114 (nTP * 2 + 1) * (nTS * 2 + 1) * (nRP * 2 + 1) * (nRS * 2 + 1) * (nERaT * 2 + 1) * (nERaR * 2 + 1) *
1115 (nRotaT * 2 + 1) * (nRotaR * 2 + 1) * (nRetT * 2 + 1) * (nRetR * 2 + 1) * (nLDRCal * 2 + 1))
1116 print("number of system variations N = ", N, " ", end="")
1117
1118 if N > 1e6:
1119 if user_yes_no_query('Warning: processing ' + str(
1120 N) + ' samples will take very long. Do you want to proceed?') == 0: sys.exit()
1121 if N > 5e6:
1122 if user_yes_no_query('Warning: the memory required for ' + str(N) + ' samples might be ' + '{0:5.1f}'.format(
1123 N / 4e6) + ' GB. Do you anyway want to proceed?') == 0: sys.exit()
1124
1125 # if user_yes_no_query('Warning: processing' + str(N) + ' samples will take very long. Do you want to proceed?') == 0: sys.exit()
1126
1127 # --- Arrays for plotting ------
1128 LDRmin = np.zeros(5)
1129 LDRmax = np.zeros(5)
1130 F11min = np.zeros(5)
1131 F11max = np.zeros(5)
1132 Etaxmin = np.zeros(5)
1133 Etaxmax = np.zeros(5)
1134
1135 # LDRrange = np.zeros(5)
1136 # LDRrange = 0.004, 0.02, 0.1, 0.3, 0.45
1137 # aLDRsimx = np.zeros(N)
1138 # aLDRsimx2 = np.zeros(N)
1139 # aLDRcorr = np.zeros(N)
1140 # aLDRcorr2 = np.zeros(N)
1141 aDOLP = np.zeros(N)
1142 aERaT = np.zeros(N)
1143 aERaR = np.zeros(N)
1144 aRotaT = np.zeros(N)
1145 aRotaR = np.zeros(N)
1146 aRetT = np.zeros(N)
1147 aRetR = np.zeros(N)
1148 aTP = np.zeros(N)
1149 aTS = np.zeros(N)
1150 aRP = np.zeros(N)
1151 aRS = np.zeros(N)
1152 aDiE = np.zeros(N)
1153 aDiO = np.zeros(N)
1154 aDiC = np.zeros(N)
1155 aRotC = np.zeros(N)
1156 aRetC = np.zeros(N)
1157 aRotL = np.zeros(N)
1158 aRetE = np.zeros(N)
1159 aRotE = np.zeros(N)
1160 aRetO = np.zeros(N)
1161 aRotO = np.zeros(N)
1162 aLDRCal = np.zeros(N)
1163 aNCalTp = np.zeros(N)
1164 aNCalTm = np.zeros(N)
1165 aNCalRp = np.zeros(N)
1166 aNCalRm = np.zeros(N)
1167 aNIt = np.zeros(N)
1168 aNIr = np.zeros(N)
1169 aTCalT = np.zeros(N)
1170 aTCalR = np.zeros(N)
1171
1172 # each np.zeros((LDRrange, N)) array has the same N-dependency
1173 aLDRcorr = np.zeros((5, N))
1174 aF11corr = np.zeros((5, N))
1175 aPLDR = np.zeros((5, N))
1176 aEtax = np.zeros((5, N))
1177
1178 # np.zeros((GHKs, N))
1179 aGHK = np.zeros((5, N))
1180
1181 atime = clock()
1182 dtime = clock()
1183
1184 # --- Calc Error signals
1185 # ---- Do the calculations of bra-ket vectors
1186 h = -1. if TypeC == 2 else 1
1187
1188 '''
1189 # from input file: measured LDRm and true LDRtrue, LDRtrue2 =>
1190 ameas = (1. - LDRmeas) / (1 + LDRmeas)
1191 atrue = (1. - LDRtrue) / (1 + LDRtrue)
1192 atrue2 = (1. - LDRtrue2) / (1 + LDRtrue2)
1193 '''
1194
1195 for iLDRCal in range(-nLDRCal, nLDRCal + 1):
1196 # from input file: LDRCal for calibration measurements
1197 LDRCal = LDRCal0
1198 if nLDRCal > 0:
1199 LDRCal = LDRCal0 + iLDRCal * dLDRCal / nLDRCal
1200 # provides the intensities of the calibration measurements at various LDRCal for signal noise errors
1201 # IoutTp, IoutTm, IoutRp, IoutRm, dIoutTp, dIoutTm, dIoutRp, dIoutRm
1202 '''
1203 IoutTp, IoutTm, IoutRp, IoutRm, It, Ir, dIoutTp, dIoutTm, dIoutRp, dIoutRm, dIt, dIr, \
1204 GT, HT, GR, HR, K, Eta, LDRsimx, LDRCorr, DTa, DRa, TTa, TRa, F11sim, LDRunCorr = \
1205 Calc(TCalT, TCalR, NCalT, NCalR, DOLP0, RotL0, RotE0, RetE0, DiE0,
1206 RotO0, RetO0, DiO0, RotC0, RetC0, DiC0, TP0, TS0, RP0, RS0,
1207 ERaT0, RotaT0, RetT0, ERaR0, RotaR0, RetR0, LDRCal)
1208 '''
1209 aCal = (1. - LDRCal) / (1 + LDRCal)
1210 for iDOLP, iRotL, iRotE, iRetE, iDiE \
1211 in [(iDOLP, iRotL, iRotE, iRetE, iDiE)
1212 for iDOLP in range(-nDOLP, nDOLP + 1)
1213 for iRotL in range(-nRotL, nRotL + 1)
1214 for iRotE in range(-nRotE, nRotE + 1)
1215 for iRetE in range(-nRetE, nRetE + 1)
1216 for iDiE in range(-nDiE, nDiE + 1)]:
1217
1218 if nDOLP > 0: DOLP = DOLP0 + iDOLP * dDOLP / nDOLP
1219 if nRotL > 0: RotL = RotL0 + iRotL * dRotL / nRotL
1220 if nRotE > 0: RotE = RotE0 + iRotE * dRotE / nRotE
1221 if nRetE > 0: RetE = RetE0 + iRetE * dRetE / nRetE
1222 if nDiE > 0: DiE = DiE0 + iDiE * dDiE / nDiE
1223
1224 # angles of emitter and laser and calibrator and receiver optics
1225 # RotL = alpha, RotE = beta, RotO = gamma, RotC = epsilon
1226 S2a = np.sin(2 * np.deg2rad(RotL))
1227 C2a = np.cos(2 * np.deg2rad(RotL))
1228 S2b = np.sin(2 * np.deg2rad(RotE))
1229 C2b = np.cos(2 * np.deg2rad(RotE))
1230 S2ab = np.sin(np.deg2rad(2 * RotL - 2 * RotE))
1231 C2ab = np.cos(np.deg2rad(2 * RotL - 2 * RotE))
1232
1233 # Laser with Degree of linear polarization DOLP
1234 IinL = 1.
1235 QinL = DOLP
1236 UinL = 0.
1237 VinL = (1. - DOLP ** 2) ** 0.5
1238
1239 # Stokes Input Vector rotation Eq. E.4
1240 A = C2a * QinL - S2a * UinL
1241 B = S2a * QinL + C2a * UinL
1242 # Stokes Input Vector rotation Eq. E.9
1243 C = C2ab * QinL - S2ab * UinL
1244 D = S2ab * QinL + C2ab * UinL
1245
1246 # emitter optics
1247 CosE = np.cos(np.deg2rad(RetE))
1248 SinE = np.sin(np.deg2rad(RetE))
1249 ZiE = (1. - DiE ** 2) ** 0.5
1250 WiE = (1. - ZiE * CosE)
1251
1252 # Stokes Input Vector after emitter optics equivalent to Eq. E.9 with already rotated input vector from Eq. E.4
1253 # b = beta
1254 IinE = (IinL + DiE * C)
1255 QinE = (C2b * DiE * IinL + A + S2b * (WiE * D - ZiE * SinE * VinL))
1256 UinE = (S2b * DiE * IinL + B - C2b * (WiE * D - ZiE * SinE * VinL))
1257 VinE = (-ZiE * SinE * D + ZiE * CosE * VinL)
1258
1259 # -------------------------
1260 # F11 assuemd to be = 1 => measured: F11m = IinP / IinE with atrue
1261 # F11sim = (IinE + DiO*atrue*(C2g*QinE - S2g*UinE))/IinE
1262 # -------------------------
1263
1264 for iRotO, iRetO, iDiO, iRotC, iRetC, iDiC, iTP, iTS, iRP, iRS, iERaT, iRotaT, iRetT, iERaR, iRotaR, iRetR \
1265 in [
1266 (iRotO, iRetO, iDiO, iRotC, iRetC, iDiC, iTP, iTS, iRP, iRS, iERaT, iRotaT, iRetT, iERaR, iRotaR, iRetR)
1267 for iRotO in range(-nRotO, nRotO + 1)
1268 for iRetO in range(-nRetO, nRetO + 1)
1269 for iDiO in range(-nDiO, nDiO + 1)
1270 for iRotC in range(-nRotC, nRotC + 1)
1271 for iRetC in range(-nRetC, nRetC + 1)
1272 for iDiC in range(-nDiC, nDiC + 1)
1273 for iTP in range(-nTP, nTP + 1)
1274 for iTS in range(-nTS, nTS + 1)
1275 for iRP in range(-nRP, nRP + 1)
1276 for iRS in range(-nRS, nRS + 1)
1277 for iERaT in range(-nERaT, nERaT + 1)
1278 for iRotaT in range(-nRotaT, nRotaT + 1)
1279 for iRetT in range(-nRetT, nRetT + 1)
1280 for iERaR in range(-nERaR, nERaR + 1)
1281 for iRotaR in range(-nRotaR, nRotaR + 1)
1282 for iRetR in range(-nRetR, nRetR + 1)]:
1283
1284 if nRotO > 0: RotO = RotO0 + iRotO * dRotO / nRotO
1285 if nRetO > 0: RetO = RetO0 + iRetO * dRetO / nRetO
1286 if nDiO > 0: DiO = DiO0 + iDiO * dDiO / nDiO
1287 if nRotC > 0: RotC = RotC0 + iRotC * dRotC / nRotC
1288 if nRetC > 0: RetC = RetC0 + iRetC * dRetC / nRetC
1289 if nDiC > 0: DiC = DiC0 + iDiC * dDiC / nDiC
1290 if nTP > 0: TP = TP0 + iTP * dTP / nTP
1291 if nTS > 0: TS = TS0 + iTS * dTS / nTS
1292 if nRP > 0: RP = RP0 + iRP * dRP / nRP
1293 if nRS > 0: RS = RS0 + iRS * dRS / nRS
1294 if nERaT > 0: ERaT = ERaT0 + iERaT * dERaT / nERaT
1295 if nRotaT > 0: RotaT = RotaT0 + iRotaT * dRotaT / nRotaT
1296 if nRetT > 0: RetT = RetT0 + iRetT * dRetT / nRetT
1297 if nERaR > 0: ERaR = ERaR0 + iERaR * dERaR / nERaR
1298 if nRotaR > 0: RotaR = RotaR0 + iRotaR * dRotaR / nRotaR
1299 if nRetR > 0: RetR = RetR0 + iRetR * dRetR / nRetR
1300
1301 # print("{0:5.2f}, {1:5.2f}, {2:5.2f}, {3:10d}".format(RotL, RotE, RotO, iN))
1302
1303 # receiver optics
1304 CosO = np.cos(np.deg2rad(RetO))
1305 SinO = np.sin(np.deg2rad(RetO))
1306 ZiO = (1. - DiO ** 2) ** 0.5
1307 WiO = (1. - ZiO * CosO)
1308 S2g = np.sin(np.deg2rad(2 * RotO))
1309 C2g = np.cos(np.deg2rad(2 * RotO))
1310 # calibrator
1311 CosC = np.cos(np.deg2rad(RetC))
1312 SinC = np.sin(np.deg2rad(RetC))
1313 ZiC = (1. - DiC ** 2) ** 0.5
1314 WiC = (1. - ZiC * CosC)
1315
1316 # analyser
1317 # For POLLY_XTs
1318 if (RS_RP_depend_on_TS_TP):
1319 RS = 1 - TS
1320 RP = 1 - TP
1321 TiT = 0.5 * (TP + TS)
1322 DiT = (TP - TS) / (TP + TS)
1323 ZiT = (1. - DiT ** 2) ** 0.5
1324 TiR = 0.5 * (RP + RS)
1325 DiR = (RP - RS) / (RP + RS)
1326 ZiR = (1. - DiR ** 2) ** 0.5
1327 CosT = np.cos(np.deg2rad(RetT))
1328 SinT = np.sin(np.deg2rad(RetT))
1329 CosR = np.cos(np.deg2rad(RetR))
1330 SinR = np.sin(np.deg2rad(RetR))
1331
1332 # cleaning pol-filter
1333 DaT = (1 - ERaT) / (1 + ERaT)
1334 DaR = (1 - ERaR) / (1 + ERaR)
1335 TaT = 0.5 * (1 + ERaT)
1336 TaR = 0.5 * (1 + ERaR)
1337
1338 S2aT = np.sin(np.deg2rad(h * 2 * RotaT))
1339 C2aT = np.cos(np.deg2rad(2 * RotaT))
1340 S2aR = np.sin(np.deg2rad(h * 2 * RotaR))
1341 C2aR = np.cos(np.deg2rad(2 * RotaR))
1342
1343 # Analyzer As before the PBS Eq. D.5; combined PBS and cleaning pol-filter
1344 ATPT = (1 + C2aT * DaT * DiT) # unpolarized transmission correction
1345 TTa = TiT * TaT * ATPT # unpolarized transmission
1346 ATP1 = 1
1347 ATP2 = Y * (DiT + C2aT * DaT) / ATPT
1348 ATP3 = Y * S2aT * DaT * ZiT * CosT / ATPT
1349 ATP4 = S2aT * DaT * ZiT * SinT / ATPT
1350 ATP = np.array([ATP1, ATP2, ATP3, ATP4])
1351 DTa = ATP2 * Y
1352
1353 ARPT = (1 + C2aR * DaR * DiR) # unpolarized transmission correction
1354 TRa = TiR * TaR * ARPT # unpolarized transmission
1355 ARP1 = 1
1356 ARP2 = Y * (DiR + C2aR * DaR) / ARPT
1357 ARP3 = Y * S2aR * DaR * ZiR * CosR / ARPT
1358 ARP4 = S2aR * DaR * ZiR * SinR / ARPT
1359 ARP = np.array([ARP1, ARP2, ARP3, ARP4])
1360 DRa = ARP2 * Y
1361
1362 # ---- Calculate signals and correction parameters for diffeent locations and calibrators
1363 if LocC == 4: # Calibrator before the PBS
1364 # print("Calibrator location not implemented yet")
1365
1366 # S2ge = np.sin(np.deg2rad(2*RotO + h*2*RotC))
1367 # C2ge = np.cos(np.deg2rad(2*RotO + h*2*RotC))
1368 S2e = np.sin(np.deg2rad(h * 2 * RotC))
1369 C2e = np.cos(np.deg2rad(2 * RotC))
1370 # rotated AinP by epsilon Eq. C.3
1371 ATP2e = C2e * ATP2 + S2e * ATP3
1372 ATP3e = C2e * ATP3 - S2e * ATP2
1373 ARP2e = C2e * ARP2 + S2e * ARP3
1374 ARP3e = C2e * ARP3 - S2e * ARP2
1375 ATPe = np.array([ATP1, ATP2e, ATP3e, ATP4])
1376 ARPe = np.array([ARP1, ARP2e, ARP3e, ARP4])
1377 # Stokes Input Vector before the polarising beam splitter Eq. E.31
1378 A = C2g * QinE - S2g * UinE
1379 B = S2g * QinE + C2g * UinE
1380 # C = (WiO*aCal*B + ZiO*SinO*(1-2*aCal)*VinE)
1381 Co = ZiO * SinO * VinE
1382 Ca = (WiO * B - 2 * ZiO * SinO * VinE)
1383 # C = Co + aCal*Ca
1384 # IinP = (IinE + DiO*aCal*A)
1385 # QinP = (C2g*DiO*IinE + aCal*QinE - S2g*C)
1386 # UinP = (S2g*DiO*IinE - aCal*UinE + C2g*C)
1387 # VinP = (ZiO*SinO*aCal*B + ZiO*CosO*(1-2*aCal)*VinE)
1388 IinPo = IinE
1389 QinPo = (C2g * DiO * IinE - S2g * Co)
1390 UinPo = (S2g * DiO * IinE + C2g * Co)
1391 VinPo = ZiO * CosO * VinE
1392
1393 IinPa = DiO * A
1394 QinPa = QinE - S2g * Ca
1395 UinPa = -UinE + C2g * Ca
1396 VinPa = ZiO * (SinO * B - 2 * CosO * VinE)
1397
1398 IinP = IinPo + aCal * IinPa
1399 QinP = QinPo + aCal * QinPa
1400 UinP = UinPo + aCal * UinPa
1401 VinP = VinPo + aCal * VinPa
1402 # Stokes Input Vector before the polarising beam splitter rotated by epsilon Eq. C.3
1403 # QinPe = C2e*QinP + S2e*UinP
1404 # UinPe = C2e*UinP - S2e*QinP
1405 QinPoe = C2e * QinPo + S2e * UinPo
1406 UinPoe = C2e * UinPo - S2e * QinPo
1407 QinPae = C2e * QinPa + S2e * UinPa
1408 UinPae = C2e * UinPa - S2e * QinPa
1409 QinPe = C2e * QinP + S2e * UinP
1410 UinPe = C2e * UinP - S2e * QinP
1411
1412 # Calibration signals and Calibration correction K from measurements with LDRCal / aCal
1413 if (TypeC == 2) or (TypeC == 1): # rotator calibration Eq. C.4
1414 # parameters for calibration with aCal
1415 AT = ATP1 * IinP + h * ATP4 * VinP
1416 BT = ATP3e * QinP - h * ATP2e * UinP
1417 AR = ARP1 * IinP + h * ARP4 * VinP
1418 BR = ARP3e * QinP - h * ARP2e * UinP
1419 # Correction parameters for normal measurements; they are independent of LDR
1420 if (not RotationErrorEpsilonForNormalMeasurements): # calibrator taken out
1421 IS1 = np.array([IinPo, QinPo, UinPo, VinPo])
1422 IS2 = np.array([IinPa, QinPa, UinPa, VinPa])
1423 GT = np.dot(ATP, IS1)
1424 GR = np.dot(ARP, IS1)
1425 HT = np.dot(ATP, IS2)
1426 HR = np.dot(ARP, IS2)
1427 else:
1428 IS1 = np.array([IinPo, QinPo, UinPo, VinPo])
1429 IS2 = np.array([IinPa, QinPa, UinPa, VinPa])
1430 GT = np.dot(ATPe, IS1)
1431 GR = np.dot(ARPe, IS1)
1432 HT = np.dot(ATPe, IS2)
1433 HR = np.dot(ARPe, IS2)
1434 elif (TypeC == 3) or (TypeC == 4): # linear polariser calibration Eq. C.5
1435 # parameters for calibration with aCal
1436 AT = ATP1 * IinP + ATP3e * UinPe + ZiC * CosC * (ATP2e * QinPe + ATP4 * VinP)
1437 BT = DiC * (ATP1 * UinPe + ATP3e * IinP) - ZiC * SinC * (ATP2e * VinP - ATP4 * QinPe)
1438 AR = ARP1 * IinP + ARP3e * UinPe + ZiC * CosC * (ARP2e * QinPe + ARP4 * VinP)
1439 BR = DiC * (ARP1 * UinPe + ARP3e * IinP) - ZiC * SinC * (ARP2e * VinP - ARP4 * QinPe)
1440 # Correction parameters for normal measurements; they are independent of LDR
1441 if (not RotationErrorEpsilonForNormalMeasurements): # calibrator taken out
1442 IS1 = np.array([IinPo, QinPo, UinPo, VinPo])
1443 IS2 = np.array([IinPa, QinPa, UinPa, VinPa])
1444 GT = np.dot(ATP, IS1)
1445 GR = np.dot(ARP, IS1)
1446 HT = np.dot(ATP, IS2)
1447 HR = np.dot(ARP, IS2)
1448 else:
1449 IS1e = np.array(
1450 [IinPo + DiC * QinPoe, DiC * IinPo + QinPoe, ZiC * (CosC * UinPoe + SinC * VinPo),
1451 -ZiC * (SinC * UinPoe - CosC * VinPo)])
1452 IS2e = np.array(
1453 [IinPa + DiC * QinPae, DiC * IinPa + QinPae, ZiC * (CosC * UinPae + SinC * VinPa),
1454 -ZiC * (SinC * UinPae - CosC * VinPa)])
1455 GT = np.dot(ATPe, IS1e)
1456 GR = np.dot(ARPe, IS1e)
1457 HT = np.dot(ATPe, IS2e)
1458 HR = np.dot(ARPe, IS2e)
1459 elif (TypeC == 6): # diattenuator calibration +-22.5° rotated_diattenuator_X22x5deg.odt
1460 # parameters for calibration with aCal
1461 AT = ATP1 * IinP + sqr05 * DiC * (ATP1 * QinPe + ATP2e * IinP) + (1 - 0.5 * WiC) * (
1462 ATP2e * QinPe + ATP3e * UinPe) + ZiC * (
1463 sqr05 * SinC * (ATP3e * VinP - ATP4 * UinPe) + ATP4 * CosC * VinP)
1464 BT = sqr05 * DiC * (ATP1 * UinPe + ATP3e * IinP) + 0.5 * WiC * (
1465 ATP2e * UinPe + ATP3e * QinPe) - sqr05 * ZiC * SinC * (ATP2e * VinP - ATP4 * QinPe)
1466 AR = ARP1 * IinP + sqr05 * DiC * (ARP1 * QinPe + ARP2e * IinP) + (1 - 0.5 * WiC) * (
1467 ARP2e * QinPe + ARP3e * UinPe) + ZiC * (
1468 sqr05 * SinC * (ARP3e * VinP - ARP4 * UinPe) + ARP4 * CosC * VinP)
1469 BR = sqr05 * DiC * (ARP1 * UinPe + ARP3e * IinP) + 0.5 * WiC * (
1470 ARP2e * UinPe + ARP3e * QinPe) - sqr05 * ZiC * SinC * (ARP2e * VinP - ARP4 * QinPe)
1471 # Correction parameters for normal measurements; they are independent of LDR
1472 if (not RotationErrorEpsilonForNormalMeasurements): # calibrator taken out
1473 IS1 = np.array([IinPo, QinPo, UinPo, VinPo])
1474 IS2 = np.array([IinPa, QinPa, UinPa, VinPa])
1475 GT = np.dot(ATP, IS1)
1476 GR = np.dot(ARP, IS1)
1477 HT = np.dot(ATP, IS2)
1478 HR = np.dot(ARP, IS2)
1479 else:
1480 IS1e = np.array(
1481 [IinPo + DiC * QinPoe, DiC * IinPo + QinPoe, ZiC * (CosC * UinPoe + SinC * VinPo),
1482 -ZiC * (SinC * UinPoe - CosC * VinPo)])
1483 IS2e = np.array(
1484 [IinPa + DiC * QinPae, DiC * IinPa + QinPae, ZiC * (CosC * UinPae + SinC * VinPa),
1485 -ZiC * (SinC * UinPae - CosC * VinPa)])
1486 GT = np.dot(ATPe, IS1e)
1487 GR = np.dot(ARPe, IS1e)
1488 HT = np.dot(ATPe, IS2e)
1489 HR = np.dot(ARPe, IS2e)
1490 else:
1491 print("Calibrator not implemented yet")
1492 sys.exit()
1493
1494 elif LocC == 3: # C before receiver optics Eq.57
1495
1496 # S2ge = np.sin(np.deg2rad(2*RotO - 2*RotC))
1497 # C2ge = np.cos(np.deg2rad(2*RotO - 2*RotC))
1498 S2e = np.sin(np.deg2rad(2 * RotC))
1499 C2e = np.cos(np.deg2rad(2 * RotC))
1500
1501 # AS with C before the receiver optics (see document rotated_diattenuator_X22x5deg.odt)
1502 AF1 = np.array([1, C2g * DiO, S2g * DiO, 0])
1503 AF2 = np.array([C2g * DiO, 1 - S2g ** 2 * WiO, S2g * C2g * WiO, -S2g * ZiO * SinO])
1504 AF3 = np.array([S2g * DiO, S2g * C2g * WiO, 1 - C2g ** 2 * WiO, C2g * ZiO * SinO])
1505 AF4 = np.array([0, S2g * SinO, -C2g * SinO, CosO])
1506
1507 ATF = (ATP1 * AF1 + ATP2 * AF2 + ATP3 * AF3 + ATP4 * AF4)
1508 ARF = (ARP1 * AF1 + ARP2 * AF2 + ARP3 * AF3 + ARP4 * AF4)
1509 ATF1 = ATF[0]
1510 ATF2 = ATF[1]
1511 ATF3 = ATF[2]
1512 ATF4 = ATF[3]
1513 ARF1 = ARF[0]
1514 ARF2 = ARF[1]
1515 ARF3 = ARF[2]
1516 ARF4 = ARF[3]
1517
1518 # rotated AinF by epsilon
1519 ATF2e = C2e * ATF[1] + S2e * ATF[2]
1520 ATF3e = C2e * ATF[2] - S2e * ATF[1]
1521 ARF2e = C2e * ARF[1] + S2e * ARF[2]
1522 ARF3e = C2e * ARF[2] - S2e * ARF[1]
1523
1524 ATFe = np.array([ATF1, ATF2e, ATF3e, ATF4])
1525 ARFe = np.array([ARF1, ARF2e, ARF3e, ARF4])
1526
1527 QinEe = C2e * QinE + S2e * UinE
1528 UinEe = C2e * UinE - S2e * QinE
1529
1530 # Stokes Input Vector before receiver optics Eq. E.19 (after atmosphere F)
1531 IinF = IinE
1532 QinF = aCal * QinE
1533 UinF = -aCal * UinE
1534 VinF = (1. - 2. * aCal) * VinE
1535
1536 IinFo = IinE
1537 QinFo = 0.
1538 UinFo = 0.
1539 VinFo = VinE
1540
1541 IinFa = 0.
1542 QinFa = QinE
1543 UinFa = -UinE
1544 VinFa = -2. * VinE
1545
1546 # Stokes Input Vector before receiver optics rotated by epsilon Eq. C.3
1547 QinFe = C2e * QinF + S2e * UinF
1548 UinFe = C2e * UinF - S2e * QinF
1549 QinFoe = C2e * QinFo + S2e * UinFo
1550 UinFoe = C2e * UinFo - S2e * QinFo
1551 QinFae = C2e * QinFa + S2e * UinFa
1552 UinFae = C2e * UinFa - S2e * QinFa
1553
1554 # Calibration signals and Calibration correction K from measurements with LDRCal / aCal
1555 if (TypeC == 2) or (TypeC == 1): # rotator calibration Eq. C.4
1556 AT = ATF1 * IinF + ATF4 * h * VinF
1557 BT = ATF3e * QinF - ATF2e * h * UinF
1558 AR = ARF1 * IinF + ARF4 * h * VinF
1559 BR = ARF3e * QinF - ARF2e * h * UinF
1560
1561 # Correction parameters for normal measurements; they are independent of LDR
1562 if (not RotationErrorEpsilonForNormalMeasurements):
1563 GT = ATF1 * IinE + ATF4 * VinE
1564 GR = ARF1 * IinE + ARF4 * VinE
1565 HT = ATF2 * QinE - ATF3 * UinE - ATF4 * 2 * VinE
1566 HR = ARF2 * QinE - ARF3 * UinE - ARF4 * 2 * VinE
1567 else:
1568 GT = ATF1 * IinE + ATF4 * h * VinE
1569 GR = ARF1 * IinE + ARF4 * h * VinE
1570 HT = ATF2e * QinE - ATF3e * h * UinE - ATF4 * h * 2 * VinE
1571 HR = ARF2e * QinE - ARF3e * h * UinE - ARF4 * h * 2 * VinE
1572
1573 elif (TypeC == 3) or (TypeC == 4): # linear polariser calibration Eq. C.5
1574 # p = +45°, m = -45°
1575 IF1e = np.array([IinF, ZiC * CosC * QinFe, UinFe, ZiC * CosC * VinF])
1576 IF2e = np.array([DiC * UinFe, -ZiC * SinC * VinF, DiC * IinF, ZiC * SinC * QinFe])
1577
1578 AT = np.dot(ATFe, IF1e)
1579 AR = np.dot(ARFe, IF1e)
1580 BT = np.dot(ATFe, IF2e)
1581 BR = np.dot(ARFe, IF2e)
1582
1583 # Correction parameters for normal measurements; they are independent of LDR --- the same as for TypeC = 6
1584 if (not RotationErrorEpsilonForNormalMeasurements): # calibrator taken out
1585 IS1 = np.array([IinE, 0, 0, VinE])
1586 IS2 = np.array([0, QinE, -UinE, -2 * VinE])
1587
1588 GT = np.dot(ATF, IS1)
1589 GR = np.dot(ARF, IS1)
1590 HT = np.dot(ATF, IS2)
1591 HR = np.dot(ARF, IS2)
1592 else:
1593 IS1e = np.array(
1594 [IinFo + DiC * QinFoe, DiC * IinFo + QinFoe, ZiC * (CosC * UinFoe + SinC * VinFo),
1595 -ZiC * (SinC * UinFoe - CosC * VinFo)])
1596 IS2e = np.array(
1597 [IinFa + DiC * QinFae, DiC * IinFa + QinFae, ZiC * (CosC * UinFae + SinC * VinFa),
1598 -ZiC * (SinC * UinFae - CosC * VinFa)])
1599 GT = np.dot(ATFe, IS1e)
1600 GR = np.dot(ARFe, IS1e)
1601 HT = np.dot(ATFe, IS2e)
1602 HR = np.dot(ARFe, IS2e)
1603
1604 elif (TypeC == 6): # diattenuator calibration +-22.5° rotated_diattenuator_X22x5deg.odt
1605 # p = +22.5°, m = -22.5°
1606 IF1e = np.array([IinF + sqr05 * DiC * QinFe, sqr05 * DiC * IinF + (1 - 0.5 * WiC) * QinFe,
1607 (1 - 0.5 * WiC) * UinFe + sqr05 * ZiC * SinC * VinF,
1608 -sqr05 * ZiC * SinC * UinFe + ZiC * CosC * VinF])
1609 IF2e = np.array([sqr05 * DiC * UinFe, 0.5 * WiC * UinFe - sqr05 * ZiC * SinC * VinF,
1610 sqr05 * DiC * IinF + 0.5 * WiC * QinFe, sqr05 * ZiC * SinC * QinFe])
1611
1612 AT = np.dot(ATFe, IF1e)
1613 AR = np.dot(ARFe, IF1e)
1614 BT = np.dot(ATFe, IF2e)
1615 BR = np.dot(ARFe, IF2e)
1616
1617 # Correction parameters for normal measurements; they are independent of LDR
1618 if (not RotationErrorEpsilonForNormalMeasurements): # calibrator taken out
1619 # IS1 = np.array([IinE,0,0,VinE])
1620 # IS2 = np.array([0,QinE,-UinE,-2*VinE])
1621 IS1 = np.array([IinFo, 0, 0, VinFo])
1622 IS2 = np.array([0, QinFa, UinFa, VinFa])
1623 GT = np.dot(ATF, IS1)
1624 GR = np.dot(ARF, IS1)
1625 HT = np.dot(ATF, IS2)
1626 HR = np.dot(ARF, IS2)
1627 else:
1628 # IS1e = np.array([IinE,DiC*IinE,ZiC*SinC*VinE,ZiC*CosC*VinE])
1629 # IS2e = np.array([DiC*QinEe,QinEe,-ZiC*(CosC*UinEe+2*SinC*VinE),ZiC*(SinC*UinEe-2*CosC*VinE)])
1630 IS1e = np.array(
1631 [IinFo + DiC * QinFoe, DiC * IinFo + QinFoe, ZiC * (CosC * UinFoe + SinC * VinFo),
1632 -ZiC * (SinC * UinFoe - CosC * VinFo)])
1633 IS2e = np.array(
1634 [IinFa + DiC * QinFae, DiC * IinFa + QinFae, ZiC * (CosC * UinFae + SinC * VinFa),
1635 -ZiC * (SinC * UinFae - CosC * VinFa)])
1636 GT = np.dot(ATFe, IS1e)
1637 GR = np.dot(ARFe, IS1e)
1638 HT = np.dot(ATFe, IS2e)
1639 HR = np.dot(ARFe, IS2e)
1640
1641
1642 else:
1643 print('Calibrator not implemented yet')
1644 sys.exit()
1645
1646 elif LocC == 2: # C behind emitter optics Eq.57
1647 # print("Calibrator location not implemented yet")
1648 S2e = np.sin(np.deg2rad(2 * RotC))
1649 C2e = np.cos(np.deg2rad(2 * RotC))
1650
1651 # AS with C before the receiver optics (see document rotated_diattenuator_X22x5deg.odt)
1652 AF1 = np.array([1, C2g * DiO, S2g * DiO, 0])
1653 AF2 = np.array([C2g * DiO, 1 - S2g ** 2 * WiO, S2g * C2g * WiO, -S2g * ZiO * SinO])
1654 AF3 = np.array([S2g * DiO, S2g * C2g * WiO, 1 - C2g ** 2 * WiO, C2g * ZiO * SinO])
1655 AF4 = np.array([0, S2g * SinO, -C2g * SinO, CosO])
1656
1657 ATF = (ATP1 * AF1 + ATP2 * AF2 + ATP3 * AF3 + ATP4 * AF4)
1658 ARF = (ARP1 * AF1 + ARP2 * AF2 + ARP3 * AF3 + ARP4 * AF4)
1659 ATF1 = ATF[0]
1660 ATF2 = ATF[1]
1661 ATF3 = ATF[2]
1662 ATF4 = ATF[3]
1663 ARF1 = ARF[0]
1664 ARF2 = ARF[1]
1665 ARF3 = ARF[2]
1666 ARF4 = ARF[3]
1667
1668 # AS with C behind the emitter --------------------------------------------
1669 # terms without aCal
1670 ATE1o, ARE1o = ATF1, ARF1
1671 ATE2o, ARE2o = 0., 0.
1672 ATE3o, ARE3o = 0., 0.
1673 ATE4o, ARE4o = ATF4, ARF4
1674 # terms with aCal
1675 ATE1a, ARE1a = 0., 0.
1676 ATE2a, ARE2a = ATF2, ARF2
1677 ATE3a, ARE3a = -ATF3, -ARF3
1678 ATE4a, ARE4a = -2 * ATF4, -2 * ARF4
1679 # rotated AinEa by epsilon
1680 ATE2ae = C2e * ATF2 + S2e * ATF3
1681 ATE3ae = -S2e * ATF2 - C2e * ATF3
1682 ARE2ae = C2e * ARF2 + S2e * ARF3
1683 ARE3ae = -S2e * ARF2 - C2e * ARF3
1684
1685 ATE1 = ATE1o
1686 ATE2e = aCal * ATE2ae
1687 ATE3e = aCal * ATE3ae
1688 ATE4 = (1 - 2 * aCal) * ATF4
1689 ARE1 = ARE1o
1690 ARE2e = aCal * ARE2ae
1691 ARE3e = aCal * ARE3ae
1692 ARE4 = (1 - 2 * aCal) * ARF4
1693
1694 # rotated IinE
1695 QinEe = C2e * QinE + S2e * UinE
1696 UinEe = C2e * UinE - S2e * QinE
1697
1698 # --- Calibration signals and Calibration correction K from measurements with LDRCal / aCal
1699 if (TypeC == 2) or (TypeC == 1): # +++++++++ rotator calibration Eq. C.4
1700 AT = ATE1o * IinE + (ATE4o + aCal * ATE4a) * h * VinE
1701 BT = aCal * (ATE3ae * QinEe - ATE2ae * h * UinEe)
1702 AR = ARE1o * IinE + (ARE4o + aCal * ARE4a) * h * VinE
1703 BR = aCal * (ARE3ae * QinEe - ARE2ae * h * UinEe)
1704
1705 # Correction parameters for normal measurements; they are independent of LDR
1706 if (not RotationErrorEpsilonForNormalMeasurements):
1707 # Stokes Input Vector before receiver optics Eq. E.19 (after atmosphere F)
1708 GT = ATE1o * IinE + ATE4o * h * VinE
1709 GR = ARE1o * IinE + ARE4o * h * VinE
1710 HT = ATE2a * QinE + ATE3a * h * UinEe + ATE4a * h * VinE
1711 HR = ARE2a * QinE + ARE3a * h * UinEe + ARE4a * h * VinE
1712 else:
1713 GT = ATE1o * IinE + ATE4o * h * VinE
1714 GR = ARE1o * IinE + ARE4o * h * VinE
1715 HT = ATE2ae * QinE + ATE3ae * h * UinEe + ATE4a * h * VinE
1716 HR = ARE2ae * QinE + ARE3ae * h * UinEe + ARE4a * h * VinE
1717
1718 elif (TypeC == 3) or (TypeC == 4): # +++++++++ linear polariser calibration Eq. C.5
1719 # p = +45°, m = -45°
1720 AT = ATE1 * IinE + ZiC * CosC * (ATE2e * QinEe + ATE4 * VinE) + ATE3e * UinEe
1721 BT = DiC * (ATE1 * UinEe + ATE3e * IinE) + ZiC * SinC * (ATE4 * QinEe - ATE2e * VinE)
1722 AR = ARE1 * IinE + ZiC * CosC * (ARE2e * QinEe + ARE4 * VinE) + ARE3e * UinEe
1723 BR = DiC * (ARE1 * UinEe + ARE3e * IinE) + ZiC * SinC * (ARE4 * QinEe - ARE2e * VinE)
1724
1725 # Correction parameters for normal measurements; they are independent of LDR
1726 if (not RotationErrorEpsilonForNormalMeasurements):
1727 # Stokes Input Vector before receiver optics Eq. E.19 (after atmosphere F)
1728 GT = ATE1o * IinE + ATE4o * VinE
1729 GR = ARE1o * IinE + ARE4o * VinE
1730 HT = ATE2a * QinE + ATE3a * UinE + ATE4a * VinE
1731 HR = ARE2a * QinE + ARE3a * UinE + ARE4a * VinE
1732 else:
1733 D = IinE + DiC * QinEe
1734 A = DiC * IinE + QinEe
1735 B = ZiC * (CosC * UinEe + SinC * VinE)
1736 C = -ZiC * (SinC * UinEe - CosC * VinE)
1737 GT = ATE1o * D + ATE4o * C
1738 GR = ARE1o * D + ARE4o * C
1739 HT = ATE2a * A + ATE3a * B + ATE4a * C
1740 HR = ARE2a * A + ARE3a * B + ARE4a * C
1741
1742 elif (TypeC == 6): # real HWP calibration +-22.5° rotated_diattenuator_X22x5deg.odt
1743 # p = +22.5°, m = -22.5°
1744 IE1e = np.array([IinE + sqr05 * DiC * QinEe, sqr05 * DiC * IinE + (1 - 0.5 * WiC) * QinEe,
1745 (1 - 0.5 * WiC) * UinEe + sqr05 * ZiC * SinC * VinE,
1746 -sqr05 * ZiC * SinC * UinEe + ZiC * CosC * VinE])
1747 IE2e = np.array([sqr05 * DiC * UinEe, 0.5 * WiC * UinEe - sqr05 * ZiC * SinC * VinE,
1748 sqr05 * DiC * IinE + 0.5 * WiC * QinEe, sqr05 * ZiC * SinC * QinEe])
1749 ATEe = np.array([ATE1, ATE2e, ATE3e, ATE4])
1750 AREe = np.array([ARE1, ARE2e, ARE3e, ARE4])
1751 AT = np.dot(ATEe, IE1e)
1752 AR = np.dot(AREe, IE1e)
1753 BT = np.dot(ATEe, IE2e)
1754 BR = np.dot(AREe, IE2e)
1755
1756 # Correction parameters for normal measurements; they are independent of LDR
1757 if (not RotationErrorEpsilonForNormalMeasurements): # calibrator taken out
1758 GT = ATE1o * IinE + ATE4o * VinE
1759 GR = ARE1o * IinE + ARE4o * VinE
1760 HT = ATE2a * QinE + ATE3a * UinE + ATE4a * VinE
1761 HR = ARE2a * QinE + ARE3a * UinE + ARE4a * VinE
1762 else:
1763 D = IinE + DiC * QinEe
1764 A = DiC * IinE + QinEe
1765 B = ZiC * (CosC * UinEe + SinC * VinE)
1766 C = -ZiC * (SinC * UinEe - CosC * VinE)
1767 GT = ATE1o * D + ATE4o * C
1768 GR = ARE1o * D + ARE4o * C
1769 HT = ATE2a * A + ATE3a * B + ATE4a * C
1770 HR = ARE2a * A + ARE3a * B + ARE4a * C
1771 else:
1772 print('Calibrator not implemented yet')
1773 sys.exit()
1774
1775 for iTCalT, iTCalR, iNCalTp, iNCalTm, iNCalRp, iNCalRm, iNIt, iNIr \
1776 in [
1777 (iTCalT, iTCalR, iNCalTp, iNCalTm, iNCalRp, iNCalRm, iNIt, iNIr)
1778 for iTCalT in range(-nTCalT, nTCalT + 1) # Etax
1779 for iTCalR in range(-nTCalR, nTCalR + 1) # Etax
1780 for iNCalTp in range(-nNCal, nNCal + 1) # noise error of calibration signals => Etax
1781 for iNCalTm in range(-nNCal, nNCal + 1) # noise error of calibration signals => Etax
1782 for iNCalRp in range(-nNCal, nNCal + 1) # noise error of calibration signals => Etax
1783 for iNCalRm in range(-nNCal, nNCal + 1) # noise error of calibration signals => Etax
1784 for iNIt in range(-nNI, nNI + 1)
1785 for iNIr in range(-nNI, nNI + 1)]:
1786
1787 # Calibration signals with aCal => Determination of the correction K of the real calibration factor
1788 IoutTp = TTa * TiC * TiO * TiE * (AT + BT)
1789 IoutTm = TTa * TiC * TiO * TiE * (AT - BT)
1790 IoutRp = TRa * TiC * TiO * TiE * (AR + BR)
1791 IoutRm = TRa * TiC * TiO * TiE * (AR - BR)
1792
1793 if nTCalT > 0: TCalT = TCalT0 + iTCalT * dTCalT / nTCalT
1794 if nTCalR > 0: TCalR = TCalR0 + iTCalR * dTCalR / nTCalR
1795 # signal noise errors
1796 # ----- random error calculation ----------
1797 # noise must be calculated from/with the actually measured signals; influence of TCalT, TCalR errors on nouse are not considered ?
1798 # actually measured signals are in input file and don't change
1799 # relative standard deviation of calibration signals with LDRcal; assumed to be statisitcally independent
1800 # error nNCal: one-sigma in steps to left and right for calibration signals
1801 if nNCal > 0:
1802 if (CalcFrom0deg):
1803 dIoutTp = (NCalT * IoutTp) ** -0.5
1804 dIoutTm = (NCalT * IoutTm) ** -0.5
1805 dIoutRp = (NCalR * IoutRp) ** -0.5
1806 dIoutRm = (NCalR * IoutRm) ** -0.5
1807 else:
1808 dIoutTp = dIoutTp0 * (IoutTp / IoutTp0)
1809 dIoutTm = dIoutTm0 * (IoutTm / IoutTm0)
1810 dIoutRp = dIoutRp0 * (IoutRp / IoutRp0)
1811 dIoutRm = dIoutRm0 * (IoutRm / IoutRm0)
1812 # print(iTCalT, iTCalR, iNCalTp, iNCalTm, iNCalRp, iNCalRm, iNIt, iNIr, IoutTp, dIoutTp)
1813 IoutTp = IoutTp * (1 + iNCalTp * dIoutTp / nNCal)
1814 IoutTm = IoutTm * (1 + iNCalTm * dIoutTm / nNCal)
1815 IoutRp = IoutRp * (1 + iNCalRp * dIoutRp / nNCal)
1816 IoutRm = IoutRm * (1 + iNCalRm * dIoutRm / nNCal)
1817
1818 IoutTp = IoutTp * TCalT / TCalT0
1819 IoutTm = IoutTm * TCalT / TCalT0
1820 IoutRp = IoutRp * TCalR / TCalR0
1821 IoutRm = IoutRm * TCalR / TCalR0
1822 # --- Results and Corrections; electronic etaR and etaT are assumed to be 1 for true and assumed true systems
1823 # calibration factor
1824 Eta = (TRa / TTa) # = TRa / TTa; Eta = Eta*/K Eq. 84; corrected according to the papers supplement Eqs. (S.10.10.1) ff
1825 # possibly real calibration factor
1826 Etapx = IoutRp / IoutTp
1827 Etamx = IoutRm / IoutTm
1828 Etax = (Etapx * Etamx) ** 0.5
1829 K = Etax / Eta
1830 # print("{0:6.3f},{1:6.3f},{2:6.3f},{3:6.3f},{4:6.3f},{5:6.3f},{6:6.3f},{7:6.3f},{8:6.3f},{9:6.3f},{10:6.3f}".format(AT, BT, AR, BR, DiC, ZiC, RetO, TP, TS, Kp, Km))
1831 # print("{0:6.3f},{1:6.3f},{2:6.3f},{3:6.3f}".format(DiC, ZiC, Kp, Km))
1832
1833 # For comparison with Volkers Libreoffice Müller Matrix spreadsheet
1834 # Eta_test_p = (IoutRp/IoutTp)
1835 # Eta_test_m = (IoutRm/IoutTm)
1836 # Eta_test = (Eta_test_p*Eta_test_m)**0.5
1837 '''
1838 for iIt, iIr \
1839 in [(iIt, iIr)
1840 for iIt in range(-nNI, nNI + 1)
1841 for iIr in range(-nNI, nNI + 1)]:
1842 '''
1843
1844 iN = iN + 1
1845 if (iN == 10001):
1846 ctime = clock()
1847 print(" estimated time ", "{0:4.2f}".format(N / 10000 * (ctime - atime)), "sec ") # , end="")
1848 print("\r elapsed time ", "{0:5.0f}".format((ctime - atime)), "sec ", end="\r")
1849 ctime = clock()
1850 if ((ctime - dtime) > 10):
1851 print("\r elapsed time ", "{0:5.0f}".format((ctime - atime)), "sec ", end="\r")
1852 dtime = ctime
1853
1854 # *** loop for different real LDRs **********************************************************************
1855 iLDR = -1
1856 for LDRTrue in LDRrange:
1857 iLDR = iLDR + 1
1858 atrue = (1 - LDRTrue) / (1 + LDRTrue)
1859 # ----- Forward simulated signals and LDRsim with atrue; from input file; not considering TiC.
1860 It = TTa * TiO * TiE * (GT + atrue * HT) # TaT*TiT*TiC*TiO*IinL*(GT+atrue*HT)
1861 Ir = TRa * TiO * TiE * (GR + atrue * HR) # TaR*TiR*TiC*TiO*IinL*(GR+atrue*HR)
1862 # # signal noise errors; standard deviation of signals; assumed to be statisitcally independent
1863 # because the signals depend on LDRtrue, the errors dIt and dIr must be calculated for each LDRtrue
1864 if (CalcFrom0deg):
1865 dIt = ((NCalT * It / IoutTp * NILfac / TCalT) ** -0.5)
1866 dIr = ((NCalR * Ir / IoutRp * NILfac / TCalR) ** -0.5)
1867 else:
1868 dIt = ((NCalT * 2 * NILfac / TCalT ) ** -0.5) * It
1869 dIr = ((NCalR * 2 * NILfac / TCalR) ** -0.5) * Ir
1870 # error nNI: one-sigma in steps to left and right for 0° signals
1871 if nNI > 0:
1872 It = It * (1 + iNIt * dIt / nNI)
1873 Ir = Ir * (1 + iNIr * dIr / nNI)
1874
1875 # LDRsim = 1/Eta*Ir/It # simulated LDR* with Y from input file
1876 LDRsim = Ir / It # simulated uncorrected LDR with Y from input file
1877
1878 # ----- Backward correction
1879 # Corrected LDRCorr with assumed true G0,H0,K0,Eta0 from forward simulated (real) LDRsim(atrue)
1880 LDRCorr = (LDRsim / (Etax / K0) * (GT0 + HT0) - (GR0 + HR0)) / ((GR0 - HR0) - LDRsim / (Etax / K0) * (GT0 - HT0))
1881
1882 # The following is a test whether the equations for calibration Etax and normal signal (GHK, LDRsim) are consistent
1883 # LDRCorr = (LDRsim / Eta * (GT + HT) - (GR + HR)) / ((GR - HR) - LDRsim / Eta * (GT - HT))
1884 # Without any correction
1885 LDRunCorr = (LDRsim / Etax * (GT / abs(GT) + HT / abs(HT)) - (GR / abs(GR) + HR / abs(HR))) / ((GR / abs(GR) - HR / abs(HR)) - LDRsim / Etax * (GT / abs(GT) - HT / abs(HT)))
1886
1887
1888 '''
1889 # -- F11corr from It and Ir and calibration EtaX
1890 Text1 = "!!! EXPERIMENTAL !!! F11corr from It and Ir with calibration EtaX: x-axis: F11corr(LDRtrue) / F11corr(LDRtrue = 0.004) - 1"
1891 F11corr = 1 / (TiO * TiE) * (
1892 (HR0 * Etax / K0 * It / TTa - HT0 * Ir / TRa) / (HR0 * GT0 - HT0 * GR0)) # IL = 1 Eq.(64); Etax/K0 = Eta0.
1893 '''
1894 # Corrected F11corr with assumed true G0,H0,K0 from forward simulated (real) It and Ir (atrue)
1895 Text1 = "!!! EXPERIMENTAL !!! F11corr from real It and Ir with real calibration EtaX: x-axis: F11corr(LDRtrue) / aF11sim0(LDRtrue) - 1"
1896 F11corr = 1 / (TiO * TiE) * (
1897 (HR0 * Etax / K0 * It / TTa - HT0 * Ir / TRa) / (HR0 * GT0 - HT0 * GR0)) # IL = 1 Eq.(64); Etax/K0 = Eta0.
1898
1899 # Text1 = "F11corr from It and Ir without corrections but with calibration EtaX: x-axis: F11corr(LDRtrue) devided by F11corr(LDRtrue = 0.004)"
1900 # F11corr = 0.5/(TiO*TiE)*(Etax*It/TTa+Ir/TRa) # IL = 1 Eq.(64)
1901
1902 # -- It from It only with atrue without corrections - for BERTHA (and PollyXTs)
1903 # Text1 = " x-axis: IT(LDRtrue) / IT(LDRtrue = 0.004) - 1"
1904 # F11corr = It/(TaT*TiT*TiO*TiE) #/(TaT*TiT*TiO*TiE*(GT0+atrue*HT0))
1905 # ! see below line 1673ff
1906
1907 aF11corr[iLDR, iN] = F11corr
1908 aLDRcorr[iLDR, iN] = LDRCorr # LDRCorr # LDRsim # for test only
1909 # aPLDR[iLDR, iN] = CalcPLDR(LDRCorr, BSR[iLDR], LDRm0)
1910 aEtax[iLDR, iN] = Etax
1911
1912 aGHK[0, iN] = GR
1913 aGHK[1, iN] = GT
1914 aGHK[2, iN] = HR
1915 aGHK[3, iN] = HT
1916 aGHK[4, iN] = K
1917
1918 aLDRCal[iN] = iLDRCal
1919 aDOLP[iN] = iDOLP
1920 aERaT[iN] = iERaT
1921 aERaR[iN] = iERaR
1922 aRotaT[iN] = iRotaT
1923 aRotaR[iN] = iRotaR
1924 aRetT[iN] = iRetT
1925 aRetR[iN] = iRetR
1926
1927 aRotL[iN] = iRotL
1928 aRotE[iN] = iRotE
1929 aRetE[iN] = iRetE
1930 aRotO[iN] = iRotO
1931 aRetO[iN] = iRetO
1932 aRotC[iN] = iRotC
1933 aRetC[iN] = iRetC
1934 aDiO[iN] = iDiO
1935 aDiE[iN] = iDiE
1936 aDiC[iN] = iDiC
1937 aTP[iN] = iTP
1938 aTS[iN] = iTS
1939 aRP[iN] = iRP
1940 aRS[iN] = iRS
1941 aTCalT[iN] = iTCalT
1942 aTCalR[iN] = iTCalR
1943
1944 aNCalTp[iN] = iNCalTp # IoutTp, IoutTm, IoutRp, IoutRm => Etax
1945 aNCalTm[iN] = iNCalTm # IoutTp, IoutTm, IoutRp, IoutRm => Etax
1946 aNCalRp[iN] = iNCalRp # IoutTp, IoutTm, IoutRp, IoutRm => Etax
1947 aNCalRm[iN] = iNCalRm # IoutTp, IoutTm, IoutRp, IoutRm => Etax
1948 aNIt[iN] = iNIt # It, Tr
1949 aNIr[iN] = iNIr # It, Tr
1950
1951 # --- END loop
1952 btime = clock()
1953 # print("\r done in ", "{0:5.0f}".format(btime - atime), "sec. => producing plots now .... some more seconds ..."), # , end="\r");
1954 print(" done in ", "{0:5.0f}".format(btime - atime), "sec. => producing plots now .... some more seconds ...")
1955 # --- Plot -----------------------------------------------------------------
1956 print("Errors from GHK correction uncertainties:")
1957 if (sns_loaded):
1958 sns.set_style("whitegrid")
1959 sns.set_palette("bright6", 6)
1960 # for older seaborn versions:
1961 # sns.set_palette("bright", 6)
1962
1963 '''
1964 fig2 = plt.figure()
1965 plt.plot(aLDRcorr[2,:],'b.')
1966 plt.plot(aLDRcorr[3,:],'r.')
1967 plt.plot(aLDRcorr[4,:],'g.')
1968 #plt.plot(aLDRcorr[6,:],'c.')
1969 plt.show
1970 '''
1971
1972 # Plot LDR
1973 def PlotSubHist(aVar, aX, X0, daX, iaX, naX):
1974 # aVar is the name of the parameter and aX is the subset of aLDRcorr which is coloured in the plot
1975 # example: PlotSubHist("DOLP", aDOLP, DOLP0, dDOLP, iDOLP, nDOLP)
1976 fig, ax = plt.subplots(nrows=1, ncols=5, sharex=True, sharey=True, figsize=(25, 2))
1977 iLDR = -1
1978 for LDRTrue in LDRrange:
1979 iLDR = iLDR + 1
1980 LDRmin[iLDR] = np.amin(aLDRcorr[iLDR, :])
1981 LDRmax[iLDR] = np.amax(aLDRcorr[iLDR, :])
1982 Rmin = LDRmin[iLDR] * 0.995 # np.min(aLDRcorr[iLDR,:]) * 0.995
1983 Rmax = LDRmax[iLDR] * 1.005 # np.max(aLDRcorr[iLDR,:]) * 1.005
1984
1985 # plt.subplot(5,2,iLDR+1)
1986 plt.subplot(1, 5, iLDR + 1)
1987 (n, bins, patches) = plt.hist(aLDRcorr[iLDR, :],
1988 bins=100, log=False,
1989 range=[Rmin, Rmax],
1990 alpha=0.5, density=False, color='0.5', histtype='stepfilled')
1991
1992 for iaX in range(-naX, naX + 1):
1993 plt.hist(aLDRcorr[iLDR, aX == iaX],
1994 range=[Rmin, Rmax],
1995 bins=100, log=False, alpha=0.3, density=False, histtype='stepfilled',
1996 label=str(round(X0 + iaX * daX / naX, 5)))
1997
1998 if (iLDR == 2):
1999 leg = plt.legend()
2000 leg.get_frame().set_alpha(0.1)
2001
2002
2003 plt.tick_params(axis='both', labelsize=9)
2004 plt.plot([LDRTrue, LDRTrue], [0, np.max(n)], 'r-', lw=2)
2005
2006 # plt.title(LID + ' ' + aVar, fontsize=18)
2007 # plt.ylabel('frequency', fontsize=10)
2008 # plt.xlabel('LDRcorr', fontsize=10)
2009 # fig.tight_layout()
2010 fig.suptitle(LID + ' with ' + str(Type[TypeC]) + ' ' + str(Loc[LocC]) + ' - ' + aVar, fontsize=14, y=1.05)
2011 # plt.show()
2012 # fig.savefig(LID + '_' + aVar + '.png', dpi=150, bbox_inches='tight', pad_inches=0)
2013 # plt.close
2014 return
2015
2016 # Plot Etax
2017 def PlotEtax(aVar, aX, X0, daX, iaX, naX):
2018 # aVar is the name of the parameter and aX is the subset of aLDRcorr which is coloured in the plot
2019 # example: PlotSubHist("DOLP", aDOLP, DOLP0, dDOLP, iDOLP, nDOLP)
2020 fig, ax = plt.subplots(nrows=1, ncols=5, sharex=True, sharey=True, figsize=(25, 2))
2021 iLDR = -1
2022 for LDRTrue in LDRrange:
2023 iLDR = iLDR + 1
2024 Etaxmin[iLDR] = np.amin(aEtax[iLDR, :])
2025 Etaxmax[iLDR] = np.amax(aEtax[iLDR, :])
2026 Rmin = Etaxmin[iLDR] * 0.995 # np.min(aLDRcorr[iLDR,:]) * 0.995
2027 Rmax = Etaxmax[iLDR] * 1.005 # np.max(aLDRcorr[iLDR,:]) * 1.005
2028
2029 # plt.subplot(5,2,iLDR+1)
2030 plt.subplot(1, 5, iLDR + 1)
2031 (n, bins, patches) = plt.hist(aEtax[iLDR, :],
2032 bins=100, log=False,
2033 range=[Rmin, Rmax],
2034 alpha=0.5, density=False, color='0.5', histtype='stepfilled')
2035 for iaX in range(-naX, naX + 1):
2036 plt.hist(aEtax[iLDR, aX == iaX],
2037 range=[Rmin, Rmax],
2038 bins=100, log=False, alpha=0.3, density=False, histtype='stepfilled',
2039 label=str(round(X0 + iaX * daX / naX, 5)))
2040 if (iLDR == 2):
2041 leg = plt.legend()
2042 leg.get_frame().set_alpha(0.1)
2043 plt.tick_params(axis='both', labelsize=9)
2044 plt.plot([Etax0, Etax0], [0, np.max(n)], 'r-', lw=2)
2045 fig.suptitle('Etax - ' + LID + ' with ' + str(Type[TypeC]) + ' ' + str(Loc[LocC]) + ' - ' + aVar, fontsize=14, y=1.05)
2046 return
2047
2048 if (nDOLP > 0): PlotSubHist("DOLP", aDOLP, DOLP0, dDOLP, iDOLP, nDOLP)
2049 if (nRotL > 0): PlotSubHist("RotL", aRotL, RotL0, dRotL, iRotL, nRotL)
2050 if (nRetE > 0): PlotSubHist("RetE", aRetE, RetE0, dRetE, iRetE, nRetE)
2051 if (nRotE > 0): PlotSubHist("RotE", aRotE, RotE0, dRotE, iRotE, nRotE)
2052 if (nDiE > 0): PlotSubHist("DiE", aDiE, DiE0, dDiE, iDiE, nDiE)
2053 if (nRetO > 0): PlotSubHist("RetO", aRetO, RetO0, dRetO, iRetO, nRetO)
2054 if (nRotO > 0): PlotSubHist("RotO", aRotO, RotO0, dRotO, iRotO, nRotO)
2055 if (nDiO > 0): PlotSubHist("DiO", aDiO, DiO0, dDiO, iDiO, nDiO)
2056 if (nDiC > 0): PlotSubHist("DiC", aDiC, DiC0, dDiC, iDiC, nDiC)
2057 if (nRotC > 0): PlotSubHist("RotC", aRotC, RotC0, dRotC, iRotC, nRotC)
2058 if (nRetC > 0): PlotSubHist("RetC", aRetC, RetC0, dRetC, iRetC, nRetC)
2059 if (nTP > 0): PlotSubHist("TP", aTP, TP0, dTP, iTP, nTP)
2060 if (nTS > 0): PlotSubHist("TS", aTS, TS0, dTS, iTS, nTS)
2061 if (nRP > 0): PlotSubHist("RP", aRP, RP0, dRP, iRP, nRP)
2062 if (nRS > 0): PlotSubHist("RS", aRS, RS0, dRS, iRS, nRS)
2063 if (nRetT > 0): PlotSubHist("RetT", aRetT, RetT0, dRetT, iRetT, nRetT)
2064 if (nRetR > 0): PlotSubHist("RetR", aRetR, RetR0, dRetR, iRetR, nRetR)
2065 if (nERaT > 0): PlotSubHist("ERaT", aERaT, ERaT0, dERaT, iERaT, nERaT)
2066 if (nERaR > 0): PlotSubHist("ERaR", aERaR, ERaR0, dERaR, iERaR, nERaR)
2067 if (nRotaT > 0): PlotSubHist("RotaT", aRotaT, RotaT0, dRotaT, iRotaT, nRotaT)
2068 if (nRotaR > 0): PlotSubHist("RotaR", aRotaR, RotaR0, dRotaR, iRotaR, nRotaR)
2069 if (nLDRCal > 0): PlotSubHist("LDRCal", aLDRCal, LDRCal0, dLDRCal, iLDRCal, nLDRCal)
2070 if (nTCalT > 0): PlotSubHist("TCalT", aTCalT, TCalT0, dTCalT, iTCalT, nTCalT)
2071 if (nTCalR > 0): PlotSubHist("TCalR", aTCalR, TCalR0, dTCalR, iTCalR, nTCalR)
2072 if (nNCal > 0): PlotSubHist("CalNoiseTp", aNCalTp, 0, 1, iNCalTp, nNCal)
2073 if (nNCal > 0): PlotSubHist("CalNoiseTm", aNCalTm, 0, 1, iNCalTm, nNCal)
2074 if (nNCal > 0): PlotSubHist("CalNoiseRp", aNCalRp, 0, 1, iNCalRp, nNCal)
2075 if (nNCal > 0): PlotSubHist("CalNoiseRm", aNCalRm, 0, 1, iNCalRm, nNCal)
2076 if (nNI > 0): PlotSubHist("SigNoiseIt", aNIt, 0, 1, iNIt, nNI)
2077 if (nNI > 0): PlotSubHist("SigNoiseIr", aNIr, 0, 1, iNIr, nNI)
2078 plt.show()
2079 plt.close
2080
2081 '''
2082 # --- Plot F11 histograms
2083 print()
2084 print(" ############################################################################## ")
2085 print(Text1)
2086 print()
2087
2088 iLDR = 5
2089 for LDRTrue in LDRrange:
2090 iLDR = iLDR - 1
2091 #aF11corr[iLDR,:] = aF11corr[iLDR,:] / aF11corr[0,:] - 1.0
2092 aF11corr[iLDR,:] = aF11corr[iLDR,:] / aF11sim0[iLDR] - 1.0
2093 # Plot F11
2094 def PlotSubHistF11(aVar, aX, X0, daX, iaX, naX):
2095 fig, ax = plt.subplots(nrows=1, ncols=5, sharex=True, sharey=True, figsize=(25, 2))
2096 iLDR = -1
2097 for LDRTrue in LDRrange:
2098 iLDR = iLDR + 1
2099
2100 #F11min[iLDR] = np.min(aF11corr[iLDR,:])
2101 #F11max[iLDR] = np.max(aF11corr[iLDR,:])
2102 #Rmin = F11min[iLDR] * 0.995 # np.min(aLDRcorr[iLDR,:]) * 0.995
2103 #Rmax = F11max[iLDR] * 1.005 # np.max(aLDRcorr[iLDR,:]) * 1.005
2104
2105 #Rmin = 0.8
2106 #Rmax = 1.2
2107
2108 #plt.subplot(5,2,iLDR+1)
2109 plt.subplot(1,5,iLDR+1)
2110 (n, bins, patches) = plt.hist(aF11corr[iLDR,:],
2111 bins=100, log=False,
2112 alpha=0.5, density=False, color = '0.5', histtype='stepfilled')
2113
2114 for iaX in range(-naX,naX+1):
2115 plt.hist(aF11corr[iLDR,aX == iaX],
2116 bins=100, log=False, alpha=0.3, density=False, histtype='stepfilled', label = str(round(X0 + iaX*daX/naX,5)))
2117
2118 if (iLDR == 2): plt.legend()
2119
2120 plt.tick_params(axis='both', labelsize=9)
2121 #plt.plot([LDRTrue, LDRTrue], [0, np.max(n)], 'r-', lw=2)
2122
2123 #plt.title(LID + ' ' + aVar, fontsize=18)
2124 #plt.ylabel('frequency', fontsize=10)
2125 #plt.xlabel('LDRcorr', fontsize=10)
2126 #fig.tight_layout()
2127 fig.suptitle(LID + ' ' + str(Type[TypeC]) + ' ' + str(Loc[LocC]) + ' - ' + aVar, fontsize=14, y=1.05)
2128 #plt.show()
2129 #fig.savefig(LID + '_' + aVar + '.png', dpi=150, bbox_inches='tight', pad_inches=0)
2130 #plt.close
2131 return
2132
2133 if (nDOLP > 0): PlotSubHistF11("DOLP", aDOLP, DOLP0, dDOLP, iDOLP, nDOLP)
2134 if (nRotL > 0): PlotSubHistF11("RotL", aRotL, RotL0, dRotL, iRotL, nRotL)
2135 if (nRetE > 0): PlotSubHistF11("RetE", aRetE, RetE0, dRetE, iRetE, nRetE)
2136 if (nRotE > 0): PlotSubHistF11("RotE", aRotE, RotE0, dRotE, iRotE, nRotE)
2137 if (nDiE > 0): PlotSubHistF11("DiE", aDiE, DiE0, dDiE, iDiE, nDiE)
2138 if (nRetO > 0): PlotSubHistF11("RetO", aRetO, RetO0, dRetO, iRetO, nRetO)
2139 if (nRotO > 0): PlotSubHistF11("RotO", aRotO, RotO0, dRotO, iRotO, nRotO)
2140 if (nDiO > 0): PlotSubHistF11("DiO", aDiO, DiO0, dDiO, iDiO, nDiO)
2141 if (nDiC > 0): PlotSubHistF11("DiC", aDiC, DiC0, dDiC, iDiC, nDiC)
2142 if (nRotC > 0): PlotSubHistF11("RotC", aRotC, RotC0, dRotC, iRotC, nRotC)
2143 if (nRetC > 0): PlotSubHistF11("RetC", aRetC, RetC0, dRetC, iRetC, nRetC)
2144 if (nTP > 0): PlotSubHistF11("TP", aTP, TP0, dTP, iTP, nTP)
2145 if (nTS > 0): PlotSubHistF11("TS", aTS, TS0, dTS, iTS, nTS)
2146 if (nRP > 0): PlotSubHistF11("RP", aRP, RP0, dRP, iRP, nRP)
2147 if (nRS > 0): PlotSubHistF11("RS", aRS, RS0, dRS, iRS, nRS)
2148 if (nRetT > 0): PlotSubHistF11("RetT", aRetT, RetT0, dRetT, iRetT, nRetT)
2149 if (nRetR > 0): PlotSubHistF11("RetR", aRetR, RetR0, dRetR, iRetR, nRetR)
2150 if (nERaT > 0): PlotSubHistF11("ERaT", aERaT, ERaT0, dERaT, iERaT, nERaT)
2151 if (nERaR > 0): PlotSubHistF11("ERaR", aERaR, ERaR0, dERaR, iERaR, nERaR)
2152 if (nRotaT > 0): PlotSubHistF11("RotaT", aRotaT, RotaT0, dRotaT, iRotaT, nRotaT)
2153 if (nRotaR > 0): PlotSubHistF11("RotaR", aRotaR, RotaR0, dRotaR, iRotaR, nRotaR)
2154 if (nLDRCal > 0): PlotSubHistF11("LDRCal", aLDRCal, LDRCal0, dLDRCal, iLDRCal, nLDRCal)
2155 if (nTCalT > 0): PlotSubHistF11("TCalT", aTCalT, TCalT0, dTCalT, iTCalT, nTCalT)
2156 if (nTCalR > 0): PlotSubHistF11("TCalR", aTCalR, TCalR0, dTCalR, iTCalR, nTCalR)
2157 if (nNCal > 0): PlotSubHistF11("CalNoise", aNCal, 0, 1/nNCal, iNCal, nNCal)
2158 if (nNI > 0): PlotSubHistF11("SigNoise", aNI, 0, 1/nNI, iNI, nNI)
2159
2160
2161 plt.show()
2162 plt.close
2163
2164 '''
2165 '''
2166 # only histogram
2167 #print("******************* " + aVar + " *******************")
2168 fig, ax = plt.subplots(nrows=5, ncols=2, sharex=True, sharey=True, figsize=(10, 10))
2169 iLDR = -1
2170 for LDRTrue in LDRrange:
2171 iLDR = iLDR + 1
2172 LDRmin[iLDR] = np.min(aLDRcorr[iLDR,:])
2173 LDRmax[iLDR] = np.max(aLDRcorr[iLDR,:])
2174 Rmin = np.min(aLDRcorr[iLDR,:]) * 0.999
2175 Rmax = np.max(aLDRcorr[iLDR,:]) * 1.001
2176 plt.subplot(5,2,iLDR+1)
2177 (n, bins, patches) = plt.hist(aLDRcorr[iLDR,:],
2178 range=[Rmin, Rmax],
2179 bins=200, log=False, alpha=0.2, density=False, color = '0.5', histtype='stepfilled')
2180 plt.tick_params(axis='both', labelsize=9)
2181 plt.plot([LDRTrue, LDRTrue], [0, np.max(n)], 'r-', lw=2)
2182 plt.show()
2183 plt.close
2184 # --- End of Plot F11 histograms
2185 '''
2186
2187 # --- Plot LDRmin, LDRmax
2188 iLDR = -1
2189 for LDRTrue in LDRrange:
2190 iLDR = iLDR + 1
2191 LDRmin[iLDR] = np.amin(aLDRcorr[iLDR, :])
2192 LDRmax[iLDR] = np.amax(aLDRcorr[iLDR, :])
2193
2194 fig2 = plt.figure()
2195 LDRrangeA = np.array(LDRrange)
2196 if((np.amax(LDRmax - LDRrangeA)-np.amin(LDRmin - LDRrangeA)) < 0.001):
2197 plt.ylim(-0.001,0.001)
2198 plt.plot(LDRrangeA, LDRmax - LDRrangeA, linewidth=2.0, color='b')
2199 plt.plot(LDRrangeA, LDRmin - LDRrangeA, linewidth=2.0, color='g')
2200
2201 plt.xlabel('LDRtrue', fontsize=18)
2202 plt.ylabel('LDRTrue-LDRmin, LDRTrue-LDRmax', fontsize=14)
2203 plt.title(LID + ' ' + str(Type[TypeC]) + ' ' + str(Loc[LocC]), fontsize=18)
2204 # plt.ylimit(-0.07, 0.07)
2205 plt.show()
2206 plt.close
2207
2208 # --- Save LDRmin, LDRmax to file
2209 # http://stackoverflow.com/questions/4675728/redirect-stdout-to-a-file-in-python
2210 with open('output_files\\' + LID + '-' + InputFile[0:-3] + '-LDR_min_max.dat', 'w') as f:
2211 with redirect_stdout(f):
2212 print(LID)
2213 print("LDRtrue, LDRmin, LDRmax")
2214 for i in range(len(LDRrangeA)):
2215 print("{0:7.4f},{1:7.4f},{2:7.4f}".format(LDRrangeA[i], LDRmin[i], LDRmax[i]))
2216
2217
2218 if (bPlotEtax):
2219 if (nDOLP > 0): PlotEtax("DOLP", aDOLP, DOLP0, dDOLP, iDOLP, nDOLP)
2220 if (nRotL > 0): PlotEtax("RotL", aRotL, RotL0, dRotL, iRotL, nRotL)
2221 if (nRetE > 0): PlotEtax("RetE", aRetE, RetE0, dRetE, iRetE, nRetE)
2222 if (nRotE > 0): PlotEtax("RotE", aRotE, RotE0, dRotE, iRotE, nRotE)
2223 if (nDiE > 0): PlotEtax("DiE", aDiE, DiE0, dDiE, iDiE, nDiE)
2224 if (nRetO > 0): PlotEtax("RetO", aRetO, RetO0, dRetO, iRetO, nRetO)
2225 if (nRotO > 0): PlotEtax("RotO", aRotO, RotO0, dRotO, iRotO, nRotO)
2226 if (nDiO > 0): PlotEtax("DiO", aDiO, DiO0, dDiO, iDiO, nDiO)
2227 if (nDiC > 0): PlotEtax("DiC", aDiC, DiC0, dDiC, iDiC, nDiC)
2228 if (nRotC > 0): PlotEtax("RotC", aRotC, RotC0, dRotC, iRotC, nRotC)
2229 if (nRetC > 0): PlotEtax("RetC", aRetC, RetC0, dRetC, iRetC, nRetC)
2230 if (nTP > 0): PlotEtax("TP", aTP, TP0, dTP, iTP, nTP)
2231 if (nTS > 0): PlotEtax("TS", aTS, TS0, dTS, iTS, nTS)
2232 if (nRP > 0): PlotEtax("RP", aRP, RP0, dRP, iRP, nRP)
2233 if (nRS > 0): PlotEtax("RS", aRS, RS0, dRS, iRS, nRS)
2234 if (nRetT > 0): PlotEtax("RetT", aRetT, RetT0, dRetT, iRetT, nRetT)
2235 if (nRetR > 0): PlotEtax("RetR", aRetR, RetR0, dRetR, iRetR, nRetR)
2236 if (nERaT > 0): PlotEtax("ERaT", aERaT, ERaT0, dERaT, iERaT, nERaT)
2237 if (nERaR > 0): PlotEtax("ERaR", aERaR, ERaR0, dERaR, iERaR, nERaR)
2238 if (nRotaT > 0): PlotEtax("RotaT", aRotaT, RotaT0, dRotaT, iRotaT, nRotaT)
2239 if (nRotaR > 0): PlotEtax("RotaR", aRotaR, RotaR0, dRotaR, iRotaR, nRotaR)
2240 if (nLDRCal > 0): PlotEtax("LDRCal", aLDRCal, LDRCal0, dLDRCal, iLDRCal, nLDRCal)
2241 if (nTCalT > 0): PlotEtax("TCalT", aTCalT, TCalT0, dTCalT, iTCalT, nTCalT)
2242 if (nTCalR > 0): PlotEtax("TCalR", aTCalR, TCalR0, dTCalR, iTCalR, nTCalR)
2243 if (nNCal > 0): PlotEtax("CalNoiseTp", aNCalTp, 0, 1, iNCalTp, nNCal)
2244 if (nNCal > 0): PlotEtax("CalNoiseTm", aNCalTm, 0, 1, iNCalTm, nNCal)
2245 if (nNCal > 0): PlotEtax("CalNoiseRp", aNCalRp, 0, 1, iNCalRp, nNCal)
2246 if (nNCal > 0): PlotEtax("CalNoiseRm", aNCalRm, 0, 1, iNCalRm, nNCal)
2247 if (nNI > 0): PlotEtax("SigNoiseIt", aNIt, 0, 1, iNIt, nNI)
2248 if (nNI > 0): PlotEtax("SigNoiseIr", aNIr, 0, 1, iNIr, nNI)
2249 plt.show()
2250 plt.close
2251
2252 #Etaxmin = np.amin(aEtax[1, :])
2253 Etaxmin = np.amin(aEtax[1, :])
2254 Etaxmax = np.amax(aEtax[1, :])
2255 Etaxstd = np.std(aEtax[1, :])
2256 Etaxmean = np.mean(aEtax[1, :])
2257 Etaxmedian = np.mean(aEtax[1, :])
2258
2259 print("Etax: mean±std, median, max-mean, mean-min")
2260 print("{0:7.4f}±{1:7.4f},{2:7.4f},+{3:7.4f},-{4:7.4f}".format(Etaxmean, Etaxstd, Etaxmedian, Etaxmax-Etaxmean, Etaxmean-Etaxmin, ))
2261
2262 '''
2263 # --- Plot K over LDRCal
2264 fig3 = plt.figure()
2265 plt.plot(LDRCal0+aLDRCal*dLDRCal/nLDRCal,aGHK[4,:], linewidth=2.0, color='b')
2266
2267 plt.xlabel('LDRCal', fontsize=18)
2268 plt.ylabel('K', fontsize=14)
2269 plt.title(LID, fontsize=18)
2270 plt.show()
2271 plt.close
2272 '''
2273
2274 # Additional plot routines ======>
2275 '''
2276 #******************************************************************************
2277 # 1. Plot LDRcorrected - LDR(measured Icross/Iparallel)
2278 LDRa = np.arange(1.,100.)*0.005
2279 LDRCorra = np.arange(1.,100.)
2280 if Y == - 1.: LDRa = 1./LDRa
2281 LDRCorra = (1./Eta*LDRa*(GT+HT)-(GR+HR))/((GR-HR)-1./Eta*LDRa*(GT-HT))
2282 if Y == - 1.: LDRa = 1./LDRa
2283 #
2284 #fig = plt.figure()
2285 plt.plot(LDRa,LDRCorra-LDRa)
2286 plt.plot([0.,0.5],[0.,0.5])
2287 plt.suptitle('LDRcorrected - LDR(measured Icross/Iparallel)', fontsize=16)
2288 plt.xlabel('LDR', fontsize=18)
2289 plt.ylabel('LDRCorr - LDR', fontsize=16)
2290 #plt.savefig('test.png')
2291 #
2292 '''
2293 '''
2294 #******************************************************************************
2295 # 2. Plot LDRsim (simulated measurements without corrections = Icross/Iparallel) over LDRtrue
2296 LDRa = np.arange(1.,100.)*0.005
2297 LDRsima = np.arange(1.,100.)
2298
2299 atruea = (1.-LDRa)/(1+LDRa)
2300 Ita = TiT*TiO*IinL*(GT+atruea*HT)
2301 Ira = TiR*TiO*IinL*(GR+atruea*HR)
2302 LDRsima = Ira/Ita # simulated uncorrected LDR with Y from input file
2303 if Y == -1.: LDRsima = 1./LDRsima
2304 #
2305 #fig = plt.figure()
2306 plt.plot(LDRa,LDRsima)
2307 plt.plot([0.,0.5],[0.,0.5])
2308 plt.suptitle('LDRsim (simulated measurements without corrections = Icross/Iparallel) over LDRtrue', fontsize=10)
2309 plt.xlabel('LDRtrue', fontsize=18)
2310 plt.ylabel('LDRsim', fontsize=16)
2311 #plt.savefig('test.png')
2312 #
2313 '''

mercurial