dkist-processing-dlnirsp 0.32.8__py3-none-any.whl → 0.33.0__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.
- dkist_processing_dlnirsp/models/constants.py +6 -0
- dkist_processing_dlnirsp/models/parameters.py +33 -3
- dkist_processing_dlnirsp/parsers/task.py +2 -25
- dkist_processing_dlnirsp/parsers/time.py +2 -2
- dkist_processing_dlnirsp/tasks/__init__.py +1 -2
- dkist_processing_dlnirsp/tasks/movie.py +1121 -0
- dkist_processing_dlnirsp/tasks/parse.py +13 -8
- dkist_processing_dlnirsp/tasks/solar.py +129 -30
- dkist_processing_dlnirsp/tests/conftest.py +46 -7
- dkist_processing_dlnirsp/tests/local_trial_workflows/l0_polcals_as_science.py +21 -18
- dkist_processing_dlnirsp/tests/local_trial_workflows/l0_solar_gain_as_science.py +21 -18
- dkist_processing_dlnirsp/tests/local_trial_workflows/l0_to_l1.py +21 -18
- dkist_processing_dlnirsp/tests/local_trial_workflows/local_trial_dev_mockers.py +1 -1
- dkist_processing_dlnirsp/tests/test_dlnirsp_constants.py +2 -0
- dkist_processing_dlnirsp/tests/test_movie.py +141 -0
- dkist_processing_dlnirsp/tests/test_parameters.py +8 -0
- dkist_processing_dlnirsp/tests/test_parse.py +10 -0
- dkist_processing_dlnirsp/tests/test_science.py +0 -9
- dkist_processing_dlnirsp/tests/test_solar.py +114 -17
- dkist_processing_dlnirsp/tests/test_wavelength_calibration.py +4 -1
- dkist_processing_dlnirsp/workflows/l0_processing.py +6 -8
- dkist_processing_dlnirsp/workflows/trial_workflow.py +7 -7
- {dkist_processing_dlnirsp-0.32.8.dist-info → dkist_processing_dlnirsp-0.33.0.dist-info}/METADATA +52 -35
- {dkist_processing_dlnirsp-0.32.8.dist-info → dkist_processing_dlnirsp-0.33.0.dist-info}/RECORD +28 -30
- docs/gain.rst +7 -3
- dkist_processing_dlnirsp/tasks/assemble_movie.py +0 -150
- dkist_processing_dlnirsp/tasks/make_movie_frames.py +0 -156
- dkist_processing_dlnirsp/tests/test_assemble_movie.py +0 -169
- dkist_processing_dlnirsp/tests/test_make_movie_frames.py +0 -98
- {dkist_processing_dlnirsp-0.32.8.dist-info → dkist_processing_dlnirsp-0.33.0.dist-info}/WHEEL +0 -0
- {dkist_processing_dlnirsp-0.32.8.dist-info → dkist_processing_dlnirsp-0.33.0.dist-info}/entry_points.txt +0 -0
- {dkist_processing_dlnirsp-0.32.8.dist-info → dkist_processing_dlnirsp-0.33.0.dist-info}/top_level.txt +0 -0
{dkist_processing_dlnirsp-0.32.8.dist-info → dkist_processing_dlnirsp-0.33.0.dist-info}/RECORD
RENAMED
|
@@ -4,21 +4,20 @@ dkist_processing_dlnirsp/config.py,sha256=3jM7P00T-Xlzfnvc3jwRiFtinW5GoTczQ6qNLL
|
|
|
4
4
|
dkist_processing_dlnirsp/dev_scripts/__init__.py,sha256=tITkbcFg1a-24sdFaWK8OyLrQSQk7AI6Ycs8PHHfHEM,83
|
|
5
5
|
dkist_processing_dlnirsp/dev_scripts/test_slitbeam_group_assignment.py,sha256=ac-8G-P2L_xW6m3tOooFlHs1N5_C6F_7k2VAU2a9_1A,4171
|
|
6
6
|
dkist_processing_dlnirsp/models/__init__.py,sha256=ItaZgbjndT5uwEv2YDQZCVAHGbiB_sjzkX8MMbIgcSo,45
|
|
7
|
-
dkist_processing_dlnirsp/models/constants.py,sha256=
|
|
7
|
+
dkist_processing_dlnirsp/models/constants.py,sha256=y4c8boq1Rp4mqtkNJi3aj1EkhUnU7fiq013aqiFOonM,6602
|
|
8
8
|
dkist_processing_dlnirsp/models/fits_access.py,sha256=5HH8NM2tAh63Aauy6oCXKJGJ2AbQPBP5L1DitVfFEs0,895
|
|
9
|
-
dkist_processing_dlnirsp/models/parameters.py,sha256=
|
|
9
|
+
dkist_processing_dlnirsp/models/parameters.py,sha256=YD2BdQRO0Yk1sz3DJP-wNehBUJvDQ7cHqEnQP6UYo6w,17210
|
|
10
10
|
dkist_processing_dlnirsp/models/tags.py,sha256=xD_XaCjMXmd70P0FoHy92XSdlabIk07RGVEyFpXpGfM,5791
|
|
11
11
|
dkist_processing_dlnirsp/models/task_name.py,sha256=LmEoI_h4UecvIMGcO5U8mGTqfToPjABuFbsYkC_rZyw,506
|
|
12
12
|
dkist_processing_dlnirsp/parsers/__init__.py,sha256=O6KcssCD39an60pqLISt1aHQ4u5ADg0TMNw1dB694Ug,81
|
|
13
13
|
dkist_processing_dlnirsp/parsers/dlnirsp_l0_fits_access.py,sha256=ziUeSWPOiFV0HdkCCfFZGPOZB-PB1OhK2qjYbVdsAb4,4314
|
|
14
14
|
dkist_processing_dlnirsp/parsers/dlnirsp_l1_fits_acess.py,sha256=K-9HRVZ02IUl0wRnhlTMnwSikTt7vYi_zSWYs0V_6-Y,878
|
|
15
15
|
dkist_processing_dlnirsp/parsers/mosaic.py,sha256=0z0sTbDQFhg2hyCp6hSKFpuaS-rOSUBvuBOT6mSSadA,31061
|
|
16
|
-
dkist_processing_dlnirsp/parsers/task.py,sha256=
|
|
17
|
-
dkist_processing_dlnirsp/parsers/time.py,sha256=
|
|
16
|
+
dkist_processing_dlnirsp/parsers/task.py,sha256=wtg8kNuxqGHaK34dJAZ92-f29-3V1QrnLGUGRAebUUk,990
|
|
17
|
+
dkist_processing_dlnirsp/parsers/time.py,sha256=bdsNRXGpiKe7nBt3rOvk5gKYtqo10nFkTR9EMwbDcsg,2093
|
|
18
18
|
dkist_processing_dlnirsp/parsers/wavelength.py,sha256=CHZDFqOpzErhaR0MSbzQ6NiagdmkVkZ-6HWRERH5TNY,972
|
|
19
19
|
dkist_processing_dlnirsp/parsers/wcs_corrections.py,sha256=yeTLowmtAIs5sjNStIKmBTZUxttOtldJSeW_adsXFYQ,1786
|
|
20
|
-
dkist_processing_dlnirsp/tasks/__init__.py,sha256=
|
|
21
|
-
dkist_processing_dlnirsp/tasks/assemble_movie.py,sha256=BxUO7_Zj_QGLXqNpp87bLawyLo4G0I0DTLZPMXpi5Mo,5539
|
|
20
|
+
dkist_processing_dlnirsp/tasks/__init__.py,sha256=zGSL-fIB0el6PCjf4VEIHU_pOTv945D95I2G4vxHtHA,924
|
|
22
21
|
dkist_processing_dlnirsp/tasks/bad_pixel_map.py,sha256=ZzG86mXped2k2PjX7okKAi3JCQGJHalBhBgFU-T8K_8,8194
|
|
23
22
|
dkist_processing_dlnirsp/tasks/dark.py,sha256=rFnVULAunChEdxEXcosxNJM_iqRGslia9cUnV1FAOQQ,3580
|
|
24
23
|
dkist_processing_dlnirsp/tasks/dlnirsp_base.py,sha256=dIpQGE0COLAXPAUbKn6dpLJj5VDCxfAVYFfX8fR6OSo,1519
|
|
@@ -28,25 +27,24 @@ dkist_processing_dlnirsp/tasks/instrument_polarization.py,sha256=G79qXg1080zsd8Z
|
|
|
28
27
|
dkist_processing_dlnirsp/tasks/l1_output_data.py,sha256=Psta0476jih-cfmpdnzmquys030sW4f4VX6ksAb-g1o,465
|
|
29
28
|
dkist_processing_dlnirsp/tasks/lamp.py,sha256=twoMHMnE2jm2OYxkeHFcjqcyQYVtEjSU2_z2mmn3Ybs,5390
|
|
30
29
|
dkist_processing_dlnirsp/tasks/linearity_correction.py,sha256=z3MpWHp0lZYB2zrfHfH7HlcKoro6TPxwEN8rpqVv08c,22716
|
|
31
|
-
dkist_processing_dlnirsp/tasks/
|
|
32
|
-
dkist_processing_dlnirsp/tasks/parse.py,sha256=
|
|
30
|
+
dkist_processing_dlnirsp/tasks/movie.py,sha256=IaZCRg2KIETEXDyyOe3FLoY5cd7eJOhMtjkiSYjElEU,44291
|
|
31
|
+
dkist_processing_dlnirsp/tasks/parse.py,sha256=WGFIssavbQg1BAbW0_jS56SoEya-X-bHkLTbxTooUFI,11218
|
|
33
32
|
dkist_processing_dlnirsp/tasks/quality_metrics.py,sha256=1ScLAinv3WG-0M7u_26gnogbJ_D84K9CP7eRvEuwb9E,7346
|
|
34
33
|
dkist_processing_dlnirsp/tasks/science.py,sha256=sNI4AYO10qe3JL62KWXR87MnfX9m85Jo4_PkQ0qd5TQ,35737
|
|
35
|
-
dkist_processing_dlnirsp/tasks/solar.py,sha256=
|
|
34
|
+
dkist_processing_dlnirsp/tasks/solar.py,sha256=hVOVwQkzO4kioPDgJz3GqSNcisfpEMbDPESJN-INh10,15494
|
|
36
35
|
dkist_processing_dlnirsp/tasks/wavelength_calibration.py,sha256=QhFlbX8h9UqkK2vx779nK6LBksp2P2yPqhAxrwcuJ4o,16851
|
|
37
36
|
dkist_processing_dlnirsp/tasks/write_l1.py,sha256=Smd9Fzp3Kx4F3nHYJJRAXqNy9n71TsYovuvFjLcUYs4,9732
|
|
38
37
|
dkist_processing_dlnirsp/tasks/mixin/__init__.py,sha256=5PMbkD6K0zTfhCxv8vg2lvJCNP81qItJ_R_7Yy3Mpwc,26
|
|
39
38
|
dkist_processing_dlnirsp/tasks/mixin/corrections.py,sha256=MRZXCEc0KBE-9cQUpRP-K3ioDYRH8_ORFlJcH2SsmWA,6803
|
|
40
39
|
dkist_processing_dlnirsp/tasks/mixin/group_id.py,sha256=u28XLVtvZ_lmzzaSX2SuA2MOiY69GC8AJsic2Vi2OSQ,11137
|
|
41
40
|
dkist_processing_dlnirsp/tests/__init__.py,sha256=UHIAs0SglAXeB7UeDgVwo1EE9QPRq3rG3BZkiCpBq7M,42
|
|
42
|
-
dkist_processing_dlnirsp/tests/conftest.py,sha256=
|
|
43
|
-
dkist_processing_dlnirsp/tests/test_assemble_movie.py,sha256=hKAIHCRQu8fZwCuWsX_4WHFrDpC0bDQ9CCI9A5bRkqg,5665
|
|
41
|
+
dkist_processing_dlnirsp/tests/conftest.py,sha256=cmYQ9PnOiEXeTpAsRmRm64MVEVYwgOyHWafQTHl932E,70413
|
|
44
42
|
dkist_processing_dlnirsp/tests/test_assemble_quality.py,sha256=djZsVSuRGl3akH3LmYjWvYuNSUFFQfS5y0S3Op7lQIE,1327
|
|
45
43
|
dkist_processing_dlnirsp/tests/test_bad_pixel_map.py,sha256=g5jWhVGSHMOtkcdiZ27G51ciud4ySjoDAjvMGLlgTIM,6093
|
|
46
44
|
dkist_processing_dlnirsp/tests/test_corrections.py,sha256=hefVNm3bgwfGQ7Wn0hi077LU_fKlDXJ0eeMl6HCRogA,7569
|
|
47
45
|
dkist_processing_dlnirsp/tests/test_dark.py,sha256=qv7SvUNgafzfdyIW11I6eSFeaXjw34-9X1ipnqKE1cY,3726
|
|
48
46
|
dkist_processing_dlnirsp/tests/test_dlnirsp_base.py,sha256=PCFklqGEqrgIhTYcatu7RfOxr_b_XjHotc36MRbUvnk,1853
|
|
49
|
-
dkist_processing_dlnirsp/tests/test_dlnirsp_constants.py,sha256=
|
|
47
|
+
dkist_processing_dlnirsp/tests/test_dlnirsp_constants.py,sha256=0E7Z4LHBDTAJ8G6TqGL7EU-MGN60Iqze4uZgZJwxqRc,6487
|
|
50
48
|
dkist_processing_dlnirsp/tests/test_dlnirsp_fits_access.py,sha256=5C5NPOkNigoNhIFNUKyrJvyt_mRjke1tkfXQcv1cnPI,5639
|
|
51
49
|
dkist_processing_dlnirsp/tests/test_geometric.py,sha256=94RDg1mGEMTibD2oPOoCKil5yUQMp_0vO4cDWzG3644,7742
|
|
52
50
|
dkist_processing_dlnirsp/tests/test_group_id.py,sha256=TpNllN6OZuYF8almsayk7pRTc4J8TcLGp1SHCBG6QAU,6279
|
|
@@ -54,32 +52,32 @@ dkist_processing_dlnirsp/tests/test_ifu_drift.py,sha256=K6ushbVQVE6AATjiP3hEgF6o
|
|
|
54
52
|
dkist_processing_dlnirsp/tests/test_instrument_polarization_calibration.py,sha256=pPXjfzi3EcaawNqvXsz3OcCF1XITEJeCzQ8-iOjlm7U,23430
|
|
55
53
|
dkist_processing_dlnirsp/tests/test_lamp.py,sha256=umy4ydYR5M3dqXTQP14qbamOleutyD1jSj3325aitl0,3940
|
|
56
54
|
dkist_processing_dlnirsp/tests/test_linearity_correction.py,sha256=JkPNtsRad2JQQ2QiJjQar9tJuCi9-ksOdEYHW_-kl58,31793
|
|
57
|
-
dkist_processing_dlnirsp/tests/
|
|
58
|
-
dkist_processing_dlnirsp/tests/test_parameters.py,sha256=
|
|
59
|
-
dkist_processing_dlnirsp/tests/test_parse.py,sha256=
|
|
55
|
+
dkist_processing_dlnirsp/tests/test_movie.py,sha256=j1ocVuy7PZCJrL-MrTczI-mFEsnECyCQ6P8uiK3mokw,4284
|
|
56
|
+
dkist_processing_dlnirsp/tests/test_parameters.py,sha256=bL30vGwFMwY2vP6-mQ-KPsr7I213PaXP7S1wKVPqq8g,10705
|
|
57
|
+
dkist_processing_dlnirsp/tests/test_parse.py,sha256=prx8K0vFGkW-YZm0YB13FBobbiMf0u1k8TuCyNF4_qE,38418
|
|
60
58
|
dkist_processing_dlnirsp/tests/test_quality.py,sha256=OBWva_E6T5RfDuo73LiTdTr7uh2FO04VpBAsSOLfjVQ,6122
|
|
61
|
-
dkist_processing_dlnirsp/tests/test_science.py,sha256=
|
|
62
|
-
dkist_processing_dlnirsp/tests/test_solar.py,sha256=
|
|
59
|
+
dkist_processing_dlnirsp/tests/test_science.py,sha256=2dpNW8-QaFqYeTbTeXqKRSWSns1b9l1iRgfhj8UBAUw,20632
|
|
60
|
+
dkist_processing_dlnirsp/tests/test_solar.py,sha256=0_QpdZFUczXCalhFrXQcMf3SWErbalnVTqV9r0558Pc,15411
|
|
63
61
|
dkist_processing_dlnirsp/tests/test_trial_create_quality_report.py,sha256=5wgj4PhiB-JRl7Sm7EUIvk5DDcFYpytpVLPmMbPuN_Y,2807
|
|
64
|
-
dkist_processing_dlnirsp/tests/test_wavelength_calibration.py,sha256=
|
|
62
|
+
dkist_processing_dlnirsp/tests/test_wavelength_calibration.py,sha256=Yp5A2I8WHrnKha56W_8o5BxVH21jervGsS0thN7ptn0,15028
|
|
65
63
|
dkist_processing_dlnirsp/tests/test_workflows.py,sha256=cRw_c90B-ZXGaw0vVWymYCE-_Ll6mBeM7aHsu-uXewo,290
|
|
66
64
|
dkist_processing_dlnirsp/tests/test_write_l1.py,sha256=J9D1QqCDe0IzYsphA4s_ciDEL0tUUSV1KLm8yo9mxyM,13335
|
|
67
65
|
dkist_processing_dlnirsp/tests/local_trial_workflows/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
68
66
|
dkist_processing_dlnirsp/tests/local_trial_workflows/l0_linearize_only.py,sha256=WpO2T2PRDiglwBB3zQDV_3Cq1RSw-ufu_iFjT5aLFJk,6750
|
|
69
|
-
dkist_processing_dlnirsp/tests/local_trial_workflows/l0_polcals_as_science.py,sha256=
|
|
70
|
-
dkist_processing_dlnirsp/tests/local_trial_workflows/l0_solar_gain_as_science.py,sha256=
|
|
71
|
-
dkist_processing_dlnirsp/tests/local_trial_workflows/l0_to_l1.py,sha256=
|
|
72
|
-
dkist_processing_dlnirsp/tests/local_trial_workflows/local_trial_dev_mockers.py,sha256=
|
|
67
|
+
dkist_processing_dlnirsp/tests/local_trial_workflows/l0_polcals_as_science.py,sha256=Ms0a_P-d-6dmz_j1hXXQYpF7hfgJljdGjRgAnMampCw,19399
|
|
68
|
+
dkist_processing_dlnirsp/tests/local_trial_workflows/l0_solar_gain_as_science.py,sha256=J_Iijqxy9pYc0olA38QOGV5_pCeoKMojqWtyKAnhL1g,20163
|
|
69
|
+
dkist_processing_dlnirsp/tests/local_trial_workflows/l0_to_l1.py,sha256=jt8oeLKENlSUbOek6hDQAhYeq2zY3FuphmkiP44lnDk,17791
|
|
70
|
+
dkist_processing_dlnirsp/tests/local_trial_workflows/local_trial_dev_mockers.py,sha256=dQ5hYJUXQDx6O7x9eQn3GbKsfcjpB_ylAmQ2N2MPsDI,12198
|
|
73
71
|
dkist_processing_dlnirsp/tests/local_trial_workflows/local_trial_helpers.py,sha256=5abEDqLyJ1mH6RYlV6ReHOqUkUste0vC6raENFQeDNY,21375
|
|
74
72
|
dkist_processing_dlnirsp/tests/local_trial_workflows/translate_files.py,sha256=bsOqBtGE9SdOZL2ROJ-murJHjymYrE_nEPNHJgy7pDc,1882
|
|
75
73
|
dkist_processing_dlnirsp/workflows/__init__.py,sha256=bDRNGCIayR8Z-dcOClvk5nTmHgKORTrZUVX9e3UpCc8,165
|
|
76
|
-
dkist_processing_dlnirsp/workflows/l0_processing.py,sha256=
|
|
77
|
-
dkist_processing_dlnirsp/workflows/trial_workflow.py,sha256=
|
|
74
|
+
dkist_processing_dlnirsp/workflows/l0_processing.py,sha256=walF4jr4qNCZv_YIh2pnmyQ0BEakGtXrS8k1lkzlBNY,3976
|
|
75
|
+
dkist_processing_dlnirsp/workflows/trial_workflow.py,sha256=PCncn1-tDHrcqPziV3LzrCCtgk6dwJpHa4Cx3ff8lQ0,4598
|
|
78
76
|
docs/Makefile,sha256=qnlVz6PuBqE39NfHWuUnHhNEA-EFgT2-WJNNNy9ttfk,4598
|
|
79
77
|
docs/bad_pixel_calibration.rst,sha256=UPBJCG1XWIFMwaR8BnvvbfdEN68s1SJ2nlxsXe1viHU,3403
|
|
80
78
|
docs/changelog.rst,sha256=ZpZPJIyl4nI0Eicku6uSrLdiinNOF2GcZwrvTEsb-Zs,346
|
|
81
79
|
docs/conf.py,sha256=wCcGpP5TUXfMTPgumKu0ZInLxYSuKILyCGi8__Omnmo,2081
|
|
82
|
-
docs/gain.rst,sha256=
|
|
80
|
+
docs/gain.rst,sha256=XyktESmH9kVyp1wtwRdvNshYC1CqA-XBWqsMG2TyhHg,5060
|
|
83
81
|
docs/geometric.rst,sha256=1iI26WJkFbFR0yG_zNbDwiZxU4i0KPtqVkUQL-aKI70,3522
|
|
84
82
|
docs/ifu_drift.rst,sha256=8Hd1XmW9ay2ig__kZJ03ut1_6M6F_NnMqrbSLrIl9tQ,1997
|
|
85
83
|
docs/index.rst,sha256=c2KAA_icOw7Ao3rWVv7lRBTEZ-9JWidL615Xrt6fSq4,378
|
|
@@ -94,8 +92,8 @@ docs/science_calibration.rst,sha256=JUMeS7KyIsL9cUuy-IdV2tQ-wQ2lBx6j8u_51ThJzVg,
|
|
|
94
92
|
docs/scientific_changelog.rst,sha256=01AWBSHg8zElnodCgAq-hMxhk9CkX5rtEENx4iz0sjI,300
|
|
95
93
|
docs/wavelength_calibration.rst,sha256=QGUd5Xmv5f7WQ1EKvw2CcgiMJQULjzdCW1hSQ8h8jj0,4123
|
|
96
94
|
licenses/LICENSE.rst,sha256=piZaQplkzOMmH1NXg6QIdo9wwo9pPCoHkvm2-DmH76E,1462
|
|
97
|
-
dkist_processing_dlnirsp-0.
|
|
98
|
-
dkist_processing_dlnirsp-0.
|
|
99
|
-
dkist_processing_dlnirsp-0.
|
|
100
|
-
dkist_processing_dlnirsp-0.
|
|
101
|
-
dkist_processing_dlnirsp-0.
|
|
95
|
+
dkist_processing_dlnirsp-0.33.0.dist-info/METADATA,sha256=4xNQA-3ecQwtXglEbvb5BBaBYSwkSLEC3mpMe7XMUIQ,30900
|
|
96
|
+
dkist_processing_dlnirsp-0.33.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
97
|
+
dkist_processing_dlnirsp-0.33.0.dist-info/entry_points.txt,sha256=p4-7cpIfxmQGFUDIP5n5noE5KADHN2-JvV03e0gOx9s,140
|
|
98
|
+
dkist_processing_dlnirsp-0.33.0.dist-info/top_level.txt,sha256=4WmLV9LQM78KTFnkHmtaOJvVHAPpz0m9ruzDS-B_cUo,49
|
|
99
|
+
dkist_processing_dlnirsp-0.33.0.dist-info/RECORD,,
|
docs/gain.rst
CHANGED
|
@@ -14,7 +14,8 @@ polarized beams. We call a single beam from a single slit a "slitbeam"; there ar
|
|
|
14
14
|
DLNIRSP gain calibration is performed by the `~dkist_processing_dlnirsp.tasks.solar` task using the following procedure.
|
|
15
15
|
The important steps are described in more detail below.
|
|
16
16
|
|
|
17
|
-
#. Apply dark, lamp, and geometric corrections to all solar gain frames and average them together.
|
|
17
|
+
#. Apply dark, lamp, and geometric corrections to all solar gain frames and average them together. For polarimetric data
|
|
18
|
+
the average is computed for each modstate and the result is demodulated. The Stokes I frame is then used for subsequent steps.
|
|
18
19
|
|
|
19
20
|
#. Compute a single characteristic solar spectrum across all slitbeams and place it into the full array.
|
|
20
21
|
|
|
@@ -37,7 +38,9 @@ Algorithm Detail
|
|
|
37
38
|
Apply Dark, Lamp, and Geometric Corrections
|
|
38
39
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
39
40
|
|
|
40
|
-
This step is mostly how it sounds.
|
|
41
|
+
This step is mostly how it sounds. For polarimetric data, each modstate is averaged separately and the final "average"
|
|
42
|
+
gain array is taken as the demodulated Stokes I signal. For intensity-mode data, a straight average over all modstates is
|
|
43
|
+
computed. The result (either Stokes I or full average) is then divided by the average lamp gain image, which
|
|
41
44
|
ensures that system illumination differences are not misidentified as true solar signal in the following steps. After
|
|
42
45
|
applying the :doc:`geometric correction </geometric>` all spectra will be on the reference wavelength grid.
|
|
43
46
|
|
|
@@ -59,7 +62,8 @@ geometric corrections. The result is a "raw" array that contains only the solar
|
|
|
59
62
|
Remove Characteristic Solar Spectra from Raw Solar Gain Frames
|
|
60
63
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
61
64
|
|
|
62
|
-
The re-distorted solar spectra are divided from the dark-corrected solar gain frames.
|
|
65
|
+
The re-distorted solar spectra are divided from the dark-corrected solar gain frames. For polarimetric data the solar
|
|
66
|
+
spectra are removed from the demodulated Stokes I dark-corrected gain signal. Because we don't use solar gains
|
|
63
67
|
with a lamp correction applied, the resulting gain image includes the full optical response of the system and can be
|
|
64
68
|
applied directly to the science data.
|
|
65
69
|
|
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
"""Task for constructing a browse movie."""
|
|
2
|
-
|
|
3
|
-
from typing import Type
|
|
4
|
-
|
|
5
|
-
import numpy as np
|
|
6
|
-
from dkist_processing_common.codecs.fits import fits_array_decoder
|
|
7
|
-
from dkist_processing_common.tasks import AssembleMovie
|
|
8
|
-
from dkist_service_configuration.logging import logger
|
|
9
|
-
from PIL import ImageDraw
|
|
10
|
-
from PIL.ImageFont import FreeTypeFont
|
|
11
|
-
|
|
12
|
-
from dkist_processing_dlnirsp.models.constants import DlnirspConstants
|
|
13
|
-
from dkist_processing_dlnirsp.models.tags import DlnirspTag
|
|
14
|
-
from dkist_processing_dlnirsp.parsers.dlnirsp_l1_fits_acess import DlnirspL1FitsAccess
|
|
15
|
-
|
|
16
|
-
__all__ = ["AssembleDlnirspMovie"]
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
class AssembleDlnirspMovie(AssembleMovie):
|
|
20
|
-
"""
|
|
21
|
-
Assemble all DLNIRSP movie frames (tagged with DlnirspTag.movie_frame()) into an mp4 movie file.
|
|
22
|
-
|
|
23
|
-
Subclassed from the `AssembleMovie` task in `dkist_processing_common` as required to add DLNIRSP specific
|
|
24
|
-
text overlays.
|
|
25
|
-
"""
|
|
26
|
-
|
|
27
|
-
constants: DlnirspConstants
|
|
28
|
-
|
|
29
|
-
MPL_COLOR_MAP = "afmhot"
|
|
30
|
-
|
|
31
|
-
@property
|
|
32
|
-
def constants_model_class(self) -> Type[DlnirspConstants]:
|
|
33
|
-
"""Get DLNIRSP constants."""
|
|
34
|
-
return DlnirspConstants
|
|
35
|
-
|
|
36
|
-
@property
|
|
37
|
-
def fits_parsing_class(self):
|
|
38
|
-
"""Parse frames as DlnirspL1FitsAccess objects."""
|
|
39
|
-
return DlnirspL1FitsAccess
|
|
40
|
-
|
|
41
|
-
def compute_frame_shape(self) -> tuple[int, int]:
|
|
42
|
-
"""Dynamically set the dimensions of the movie based on L1 file shape."""
|
|
43
|
-
movie_frame_arrays = self.read(tags=[DlnirspTag.movie_frame()], decoder=fits_array_decoder)
|
|
44
|
-
random_frame = next(movie_frame_arrays)
|
|
45
|
-
raw_L1_shape = random_frame.shape
|
|
46
|
-
flipped_shape = raw_L1_shape[::-1]
|
|
47
|
-
|
|
48
|
-
standard_HD_num_pix = 1920 * 1080
|
|
49
|
-
frame_num_pix = np.prod(flipped_shape)
|
|
50
|
-
scale_factor = np.sqrt(standard_HD_num_pix / frame_num_pix)
|
|
51
|
-
scaled_shape = tuple(int(i * scale_factor) for i in flipped_shape)
|
|
52
|
-
|
|
53
|
-
return scaled_shape
|
|
54
|
-
|
|
55
|
-
def pre_run(self) -> None:
|
|
56
|
-
"""Set the movie frame shape prior to running."""
|
|
57
|
-
super().pre_run()
|
|
58
|
-
frame_shape = self.compute_frame_shape()
|
|
59
|
-
logger.info(f"Setting movie shape to {frame_shape}")
|
|
60
|
-
self.MOVIE_FRAME_SHAPE = frame_shape
|
|
61
|
-
|
|
62
|
-
@property
|
|
63
|
-
def num_images(self) -> int:
|
|
64
|
-
"""
|
|
65
|
-
Total number of images in final movie.
|
|
66
|
-
|
|
67
|
-
Overloaded from `dkist-processing-common` so we can handle all the levels of instrument looping.
|
|
68
|
-
"""
|
|
69
|
-
return (
|
|
70
|
-
self.constants.num_mosaic_repeats
|
|
71
|
-
* self.constants.num_dither_steps
|
|
72
|
-
* self.constants.num_mosaic_tiles
|
|
73
|
-
)
|
|
74
|
-
|
|
75
|
-
def tags_for_image_n(self, n: int) -> list[str]:
|
|
76
|
-
"""Return tags that grab the n'th movie image.
|
|
77
|
-
|
|
78
|
-
Overloaded from `dkist-processing-common` so we can handle all the levels of instrument looping.
|
|
79
|
-
"""
|
|
80
|
-
mosaic_num = n // (self.constants.num_dither_steps * self.constants.num_mosaic_tiles)
|
|
81
|
-
dither_step = (n // self.constants.num_mosaic_tiles) % self.constants.num_dither_steps
|
|
82
|
-
tile_num = n % self.constants.num_mosaic_tiles
|
|
83
|
-
X_tile, Y_tile = np.unravel_index(
|
|
84
|
-
tile_num, (self.constants.num_mosaic_tiles_x, self.constants.num_mosaic_tiles_y)
|
|
85
|
-
)
|
|
86
|
-
# mosaic tile nums are 1-indexed
|
|
87
|
-
X_tile += 1
|
|
88
|
-
Y_tile += 1
|
|
89
|
-
|
|
90
|
-
tags = [
|
|
91
|
-
DlnirspTag.mosaic_num(mosaic_num),
|
|
92
|
-
DlnirspTag.dither_step(dither_step),
|
|
93
|
-
DlnirspTag.mosaic_tile_x(X_tile),
|
|
94
|
-
DlnirspTag.mosaic_tile_y(Y_tile),
|
|
95
|
-
]
|
|
96
|
-
logger.info(f"AssembleMovie.tags_for_image_n: {tags = }")
|
|
97
|
-
return tags
|
|
98
|
-
|
|
99
|
-
def write_overlay(self, draw: ImageDraw, fits_obj: DlnirspL1FitsAccess) -> None:
|
|
100
|
-
"""
|
|
101
|
-
Mark each movie frame the instrument, wavelength, and observe time.
|
|
102
|
-
|
|
103
|
-
Additionally, add labels for the 4 Stokes sub-frames if the data are polarimetric.
|
|
104
|
-
"""
|
|
105
|
-
self.write_line(
|
|
106
|
-
draw=draw,
|
|
107
|
-
text=f"INSTRUMENT: {self.constants.instrument}",
|
|
108
|
-
line=3,
|
|
109
|
-
column="right",
|
|
110
|
-
font=self.font_36,
|
|
111
|
-
)
|
|
112
|
-
self.write_line(
|
|
113
|
-
draw=draw,
|
|
114
|
-
text=f"WAVELENGTH: {fits_obj.wavelength} nm",
|
|
115
|
-
line=2,
|
|
116
|
-
column="right",
|
|
117
|
-
font=self.font_36,
|
|
118
|
-
)
|
|
119
|
-
self.write_line(
|
|
120
|
-
draw=draw,
|
|
121
|
-
text=f"OBS TIME: {fits_obj.time_obs}",
|
|
122
|
-
line=1,
|
|
123
|
-
column="right",
|
|
124
|
-
font=self.font_36,
|
|
125
|
-
)
|
|
126
|
-
|
|
127
|
-
if self.constants.correct_for_polarization:
|
|
128
|
-
# The `line` on which an item is drawn is a multiple of the height of that line.
|
|
129
|
-
IQ_line = self.get_middle_line(draw=draw, text="I Q", font=self.font_36)
|
|
130
|
-
|
|
131
|
-
# Subtract 1 from the UV line so that it's below IQ_line
|
|
132
|
-
UV_line = IQ_line - 1
|
|
133
|
-
|
|
134
|
-
self.write_line(
|
|
135
|
-
draw=draw, text="I Q", line=IQ_line, column="middle", font=self.font_36
|
|
136
|
-
)
|
|
137
|
-
self.write_line(
|
|
138
|
-
draw=draw, text="U V", line=UV_line, column="middle", font=self.font_36
|
|
139
|
-
)
|
|
140
|
-
|
|
141
|
-
def get_middle_line(self, draw: ImageDraw, text: str, font: FreeTypeFont) -> int:
|
|
142
|
-
"""
|
|
143
|
-
Get the line number for the middle of the frame.
|
|
144
|
-
|
|
145
|
-
We need to compute this in real time because the frame size is dynamically based on the L1 file shape.
|
|
146
|
-
"""
|
|
147
|
-
_, _, _, text_height = draw.textbbox(xy=(0, 0), text=text, font=font)
|
|
148
|
-
# See `write_line` in `dkist-processing-common` for why this is the expression.
|
|
149
|
-
line = (self.MOVIE_FRAME_SHAPE[1] // 2) / (self.TEXT_MARGIN_PX + text_height)
|
|
150
|
-
return line
|
|
@@ -1,156 +0,0 @@
|
|
|
1
|
-
"""Task for turning output science frames into movie frames."""
|
|
2
|
-
|
|
3
|
-
import numpy as np
|
|
4
|
-
from astropy.io import fits
|
|
5
|
-
from astropy.visualization import ZScaleInterval
|
|
6
|
-
from dkist_processing_common.codecs.fits import fits_array_encoder
|
|
7
|
-
from dkist_processing_common.codecs.fits import fits_hdu_decoder
|
|
8
|
-
from dkist_service_configuration.logging import logger
|
|
9
|
-
|
|
10
|
-
from dkist_processing_dlnirsp.models.tags import DlnirspTag
|
|
11
|
-
from dkist_processing_dlnirsp.tasks.dlnirsp_base import DlnirspTaskBase
|
|
12
|
-
|
|
13
|
-
__all__ = ["MakeDlnirspMovieFrames"]
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
class MakeDlnirspMovieFrames(DlnirspTaskBase):
|
|
17
|
-
"""Task class for making individual movie frames that will be used for the browse movie."""
|
|
18
|
-
|
|
19
|
-
def run(self) -> None:
|
|
20
|
-
"""
|
|
21
|
-
Construct movie frames from the set of output science frames.
|
|
22
|
-
|
|
23
|
-
For now just make a single movie frame for every output frame. If the data are polarimetric then all 4
|
|
24
|
-
Stokes images will be put together in a grid.
|
|
25
|
-
"""
|
|
26
|
-
if self.constants.correct_for_polarization:
|
|
27
|
-
logger.info("Making polarimetric movie frames")
|
|
28
|
-
else:
|
|
29
|
-
logger.info("Making spectrographic movie frames")
|
|
30
|
-
|
|
31
|
-
self.make_movie_frames()
|
|
32
|
-
|
|
33
|
-
def make_movie_frames(self):
|
|
34
|
-
"""Make a movie frame for every output frame."""
|
|
35
|
-
for mosaic_num in range(self.constants.num_mosaic_repeats):
|
|
36
|
-
for dither_step in range(self.constants.num_dither_steps):
|
|
37
|
-
for X_tile in range(1, self.constants.num_mosaic_tiles_x + 1):
|
|
38
|
-
for Y_tile in range(1, self.constants.num_mosaic_tiles_y + 1):
|
|
39
|
-
if self.constants.correct_for_polarization:
|
|
40
|
-
data, header = self.make_single_polarimetric_frame(
|
|
41
|
-
mosaic_num=mosaic_num,
|
|
42
|
-
dither_step=dither_step,
|
|
43
|
-
X_tile_num=X_tile,
|
|
44
|
-
Y_tile_num=Y_tile,
|
|
45
|
-
)
|
|
46
|
-
else:
|
|
47
|
-
data, header = self.make_single_spectrographic_frame(
|
|
48
|
-
mosaic_num=mosaic_num,
|
|
49
|
-
dither_step=dither_step,
|
|
50
|
-
X_tile_num=X_tile,
|
|
51
|
-
Y_tile_num=Y_tile,
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
self.write(
|
|
55
|
-
data=data,
|
|
56
|
-
header=header,
|
|
57
|
-
tags=[
|
|
58
|
-
DlnirspTag.movie_frame(),
|
|
59
|
-
DlnirspTag.mosaic_num(mosaic_num),
|
|
60
|
-
DlnirspTag.dither_step(dither_step),
|
|
61
|
-
DlnirspTag.mosaic_tile_x(X_tile),
|
|
62
|
-
DlnirspTag.mosaic_tile_y(Y_tile),
|
|
63
|
-
],
|
|
64
|
-
encoder=fits_array_encoder,
|
|
65
|
-
)
|
|
66
|
-
|
|
67
|
-
def make_single_polarimetric_frame(
|
|
68
|
-
self, mosaic_num: int, dither_step: int, X_tile_num: int, Y_tile_num: int
|
|
69
|
-
) -> tuple[np.ndarray, fits.Header]:
|
|
70
|
-
"""
|
|
71
|
-
Extract and grid together all 4 Stokes frames for a given instrument loop tuple.
|
|
72
|
-
|
|
73
|
-
The data are also scaled for visual appeal.
|
|
74
|
-
"""
|
|
75
|
-
stokes_dict = dict()
|
|
76
|
-
for stokes in self.constants.stokes_params:
|
|
77
|
-
tags = [
|
|
78
|
-
DlnirspTag.frame(),
|
|
79
|
-
DlnirspTag.calibrated(),
|
|
80
|
-
DlnirspTag.mosaic_num(mosaic_num),
|
|
81
|
-
DlnirspTag.dither_step(dither_step),
|
|
82
|
-
DlnirspTag.mosaic_tile_x(X_tile_num),
|
|
83
|
-
DlnirspTag.mosaic_tile_y(Y_tile_num),
|
|
84
|
-
]
|
|
85
|
-
hdu = next(self.read(tags=tags, decoder=fits_hdu_decoder))
|
|
86
|
-
data_2D = self.grab_wavelength_slice(hdu.data)
|
|
87
|
-
stokes_dict[stokes] = self.scale_for_rendering(data_2D)
|
|
88
|
-
|
|
89
|
-
# Don't care which hdu we get
|
|
90
|
-
header = hdu.header
|
|
91
|
-
movie_array = self.grid_movie_frame(
|
|
92
|
-
top_left=stokes_dict["I"],
|
|
93
|
-
top_right=stokes_dict["Q"],
|
|
94
|
-
bottom_left=stokes_dict["U"],
|
|
95
|
-
bottom_right=stokes_dict["V"],
|
|
96
|
-
)
|
|
97
|
-
return movie_array, header
|
|
98
|
-
|
|
99
|
-
def make_single_spectrographic_frame(
|
|
100
|
-
self, mosaic_num: int, dither_step: int, X_tile_num: int, Y_tile_num: int
|
|
101
|
-
) -> tuple[np.ndarray, fits.Header]:
|
|
102
|
-
"""Load a output spectrographic frame, extract a single wavelength, and scale for visual appeal."""
|
|
103
|
-
tags = [
|
|
104
|
-
DlnirspTag.frame(),
|
|
105
|
-
DlnirspTag.calibrated(),
|
|
106
|
-
DlnirspTag.mosaic_num(mosaic_num),
|
|
107
|
-
DlnirspTag.dither_step(dither_step),
|
|
108
|
-
DlnirspTag.mosaic_tile_x(X_tile_num),
|
|
109
|
-
DlnirspTag.mosaic_tile_y(Y_tile_num),
|
|
110
|
-
]
|
|
111
|
-
hdu = next(self.read(tags=tags, decoder=fits_hdu_decoder))
|
|
112
|
-
|
|
113
|
-
data_2D = self.grab_wavelength_slice(hdu.data)
|
|
114
|
-
scaled_data = self.scale_for_rendering(data_2D)
|
|
115
|
-
|
|
116
|
-
movie_array = self.scale_for_rendering(scaled_data)
|
|
117
|
-
|
|
118
|
-
return movie_array, hdu.header
|
|
119
|
-
|
|
120
|
-
@staticmethod
|
|
121
|
-
def grab_wavelength_slice(data: np.ndarray):
|
|
122
|
-
"""Convert a 3D IFU image into a 2D movie frame by extracting a certain wavelength region."""
|
|
123
|
-
wavelength_dim_size = data.shape[0]
|
|
124
|
-
middle_index = int(np.mean(range(wavelength_dim_size)))
|
|
125
|
-
return data[middle_index, :, :]
|
|
126
|
-
|
|
127
|
-
@staticmethod
|
|
128
|
-
def scale_for_rendering(data: np.ndarray):
|
|
129
|
-
"""
|
|
130
|
-
Scale the output frame data using a normalization function to facilitate display as a movie frame.
|
|
131
|
-
|
|
132
|
-
Non-number pixels (nan, inf, -inf) are set to black.
|
|
133
|
-
"""
|
|
134
|
-
bad_idx = ~np.isfinite(data)
|
|
135
|
-
data[bad_idx] = np.nanmedian(data)
|
|
136
|
-
zscale = ZScaleInterval()
|
|
137
|
-
scaled_data = zscale(data)
|
|
138
|
-
scaled_data[bad_idx] = 0.0
|
|
139
|
-
return scaled_data
|
|
140
|
-
|
|
141
|
-
@staticmethod
|
|
142
|
-
def grid_movie_frame(
|
|
143
|
-
top_left: np.ndarray,
|
|
144
|
-
top_right: np.ndarray,
|
|
145
|
-
bottom_left: np.ndarray,
|
|
146
|
-
bottom_right: np.ndarray,
|
|
147
|
-
) -> np.ndarray:
|
|
148
|
-
"""Combine multiple arrays into a 2x2 grid."""
|
|
149
|
-
result = np.concatenate(
|
|
150
|
-
(
|
|
151
|
-
np.concatenate((top_left, top_right), axis=1),
|
|
152
|
-
np.concatenate((bottom_left, bottom_right), axis=1),
|
|
153
|
-
),
|
|
154
|
-
axis=0,
|
|
155
|
-
)
|
|
156
|
-
return result
|
|
@@ -1,169 +0,0 @@
|
|
|
1
|
-
import numpy as np
|
|
2
|
-
import pytest
|
|
3
|
-
from dkist_processing_common._util.scratch import WorkflowFileSystem
|
|
4
|
-
from moviepy.video.io.VideoFileClip import VideoFileClip
|
|
5
|
-
|
|
6
|
-
from dkist_processing_dlnirsp.models.tags import DlnirspTag
|
|
7
|
-
from dkist_processing_dlnirsp.tasks.assemble_movie import AssembleDlnirspMovie
|
|
8
|
-
from dkist_processing_dlnirsp.tests.conftest import DlnirspTestingConstants
|
|
9
|
-
from dkist_processing_dlnirsp.tests.conftest import MovieFrameHeaders
|
|
10
|
-
from dkist_processing_dlnirsp.tests.conftest import tag_on_mosaic_dither_loops
|
|
11
|
-
from dkist_processing_dlnirsp.tests.conftest import write_frames_to_task
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def write_movie_frames_to_task(
|
|
15
|
-
task,
|
|
16
|
-
dither_mode_on: bool,
|
|
17
|
-
num_mosaics: int,
|
|
18
|
-
num_X_tiles: int,
|
|
19
|
-
num_Y_tiles: int,
|
|
20
|
-
array_shape: tuple[int, int],
|
|
21
|
-
) -> int:
|
|
22
|
-
dataset = MovieFrameHeaders(
|
|
23
|
-
dither_mode_on=dither_mode_on,
|
|
24
|
-
num_mosaics=num_mosaics,
|
|
25
|
-
num_X_tiles=num_X_tiles,
|
|
26
|
-
num_Y_tiles=num_Y_tiles,
|
|
27
|
-
array_shape=array_shape,
|
|
28
|
-
)
|
|
29
|
-
|
|
30
|
-
num_written_frames = write_frames_to_task(
|
|
31
|
-
task=task,
|
|
32
|
-
frame_generator=dataset,
|
|
33
|
-
extra_tags=[
|
|
34
|
-
DlnirspTag.movie_frame(),
|
|
35
|
-
],
|
|
36
|
-
tag_func=tag_on_mosaic_dither_loops,
|
|
37
|
-
data_func=make_movie_frame_data,
|
|
38
|
-
)
|
|
39
|
-
return num_written_frames
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
def make_movie_frame_data(frame: MovieFrameHeaders) -> np.ndarray:
|
|
43
|
-
shape = frame.array_shape[1:]
|
|
44
|
-
data = np.zeros(shape)
|
|
45
|
-
total_frames = frame.dataset_shape[0]
|
|
46
|
-
current_index = frame.index + 1
|
|
47
|
-
horizontal_frac = int((current_index / total_frames) * shape[0])
|
|
48
|
-
data[:horizontal_frac, :] = 1.0
|
|
49
|
-
|
|
50
|
-
return data
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
@pytest.fixture
|
|
54
|
-
def assemble_movie_task(recipe_run_id, dither_mode_on, tmp_path, link_constants_db):
|
|
55
|
-
num_mosaics = 4
|
|
56
|
-
num_X_tiles = 3
|
|
57
|
-
num_Y_tiles = 2
|
|
58
|
-
|
|
59
|
-
constants = DlnirspTestingConstants(
|
|
60
|
-
NUM_MOSAIC_REPEATS=num_mosaics,
|
|
61
|
-
NUM_MOSAIC_TILES_X=num_X_tiles,
|
|
62
|
-
NUM_MOSAIC_TILES_Y=num_Y_tiles,
|
|
63
|
-
NUM_DITHER_STEPS=int(dither_mode_on) + 1,
|
|
64
|
-
)
|
|
65
|
-
link_constants_db(recipe_run_id, constants)
|
|
66
|
-
|
|
67
|
-
with AssembleDlnirspMovie(
|
|
68
|
-
recipe_run_id=recipe_run_id,
|
|
69
|
-
workflow_name="workflow_name",
|
|
70
|
-
workflow_version="workflow_version",
|
|
71
|
-
) as task:
|
|
72
|
-
task.scratch = WorkflowFileSystem(scratch_base_path=tmp_path, recipe_run_id=recipe_run_id)
|
|
73
|
-
|
|
74
|
-
yield task, num_mosaics, num_X_tiles, num_Y_tiles
|
|
75
|
-
task._purge()
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
@pytest.mark.parametrize("dither_mode_on", [pytest.param(True, id="dither_mode_on")])
|
|
79
|
-
@pytest.mark.parametrize(
|
|
80
|
-
"is_polarimetric, requires_shrinking",
|
|
81
|
-
[
|
|
82
|
-
pytest.param(True, True, id="polarimetric_shrink"),
|
|
83
|
-
pytest.param(False, False, id="spectrographic_noshrink"),
|
|
84
|
-
pytest.param(True, False, id="polarimetric_noshrink"),
|
|
85
|
-
],
|
|
86
|
-
)
|
|
87
|
-
def test_assemble_movie(
|
|
88
|
-
assemble_movie_task,
|
|
89
|
-
dither_mode_on,
|
|
90
|
-
is_polarimetric,
|
|
91
|
-
requires_shrinking,
|
|
92
|
-
mocker,
|
|
93
|
-
fake_gql_client,
|
|
94
|
-
):
|
|
95
|
-
"""
|
|
96
|
-
Given: An AssembleDlnirspMovie task and associated MOVIE_FRAME files
|
|
97
|
-
When: Running the task
|
|
98
|
-
Then: A movie is generated with the correct size
|
|
99
|
-
"""
|
|
100
|
-
mocker.patch(
|
|
101
|
-
"dkist_processing_common.tasks.mixin.metadata_store.GraphQLClient", new=fake_gql_client
|
|
102
|
-
)
|
|
103
|
-
task, num_mosaics, num_X_tiles, num_Y_tiles = assemble_movie_task
|
|
104
|
-
|
|
105
|
-
if requires_shrinking:
|
|
106
|
-
movie_shape = (1080 * 2, 1920 * 2) # Intentionally "backward" from normal
|
|
107
|
-
expected_shape = (1080, 1920)[::-1]
|
|
108
|
-
else:
|
|
109
|
-
movie_shape = (1920 // 2 - 1, 1080 // 2 - 1) # Weird aspect ratio
|
|
110
|
-
expected_shape = (1920, 1080)[::-1] # Because AssembleMovie will force even dimensions
|
|
111
|
-
write_movie_frames_to_task(
|
|
112
|
-
task,
|
|
113
|
-
dither_mode_on=dither_mode_on,
|
|
114
|
-
num_mosaics=num_mosaics,
|
|
115
|
-
num_X_tiles=num_X_tiles,
|
|
116
|
-
num_Y_tiles=num_Y_tiles,
|
|
117
|
-
array_shape=movie_shape,
|
|
118
|
-
)
|
|
119
|
-
|
|
120
|
-
task()
|
|
121
|
-
|
|
122
|
-
movie_file = list(task.read(tags=[DlnirspTag.movie()]))
|
|
123
|
-
assert len(movie_file) == 1
|
|
124
|
-
assert movie_file[0].exists()
|
|
125
|
-
clip = VideoFileClip(str(movie_file[0]))
|
|
126
|
-
assert tuple(clip.size) == expected_shape
|
|
127
|
-
|
|
128
|
-
# import os
|
|
129
|
-
# os.system(f"cp {movie_file[0]} foo.mp4")
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
@pytest.mark.parametrize(
|
|
133
|
-
"dither_mode_on",
|
|
134
|
-
[pytest.param(True, id="dither_mode_on"), pytest.param(False, id="dither_mode_off")],
|
|
135
|
-
)
|
|
136
|
-
def test_tags_for_images(assemble_movie_task, dither_mode_on):
|
|
137
|
-
"""
|
|
138
|
-
Given: A `AssembleDlnirspMovie` task with constants describing the number of L1 frames
|
|
139
|
-
When: Computing the tags for a certain movie image
|
|
140
|
-
Then: The correct tags are returned
|
|
141
|
-
"""
|
|
142
|
-
task, num_mosaics, num_X_tiles, num_Y_tiles = assemble_movie_task
|
|
143
|
-
num_dither = int(dither_mode_on) + 1
|
|
144
|
-
|
|
145
|
-
assert task.num_images == num_mosaics * num_dither * num_X_tiles * num_Y_tiles
|
|
146
|
-
|
|
147
|
-
expected_mosaic_values = sum(
|
|
148
|
-
[[i for _ in range(num_X_tiles * num_Y_tiles * num_dither)] for i in range(num_mosaics)], []
|
|
149
|
-
)
|
|
150
|
-
expected_dither_values = (
|
|
151
|
-
sum([[d] * num_X_tiles * num_Y_tiles for d in range(num_dither)], []) * num_mosaics
|
|
152
|
-
)
|
|
153
|
-
expected_X_tile_values = (
|
|
154
|
-
sum([[i for _ in range(num_Y_tiles)] for i in range(1, num_X_tiles + 1)] * num_mosaics, [])
|
|
155
|
-
* num_dither
|
|
156
|
-
)
|
|
157
|
-
expected_Y_tile_values = (
|
|
158
|
-
list(range(1, num_Y_tiles + 1)) * num_X_tiles * num_mosaics * num_dither
|
|
159
|
-
)
|
|
160
|
-
|
|
161
|
-
for n in range(task.num_images):
|
|
162
|
-
assert sorted(task.tags_for_image_n(n)) == sorted(
|
|
163
|
-
[
|
|
164
|
-
DlnirspTag.mosaic_num(expected_mosaic_values[n]),
|
|
165
|
-
DlnirspTag.dither_step(expected_dither_values[n]),
|
|
166
|
-
DlnirspTag.mosaic_tile_x(expected_X_tile_values[n]),
|
|
167
|
-
DlnirspTag.mosaic_tile_y(expected_Y_tile_values[n]),
|
|
168
|
-
]
|
|
169
|
-
)
|