dkist-processing-cryonirsp 1.9.0__py3-none-any.whl → 1.10.0rc1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. changelog/167.feature.rst +1 -0
  2. dkist_processing_cryonirsp/config.py +4 -1
  3. dkist_processing_cryonirsp/models/constants.py +14 -1
  4. dkist_processing_cryonirsp/models/parameters.py +11 -19
  5. dkist_processing_cryonirsp/parsers/cryonirsp_l0_fits_access.py +3 -2
  6. dkist_processing_cryonirsp/tasks/__init__.py +1 -1
  7. dkist_processing_cryonirsp/tasks/parse.py +15 -3
  8. dkist_processing_cryonirsp/tasks/sp_wavelength_calibration.py +300 -0
  9. dkist_processing_cryonirsp/tasks/write_l1.py +6 -16
  10. dkist_processing_cryonirsp/tests/conftest.py +13 -20
  11. dkist_processing_cryonirsp/tests/header_models.py +12 -0
  12. dkist_processing_cryonirsp/tests/local_trial_workflows/l0_cals_only.py +17 -17
  13. dkist_processing_cryonirsp/tests/local_trial_workflows/l0_to_l1.py +17 -19
  14. dkist_processing_cryonirsp/tests/local_trial_workflows/local_trial_helpers.py +3 -3
  15. dkist_processing_cryonirsp/tests/test_cryo_constants.py +4 -1
  16. dkist_processing_cryonirsp/tests/test_parameters.py +4 -0
  17. dkist_processing_cryonirsp/tests/test_parse.py +28 -2
  18. dkist_processing_cryonirsp/tests/{test_sp_dispersion_axis_correction.py → test_sp_wavelength_calibration.py} +6 -23
  19. dkist_processing_cryonirsp/tests/test_write_l1.py +15 -15
  20. dkist_processing_cryonirsp/workflows/sp_l0_processing.py +3 -3
  21. dkist_processing_cryonirsp/workflows/trial_workflows.py +3 -3
  22. {dkist_processing_cryonirsp-1.9.0.dist-info → dkist_processing_cryonirsp-1.10.0rc1.dist-info}/METADATA +14 -13
  23. {dkist_processing_cryonirsp-1.9.0.dist-info → dkist_processing_cryonirsp-1.10.0rc1.dist-info}/RECORD +27 -25
  24. docs/index.rst +1 -0
  25. docs/wavelength_calibration.rst +62 -0
  26. dkist_processing_cryonirsp/tasks/sp_dispersion_axis_correction.py +0 -465
  27. {dkist_processing_cryonirsp-1.9.0.dist-info → dkist_processing_cryonirsp-1.10.0rc1.dist-info}/WHEEL +0 -0
  28. {dkist_processing_cryonirsp-1.9.0.dist-info → dkist_processing_cryonirsp-1.10.0rc1.dist-info}/top_level.txt +0 -0
@@ -1,18 +1,19 @@
1
1
  changelog/.gitempty,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ changelog/167.feature.rst,sha256=UDCWFhNjmut91SbtIICb3Y5_MiPJ4zSPc0chd6y8AJU,142
2
3
  dkist_processing_cryonirsp/__init__.py,sha256=Z6-kB7fXXUI-F7Vz1HnEaja2h8qgH9IZExRl1lUxvZg,350
3
- dkist_processing_cryonirsp/config.py,sha256=xNkUNJ1BeBxJX881mTCIEbirZlD5_5txpV1QqkbfRM0,507
4
+ dkist_processing_cryonirsp/config.py,sha256=DlU2dr_oORrwytQVmEUSg3IRPXxE4vhAWiCiw7ykvzo,641
4
5
  dkist_processing_cryonirsp/codecs/__init__.py,sha256=du1iitvsudSSOMENSywXmXSLOlvIocJsPbvfEcyqFNc,159
5
6
  dkist_processing_cryonirsp/codecs/fits.py,sha256=EAdPcqWXMEWtWnRDLH_LX20giPoLVfmKBawb9J2z0wM,1718
6
7
  dkist_processing_cryonirsp/models/__init__.py,sha256=m6UekKftTahNJ3W5K3mZSz4Y4ZZpHRxF_ZAxuaKYL7o,12
7
8
  dkist_processing_cryonirsp/models/beam_boundaries.py,sha256=FyiLd2iCWA6TUojeGaqQ_ULxvakDY13VxqUJVlmYvV0,1159
8
- dkist_processing_cryonirsp/models/constants.py,sha256=aKhSu4Hp0kKRgO6muMli2W4DC3zP0sEm4TzK--hyJXQ,11062
9
+ dkist_processing_cryonirsp/models/constants.py,sha256=rFCkE-bZhbCABKVtQom5iTfPgDqDzsKkrtTnngZExkM,11528
9
10
  dkist_processing_cryonirsp/models/exposure_conditions.py,sha256=slFq5-Qz4fRpJKDBabbm4evPWLQVYmT-Uf9rk7nI734,813
10
- dkist_processing_cryonirsp/models/parameters.py,sha256=icAnYJvVCSJiNoT9SuYTZfDx6imwcq7QwfCY3_qQAIY,13154
11
+ dkist_processing_cryonirsp/models/parameters.py,sha256=Yn6GPEGnMiQyEL9n2BPx9LIVWPSdVXmcIX9OzzDOvPc,13144
11
12
  dkist_processing_cryonirsp/models/tags.py,sha256=ac0MnYlsn8-w7IioOvWeo7mBaDKE9o9TlRpxCH1OsRc,5743
12
13
  dkist_processing_cryonirsp/models/task_name.py,sha256=xK4AKwgOx2uANbjhr0Q5Q3R9iPxLfkVKxWYY8wWjKhE,439
13
14
  dkist_processing_cryonirsp/parsers/__init__.py,sha256=m6UekKftTahNJ3W5K3mZSz4Y4ZZpHRxF_ZAxuaKYL7o,12
14
15
  dkist_processing_cryonirsp/parsers/check_for_gains.py,sha256=v-eD1LG0dlFoZXz5Y-2ZyPvRL2TZ8gWfr5cN6YNYqvo,2341
15
- dkist_processing_cryonirsp/parsers/cryonirsp_l0_fits_access.py,sha256=HtkmVdhEZxasKQyxWQyrirmiDrzAVfr3QCC2ldzBdSk,5617
16
+ dkist_processing_cryonirsp/parsers/cryonirsp_l0_fits_access.py,sha256=rMB4mrUGQnQ6nHEZVegkdGpnW4Q2iXG5YRAaAq9tOW4,5608
16
17
  dkist_processing_cryonirsp/parsers/cryonirsp_l1_fits_access.py,sha256=sc8MzxYMc8E1eFrL5KguAGHViCMJhaDfiBtZPml4ELg,886
17
18
  dkist_processing_cryonirsp/parsers/exposure_conditions.py,sha256=Mcud-0PQK0oJSxbqtQUtVk0t8b6YBEFSyGsGbG5UqGg,8445
18
19
  dkist_processing_cryonirsp/parsers/map_repeats.py,sha256=PjZ986bqkCdii-EOzU045cWqadxQC_nyyqwWYIpYdls,1566
@@ -23,7 +24,7 @@ dkist_processing_cryonirsp/parsers/polarimetric_check.py,sha256=HBzg9Zi9-M1M2jh4
23
24
  dkist_processing_cryonirsp/parsers/scan_step.py,sha256=7XNUq48qbdpV8GeaBeG9XFRDkYlgw8Fjd6ByFZ24OAc,18972
24
25
  dkist_processing_cryonirsp/parsers/time.py,sha256=dpajm3tfrih-8pjlOWOvZVJVP2FihR87HFQSjR_KPYI,2543
25
26
  dkist_processing_cryonirsp/parsers/wavelength.py,sha256=Ay5hZiDNV25-N_QXZINTCgn1ToiP2jvwumkbirBiJGk,883
26
- dkist_processing_cryonirsp/tasks/__init__.py,sha256=JyM9oA1A6t5sPsbaNmnK9_e6t00kUYzDZzqmSg0nVjE,1061
27
+ dkist_processing_cryonirsp/tasks/__init__.py,sha256=iSODAESNU6zBZo_t44LeTmS1oj_l6EVF7k8xSNtppnk,1057
27
28
  dkist_processing_cryonirsp/tasks/assemble_movie.py,sha256=UrxfKSsT3mBkV2LYvnePzKr9nXlvjpoa5amY5C3ftFI,7350
28
29
  dkist_processing_cryonirsp/tasks/bad_pixel_map.py,sha256=z-ACCwHqiRANsR7gkkCIycPpgOdR04Mo85WLAPiAJno,3961
29
30
  dkist_processing_cryonirsp/tasks/beam_boundaries_base.py,sha256=-sKmBDuNq22QZBe6Vdu5aaiOxeikM6bICpkZ4lBP--g,9688
@@ -36,21 +37,21 @@ dkist_processing_cryonirsp/tasks/instrument_polarization.py,sha256=xS2jcngnibDCL
36
37
  dkist_processing_cryonirsp/tasks/l1_output_data.py,sha256=3RFt493MEJxdpF81gcp8FDlQ8vGZ0GXEDYQFWIufumI,1554
37
38
  dkist_processing_cryonirsp/tasks/linearity_correction.py,sha256=n9vK9cT7NWkpAM9J6wOYDj95Kh0va_ot-hdncd7ye0Y,24199
38
39
  dkist_processing_cryonirsp/tasks/make_movie_frames.py,sha256=I7s3Tml6AevHci0kTPF71mNjXNl3wlG57Jh7ghnndeg,13928
39
- dkist_processing_cryonirsp/tasks/parse.py,sha256=5nkCjKeCi6oKHzBXmqs81yZwyRPBmIMmL8Lh53CEv4E,13114
40
+ dkist_processing_cryonirsp/tasks/parse.py,sha256=8efntsSPkNl_sokRU2SEStZBCRJvnXDsCelVumOUwH8,13824
40
41
  dkist_processing_cryonirsp/tasks/quality_metrics.py,sha256=jyx2YZzLb5sVxbJ_H6PaKQqZbyZy9QuuLqu18jsnncQ,11447
41
42
  dkist_processing_cryonirsp/tasks/science_base.py,sha256=YYUQUfLeuzDb6E5TecOH22orTN4-hWocoYaGOq6Zoro,18637
42
43
  dkist_processing_cryonirsp/tasks/sp_beam_boundaries.py,sha256=XI3iepNe04xaU4ilqxrlOgYDkv5I5rUc0RXEE1Rwt0o,10296
43
- dkist_processing_cryonirsp/tasks/sp_dispersion_axis_correction.py,sha256=w3DHEWEJwl3zuKuUB6kzG3vuBWJM84cZGbfeFQKWwJE,18279
44
44
  dkist_processing_cryonirsp/tasks/sp_geometric.py,sha256=_M_e_blz4mKDIUWSasonnOzbZ6EUbHp9pAZXQx4zY7U,24387
45
45
  dkist_processing_cryonirsp/tasks/sp_science.py,sha256=QWyAEkXYamAcWxi62-tVD6ptuQ6vt8yIzuCKzCIYW20,13643
46
46
  dkist_processing_cryonirsp/tasks/sp_solar_gain.py,sha256=d4UABsMxyzCMduVxptHY_TCGqS-l-W5iuhW7HJwVPkA,21024
47
- dkist_processing_cryonirsp/tasks/write_l1.py,sha256=nLAV0fx_bRFA7WAPrdxJQKogGSRj3pscDJXzhogrVuw,41476
47
+ dkist_processing_cryonirsp/tasks/sp_wavelength_calibration.py,sha256=E9HBmlzvvUEgoAamlO-E0MngYKjuUVq3WwK0DRDLvPk,12843
48
+ dkist_processing_cryonirsp/tasks/write_l1.py,sha256=Jzg09WUYi8uY5o6By7JOsFP0CHpfPCVC4M2UvLSO2PA,41169
48
49
  dkist_processing_cryonirsp/tasks/mixin/__init__.py,sha256=m6UekKftTahNJ3W5K3mZSz4Y4ZZpHRxF_ZAxuaKYL7o,12
49
50
  dkist_processing_cryonirsp/tasks/mixin/corrections.py,sha256=rcKmckBJkoExcX0XW1i3OZzuMu1i7tX5Hgwy15chU50,6566
50
51
  dkist_processing_cryonirsp/tasks/mixin/shift_measurements.py,sha256=EbU3VQ_1QLbENHO_SfhWc7d573UwbofKU-PpbfBPKI8,11620
51
52
  dkist_processing_cryonirsp/tests/__init__.py,sha256=m6UekKftTahNJ3W5K3mZSz4Y4ZZpHRxF_ZAxuaKYL7o,12
52
- dkist_processing_cryonirsp/tests/conftest.py,sha256=oeZw5KXlvm_UasgFc3uzxD2Z2uTg5-rJu7Do9wIKJKU,18131
53
- dkist_processing_cryonirsp/tests/header_models.py,sha256=klif5-UzTzvAqpj5cJCdLtyodJZS_awhy53NUHyucTw,20601
53
+ dkist_processing_cryonirsp/tests/conftest.py,sha256=ThhhNZ61a-qRMiPEM7PgLwKTw9L4C5nh0IHLDnwtTRo,18016
54
+ dkist_processing_cryonirsp/tests/header_models.py,sha256=eQWRwJzWCIK8-ak1oLWf88u7eo7ERxPMrmQHuphUfX8,21115
54
55
  dkist_processing_cryonirsp/tests/test_assemble_movie.py,sha256=YNZINIFXR9kZBlE1AIvjlVmwwhZJeVYOOPk7Q8IVkcI,6222
55
56
  dkist_processing_cryonirsp/tests/test_assemble_qualilty.py,sha256=upk-oUqVBHGK3F0eemshLpAPrnfh9mbeuZXow4E1Rmc,16859
56
57
  dkist_processing_cryonirsp/tests/test_bad_pixel_maps.py,sha256=TsUIaCWQolOJCU2YOhxxmXWby6j3NhCkB2W2jDgb9OM,4855
@@ -58,33 +59,33 @@ dkist_processing_cryonirsp/tests/test_ci_beam_boundaries.py,sha256=h-v79qi4VohcX
58
59
  dkist_processing_cryonirsp/tests/test_ci_science.py,sha256=PryW50DZaKiTcLaSvhfaolrosXObj7-O1jweCJeLM_Y,14403
59
60
  dkist_processing_cryonirsp/tests/test_corrections.py,sha256=Q_prvaXKdmpebEa5d05s86pcGB9VTjsGB0g5AfEB2Ks,4536
60
61
  dkist_processing_cryonirsp/tests/test_cryo_base.py,sha256=9dSQ_3j_n04NX-nbdAFWhdHGwMe720Vyx0Jxof9eySo,6647
61
- dkist_processing_cryonirsp/tests/test_cryo_constants.py,sha256=OanX9nPCvhFe9mBV0SRCsClqiSaHi8YxgG2HoESrzTk,2827
62
+ dkist_processing_cryonirsp/tests/test_cryo_constants.py,sha256=WP3cHUF7g9urUt_BuchkbG6ldjM07QltClxRPLnmjsw,3008
62
63
  dkist_processing_cryonirsp/tests/test_dark.py,sha256=9WQDoVw1qwaqK-iaVfjOKbIusr4SJrR1rGiPZAWhNIU,11669
63
64
  dkist_processing_cryonirsp/tests/test_gain.py,sha256=KAkIXJnifVx7CHnKBY-7EhhUi5b8t5U8wBOL9F8M0gM,11260
64
65
  dkist_processing_cryonirsp/tests/test_instrument_polarization.py,sha256=COiopx4ueVPeyQO12eVP125nqBrgsnCa0ddo8y6Qrxs,19711
65
66
  dkist_processing_cryonirsp/tests/test_linearity_correction.py,sha256=r1EwZsW1yO0B0ERGn1kDciZKvjipN_LVHFXR-XIJmP0,9350
66
67
  dkist_processing_cryonirsp/tests/test_make_movie_frames.py,sha256=WznHp9dV2-jbJYzRniCAIbSHCGNc0SpSzyVDSrZkYd4,4904
67
- dkist_processing_cryonirsp/tests/test_parameters.py,sha256=yVyUmLst26Ws-_21lS727HkP08DcQh9kycZb9ICsHGY,10948
68
- dkist_processing_cryonirsp/tests/test_parse.py,sha256=qop-scwjeN70xdgFxDiHuPjDy4b4rnA11W8Q5BkcL9o,56006
68
+ dkist_processing_cryonirsp/tests/test_parameters.py,sha256=hy0ssu2OJmkHFKlGd0_d6EW10YjWsqGb68rOFlPqGuo,11105
69
+ dkist_processing_cryonirsp/tests/test_parse.py,sha256=Ejullo7r7vR0zYRCd714z4berKwXrwSnv8xMVRVqNd4,57090
69
70
  dkist_processing_cryonirsp/tests/test_quality.py,sha256=qrJBYjnZOhmQ4vjDcDV3FVSUAdktFgs-pRaHX4cf2G0,8129
70
71
  dkist_processing_cryonirsp/tests/test_sp_beam_boundaries.py,sha256=tLQToWStb4Yu2jEHkzv2FyifO_QPwegzttyNKjX8JPk,4880
71
- dkist_processing_cryonirsp/tests/test_sp_dispersion_axis_correction.py,sha256=Z0t_v85ATh9ntlngUa8v_hqs0ZCd4nkakpHNeCVRwiE,6141
72
72
  dkist_processing_cryonirsp/tests/test_sp_geometric.py,sha256=ZnusZvxsJ8YX-rg0R1azg7-DPr4vz5q2NE030bsuWXo,15691
73
73
  dkist_processing_cryonirsp/tests/test_sp_make_movie_frames.py,sha256=Kn8U_HzaaHW2bHmBxsotdjmpBhd_Ft6pLWhVsMWIJE8,5322
74
74
  dkist_processing_cryonirsp/tests/test_sp_science.py,sha256=fCmyXh27nxKU_N90yW1WqPGq1mZ6ODrw0UvtMB1elHI,19835
75
75
  dkist_processing_cryonirsp/tests/test_sp_solar.py,sha256=IdZZ2RvCwKk6_q_JKo93nFFk0HJ74yUxHxq9W1LppJE,10008
76
+ dkist_processing_cryonirsp/tests/test_sp_wavelength_calibration.py,sha256=SZMixYxMnIksvQpTiXt8MiwLbyZiDyKE6CW2vjl4af8,5666
76
77
  dkist_processing_cryonirsp/tests/test_trial_create_quality_report.py,sha256=x8dRAMyawQVYZQGsuO36DMZxK4L13hZBUn86qbhJiNk,2805
77
78
  dkist_processing_cryonirsp/tests/test_workflows.py,sha256=2a-TUMbVEyNjHYNyzo2UQMLg5PSaEx6iV9hOsGp-Mck,291
78
- dkist_processing_cryonirsp/tests/test_write_l1.py,sha256=VDSRU7j4eylYlmYQYKn32Od751NmG7qzhpoaFYFWQDM,17729
79
+ dkist_processing_cryonirsp/tests/test_write_l1.py,sha256=Ijf1Dxa-jCkMjEcPuSRbtCsFzfHH-nifn2AQ84qg1zg,17644
79
80
  dkist_processing_cryonirsp/tests/local_trial_workflows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
80
- dkist_processing_cryonirsp/tests/local_trial_workflows/l0_cals_only.py,sha256=nWs3Qg3f4DHqN_6JBKDaR5q9TncgR_PeRWw3_bUBZWA,20110
81
- dkist_processing_cryonirsp/tests/local_trial_workflows/l0_to_l1.py,sha256=KaxxMeo_sOMWgekNVkPsTJt6XWU2Ov7rnMkBtG_sKcc,23938
81
+ dkist_processing_cryonirsp/tests/local_trial_workflows/l0_cals_only.py,sha256=jUC6EnzBLwso7DBCtmhTdPJw3zlrIJYW0KTKNlWgGAM,20088
82
+ dkist_processing_cryonirsp/tests/local_trial_workflows/l0_to_l1.py,sha256=Ab1IeXfys130jkRs0iNIPv2rZFXg-IDCNkK4Z_wdOuI,23909
82
83
  dkist_processing_cryonirsp/tests/local_trial_workflows/linearize_only.py,sha256=kl9yrE1EbgxNn__x4q0WYoZIvS8zefcOPbQQdxB4_ZE,3280
83
- dkist_processing_cryonirsp/tests/local_trial_workflows/local_trial_helpers.py,sha256=FteYoLXR6BW3MBb-Wc6-O8mRj26U2U6T95_itslDhEo,20966
84
+ dkist_processing_cryonirsp/tests/local_trial_workflows/local_trial_helpers.py,sha256=DQDpjc6_I5o6dIPv5hK65oBKG0vksp9lY4k9A0hu1D4,20953
84
85
  dkist_processing_cryonirsp/workflows/__init__.py,sha256=iEbV3oiKmkfmdZjeNJxqw08IIZnYSroq-2b-ARpkLFQ,112
85
86
  dkist_processing_cryonirsp/workflows/ci_l0_processing.py,sha256=8-96ZWi_hnzsashkFaaK6YjO0CUk_2iO_gCoHTmGow8,3823
86
- dkist_processing_cryonirsp/workflows/sp_l0_processing.py,sha256=Afy8JTTKcjRHh7c-hjnbXy6iP16OafHiVivoLWhDBUg,4254
87
- dkist_processing_cryonirsp/workflows/trial_workflows.py,sha256=UvSvsho6gYWliJ_sRN_uYbt5jBdA68hVyLiyr6X5QTo,8088
87
+ dkist_processing_cryonirsp/workflows/sp_l0_processing.py,sha256=TFycCbC_N3MhM0rEHpEPmKtfJLNaVY3csR6uDrRCKI4,4245
88
+ dkist_processing_cryonirsp/workflows/trial_workflows.py,sha256=eLrROaZiyZwn8ta34oSO06aH_D9VPoqWinjDMN-9VN4,8079
88
89
  docs/Makefile,sha256=qnlVz6PuBqE39NfHWuUnHhNEA-EFgT2-WJNNNy9ttfk,4598
89
90
  docs/bad_pixel_calibration.rst,sha256=bHRclUItBA1QbGlek36B1yN5WHN53WkfjKUvZaq_j2I,2452
90
91
  docs/beam_angle_calculation.rst,sha256=-yUPFRl6SbPBIj-wOwylEymQDMQnkay7kAIAiubpQT8,2941
@@ -92,7 +93,7 @@ docs/beam_boundary_computation.rst,sha256=khyc_uW5zII6c0vN1lOvrwMAr5WO1XFFIou3QB
92
93
  docs/changelog.rst,sha256=S2jPASsWlQxSlAPqdvNrYvhk9k3FcFWNXFNDYXBSjl4,120
93
94
  docs/ci_science_calibration.rst,sha256=6HLt4ljL49sYH_iFU-Nz8KSWLyS8h_SSkzgUv-LsfqM,1704
94
95
  docs/conf.py,sha256=cv1Gct6NbY_kxJEKqw-mMIoauxtWVZeNzRLFqX1_GUw,2038
95
- docs/index.rst,sha256=FZY5WfJ16HQyslyaJxgTLs6XCD73_aFFdH4CjzagNjs,445
96
+ docs/index.rst,sha256=l6vH2FhWpuz0X1SbgfaMBoCACMPRuhHCs9dTxW1Hcaw,472
96
97
  docs/l0_to_l1_cryonirsp_ci-full-trial.rst,sha256=-uhtnd51ttJYw9T5hs5A9HQWpXJkOJmvfXf1INFT3MI,582
97
98
  docs/l0_to_l1_cryonirsp_ci.rst,sha256=OhGTy9CBTqQJ04XhThTws8KBnGLFiP5vBX0DlX6NXKA,458
98
99
  docs/l0_to_l1_cryonirsp_sp-full-trial.rst,sha256=cKdRI7qVEVYsqqgYuL9nzqFP3uTR4cu305WfjmmyetY,582
@@ -104,8 +105,9 @@ docs/requirements.txt,sha256=Kbl_X4c7RQZw035YTeNB63We6I7pvXFU4T0Uflp2yDY,29
104
105
  docs/requirements_table.rst,sha256=FaqSag9kPi77gWPhzeo_tFEhRFjb3qUuNqqQe1K76NM,297
105
106
  docs/scientific_changelog.rst,sha256=01AWBSHg8zElnodCgAq-hMxhk9CkX5rtEENx4iz0sjI,300
106
107
  docs/sp_science_calibration.rst,sha256=XL-H_hyzqwPHYNW3j-muItX_hGqMi-gjFRQbHp60LlU,2997
108
+ docs/wavelength_calibration.rst,sha256=s7ds_QKlVJ68fdONSY3DOBvHHaQC0JR_D4goG_VVKWw,3457
107
109
  licenses/LICENSE.rst,sha256=piZaQplkzOMmH1NXg6QIdo9wwo9pPCoHkvm2-DmH76E,1462
108
- dkist_processing_cryonirsp-1.9.0.dist-info/METADATA,sha256=ldY1xHkvAxyI_K4JmhwFjzAg4Tx73hxCqqjIuYSZINM,22052
109
- dkist_processing_cryonirsp-1.9.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
110
- dkist_processing_cryonirsp-1.9.0.dist-info/top_level.txt,sha256=Sm9b1ddKnsF9Bh3mqDOct1Sm7k8I9aN7vGHgpmu-MlQ,51
111
- dkist_processing_cryonirsp-1.9.0.dist-info/RECORD,,
110
+ dkist_processing_cryonirsp-1.10.0rc1.dist-info/METADATA,sha256=aYUp1rzLQuMN0qnC4k9OdBurJb_iO0fLG_zfemf40hQ,22111
111
+ dkist_processing_cryonirsp-1.10.0rc1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
112
+ dkist_processing_cryonirsp-1.10.0rc1.dist-info/top_level.txt,sha256=Sm9b1ddKnsF9Bh3mqDOct1Sm7k8I9aN7vGHgpmu-MlQ,51
113
+ dkist_processing_cryonirsp-1.10.0rc1.dist-info/RECORD,,
docs/index.rst CHANGED
@@ -14,6 +14,7 @@
14
14
  bad_pixel_calibration
15
15
  beam_boundary_computation
16
16
  beam_angle_calculation
17
+ wavelength_calibration
17
18
  ci_science_calibration
18
19
  sp_science_calibration
19
20
  autoapi/index
@@ -0,0 +1,62 @@
1
+ Wavelength Calibration
2
+ ============================
3
+
4
+ Overview
5
+ --------
6
+
7
+ The `~dkist_processing_cryonirsp.tasks.sp_wavelength_calibration` task provides an absolute wavelength calibration of
8
+ Cryo-NIRSP solar spectra by using the routines provided by the
9
+ `solar-wavelength-calibration <https://docs.dkist.nso.edu/projects/solar-wavelength-calibration/en/latest/>`_ library.
10
+
11
+ Workflow
12
+ --------
13
+
14
+ #. **Input Spectrum**: Compute a spatially averaged input spectrum from solar gain images.
15
+ #. **Initial Guess**: Use Level 0 headers to generate a first-guess wavelength solution.
16
+ #. **Fitting**: Fit the representative spectrum using the `solar-wavelength-calibration <https://docs.dkist.nso.edu/projects/solar-wavelength-calibration/en/latest/>`_ library, refining the wavelength solution.
17
+ #. **Header Encoding**: Save the fit results as FITS header keywords, parameterizing the solution for downstream use.
18
+
19
+ Wavelength Solution Encoding
20
+ ----------------------------
21
+
22
+ The wavelength solution is stored in FITS headers using the following keywords (see `Greisen et al (2006) <https://ui.adsabs.harvard.edu/abs/2006A%26A...446..747G/abstract>`_, Section 5 and Table 6):
23
+
24
+ +---------+--------------------------+----------------+
25
+ | Keyword | Description | Units |
26
+ +=========+==========================+================+
27
+ | `CTYPE1`| Spectral coordinate type | "AWAV-GRA" |
28
+ +---------+--------------------------+----------------+
29
+ | `CUNIT1`| Wavelength unit | "nm" |
30
+ +---------+--------------------------+----------------+
31
+ | `CRPIX1`| Reference pixel | |
32
+ +---------+--------------------------+----------------+
33
+ | `CRVAL1`| Reference wavelength | nm |
34
+ +---------+--------------------------+----------------+
35
+ | `CDELT1`| Linear dispersion | nm / px |
36
+ +---------+--------------------------+----------------+
37
+ | `PV1_0` | Grating constant | 1 / m |
38
+ +---------+--------------------------+----------------+
39
+ | `PV1_1` | Spectral order | |
40
+ +---------+--------------------------+----------------+
41
+ | `PV1_1` | Incident light angle | deg |
42
+ +---------+--------------------------+----------------+
43
+
44
+ Note: The units of `PV1_0` are always 1 / m.
45
+
46
+ Fitted Parameters
47
+ -----------------
48
+
49
+ The fitting process can optimize several parameters. The parameters that are free in Cryo-NIRSP fits are:
50
+
51
+ - **crval**: Wavelength zero-point.
52
+ - **dispersion**: Linear dispersion, allowed to vary within a few percent of the nominal value.
53
+ - **opacity_factor**: Atmospheric absorption scaling, to match telluric line strengths.
54
+ - **continuum_level**: Overall spectrum scaling, to match the observed continuum.
55
+ - **straylight_fraction**: Fraction of stray or scattered light added to the observed spectrum, affecting line depths and continuum.
56
+ - **resolving_power**: Spectral resolving power (:math:`R = \frac{\lambda}{\Delta\lambda}`), characterizing the instrument's ability to distinguish close spectral features.
57
+ - **incident_light_angle**: Angle at which light enters the grating, influencing the wavelength solution through the grating equation.
58
+
59
+
60
+ For more details on the fitting algorithms and parameterization, see the
61
+ `solar-wavelength-calibration documentation <https://docs.dkist.nso.edu/projects/solar-wavelength-calibration/en/latest/>`_
62
+ and `Greisen et al. (2006) <https://ui.adsabs.harvard.edu/abs/2006A%26A...446..747G/abstract>`_.
@@ -1,465 +0,0 @@
1
- """Cryonirsp SP dispersion axis calibration task."""
2
- import warnings
3
-
4
- import numpy as np
5
- from astropy import constants as const
6
- from astropy import units as u
7
- from astropy.coordinates import EarthLocation
8
- from astropy.coordinates.spectral_coordinate import SpectralCoord
9
- from astropy.io import fits
10
- from astropy.time import Time
11
- from astropy.wcs import WCS
12
- from dkist_processing_common.codecs.asdf import asdf_encoder
13
- from dkist_processing_common.models.dkist_location import location_of_dkist
14
- from dkist_service_configuration.logging import logger
15
- from scipy.ndimage import gaussian_filter1d
16
- from scipy.optimize import differential_evolution
17
- from scipy.optimize import OptimizeResult
18
- from sunpy.coordinates import HeliocentricInertial
19
-
20
- from dkist_processing_cryonirsp.codecs.fits import cryo_fits_access_decoder
21
- from dkist_processing_cryonirsp.codecs.fits import cryo_fits_array_decoder
22
- from dkist_processing_cryonirsp.models.tags import CryonirspTag
23
- from dkist_processing_cryonirsp.parsers.cryonirsp_l0_fits_access import CryonirspL0FitsAccess
24
- from dkist_processing_cryonirsp.tasks.cryonirsp_base import CryonirspTaskBase
25
-
26
- __all__ = ["SPDispersionAxisCorrection"]
27
-
28
-
29
- class SPDispersionAxisCorrection(CryonirspTaskBase):
30
- """Task class for correcting the dispersion axis wavelength values.
31
-
32
- Parameters
33
- ----------
34
- recipe_run_id : int
35
- id of the recipe run used to identify the workflow run this task is part of
36
- workflow_name : str
37
- name of the workflow to which this instance of the task belongs
38
- workflow_version : str
39
- version of the workflow to which this instance of the task belongs
40
-
41
- """
42
-
43
- record_provenance = True
44
-
45
- def run(self):
46
- """
47
- Run method for the task.
48
-
49
- For each beam
50
- - Gather 1D characteristic spectrum.
51
- - Compute the theoretical dispersion.
52
- - Load the telluric and non-telluric FTS atlases and grab only the portion of the atlases that pertain to the current observation.
53
- - Shift the preliminary wavelength vector (from the data) so that it generally aligns with the FTS atlas data.
54
- - Account for the speed at which DKIST was moving relative to the sun's center at the time of observation.
55
- - Define fitting bounds and fit the profile using scipy.optimize.differential_evolution.
56
- - Write results to disk.
57
-
58
-
59
- Returns
60
- -------
61
- None
62
- """
63
- spectrum = self.load_1d_char_spectrum()
64
-
65
- solar_header = self.load_header()
66
-
67
- dispersion, order, alpha = self.get_theoretical_dispersion()
68
-
69
- expected_wavelength_vector = self.compute_expected_wavelength_vector(spectrum, solar_header)
70
-
71
- (
72
- telluric_atlas_wave,
73
- telluric_atlas_trans,
74
- solar_atlas_wave_air,
75
- solar_atlas_trans_flipped,
76
- ) = self.load_and_resample_fts_atlas(expected_wavelength_vector)
77
-
78
- (fts_wave, fts_solar, fts_telluric) = self.initial_alignment(
79
- spectrum,
80
- expected_wavelength_vector,
81
- solar_atlas_wave_air,
82
- solar_atlas_trans_flipped,
83
- telluric_atlas_wave,
84
- telluric_atlas_trans,
85
- )
86
-
87
- doppler_shift = self.get_doppler_shift()
88
-
89
- fit_result = self.fit_dispersion_axis_to_FTS(
90
- fts_wave,
91
- fts_telluric,
92
- fts_solar,
93
- dispersion,
94
- alpha,
95
- doppler_shift,
96
- spectrum,
97
- order,
98
- self.constants.grating_constant,
99
- )
100
-
101
- self.write_fit_results(spectrum, order, fit_result)
102
-
103
- def write_fit_results(
104
- self, spectrum: np.ndarray, order: int, fit_result: OptimizeResult
105
- ) -> None:
106
- """Save the fit results to disk to later be used to update the l1 headers."""
107
- updated_headers = {
108
- "CRPIX1": np.size(spectrum) // 2 + 1,
109
- "CRVAL1": fit_result.x[0],
110
- "CDELT1": fit_result.x[1],
111
- "PV1_0": self.constants.grating_constant,
112
- "PV1_1": order,
113
- "PV1_2": fit_result.x[2],
114
- "CRPIX1A": np.size(spectrum) // 2 + 1,
115
- "CRVAL1A": fit_result.x[0],
116
- "CDELT1A": fit_result.x[1],
117
- "PV1_0A": self.constants.grating_constant,
118
- "PV1_1A": order,
119
- "PV1_2A": fit_result.x[2],
120
- }
121
-
122
- self.write(
123
- data=updated_headers,
124
- tags=[CryonirspTag.task_spectral_fit(), CryonirspTag.intermediate()],
125
- encoder=asdf_encoder,
126
- )
127
-
128
- def load_1d_char_spectrum(self) -> np.ndarray:
129
- """Load intermediate 1d characteristic measured_spectra for beam 1."""
130
- # Only fitting with the left beam.
131
- beam = 1
132
- array_generator = self.read(
133
- tags=[CryonirspTag.intermediate_frame(beam=beam), CryonirspTag.task("SOLAR_CHAR_SPEC")],
134
- decoder=cryo_fits_array_decoder,
135
- )
136
-
137
- return next(array_generator)
138
-
139
- def load_header(self) -> fits.header.Header:
140
- """Grab a header from a random solar gain frame to be used to find a rough initial wavelength estimate."""
141
- # Only fitting with the left beam.
142
- beam = 1
143
- solar_tags = [CryonirspTag.linearized_frame(), CryonirspTag.task("SOLAR_GAIN")]
144
- solar_obj = next(
145
- self.read(
146
- tags=solar_tags,
147
- decoder=cryo_fits_access_decoder,
148
- fits_access_class=CryonirspL0FitsAccess,
149
- )
150
- )
151
- solar_header = solar_obj.header
152
- return solar_header
153
-
154
- def get_theoretical_dispersion(self) -> tuple[u.Quantity, int, float]:
155
- """Compute theoretical dispersion value using the following grating equation.
156
-
157
- m = d/lambda * (sin(alpha) + sin(beta))
158
-
159
- where
160
- m = order
161
- d = grating spacing
162
- lambda = wavelength
163
- alpha = incident angle
164
- beta = diffraction angle
165
-
166
- """
167
- wavelength = self.constants.wavelength * u.nanometer
168
- grating_position_angle_phi = np.deg2rad(self.constants.grating_position_deg)
169
- grating_littrow_angle_theta = np.deg2rad(self.constants.grating_littrow_angle_deg)
170
- alpha = grating_position_angle_phi + grating_littrow_angle_theta
171
- beta = grating_position_angle_phi - grating_littrow_angle_theta
172
- grating_spacing_distance = (1.0 / self.constants.grating_constant) * u.m
173
- order = int(grating_spacing_distance / wavelength * (np.sin(alpha) + np.sin(beta)))
174
- camera_mirror_focal_length = self.parameters.camera_mirror_focal_length_mm
175
- pixpitch = self.parameters.pixel_pitch_micron
176
- linear_disp = order / (grating_spacing_distance * np.cos(beta)) * camera_mirror_focal_length
177
- theoretical_dispersion = (pixpitch / linear_disp).to(u.nanometer)
178
-
179
- return theoretical_dispersion, order, alpha
180
-
181
- def compute_expected_wavelength_vector(
182
- self, spectrum: np.ndarray, header: fits.header.Header
183
- ) -> u.Quantity:
184
- """Compute the expected wavelength vector based on the header information.""" ""
185
- # resample atlases
186
- number_of_wave_pix = np.size(spectrum)
187
- header["CRPIX1"] = number_of_wave_pix // 2 + 1
188
- with warnings.catch_warnings():
189
- warnings.simplefilter("ignore") ## TO ELIMINATE datafix warnings
190
- wcs = WCS(header)
191
- # get wavelength based on header info (not fully accurate)
192
- expected_wavelength_vector = wcs.spectral.pixel_to_world(
193
- np.arange(number_of_wave_pix)
194
- ).to(u.nm)
195
-
196
- return expected_wavelength_vector
197
-
198
- def load_and_resample_fts_atlas(
199
- self, expected_wavelength_vector: u.Quantity
200
- ) -> tuple[u.Quantity, np.ndarray, u.Quantity, np.ndarray]:
201
- """Load telluric and non-telluric FTS atlas data, resample both atlases to be on the same, linear wavelength grid, select the portion of atlas that pertains to bandpass used."""
202
- solar_atlas_wavelength, solar_atlas_transmission = self.parameters.solar_atlas
203
- solar_atlas_wavelength = solar_atlas_wavelength * u.nm
204
- telluric_atlas_wavelength, telluric_atlas_transmission = self.parameters.telluric_atlas
205
- telluric_atlas_wavelength = telluric_atlas_wavelength * u.nm
206
-
207
- expected_wavelength_range = (
208
- expected_wavelength_vector.max() - expected_wavelength_vector.min()
209
- )
210
- min_wavelength = expected_wavelength_vector.min() - 0.25 * expected_wavelength_range
211
- max_wavelength = expected_wavelength_vector.max() + 0.25 * expected_wavelength_range
212
-
213
- cropped_telluric_mask = (telluric_atlas_wavelength > min_wavelength) * (
214
- telluric_atlas_wavelength < max_wavelength
215
- )
216
- telluric_atlas_wavelength = telluric_atlas_wavelength[cropped_telluric_mask]
217
- telluric_atlas_transmission = telluric_atlas_transmission[cropped_telluric_mask]
218
-
219
- cropped_solar_mask = (solar_atlas_wavelength > min_wavelength) * (
220
- solar_atlas_wavelength < max_wavelength
221
- )
222
- solar_atlas_wavelength = solar_atlas_wavelength[cropped_solar_mask]
223
- solar_atlas_transmission = solar_atlas_transmission[cropped_solar_mask]
224
-
225
- return (
226
- telluric_atlas_wavelength,
227
- telluric_atlas_transmission,
228
- solar_atlas_wavelength,
229
- solar_atlas_transmission,
230
- )
231
-
232
- def get_doppler_shift(self) -> u.Quantity:
233
- """Find the speed at which DKIST is moving relative to the Sun's center.
234
-
235
- Positive values refer to when DKIST is moving away from the sun.
236
- """
237
- coord = location_of_dkist.get_gcrs(obstime=Time(self.constants.solar_gain_ip_start_time))
238
- heliocentric_coord = coord.transform_to(
239
- HeliocentricInertial(obstime=Time(self.constants.solar_gain_ip_start_time))
240
- )
241
- obs_vr_kms = heliocentric_coord.d_distance
242
- return obs_vr_kms
243
-
244
- def initial_alignment(
245
- self,
246
- spectrum: np.ndarray,
247
- expected_wavelength_vector: SpectralCoord,
248
- solar_atlas_wave_air: u.Quantity,
249
- solar_atlas_trans_flipped: np.ndarray,
250
- telluric_atlas_wave: u.Quantity,
251
- telluric_atlas_trans: np.ndarray,
252
- ) -> tuple[np.ndarray, np.ndarray, np.ndarray]:
253
- """Determine a shift of the preliminary wavelength vector so that it generally aligns with the data itself."""
254
- shifts = np.linspace(-2, 2, 550) * u.nm
255
- merit = np.zeros(len(shifts))
256
- for n, shift in enumerate(shifts):
257
- preliminary_wavelength = expected_wavelength_vector + shift
258
- fts_solar = np.interp(
259
- preliminary_wavelength, solar_atlas_wave_air, solar_atlas_trans_flipped
260
- )
261
- fts_telluric = np.interp(
262
- preliminary_wavelength, telluric_atlas_wave, telluric_atlas_trans
263
- )
264
- # calculate a merit value to be minimized
265
- merit[n] = np.std(spectrum - fts_solar * fts_telluric)
266
-
267
- # get minimum
268
- shift = shifts[np.argmin(merit)]
269
-
270
- # recalculate spectral axis and atlas spectrum for the best shift value
271
- fts_wave = expected_wavelength_vector + shift
272
- fts_solar = np.interp(fts_wave, solar_atlas_wave_air, solar_atlas_trans_flipped)
273
- fts_telluric = np.interp(fts_wave, telluric_atlas_wave, telluric_atlas_trans)
274
-
275
- return fts_wave.value, fts_solar, fts_telluric
276
-
277
- @staticmethod
278
- def fitness(
279
- parameters: np.ndarray,
280
- spectrum: np.ndarray,
281
- fts_wave: np.ndarray,
282
- fts_telluric: np.ndarray,
283
- fts_solar: np.ndarray,
284
- order: int,
285
- grating_constant: float,
286
- doppler_shift: float,
287
- ) -> float:
288
- """
289
- Model function for profile fitting.
290
-
291
- Parameters
292
- ----------
293
- crval1
294
- Wavelength at crpix1
295
-
296
- cdelt1
297
- Spectral dispersion at crpix1
298
-
299
- incident_light_angle
300
- Incident angle in degrees
301
-
302
- resolving_power
303
- Resolving power -- used to estimate the line spread function (may not be correct off limb)
304
-
305
- opacity
306
- Opacity scaling applied to telluric absorption
307
-
308
- stray_light_frac
309
- Inferred straylight fraction in the spectrograph --> This scales the lines non-linearly.
310
-
311
- continuum_amplitude
312
- Amplitude of the scattered light continuum
313
- """
314
- (
315
- crval1,
316
- cdelt1,
317
- incident_light_angle,
318
- resolving_power,
319
- opacity,
320
- stray_light_frac,
321
- continuum_amplitude,
322
- ) = parameters
323
-
324
- # calculate the spectral axis
325
- # Representations of spectral coordinates in FITS
326
- # https://ui.adsabs.harvard.edu/abs/2006A%26A...446..747G/abstract
327
- # https://specreduce.readthedocs.io/en/latest/api/specreduce.utils.synth_data.make_2d_arc_image.html
328
-
329
- number_of_wave_pix = np.size(spectrum)
330
-
331
- non_linear_header = {
332
- "CTYPE1": "AWAV-GRA", # Grating dispersion function with air wavelengths
333
- "CUNIT1": "nm", # Dispersion units
334
- "CRPIX1": number_of_wave_pix // 2 + 1, # Reference pixel [pix]
335
- "PV1_0": grating_constant, # Grating density
336
- "PV1_1": order, # Diffraction order
337
- "CRVAL1": crval1, # Reference value [nm] (<<<< TO BE OPTMIZED <<<<<<)
338
- "CDELT1": cdelt1, # Linear dispersion [nm/pix] (<<<< TO BE OPTMIZED <<<<<<)
339
- "PV1_2": incident_light_angle, # Incident angle [deg] (<<<< TO BE OPTMIZED <<<<<<)
340
- }
341
-
342
- non_linear_wcs = WCS(non_linear_header)
343
- wavelength_vector = (
344
- (non_linear_wcs.spectral.pixel_to_world(np.arange(number_of_wave_pix))).to(u.nm).value
345
- )
346
-
347
- # Gaussian convolution of the FTS atlas
348
- fwhm_wavelength = np.divide(crval1, resolving_power)
349
- sigma_wavelength = fwhm_wavelength / (2.0 * np.sqrt(2.0 * np.log(2)))
350
- kern_pix = sigma_wavelength / np.abs(cdelt1)
351
-
352
- # interpolate the telluric spectral atlas onto the new wavelength axis and scale by the opacity value that is being optimized
353
- fts_atmosphere_interp = np.interp(wavelength_vector, fts_wave, fts_telluric)
354
- fts_telluric_interp = np.exp(opacity * np.log(fts_atmosphere_interp))
355
-
356
- # interpolate the solar spectral atlas onto the new wavelength axis and apply a shift according to the Doppler shift due to orbital motions
357
- fts_solar_interp = np.interp(
358
- wavelength_vector,
359
- fts_wave + doppler_shift / (const.c.to("km/s")).value * crval1,
360
- fts_solar,
361
- )
362
-
363
- # apply telluric absorption spectrum to solar spectrum
364
- fts_modulated = fts_telluric_interp * fts_solar_interp
365
- # add flat value of straylight contamination
366
- fts_modulated_with_straylight = (fts_modulated + stray_light_frac) / (
367
- 1.0 + stray_light_frac
368
- )
369
- # scale for total intensity of the continuum
370
- fit_amplitude = fts_modulated_with_straylight * continuum_amplitude
371
-
372
- # convolution for spectrograph line spread function
373
- fit_amplitude = gaussian_filter1d(fit_amplitude, kern_pix)
374
-
375
- # chisquare calculation for fit metric
376
- res_amplitude = np.sum((spectrum - fit_amplitude) ** 2)
377
-
378
- return res_amplitude
379
-
380
- def fit_dispersion_axis_to_FTS(
381
- self,
382
- fts_wave: np.ndarray,
383
- fts_telluric: np.ndarray,
384
- fts_solar: np.ndarray,
385
- dispersion: u.Quantity,
386
- alpha: float,
387
- doppler_shift: u.Quantity,
388
- spectrum: np.ndarray,
389
- order: int,
390
- grating_constant: float,
391
- ) -> OptimizeResult:
392
- """Define the bounds and send the fitting model on its way."""
393
- parameter_names = (
394
- "crval1 (wavelength at crpix1)",
395
- "cdelt1 (spectral dispersion at crpix1)",
396
- "incident_light_angle",
397
- "resolving_power",
398
- "opacity",
399
- "stray_light_frac",
400
- "continuum_amplitude",
401
- )
402
- crpix1_updated = np.size(spectrum) // 2 + 1
403
- crval1 = fts_wave[crpix1_updated] # initial guess
404
- bounds = [
405
- # [nm[ +\- 0.5 nm range used for finding CRVAL1
406
- (crval1 - 0.5, crval1 + 0.5),
407
- # [nm/pix] 5% bounds on the dispersion at CRPIX1
408
- (
409
- dispersion.value - 0.05 * dispersion.value,
410
- dispersion.value + 0.05 * dispersion.value,
411
- ),
412
- # [radian] Incident angle range is +/- 5 degree from value in header
413
- (np.rad2deg(alpha) - 5, np.rad2deg(alpha) + 5),
414
- # resolving power range
415
- (20000, 125000),
416
- # opacity factor bounds
417
- (0.0, 10),
418
- # straylight fraction
419
- (0.0, 0.5),
420
- # continuum intensity correction
421
- (0.8 * np.nanpercentile(spectrum, 75), 1.2 * np.nanpercentile(spectrum, 75)),
422
- ]
423
-
424
- for repeat_fit in range(5): # repeat just in case the fitting gets stuck in a local minimum
425
- fit_result = differential_evolution(
426
- SPDispersionAxisCorrection.fitness,
427
- args=(
428
- spectrum,
429
- fts_wave,
430
- fts_telluric,
431
- fts_solar,
432
- order,
433
- grating_constant,
434
- doppler_shift.value,
435
- ),
436
- popsize=2,
437
- maxiter=300,
438
- bounds=bounds,
439
- disp=True,
440
- polish=True,
441
- tol=1.0e-9,
442
- )
443
- if fit_result.fun < 0.03:
444
- logger.info(" Convergence good based on fit func value")
445
- break
446
-
447
- logger.info("Fitted Values:")
448
- logger.info(" ")
449
- for p in range(len(parameter_names)):
450
- logger.info(
451
- f"Parameter: {parameter_names[p]}, Fit Result: {fit_result.x[p]}, Bounds: {bounds[p]}"
452
- )
453
-
454
- fit_amplitude = SPDispersionAxisCorrection.fitness(
455
- fit_result.x,
456
- spectrum,
457
- fts_wave,
458
- fts_telluric,
459
- fts_solar,
460
- order,
461
- grating_constant,
462
- doppler_shift.value,
463
- )
464
-
465
- return fit_result