From bb74daa389d67f858d46625203f881bc749ca4c1 Mon Sep 17 00:00:00 2001 From: DanRyanIrish Date: Fri, 15 Nov 2024 13:45:22 +0000 Subject: [PATCH] Add generic projective frame. Good for representing images from unknown instruments. --- xrayvision/coordinates/.frames.py.swp | Bin 0 -> 16384 bytes xrayvision/coordinates/__init__.py | 0 xrayvision/coordinates/frames.py | 119 ++++++++++++++++++ .../coordinates/tests/.test_frames.py.swp | Bin 0 -> 12288 bytes xrayvision/coordinates/tests/__init__.py | 0 xrayvision/coordinates/tests/test_frames.py | 72 +++++++++++ 6 files changed, 191 insertions(+) create mode 100644 xrayvision/coordinates/.frames.py.swp create mode 100644 xrayvision/coordinates/__init__.py create mode 100644 xrayvision/coordinates/frames.py create mode 100644 xrayvision/coordinates/tests/.test_frames.py.swp create mode 100644 xrayvision/coordinates/tests/__init__.py create mode 100644 xrayvision/coordinates/tests/test_frames.py diff --git a/xrayvision/coordinates/.frames.py.swp b/xrayvision/coordinates/.frames.py.swp new file mode 100644 index 0000000000000000000000000000000000000000..2f0fcb3b793d68dd383b671c9fb3481d449c95e6 GIT binary patch literal 16384 zcmeHO&5s;M6|XpaB@i5$NC>2e%B(=M)@*Oqn_zpT0oKbpSu0*IJ7dSOW%btd)XX&Q z>1uUXZ+1WiAxm(9Gan}|fCQ3r20;`li8ur#5Fj}4p+x$_m-#vG48!p-W8dqZ?Y36$-FJ73v9^dq8KnaeQ|0_) zB)4>Zr?IrMx^#YZ-8iwUcuUI0hU8jseGjW56-s7;p?Y2L2Bi z(8&q*RrqnD@Fgg|?>qE;fARZ~;=6OGzWC|B90QI4$ADwNG2j?*3^)cH1C9a5fMdWh z;28KHWI(hTdlsAjw`hZp=l|vY|L-RmdkuI2kibdcZy#ptufVIoE5OUZJ>a{*cYtpL zw}F$uuO4FTYrr+&6Tojj#MoWn31AU;TvxC`6_ZUC#m zOYdjwXTVPZ1;oH5U<-H}I0ZZay!bx!2Pojvz>~nIfR6%izL&AT0DlI41H1y<1AYh` z0NcPCa2}`tZ@h=Ge*!-Mz7Dj2^T0WP#^rV3Wgx~lHGoavQQ%KV()_wi)bQ!!`5^NM zB0unY-6-}|E8}&JPv5*&;YBL;wDPB0j+Gp#WTqSy&S`Z-)s$8HBFbeo_u8_%$QZSx zV<-kkaLnmvC{?;RTiG$&AHSpHODcc1No4sPEmS=3n9l>Xn64eyGhI7-n#?!Y%q9$o zomFr_ru#DW%uhyLg&p1#nb10|4u_`3D@LHQxMpOA6;p~#^#X6GzSJS!1~QYtyd=Z} z5%ZShf;VmtHt4mX8qX9DRE+*LZ>#5Ht`(}SDMrz_yJ?okekwb|E~$W)MCogPv1|j8 zXEz$vSR8~|{mj^mOr_4#m~X3C8d>-nE6wp%Q=DlL2eN89ukoE!eNhHF+?R#N3;coz zBd&7IrAVUz(L_xf&8_QOebEi$ZecjbQK?jn{ymZDR3!tmv|-YoDP6LMIo~xFWp>dd zMXxI6YkUt)_i9`v8n0Z5$VeOOsBUE6gi0tjayx=v#nLh@6i?WZ>oCf^Kt?jtp@?jJ z@j)cm-s7q4hUj_V8AV&VD1a)idy;s?kPYAY;(Cx^kUOdBQ+1efk!30f@jh7F^1(w4 zYfoASFDeM|E@+KyZ4GrH+UGIIhTC?4Y*&FwQ<)_y#`|Sm)3IvNpjgXN;<%0JP?EMU zCp;-fvaD8dz0zFYrWtH)Ddxh6$?ECThF@Q#-K>~2qXNvSFIO<{X;xR(cpDyy{Vo

311^A%mH8SgMS{WsI304UE2t00WH_J&uY>^Fjzw z!cC~niX}a%$3_)&K#}B7a5)@RnupdrMVvCgjNG*m0T+1r1Pa=;~jJ54U0P!EpFoq+!}D) zl8Lkx>Qtn-r9mxj1u3uu5w7E7cR|%g9`6h;h)j+wyh!&LW?dDr5gb)^E+V5 z*R1h(*l0F+H9pUuBel{^u^HH*`Xk28YAWXmMc%>>L@-vImbGK{AFiS~labRoqy7JD z*pHvZ9-a38<@5btV!!__;G4i6a29wNpgaHr-ohULO@Q|QZQ$d;$AEu9&+mXA19t(+ z0g&$dfj^?39|7)g3^)cH1C9a5fMdWh;23ZWI0hU8M=(%sYOv*@ytha~uY)}d{WQ5W zzj?*Ky7BoHFHa~jSA9qFWBK%B=@vNNVVj-ZE0;Dmnp@X4ZOX5-cahoLQKfNx_Xcvi zl_1Zw>aXF?(O#Kl-k08&DmD`Yv1hjDiy><`CfGbeka8z%o>3+*!Ny&*iMWfq>z6lu zY&HGM>pMGJ+fOw-JmbKFmg-84-yE4cku$%wI71WZu-e{66UKvbe`fy;O$&Ti_SL@R zic-~mJO;pX9{T$@R~>G)`ShHL_q0y3wdG~xyL)*HyZ-*NsVqK|Jc^djK6(BLOgJRz ziU$Og*|ooERuN3fmXZpG6SlWZv!NJmr%mp`X6-1yRh&%<7Aa$h8h+S{uiXiLahCt#6gxGX?YGztzx|{0m zB!jM=jJH+r;&nv?5AJalL2oPG6a*2`qkHnYq6p%@s=BAU=OY`zgGx2?OQx&dt9tdX zS8pbyckJh%xk4{kErRQQLVoF<@4Cx3=03heNZSp3*5^Yv5S_EH!mjb+`bML<+_<>h zv?uLfFASGBi^6zmpS#0dKla0*{MHLY-u44GVet}3)K90w-2scOXgE2tZqW*81rAjp zO*)MW3uL*aPUfS=BlLkY&mHQbJGBB@0j+>mKr5gX&mKr5gX&fgyqNkiT?+$7gn_tUr4bKbW?tg&GNMkLPtb@)LH%^Kl2jn`(c;6QP1}_k}w$dQXVH}tw!3cL&bx9PD##k zs7?UY&DsjmrW&<{by#k?Z}qzU#0ht>C9AY$A7T~cR(Q;5##rq*Ev&3_tl6Ap$%Q3H z@R)TxbW3zvkb2kcr_4;PL2YXEZ9K-91#YzL)?*F3i5Io)75TDk+cu`n@1=pCY}wml zZo}nX%)IG#$uMHM-TLKc*BYBou2n4Yd}RqA$V{IV^k3y_z)Jld0f|#o}0Q89jGk)T!b17>k*)t!&VP#hHP- z@5igH>G75aAIm#66UEiE=^{<7HtW`rZpHhiOc!}Ss8eif;t$wrXnr1f`yOcbJER^HNPSnLG zqM@jtR>$9mMl7q7nP7V=UUfo5u`CK4RS7F~D*B6Jn%B}wUsfD(2+9K&M{iVQpdsFG z%7T-fKy^wvY9f}lW!I@)>1eY)Qj-Re<#IgwZEm%2zP2kToJan?@NL4mRq-BG(z0e_ zg;cE+{u6beBrCFXx~Lr<4ruXAx>b4*-I95SuLy%E#J7baCF>KP4B6*zrK5ach@1w= y7Y)lZzSHs$2T2@m0h;c{~0u{})y literal 0 HcmV?d00001 diff --git a/xrayvision/coordinates/tests/__init__.py b/xrayvision/coordinates/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/xrayvision/coordinates/tests/test_frames.py b/xrayvision/coordinates/tests/test_frames.py new file mode 100644 index 0000000..8a9f89b --- /dev/null +++ b/xrayvision/coordinates/tests/test_frames.py @@ -0,0 +1,72 @@ +import astropy.units as u +import numpy as np +import pytest +from astropy.wcs import WCS +from sunpy.coordinates import HeliographicStonyhurst +from xrayvision.coordinates.frames import Projective, projective_frame_to_wcs, projective_wcs_to_frame + + +@pytest.fixture +def projective_wcs(): + w = WCS(naxis=2) + + w.wcs.dateobs = "2024-01-01 00:00:00.000" + w.wcs.crpix = [10, 20] + w.wcs.cdelt = np.array([2, 2]) + w.wcs.crval = [0, 0] + w.wcs.ctype = ["PJLN-TAN", "PJLT-TAN"] + + w.wcs.aux.hgln_obs = 10 + w.wcs.aux.hglt_obs = 20 + w.wcs.aux.dsun_obs = 1.5e11 + + return w + + +@pytest.fixture +def projective_frame(): + obstime = "2024-01-01" + observer = HeliographicStonyhurst(10 * u.deg, 20 * u.deg, 1.5e11 * u.m, obstime=obstime) + + frame_args = {"obstime": obstime, "observer": observer, "rsun": 695_700_000 * u.m} + + frame = Projective(**frame_args) + return frame + + +def test_projective_wcs_to_frame(projective_wcs): + frame = projective_wcs_to_frame(projective_wcs) + assert isinstance(frame, Projective) + + assert frame.obstime.isot == "2024-01-01T00:00:00.000" + assert frame.rsun == 695700 * u.km + assert frame.observer == HeliographicStonyhurst( + 10 * u.deg, 20 * u.deg, 1.5e11 * u.m, obstime="2024-01-01T00:00:00.000" + ) + + +def test_projective_wcs_to_frame_none(): + w = WCS(naxis=2) + w.wcs.ctype = ["ham", "cheese"] + frame = projective_wcs_to_frame(w) + + assert frame is None + + +def test_projective_frame_to_wcs(projective_frame): + wcs = projective_frame_to_wcs(projective_frame) + + assert isinstance(wcs, WCS) + assert wcs.wcs.ctype[0] == "PJLN-TAN" + assert wcs.wcs.cunit[0] == "arcsec" + assert wcs.wcs.dateobs == "2024-01-01 00:00:00.000" + + assert wcs.wcs.aux.rsun_ref == projective_frame.rsun.to_value(u.m) + assert wcs.wcs.aux.dsun_obs == 1.5e11 + assert wcs.wcs.aux.hgln_obs == 10 + assert wcs.wcs.aux.hglt_obs == 20 + + +def test_projective_frame_to_wcs_none(): + wcs = projective_frame_to_wcs(HeliographicStonyhurst()) + assert wcs is None