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.
Files changed (32) hide show
  1. dkist_processing_dlnirsp/models/constants.py +6 -0
  2. dkist_processing_dlnirsp/models/parameters.py +33 -3
  3. dkist_processing_dlnirsp/parsers/task.py +2 -25
  4. dkist_processing_dlnirsp/parsers/time.py +2 -2
  5. dkist_processing_dlnirsp/tasks/__init__.py +1 -2
  6. dkist_processing_dlnirsp/tasks/movie.py +1121 -0
  7. dkist_processing_dlnirsp/tasks/parse.py +13 -8
  8. dkist_processing_dlnirsp/tasks/solar.py +129 -30
  9. dkist_processing_dlnirsp/tests/conftest.py +46 -7
  10. dkist_processing_dlnirsp/tests/local_trial_workflows/l0_polcals_as_science.py +21 -18
  11. dkist_processing_dlnirsp/tests/local_trial_workflows/l0_solar_gain_as_science.py +21 -18
  12. dkist_processing_dlnirsp/tests/local_trial_workflows/l0_to_l1.py +21 -18
  13. dkist_processing_dlnirsp/tests/local_trial_workflows/local_trial_dev_mockers.py +1 -1
  14. dkist_processing_dlnirsp/tests/test_dlnirsp_constants.py +2 -0
  15. dkist_processing_dlnirsp/tests/test_movie.py +141 -0
  16. dkist_processing_dlnirsp/tests/test_parameters.py +8 -0
  17. dkist_processing_dlnirsp/tests/test_parse.py +10 -0
  18. dkist_processing_dlnirsp/tests/test_science.py +0 -9
  19. dkist_processing_dlnirsp/tests/test_solar.py +114 -17
  20. dkist_processing_dlnirsp/tests/test_wavelength_calibration.py +4 -1
  21. dkist_processing_dlnirsp/workflows/l0_processing.py +6 -8
  22. dkist_processing_dlnirsp/workflows/trial_workflow.py +7 -7
  23. {dkist_processing_dlnirsp-0.32.8.dist-info → dkist_processing_dlnirsp-0.33.0.dist-info}/METADATA +52 -35
  24. {dkist_processing_dlnirsp-0.32.8.dist-info → dkist_processing_dlnirsp-0.33.0.dist-info}/RECORD +28 -30
  25. docs/gain.rst +7 -3
  26. dkist_processing_dlnirsp/tasks/assemble_movie.py +0 -150
  27. dkist_processing_dlnirsp/tasks/make_movie_frames.py +0 -156
  28. dkist_processing_dlnirsp/tests/test_assemble_movie.py +0 -169
  29. dkist_processing_dlnirsp/tests/test_make_movie_frames.py +0 -98
  30. {dkist_processing_dlnirsp-0.32.8.dist-info → dkist_processing_dlnirsp-0.33.0.dist-info}/WHEEL +0 -0
  31. {dkist_processing_dlnirsp-0.32.8.dist-info → dkist_processing_dlnirsp-0.33.0.dist-info}/entry_points.txt +0 -0
  32. {dkist_processing_dlnirsp-0.32.8.dist-info → dkist_processing_dlnirsp-0.33.0.dist-info}/top_level.txt +0 -0
@@ -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=0TV_K6WbvUlDQdNRxx_qblQ_dwN7RGU7ng2iDOBQedo,6386
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=PsaZSNE4Uyov1xGMqRqh6kb5F8NnDDm3QRHkoiDAsYY,15812
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=9_JzhqfU9os-6uUpn1FlNd2d1yWfD0dB4u0H0OruTbs,1619
17
- dkist_processing_dlnirsp/parsers/time.py,sha256=DsnGxT4coH6FjiHsLr5gimW8lGExE5y_E6zzUH89HMM,2072
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=6N5xdCM3FeTpzmBUgUnJ5mKF2N3vBfcj-SNqVQ9ZHiw,996
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/make_movie_frames.py,sha256=zxyAWNnPFbG7jpUEe3ekRyJGjk706T9a-yiA3eoWi5M,6290
32
- dkist_processing_dlnirsp/tasks/parse.py,sha256=ZtqM6dyxxnnbVTAun040EuxfQZEQcnkXzZffXSBTYkk,10919
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=NyLYkRophfXaVtvnGuNEvkcE8JNcmCJVuobNYAZ7KjQ,11135
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=Xp02ZyHi6X3FzyY_IQOjLsH3gOA9zK7KGo9gpeeO6jw,68768
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=RFNf-Hj835NlE45vygxh01kJm8YdCJJ3UUwzJRYJHE8,6411
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/test_make_movie_frames.py,sha256=fR1xJEFJMK0xUu8-EyOS_6mIX_ZO2J_nM0k3ud8xtYM,3648
58
- dkist_processing_dlnirsp/tests/test_parameters.py,sha256=KpBeisM4BIF5Kl6ZxZqk3yCozndmLMlzNgo0ij0hmYw,10328
59
- dkist_processing_dlnirsp/tests/test_parse.py,sha256=UIII4R6JruUEFIlYDRwTwiBqyf4ldYxAhCWHM-jcd6E,38005
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=1DKqKNAEZEsVCffYz_TiEc2REG7cBIfGeig1kJK4ZtE,20902
62
- dkist_processing_dlnirsp/tests/test_solar.py,sha256=jTNnxs5fE8R_hLvmdAU9x4RXJaSpJWGQajL7kzXTxPQ,12111
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=GFGXtl0KdClolknAwfR0aG5t-Ux5N5mynol4dKp0cn8,14830
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=ZDefUSKggIH2ebzUziQWU_A2yWeX68vjqzC11MNkzJU,19338
70
- dkist_processing_dlnirsp/tests/local_trial_workflows/l0_solar_gain_as_science.py,sha256=Nv8qi-U2mUpWRn8rfx0ckn6v9OUGbfSND-fX9WVRaU0,20102
71
- dkist_processing_dlnirsp/tests/local_trial_workflows/l0_to_l1.py,sha256=MfCqHOO9RC24FRqGUKfPiTGUZh7rft9NklYKej-oM00,17757
72
- dkist_processing_dlnirsp/tests/local_trial_workflows/local_trial_dev_mockers.py,sha256=zEnx_mOTwF8QRM8BZ2Nn0MntfFIkrMVQZDUbmqCmDJk,12191
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=m7zNXo9XoBwXzfiDQTmf4mPgJrTXY15DvqrAXwsx7Mg,4117
77
- dkist_processing_dlnirsp/workflows/trial_workflow.py,sha256=eqfRtWSuusM-5yvDjlabeCKolAswvw7rOqFEohFjOhI,4732
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=ytH5AhcCkLlXCKg4enL60p1mBquOv2Bc_T6gvq2-L3Q,4568
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.32.8.dist-info/METADATA,sha256=ORbWeb4x6DYDu3wN0vVwL00qSayzvXv-2CEQYqyR-0s,30061
98
- dkist_processing_dlnirsp-0.32.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
99
- dkist_processing_dlnirsp-0.32.8.dist-info/entry_points.txt,sha256=p4-7cpIfxmQGFUDIP5n5noE5KADHN2-JvV03e0gOx9s,140
100
- dkist_processing_dlnirsp-0.32.8.dist-info/top_level.txt,sha256=4WmLV9LQM78KTFnkHmtaOJvVHAPpz0m9ruzDS-B_cUo,49
101
- dkist_processing_dlnirsp-0.32.8.dist-info/RECORD,,
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. Importantly, all solar gain images are divided by the average lamp gain image, which
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. Because we don't use solar gains
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
- )