From 43d6e9dabbad567b64f5f61c9c7638681586039b Mon Sep 17 00:00:00 2001 From: perrygreenfield Date: Thu, 9 Nov 2023 10:45:42 -0500 Subject: [PATCH 1/8] fix mask issue for IFU example --- docs/gwcs/ifu-regions.png | Bin 14063 -> 18619 bytes docs/gwcs/ifu.rst | 24 ++++++++++++------------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/gwcs/ifu-regions.png b/docs/gwcs/ifu-regions.png index a778ebfb78ae2114d501775360d81a03380fcbad..d5d22bf8121e5cf51ec2b9b1a0a1d5d45f164b34 100644 GIT binary patch literal 18619 zcmeIac{G*%+cth}a}o)ehl)&vqL679Wk}{B%21SfCc`%DbmPvH6jCzJLS>dQnIa@Z zW-=2pYny)OrThDRzR&u->s{}=-hZF9?pAy6_P(yqb$-s_IF9rD+>bTX6pv7{P$CF& zL|I8e3qgpe5QNx>f($;{I>kK;e@VJtz3Hm$aNpJaj`Ka_#vNBjTL)KLtGiqe?m4?y zIoOK|i3^=S!)58}>gaMwSlI60Ul4L|wh-nwn)HK<9CB1La6u57JLn%wrd);{dVpF!O;)gT8eFAHl~a7ej3i` z4K?OTKk3vPNbWJrN$Y=*+dpKOJJ2nV%U2&<#P*4g14}DNL>h^lASY^$tE!gk%DOyr zBN8_y<hAme0oCE?1g80-?;`R41(;C<}JWqT${A;+%)dHFwf`2RV9 z_V*2h%|IZkGtcOQj;7{`Mkm{L3_i|0RMWyDBantusCV*`<7rwdN$cJ`BbE!+&li}H z2*w9Lzb8FCrPv=&Ye^y>o}HN)!R@2OseSWm&x6*R?B6cPU$j`WP~C5qv*`+(KTi;i zbG+#wBx7(`?N-#+gw>RL(^hNi?f2F!N}us&FXSwT?olaQ)DuK;8&TvYu>yC)n?A}*4wROJf~uJ&n0nW5vJ#P%+3>B2Ak=k1loRGRruWGIeR2l zA$i2_>J=xMoRQRa(WjEIGOs23zuyMaKln-V$fd#j1}i~OH`-!jP@4X1+m@5G$mW@| zTOE`PQn9;H?jfRnw+A(JlHRwDti22yKjwVWIV41sgDNTW)o(vVHKin_ch6@{MZ7jk z%_W$wXr_H+mi?l2EnJ&hG~$ENhzxV-{KeJMI&#JJo5)L zC1dS4wn9x2ytG!ixWpJM;afari2dQulS~N7tEYplaucU)K3}|Ov9o;GfbRLYCKn_s z&Ir}A?EbsB0KaQ;g>@SwTuZc6c=aErxl4GNXexqvuCVM>=l92tB`9=m5TXD0cCIYG zl*~@8FMcd!y1&u7HFDan9l?ikF`0H(;`UV-X!43=>cmgeCQ7wnMt#s+IQrNWK{zF@ z)_Ss6bVSsie>%#>x%CMB>{GiW&$#g6*Jss~AFJ{)(ToQ8QIK)9bGHyVXK`EY|E9a= z?_5Uzd>q3@T8m7?o{b@$PXF=9O^C4&8_&h$Xl}3cxYJa6=zIY7c8D?7ZR5Cm{dRUJY`>TxHOl5Jv0Y^r_ zqgJC`5IO&v+_wE!z%!-hPiDmyi8QeMhZnba6q}@%#+Rim#G5B+E3r}^0IA5BIGH^Zmv&cXBG2q-S1!> zD&|G74M(Zop0?7uG^U7yZy;>M{utz!g}qXG#itF*2`+d?_W20EE`4Z$wzyWRIYTX; zhO)sy0$)MLA!YbZWk7I;mP6(Wd&;9#4$hjVN2#zJhjjIuogOW#hRQe6=-O(C4Cj;Z zk&qA*39N?1HOh5vyY^pUeeVV~NY-c}&wJK{DYwnVfUUx2r_vf% zkJKWGF^}Gz44@$$e`#CTt@~T_7CacyLsO*V`ewRyfc`~rqQkr=cs7?xWQZw9{4u|3 zbE^|_e+7ykxX%eD(=T!rZt-3H_i=&3!5cx(=O)%^5fa8)#O7k2^yTKt?SC68Vv3sC z7Dwbv4+|k4ldzUDd$GV!rF?|CNy@+0orDl+q>o{g){=u}oX7bL-t%*xiq@5^4;7458yhT>D3dguD$fts%Gl{ln77s^j8-C=~d=P}k9L<&#+AVjb=ipnK96|4`Qbrg(;GJ2``^ z)pmvO-Z2#X70=DDW5lCP|6YbzG8oo|q0rTDA(@El;unrNL_X0}FwU?tSr_?uw3wf_%}{8pPpOV zzmp-}#fl);b<^yX$hQ~-|(lp1UAkYZSXNB~V#h4t(7Zg%d zdT3C)K@yEH3a5Lqx#c)-<7Rpj>tE|+eg*TJ^AY4Z#9Vi-PP_ZU`Fl7rJnZz*n`#oa zaJ#z&899Z?jqq5hAM;d2@}3iu2AE<^EBA^XXNQrDcQ5ycKgq0+V1kF013ONx2Sh4A;Vx-F9wiDRdBcVuD$rt;J(0pRni7m8(G* z&|b3g|5&imACF0_p`}uC2?^2t*#POgGWdcb(^cgQ5;=O?r0jzFTN>uV@bL8@t~uyXY`l*a7Q4d#x_ z3zV&B-k?IjRj_&&Ha_VT@H1`Rv7cefI(MA~4ca$cOcA=9CGly&jwN1t{Ay5U6 zO4u93%2qhO20V3?kA#?8dF)-v`u^VD2{1F=1J7L_u8h=BDhKJPUJ5d$NL8zMQ@Vu^ z&s>RDjLz}Al6=x^0ZX08Tp3bMdmug#k5NKhPj%K_e+nA|8GwRaMWB1g4oAiXC7vs5 z-c;u_b7-TFPIat~^Sc75} zDjw6qa;z_qOn4woY~XXx#Q0-{b>VBs3^}}=O!aq?lSJrQAXX`3StGOfiYkdb(Slv& zEU&^qI=-tisPr^am#5f*iw4ro`;*cS3h(L`>u;Tswl2NY@N2k-?+giXMBSBcUFR#c z9)pUTTS;?ShZ>wPln`DMZ`0dVJ3DGCWQmY%uwdJOzPhH7W)M7`h?>YEFL}g1YMNqS z>%Xt4iTJXY2i5CNKs7}0*h39GBxFC${66$-kRX`*#Y^vHFvJHQ<{YWD9R2`oY*vo5 zRj)yS6cN=aO9;$SHVkRnYpK}xS>wneu8ANNp)3J-I$B!ERA4mm zerJqZxNz2_>h^qZe(&1sHy&m8L8l z-jdpOD5~7@`*pY>cGU53-JQI$DHizF%qKc^9X@)k^RZpx)xU3i0jouJb#-woXXoV1 zulu;Uxy|NZxNsq>xVX5tw{GmMwY7C;kmO(_&-JzSe7~Wk6c^P!k6ESN@~Lxza;!)M zXKBEgNcC2|@LEB_uIlE9U$wEv80nDvh)?-s^exvBpUrz~(?W)YN(&1MvrpKi9+Hc82fG9}AUD9P94wy&n1U)vF7( z-xCt52L}h=WNBxpM9$66cXxJfS4}INOzP?BS=;0kVhIyqIntKWgrQQMEaqq?nRuA| z_^$=hUziebtSu%F2k>0y-MXEc)K@4E`hikV6H{bKc|uLms-g@kcw2XQ_gIf8v!*a`0V! z#UkTXs3!Z{ymISDNcnott@Qw5@5_-B65)BJKPY|1Sw}klIz%UCKPZ8^FN>^qsZjaM zN##yu-q)$C?Q$kDMh{{a%jbpa$DPjJF4X`ZJJ%k8oVWb`p8ZGpnFwZ*x;u-d<+~dLc5FObZ$u5=bf%kDII5qa?fi>#Vd~0pJg@(l2m=E{ z`9kr4>wsMe`?^T@_zYn_zjwXY#ILIk{AFfud#SzV%JA$u~)_NXFUPz#7+NMB&KP1(ZrKJTwSwdq_P4lLo+$1Tii7SF4 zkZ3xTIZ1qP%KiYJhXcKwq&L`HuMpJ}s>V;fOmMWl{%JHSVL4P{#yDPC64=dDU}F=TjT0^^UF zNtxz&eI_ju{q^7%pB5zi2tcK+k>2$F_|aG8(+34?jTAnU*t=Eh;lzjV>7WqcWaCr* z@bAVCrLUmIVd7<4N}g0WsY0FgR)*LU@1=KSEt;%Is*SbIZKQ)!yL9 z#@u#6GjXe%+*!l&qenox2j)KVH;JA%X>4ZTjeHo&VkV0r*U%c%jjBtTh> zFpE=gwCBIRXbV+N_5|>opi-x-nazBF3*HD|s3iusOWEGO8BjRSHJetj3ity@rqr>) z#j3cIkMG?pY1F*in1GVPFjIt(C~9y}v|-iw%yC33KqZhyzH`Y9 z8zlRooOU=2`UzJ`<2rkS#zI&Z-`* zd_@=50AR9?ue>?NMFGxt#bf8@5td~m3!b(2IMgWLYxT%Ppc5xmDsV@2rC>r+bZP$EsCjxHZmPukqzIOAP?QtWaDtFG-kWJpHa2TbYAXE?dpJQ%n(>4$O}wJU&mPFQ2asln2TPjo0vnN=3(?y~}GqKGRz^E@DljK_GmtO!g0+ZI9>o2Ts0|?!9G5z`6 zA_}@V0I-_rcn@&#N1==wMe&+`-$jQZ0iybjxz6%Fe~}CZ8ATNv!~+Fb5v3<$vz-S7 zBZ9yrzefM6Q@JLOE|8y6(7?bJN49ble3Iiz-CXy%OYqi|0UT1aE$$6*O6URu;tjDc z`6*6R_iHfZ7w@M6hXfg54T*5$&A8vd7S&!Tybh&BCT#(fKFAd<1ja*R@Vn?bymzF*OA2U!W5K~Bhp}!{|sz@3Q!RnLepXjRC4&8^< z-;@{OGCRJzB+WB22oM;lA%{GO{6e=7bEumdEb9rH1wxbck`ijbvuuHqKc7UmTci8 zKkkKN%#}V@tUkm-!b7Skm#m{6H`=!2+hM1hFx?IhTDXZ<&M?>I9=?p`=UZtvYRgOo z`iB}w&pNY!e8R-brGJ+vYq3PiP932ngHIwnI=c^DcSkuE4JfTa3o;j2HZ4(E=Ufn) zYX5v%?2&cF&!Zk5?QO6r_L_93Zl2QljnOT&v5QGI?y2dH<(UI)_Qb*{N8asHe!JR?*q)} zl&To2U%YI~0*pYx%|MqH72MzuiFnk1sx@de9D8X11#>D^}t8v zv7Hp`+87XTv0ia{#!AkGm8KSvTN_r)#?xov|Z z9MU&Y8YAubKHhKd_gZh*Il~H%cY#M((<38~eR+A|`mJKy*>(5A;$rLJ3eW5}Z*<(; zii9fHwAdvaxds&LUoHe$+X8F-zVDQ()A?tEBwF`&x82$#r!zA%m7d7$m0q;#PhIk! zmSPdJ)F6n6k9Zf@SMNR;a_coREU|z6`SWKn+=i{2yL$$WsKcv*>+GuvcX21)HAC^72dUha<&odd`&P<+#oFurE(e5Lq!qvB-*6*ipFMjwxWhy$lx>0*f&>k95Jc7lze7utus5cP* zQ2H7W*eI3RwQuUZB~|NZ(N&{hS?I&h^Qh68cgsSKpVh+Qa0IhP>Ub0C?^DrHSr!^k z7nt`b0-g&@8C$M#);hkpQx|B}nW|hV>ki=EYI|cLGL=B^Qr2>DamlX}6Bo~@)-wUc zKRVjjM4kJXwVmA!&MC*QmO4>UQI)cI?+N;=&ncTGBc(D8$%C9P9#SHyBad@wlkBhX zbjfe8Ty9`x5xpOp>dt`}z-6KY_jiteWoKtcU4n&$g$Srqt9ag)(9b578vY&*>wE3C%$W^ zc4rjjBDp2QQv~x$uZ(Oph>P9%ND{^>uGVYh{u(-Mc_BjON}WDGCRNO3=1uv=2h=`q1P%IdhlxM z%c~gKR{g3K2B4N!;IpvyZ$YwaCs6WSUtd34xAW6N?%T(J!xvnpRKYFET&CwX1{_M9 zo=1>x?2Kn+=M0!Z1z=-<@Z{XzYFr0D+sQO>XHx_&QVF*rq;RCCr(Xl=>34c+%t$Iv z!f5(h0;so8sH`+;3=1JVtwt z2-@pJka)Nag#@t905;H453F~LSAy|vQvV5+D0*ndNW;x)XkQel>AwHILCNI~rDkWG zZ2C;S!tL16!6t<2rsJL)@mu?)47I0+NXK6@V%9*Ji(a^N01df=*&o|XV!5DL-&=V0 zX!(jh;txz}*y-b)g)Iqj95MDH0N9VvL)ctK>EkK-&I9s9iqO;hCt*wL<_dqO$U##9 ziO7JJ*5Df8DsHYQ+SeFVI*oPTBlh%1KVN^v z&rwTl3Tp8vU%c;{Yb^JsFfm?1q{c$dXIB**OnZQ7I^6;BfHs>+SS3G}<_!M}J^h6YygkVA)?mtdwn%!SkO< zCQA|7u>=yt1Wd0vEfKGGm;@^HO?s()s;C||v}!lFmFiKGFzr`hLM|x==xTn%Nh3{w zNLJKV?|swZJk%g1OoXlCVxm-7EvuUpU{cSuPI#enHFE&oZ_Hpc;xQndSKdyN2_986QEVlMchF@7(JbuY+(YxR^mQ12`k1@xyA25*r=bk z!eJa+QM;yO4(T?hgrRl?_C+KV?>gB)?3ycGU*udv=8vH$Ef%-YAvC$5pw|UJFUbgQ z)n;TO(O5ZO!<%jAvxueBRDj7 zpwSA3K4xzp^SIu&9UBPVf`9n9o~OuK{`N)fQC~S0H-B%gM!~URKKl@FhL(s zqP6N~nE;1xEi9plA8h!pSSoAGPYG=kGy!+6+S;w9(^)y#8st3O>`!7im_5MbodpHV zgRek?fD0@~!BtPQ3>y~xNl|AY9&`rCKW98$jK8Bu8C+^bWm-wd9D{m_XB~gAWrJL` zCAa`RxBrRJxa7a7!&Oky4UQvU6L76-e!bcVr9cPi9q;QBdF}LZXpI}7?McFy*~fxq z7C;M{h@fP>KSTd4E*>SV2TIJnv@eHviWk70W?)yb#(Za@s z_^+mGeBF4ya0mfM3#=Y(V0CytE>Zp?Sg3(78?Ei_7uS6T zN*sFQBwch24YL6@8u_eut8n}8`cey4t=xegENV8kdcykrdL8GUMn=4sb$+{v=VX-E z&v%V$9r83*-PyYRMK&?Aznj(5tK(HqU$AIntG|0L*SOMfbI3hmv2xS+tZ{|JfZ~aq z&dCvI-m)$HqNXM5Y#`?s_+)VfI-Zzr({UI#0dWO zWf8Vo^l@P|fOT_vr&(E98J;xaeD*+X@0$6VQUuDqawjPIVxBAJ-QC@3G@>Z9cXhQK zZwOP|jlCXyMpIW;mtfYFsVU1Th>$i;p5fRVE14Cck^Y5874@?Q?5^{jImux6{q2d}b3O!D=sO7Sj$FNZ)v(O@9szgJVff9$ zKuHd0?~z>{9f|tJo>$MFJv&?X=H|OAfSX^6S!wk=p^I<|KQ&G=@zR!$o9?{~QPYh< zo@H4OsxM7G*Y@(sd-F#15jl;T-(Kf+;ci`hqqLVVS#48)u77*iXq8xQl za1??kKBGn2{3*S288at#4@4gE;oIKX;lg$svRp`wJEVqKrKcdDDIaGIAaXto%~w{) z9+B=Fd~+ncEC}-8C>2J$w6q0M&gBMqCzJ;xGu0)<1IG9>s3_YqXzs`nViu_kMUMya zoB7jM5y|ZpkZ3wU0>TekaEoL0&2L0X?LCE2D@0Pbb1eJkS5*A*2hh{xbL~8IRv56C z0g~bSM+~yxzXk;dp#X`TBJ)$8R$03}q#d*})okzBj~o)P0#OaB9Q18H5{?Lm#dyYN zRA6exD9EV3-`GCQSD60|tr=vrR7`I<e+iJ7ab1vPCDCaZcuR| zNdI+RgX0`}`8_n7XvXycSkkAb^`<|G9i2&m9NKg^{Z6p#d9xI#IB1@n2)OB{kfCo2 z`4^!)UVGGZTiB|@?UXNcwh=CbA`qEpS)55#%7U-s5tsl$c8|eG!9o3thOCR%XOKH*+eGinm~=OPFK9iTtgL%2+@$Oj4NvcOah zYHMtb#8`yt-@Wt?tHCWICRF9FKE5kt{xAic3aj-#RVmO#VKj4V8k0D(u|Jfh65u%| zlz0@LgK$=FOldHfh8{+`n%-}{h29NxQv3GdJ2TYS36vmGaY0)x}m?Lv=5zjLO?P;s-dQv<|{b{m=ZxS=*R@2^)YXhHOxB_8z_j7 z=mzVL5JyO=NoVO;0BC4B>3<^gwy`fwlXBn-MRYob>-uMR-Y74dS5Pvm(LLc&``E;N z3~aRvzR+ZK^>ujMB3e&t(LE`w&1d1+D+EtX97WB)Fr*FBL?D=Rp<@>KKpD-{i7He( zB%%0cy)_@A^Ir(jP1F8F9Jxt|f8`O1l>Z3E&c|wx>KJ%g&2Y-Dy?e96hTx4z9xOeqA0y(y8=Q?P80Req3oz~q0B3YQaGRw}R*lA~}L=|Bvhl3JfCVC!&m-yOKpmO@(1Z}Ny0^DSY(4?53U5Qr zBP%}ht^g_FvM4*Jcu&eRN}Y=l4H~_zh*Q%vtPtv4s3W6ulN2weUOy6>q45Kbg{^^6 z$eL246FiV7ksYu~B=jep&7>7MkZ?#Y+(WxRgBXnVDqyt{1r%i1$Y;*nb!P!)i$Q~9 zVIFsyf3OoJ=Uj&=$kqnb69{jQIaD5G0r=pbN!A0#`DeQjr{Ir3&=cX`D2`hE1p0nd z12PcFQ{SPNrVsp|G)pltdm=tu?QiH5CT9`gXX&|1nPDg2kz%N89-}>Mb=Rd7W&iFeOI2%=JP&NM#n4w zHst8%_xNlMW#E=7^+Onii=CdYyp+TR-+#RdgJ_7xFAw9cJJG@>!}IN%!?=8qi@Lvm z&!q9&sfTL{rTHbF1*PL>4O2HZHr5)$*`)}Txa~B$^|7+iviNI zn*1C!+io{pVE|BG|6lVG`4ua{hK7cnK?Z;<1q1~zfIj+@jTUK&fL^B75-#E*C9%6Q z+kF7Z<@p3R7DsZvcMmCUYvrFih7N6;PD+xi19m&>PijJAU|`8iP~lQwYy5>9wC3f zymxvDF#YZ~x!q^nvmZuw^KSQc50<%ffBTlwS70$uF1K}=@HR<9sU`aCx5*fjJh&a) zc{cL8&{r6ANXSjWa5et*Aq?%lBD)|SH?YZHU}R*pne9w7EO(vNq!GQ}%CtKrUcKzX zf|tIS>69N?(J#2d^yJP#&I8z#bDvIpjJV7nNNqv3vF)<#QFP$%Pt;Ppn33HxApXTU zeFlq94NY;{{~ZkhK!l2CXzrk|=uwCbl(WM@6ZoP(hSb3?S%;y;7?p_7rqMw`oQbJy z7K##E1{MeG!Jv_P8wJJJ7#O7rI>W{m!-`IYbmW(q#YF+?ZDQm$>XSe)h-;OivN{Nx$0C5wL2G&Lt(_ANVx7Jxwgs!5XCT5 z|0>&vvzBXu;B?JpsO1$xBt`vZ0*2+wou*f9`cKkmWt2gR<)F7dItJHO;#ktl*W8*xrdQa z7=t+2_qCQG_b=~cFn|!D*raXz7DAaZ;2HR5baduF@bG`UBzZXA^gO2D_#pyNg$s#u zd>Z+v1++N)zt)@RC>gFwYw@V&-KYsA-k%{aNB55!R{=@_pJfAp=_Z|2|AfW~(;sGm01nQ3LvNCn z3Zq?Ro{_8uZ5V(Kux0;&PLW2)%XaE`l){X@h|QI<{qy=i3}YT)mYOUyOh@_~CZF-D zD#}UStakYb845K1t3*e*#HG^Dj{e@m3c(#F;*yE;lAq)Q&ac`2w~PJPp*50E@jeXM zzGa~2As9dpm^&Ma&%M^&Q0#}EHbA5U>}aqL76xB;Tp0PDGg&Q_`6wtfoby)dhw587 zv)Z80&p&Id-j9yos_ijO$YIyd-rt@lyB@OhZky3&Ed!^QwfJ$CWjDXTwtY6n^I67B zL5AAbzk^kjJEMDi%6*1da{D)mhwkkD3h1+#8T@wI($*);>+Ye-wH_g#rLhs4TdTeU z-^k2Yy1o*+x*z9A@)nL#fe4`qs{$pY5A>}_;s2jXeXQO+m;4W zQ(Lv%aypU?9p)b4^~RXl5ch=Wy#m$;gdKP8?#-p<=ftnvb0)=Eba?PTr7~uS67p}^PJ;$(Ph>Vd%f>&g};(%X50K; z<*57a8oM>FY#vDi9b&EL)fcb3ePlih4eA5&kECI+BjQ!eVsGZyo!yDz^0n!PFroLQ zmZpOdDW8+RVs_a_Zi!##74kFSPq?_QzoMb);Ipk6w!1>wzq=}T(^ynQu%xPczP;ql z??+RwFI~+z!W!*f`}SA({=)in{_y5s@#T}wH&~1^7>5U~th#G*O|})$KhPDh@Su{% zc>a7WbmP^r?hN69T!MD7b-!ZCeB=I*Jx;HBVaQh_L~aE)MTo*B5&>=uOJPQ=TMzC#u^F&T(Zu|GLIsPng4foH+qW)E@9k?{6-z!GE_b=ad(GQur-gj=63cNTY3;@*OmEu#wl5E8BZB@e)THWl z)^(R=|5D0te=Tt$d4G5Pq3o_qqnxY>U4oxML%S2Pj-f$nlG*hlivjozVPZ7;G*3UZ z_4r5J-cIv#&FLJeuAQ4H>2h90aTV>M1``vA*jEOih1YAoj1;R>~p)t_)cT} z^xR-ps7tk>brJj@wj)2a(heEL+cBM1K$Wg z^~D{&Hv5SxJPKsYNl8hhE5*>TRZ1u|weLciP02k6dEeR?(B7cauq zyR!k(mA6ZO^{_SW%C(A}9~XVregfgc#vf{6Peovs@4uCv|Kwy8i2IHuP%uX*8YGvo z#tigjAtO*-56&MRlmt>iUHx$%E+i7JL2A3tuM3?O&qt%GDyx| zUEjXJ_Tg|JxcQSx&BJ#s8b92fn^9eN*gB`;<}P^W2lFoT(r(-$@#EILQ29Pdq2`+< zUESk8HJGLzr*n_()5>3m?uD9{yeirkZcc9HVC3cJQN4Y-uCb9D_q_F|9HVli&0Upy zWBXs;sm#1S+psnkdTjRxliIzJh5n-Jr>=!|%ys82DnfTY$FhC!m5;N(EaHwY zjki(}J(2F5pKoA-KF7_vz$4nq%8yY80Xcf@lB$hO4h&pmeEzHg=LF_a8T=tJ z`FoEuWcJOGJeS5pMd4I+654rj{d)Ca-lWde-Q5Og8H=>X+s`d67u**I;W+Qi#=-#F zT8WB|&Mq$2L&x)vJw8)G_f&ncVpZ+6*Id@D{#jc~%Z~9Ua`Ag!C*sHyoyWt(KRdA* zIn^`FwlmCGVYVp(*;fCzG2x9iLin}QErCxd?hyX(4|n($hx-fbIFf>>>mafnD&IifuB&o@)cNr%L zfBHrw`H?Fl&T}djrMRo18?h@ASaQN*wjZ1|0mAP2-6mRFIrPV8)&(X_0-%#OF z5fU8S3J>#Kw$&!T@;-Mgqy;9k(BEGie9dn6UH~m&wrs5HuLkR7|d0Pz!aGX=kF%P)|l#@duFP4_GN2iAp}l_ugGm)58QqI68oRyD4}b!Z~vS{v4JTtIC}#Fae4C`%L{d@SJBjja`;Fz zg?UI1&lgH8f1Qulpu&yQ@LAUBpRht^Ym^7eAhQ+qA z(1#kanrM1D+uqyTD|kF4D>pZ{cZ^2vY`Cjod3%ZMFk!R$P4X!o`c}G^-#H@kgmxLB=u|88m^! z1gBSMiSAzK!oq~yaZ*C?*vVwjbzmy_3 zF{oou;wb0DUi`27g#pfnT;zSeT|8d6(TC)!Vk{R>iLej)w6QS9mjxo)`rp%BsGAE{ zZ6$jy*E5E3yUgd7yoA#~KdYt9TpRC0D*( zcXZxus_>hdC{#7kcG>MWu_AZ;f45r5n$7dAw}47y4Yaq+&=6?4jGi)MhJ!|r z6;4jU5U3b5tBYis-K)2UmO@i$yl*=<^EAA0k2my$fyP+S6Y0XPeQAvq{Q`!^?XttH zqG$pDM{2AF;GQ@nJ9I~H2uygo1FgQ#PLeV0S-L+(f~EbQ7D z8rgl_SBZ1auby5g8M(-K+wmbkKmR%K<8%9aOZ)aemOY}M+}QUSJ8U9i))0E`snRDZ z_Dfx@agw6!ha2c2Wr_un%b$Q}Xo3GDj8usoaCq-pv;R)z|6K_G8^QmdPyb7g``>_v f|5uw4_AzfFBtD8Qx;y}+f+$~AQ^>nw>i_=%69WQ$ literal 14063 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 XmQh*g@_@7GDER%x-=uwg>bw5}&=H93 diff --git a/docs/gwcs/ifu.rst b/docs/gwcs/ifu.rst index caf2bd06..3b1480c1 100644 --- a/docs/gwcs/ifu.rst +++ b/docs/gwcs/ifu.rst @@ -36,6 +36,16 @@ First, import the usual packages. >>> from gwcs import wcs, selector >>> from gwcs import coordinate_frames as cf +Next, create the appropriate mapper object corresponding to the figure above: + + >>> y, x = np.mgrid[:1000, :500] + >>> fmask = (((-x + 0.01 * y + 0.00002 * y**2)/ 500) * 13 - 0.5) + 14 + >>> mask = fmask.astype(np.int8) + >>> mask[(mask % 2) == 1] = 0 + >>> mask[mask > 13] = 0 + >>> mask = mask // 2 + >>> labelmapper = selector.LabelMapperArray(mask) + The output frame is common for all slits and is a composite frame with two subframes, `~gwcs.coordinate_frames.CelestialFrame` and `~gwcs.coordinate_frames.SpectralFrame`. @@ -59,28 +69,18 @@ In this example the mask is an array with the size of the detector where each it corresponds to a pixel on the detector and its value is the slice number (label) this pixel belongs to. -Assuming the array is stored in -`ASDF `__ format, create the mask: - -.. doctest-skip-all - - >>> import asdf - >>> f = asdf.open('mask.asdf') - >>> data = f.tree['mask'] - >>> mask = selector.LabelMapperArray(data) - Create the pixel to world transform for the entire IFU: >>> regions_transform = selector.RegionsSelector(inputs=['x','y'], ... outputs=['ra', 'dec', 'lam'], ... selector=transforms, - ... label_mapper=mask, + ... label_mapper=labelmapper, ... undefined_transform_value=np.nan) The WCS object now can evaluate simultaneously the transforms of all slices. >>> wifu = wcs.WCS(forward_transform=regions_transform, output_frame=cframe, input_frame=det) - >>> y, x = mask.mapper.shape + >>> y, x = labelmapper.mapper.shape >>> y, x = np.mgrid[:y, :x] >>> r, d, l = wifu(x, y) From 9f8c21660755802579d0931150951a2593be7927 Mon Sep 17 00:00:00 2001 From: perrygreenfield Date: Thu, 9 Nov 2023 11:07:46 -0500 Subject: [PATCH 2/8] remove asdf in fits examples --- docs/index.rst | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index b2b8cf58..0fedbe4e 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -240,31 +240,6 @@ Save a WCS object as a pure ASDF file :ref:`pure_asdf` -Save a WCS object as an ASDF extension in a FITS file -+++++++++++++++++++++++++++++++++++++++++++++++++++++ - - -.. doctest-skip:: - - >>> from astropy.io import fits - >>> from asdf import fits_embed - >>> hdul = fits.open("example_imaging.fits") - >>> hdul.info() - Filename: example_imaging.fits - No. Name Ver Type Cards Dimensions Format - 0 PRIMARY 1 PrimaryHDU 775 () - 1 SCI 1 ImageHDU 71 (600, 550) float32 - >>> tree = {"sci": hdul[1].data, - ... "wcs": wcsobj} - >>> fa = fits_embed.AsdfInFits(hdul, tree) - >>> fa.write_to("imaging_with_wcs_in_asdf.fits") - >>> fits.info("imaging_with_wcs_in_asdf.fits") - Filename: example_with_wcs.asdf - No. Name Ver Type Cards Dimensions Format - 0 PRIMARY 1 PrimaryHDU 775 () - 1 SCI 1 ImageHDU 71 (600, 550) float32 - 2 ASDF 1 BinTableHDU 11 1R x 1C [5086B] - Reading a WCS object from a file ++++++++++++++++++++++++++++++++ @@ -280,12 +255,6 @@ from a pure ASDF file or from an ASDF extension in a FITS file. >>> wcsobj = asdf_file.tree['wcs'] -.. doctest-skip:: - - >>> import asdf - >>> fa = asdf.open("imaging_with_wcs_in_asdf.fits") - >>> wcsobj = fa.tree["wcs"] - Other Examples -------------- From 5ee8d2180d41b0f1c88645035efadfea38e555d8 Mon Sep 17 00:00:00 2001 From: perrygreenfield Date: Thu, 9 Nov 2023 11:29:09 -0500 Subject: [PATCH 3/8] remove asdf in fits examples --- docs/gwcs/using_wcs.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/gwcs/using_wcs.rst b/docs/gwcs/using_wcs.rst index 7ccfc58d..a8430c58 100644 --- a/docs/gwcs/using_wcs.rst +++ b/docs/gwcs/using_wcs.rst @@ -109,6 +109,9 @@ Inverse Transformations Often, it is useful to be able to compute inverse transformation that converts coordinates from the output frame back to the coordinates in the input frame. +Note. the ``backward_transform`` attribute is equivalent to +``forward_transform.inverse``. + In this section, for illustration purpose, we will be using the same 2D imaging WCS from ``imaging_wcs_wdist.asdf`` created in :ref:`imaging_example` whose forward transformation converts image coordinates to world coordinates and @@ -175,3 +178,4 @@ point far away from the image for which numerical inverse fails. [5.31656943e-06 2.72052603e-10] [6.81557583e-06 1.06560533e-06] [3.96365344e-04 6.41822468e-05]] + From ad5f65816134248aa10c6bb660f13842ca0b393b Mon Sep 17 00:00:00 2001 From: perrygreenfield Date: Tue, 14 Nov 2023 13:06:18 -0500 Subject: [PATCH 4/8] final changes --- docs/gwcs/fits_analog.rst | 101 ++++++++++++++++++++++++++++++++++ docs/index.rst | 111 +++++++++++++++++++------------------- 2 files changed, 157 insertions(+), 55 deletions(-) create mode 100644 docs/gwcs/fits_analog.rst diff --git a/docs/gwcs/fits_analog.rst b/docs/gwcs/fits_analog.rst new file mode 100644 index 00000000..43632d02 --- /dev/null +++ b/docs/gwcs/fits_analog.rst @@ -0,0 +1,101 @@ +.. _fits_equivalent_example + +FITS Equivalent WCS Example +=========================== + +The following example shows how to construct a GWCS object equivalent to +a FITS imaging WCS without distortion, defined in this FITS imaging header:: + + WCSAXES = 2 / Number of coordinate axes + WCSNAME = '47 Tuc ' / Coordinate system title + CRPIX1 = 2048.0 / Pixel coordinate of reference point + CRPIX2 = 1024.0 / Pixel coordinate of reference point + PC1_1 = 1.290551569736E-05 / Coordinate transformation matrix element + PC1_2 = 5.9525007864732E-06 / Coordinate transformation matrix element + PC2_1 = 5.0226382102765E-06 / Coordinate transformation matrix element + PC2_2 = -1.2644844123757E-05 / Coordinate transformation matrix element + CDELT1 = 1.0 / [deg] Coordinate increment at reference point + CDELT2 = 1.0 / [deg] Coordinate increment at reference point + CUNIT1 = 'deg' / Units of coordinate increment and value + CUNIT2 = 'deg' / Units of coordinate increment and value + CTYPE1 = 'RA---TAN' / TAN (gnomonic) projection + SIP distortions + CTYPE2 = 'DEC--TAN' / TAN (gnomonic) projection + SIP distortions + CRVAL1 = 5.63056810618 / [deg] Coordinate value at reference point + CRVAL2 = -72.05457184279 / [deg] Coordinate value at reference point + LONPOLE = 180.0 / [deg] Native longitude of celestial pole + LATPOLE = -72.05457184279 / [deg] Native latitude of celestial pole + RADESYS = 'ICRS' / Equatorial coordinate system + + +The following imports are generally useful: + + >>> import numpy as np + >>> from astropy.modeling import models + >>> from astropy import coordinates as coord + >>> from astropy import units as u + >>> from gwcs import wcs + >>> from gwcs import coordinate_frames as cf + +The ``forward_transform`` is constructed as a combined model using `astropy.modeling`. +The ``frames`` are subclasses of `~gwcs.coordinate_frames.CoordinateFrame`. Although strings are +acceptable as ``coordinate_frames`` it is recommended this is used only in testing/debugging. + +Using the `~astropy.modeling` package create a combined model to transform +detector coordinates to ICRS following the FITS WCS standard convention. + +First, create a transform which shifts the input ``x`` and ``y`` coordinates by ``CRPIX``. We subtract 1 from the CRPIX values because the first pixel is considered pixel ``1`` in FITS WCS: + + >>> shift_by_crpix = models.Shift(-(2048 - 1)*u.pix) & models.Shift(-(1024 - 1)*u.pix) + +Create a transform which rotates the inputs using the ``PC matrix``. + + >>> matrix = np.array([[1.290551569736E-05, 5.9525007864732E-06], + ... [5.0226382102765E-06 , -1.2644844123757E-05]]) + >>> rotation = models.AffineTransformation2D(matrix * u.deg, + ... translation=[0, 0] * u.deg) + >>> rotation.input_units_equivalencies = {"x": u.pixel_scale(1*u.deg/u.pix), + ... "y": u.pixel_scale(1*u.deg/u.pix)} + >>> rotation.inverse = models.AffineTransformation2D(np.linalg.inv(matrix) * u.pix, + ... translation=[0, 0] * u.pix) + >>> rotation.inverse.input_units_equivalencies = {"x": u.pixel_scale(1*u.pix/u.deg), + ... "y": u.pixel_scale(1*u.pix/u.deg)} + +Create a tangent projection and a rotation on the sky using ``CRVAL``. + + >>> tan = models.Pix2Sky_TAN() + >>> celestial_rotation = models.RotateNative2Celestial(5.63056810618*u.deg, -72.05457184279*u.deg, 180*u.deg) + + >>> det2sky = shift_by_crpix | rotation | tan | celestial_rotation + >>> det2sky.name = "linear_transform" + +Create a ``detector`` coordinate frame and a ``celestial`` ICRS frame. + + >>> detector_frame = cf.Frame2D(name="detector", axes_names=("x", "y"), + ... unit=(u.pix, u.pix)) + >>> sky_frame = cf.CelestialFrame(reference_frame=coord.ICRS(), name='icrs', + ... unit=(u.deg, u.deg)) + +This WCS pipeline has only one step - from ``detector`` to ``sky``: + + >>> pipeline = [(detector_frame, det2sky), + ... (sky_frame, None) + ... ] + >>> wcsobj = wcs.WCS(pipeline) + >>> print(wcsobj) + From Transform + -------- ---------------- + detector linear_transform + icrs None + +To convert a pixel (x, y) = (1, 2) to sky coordinates, call the WCS object as a function: + + >>> sky = wcsobj(1*u.pix, 2*u.pix, with_units=True) + >>> print(sky) + + +The :meth:`~gwcs.wcs.WCS.invert` method evaluates the :meth:`~gwcs.wcs.WCS.backward_transform` +if available, otherwise applies an iterative method to calculate the reverse coordinates. + + >>> wcsobj.invert(sky) + (, ) diff --git a/docs/index.rst b/docs/index.rst index 0fedbe4e..a4ec9911 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -124,35 +124,36 @@ There are two ways to save the WCS to a file: - `Save a WCS object as an ASDF extension in a FITS file`_ -A step by step example of constructing an imaging GWCS object. +A step-by-step example of constructing an imaging GWCS object. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -The following example shows how to construct a GWCS object equivalent to -a FITS imaging WCS without distortion, defined in this FITS imaging header:: - - WCSAXES = 2 / Number of coordinate axes - WCSNAME = '47 Tuc ' / Coordinate system title - CRPIX1 = 2048.0 / Pixel coordinate of reference point - CRPIX2 = 1024.0 / Pixel coordinate of reference point - PC1_1 = 1.290551569736E-05 / Coordinate transformation matrix element - PC1_2 = 5.9525007864732E-06 / Coordinate transformation matrix element - PC2_1 = 5.0226382102765E-06 / Coordinate transformation matrix element - PC2_2 = -1.2644844123757E-05 / Coordinate transformation matrix element - CDELT1 = 1.0 / [deg] Coordinate increment at reference point - CDELT2 = 1.0 / [deg] Coordinate increment at reference point - CUNIT1 = 'deg' / Units of coordinate increment and value - CUNIT2 = 'deg' / Units of coordinate increment and value - CTYPE1 = 'RA---TAN' / TAN (gnomonic) projection + SIP distortions - CTYPE2 = 'DEC--TAN' / TAN (gnomonic) projection + SIP distortions - CRVAL1 = 5.63056810618 / [deg] Coordinate value at reference point - CRVAL2 = -72.05457184279 / [deg] Coordinate value at reference point - LONPOLE = 180.0 / [deg] Native longitude of celestial pole - LATPOLE = -72.05457184279 / [deg] Native latitude of celestial pole - RADESYS = 'ICRS' / Equatorial coordinate system +The following example shows how to construct a GWCS object that maps +input pixel coordinates to sky coordinates. This example +involves 4 sequential transformations: +- Adjusting pixel coordinates such that the center of the array has + (0, 0) value (typical of most WCS definitions, but any pixel may + be the reference that is tied to the sky reference, even the (0, 0) + pixel, or even pixels outside of the detector). +- Scaling pixels such that the center pixel of the array has the expected + angular scale. (I.e., applying the plate scale) +- Projecting the resultant coordinates onto the sky using the tangent + projection. If the field of view is small, the inaccuracies resulting + leaving this out will be small; however, this is generally applied. +- Transforming the center pixel to the appropriate celestial coordinate + with the approprate orientation on the sky. For simplicity's sake, + we assume the detector array is already oriented with north up, and + that the array has the appropriate parity as the sky coordinates. + + +The detector has a 1000 pixel by 1000 pixel array. + +For simplicity, no units will be used, but instead will be implicit. The following imports are generally useful: +.. doctest-skip:: + >>> import numpy as np >>> from astropy.modeling import models >>> from astropy import coordinates as coord @@ -160,51 +161,50 @@ The following imports are generally useful: >>> from gwcs import wcs >>> from gwcs import coordinate_frames as cf -The ``forward_transform`` is constructed as a combined model using `astropy.modeling`. -The ``frames`` are subclasses of `~gwcs.coordinate_frames.CoordinateFrame`. Although strings are -acceptable as ``coordinate_frames`` it is recommended this is used only in testing/debugging. +In the following transformation definitions, angular units are in degrees by +default. -Using the `~astropy.modeling` package create a combined model to transform -detector coordinates to ICRS following the FITS WCS standard convention. +.. doctest-skip:: -First, create a transform which shifts the input ``x`` and ``y`` coordinates by ``CRPIX``. We subtract 1 from the CRPIX values because the first pixel is considered pixel ``1`` in FITS WCS: + >>> pixelshift = models.Shift(-500) & models.Shift(-500) + >>> pixelscale = models.Scale(0.1 / 3600.) & models.Scale(0.1 / 3600.) # 0.1 arcsec/pixel + >>> tangent_projection = models.Pix2Sky_TAN() + >>> celestial_rotation = models.RotateNative2Celestial(30., 45., 180.) - >>> shift_by_crpix = models.Shift(-(2048 - 1)*u.pix) & models.Shift(-(1024 - 1)*u.pix) +For the last transformation, the 3 arguments are, respectively: -Create a transform which rotates the inputs using the ``PC matrix``. +- Celestial longitude (i.e., RA) of the fiducial point (e.g., (0, 0) in the input + spherical coordinates). + In this case we put the detector center at 30 degrees (RA = 2 hours) +- Celestial latitude (i.e., Dec) of the fiducial point. Here Dec = 45 degrees. +- Longitude of celestial pole in input coordinate system. With north up, this + always corresponds to a value of 180. - >>> matrix = np.array([[1.290551569736E-05, 5.9525007864732E-06], - ... [5.0226382102765E-06 , -1.2644844123757E-05]]) - >>> rotation = models.AffineTransformation2D(matrix * u.deg, - ... translation=[0, 0] * u.deg) - >>> rotation.input_units_equivalencies = {"x": u.pixel_scale(1*u.deg/u.pix), - ... "y": u.pixel_scale(1*u.deg/u.pix)} - >>> rotation.inverse = models.AffineTransformation2D(np.linalg.inv(matrix) * u.pix, - ... translation=[0, 0] * u.pix) - >>> rotation.inverse.input_units_equivalencies = {"x": u.pixel_scale(1*u.pix/u.deg), - ... "y": u.pixel_scale(1*u.pix/u.deg)} +The more general case where the detector is not aligned with north, would have +a rotation transform after the pixelship and pixelscale transformations to +align the detector coordinates with north up. -Create a tangent projection and a rotation on the sky using ``CRVAL``. +The net transformation from pixel coordinates to celestial coordinates then +becomes: - >>> tan = models.Pix2Sky_TAN() - >>> celestial_rotation = models.RotateNative2Celestial(5.63056810618*u.deg, -72.05457184279*u.deg, 180*u.deg) +.. doctest-skip:: + + >>> det2sky = pixelshift | pixelscale | tangent_projection | celestial_rotation - >>> det2sky = shift_by_crpix | rotation | tan | celestial_rotation - >>> det2sky.name = "linear_transform" +The remaining elements to defining the WCS are he input and output +frames of reference. While the GWCS scheme allows intermediate frames +of reference, this example doesn't have any. The output frame is +expressed with no associated transform -Create a ``detector`` coordinate frame and a ``celestial`` ICRS frame. +.. doctest-skip:: >>> detector_frame = cf.Frame2D(name="detector", axes_names=("x", "y"), ... unit=(u.pix, u.pix)) >>> sky_frame = cf.CelestialFrame(reference_frame=coord.ICRS(), name='icrs', ... unit=(u.deg, u.deg)) - -This WCS pipeline has only one step - from ``detector`` to ``sky``: - - >>> pipeline = [(detector_frame, det2sky), - ... (sky_frame, None) - ... ] - >>> wcsobj = wcs.WCS(pipeline) + >>> wcsobj = wcs.WCS([(detector_frame, det2sky), + ... (sky_frame, None) + ... ] >>> print(wcsobj) From Transform -------- ---------------- @@ -213,7 +213,7 @@ This WCS pipeline has only one step - from ``detector`` to ``sky``: To convert a pixel (x, y) = (1, 2) to sky coordinates, call the WCS object as a function: - >>> sky = wcsobj(1*u.pix, 2*u.pix, with_units=True) + >>> sky = wcsobj(1, 2) >>> print(sky) @@ -278,6 +278,7 @@ Using ``gwcs`` gwcs/pure_asdf.rst gwcs/wcs_validation.rst gwcs/points_to_wcs.rst + gwcs/fits_analog.rst See also From 275707f992e12f464eeb23e34da571a34665ed2c Mon Sep 17 00:00:00 2001 From: perrygreenfield Date: Tue, 14 Nov 2023 14:18:45 -0500 Subject: [PATCH 5/8] update CHANGE.rst with PR number --- CHANGES.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 0582181c..6e966aa2 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,10 +1,11 @@ 0.20.0 (unreleased) ------------------- -other -^^^^^ +- Improve documentation (part 1) [#483] -- Replace ``pkg_resources`` with ``importlib.metadata``. [#478] +- other +^^^^^ + - Replace ``pkg_resources`` with ``importlib.metadata``. [#478] 0.19.0 (2023-09-15) ------------------- From f205bc5e4bbf20ef07d49f477c8e8588be74615e Mon Sep 17 00:00:00 2001 From: perrygreenfield Date: Thu, 16 Nov 2023 10:21:08 -0500 Subject: [PATCH 6/8] add missing doctest-skip directives --- docs/index.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/index.rst b/docs/index.rst index a4ec9911..a2bc8432 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -213,6 +213,8 @@ expressed with no associated transform To convert a pixel (x, y) = (1, 2) to sky coordinates, call the WCS object as a function: +.. doctest-skip:: + >>> sky = wcsobj(1, 2) >>> print(sky) >> wcsobj.invert(sky) (, ) From c72f87603b93505303408f48c7be27347c7c8e24 Mon Sep 17 00:00:00 2001 From: perrygreenfield Date: Wed, 22 Nov 2023 15:42:28 -0500 Subject: [PATCH 7/8] address review comments --- CHANGES.rst | 4 +--- docs/gwcs/fits_analog.rst | 11 ++++++----- docs/gwcs/ifu.rst | 2 ++ docs/index.rst | 6 ++---- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 6e966aa2..5e12b8f3 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -3,9 +3,7 @@ - Improve documentation (part 1) [#483] -- other -^^^^^ - - Replace ``pkg_resources`` with ``importlib.metadata``. [#478] +- Replace ``pkg_resources`` with ``importlib.metadata``. [#478] 0.19.0 (2023-09-15) ------------------- diff --git a/docs/gwcs/fits_analog.rst b/docs/gwcs/fits_analog.rst index 43632d02..b7952f62 100644 --- a/docs/gwcs/fits_analog.rst +++ b/docs/gwcs/fits_analog.rst @@ -1,4 +1,4 @@ -.. _fits_equivalent_example +.. _fits_equivalent_example: FITS Equivalent WCS Example =========================== @@ -27,7 +27,7 @@ a FITS imaging WCS without distortion, defined in this FITS imaging header:: RADESYS = 'ICRS' / Equatorial coordinate system -The following imports are generally useful: +For this example the following imports are needed: >>> import numpy as np >>> from astropy.modeling import models @@ -87,15 +87,16 @@ This WCS pipeline has only one step - from ``detector`` to ``sky``: detector linear_transform icrs None -To convert a pixel (x, y) = (1, 2) to sky coordinates, call the WCS object as a function: +Now we have a complete WCS object. The next example will use it to convert pixel +coordinates(1, 2) to sky coordinates: >>> sky = wcsobj(1*u.pix, 2*u.pix, with_units=True) >>> print(sky) -The :meth:`~gwcs.wcs.WCS.invert` method evaluates the :meth:`~gwcs.wcs.WCS.backward_transform` -if available, otherwise applies an iterative method to calculate the reverse coordinates. +The :meth:`~gwcs.wcs.WCS.invert` method evaluates the :meth:`~gwcs.wcs.WCS.backward_transform` to provide a mapping from sky coordinates to pixel coordinates +if available, otherwise it applies an iterative method to calculate the pixel coordinates. >>> wcsobj.invert(sky) (, ) diff --git a/docs/gwcs/ifu.rst b/docs/gwcs/ifu.rst index 3b1480c1..200731fd 100644 --- a/docs/gwcs/ifu.rst +++ b/docs/gwcs/ifu.rst @@ -38,6 +38,8 @@ First, import the usual packages. Next, create the appropriate mapper object corresponding to the figure above: + >>> # Ignore the details of how this mask is constructed; they are using + >>> # array operations to generate the mask displayed for this example. >>> y, x = np.mgrid[:1000, :500] >>> fmask = (((-x + 0.01 * y + 0.00002 * y**2)/ 500) * 13 - 0.5) + 14 >>> mask = fmask.astype(np.int8) diff --git a/docs/index.rst b/docs/index.rst index a2bc8432..69cccf48 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -121,8 +121,6 @@ There are two ways to save the WCS to a file: - `Save a WCS object as a pure ASDF file`_ -- `Save a WCS object as an ASDF extension in a FITS file`_ - A step-by-step example of constructing an imaging GWCS object. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -171,7 +169,7 @@ default. >>> tangent_projection = models.Pix2Sky_TAN() >>> celestial_rotation = models.RotateNative2Celestial(30., 45., 180.) -For the last transformation, the 3 arguments are, respectively: +For the last transformation, the three arguments are, respectively: - Celestial longitude (i.e., RA) of the fiducial point (e.g., (0, 0) in the input spherical coordinates). @@ -181,7 +179,7 @@ For the last transformation, the 3 arguments are, respectively: always corresponds to a value of 180. The more general case where the detector is not aligned with north, would have -a rotation transform after the pixelship and pixelscale transformations to +a rotation transform after the pixelshift and pixelscale transformations to align the detector coordinates with north up. The net transformation from pixel coordinates to celestial coordinates then From fb48cac646d8adc9d5c4abffa1b9998cb7b61a67 Mon Sep 17 00:00:00 2001 From: Nadia Dencheva Date: Mon, 18 Dec 2023 12:37:27 -0500 Subject: [PATCH 8/8] move change log; add text --- CHANGES.rst | 4 ++-- docs/index.rst | 62 +++++++++++++++++++++++++++++++++----------------- 2 files changed, 43 insertions(+), 23 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index dff24ac8..7f01f4d0 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,11 +1,11 @@ 0.21.0 (unreleased) ------------------- +- Improve documentation (part 1) [#483] + 0.20.0 (2023-11-29) ------------------- -- Improve documentation (part 1) [#483] - - Replace ``pkg_resources`` with ``importlib.metadata``. [#478] - Serialize and deserialize ``pixel_shape`` with asdf. [#480] diff --git a/docs/index.rst b/docs/index.rst index 69cccf48..7a6ad21f 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -102,22 +102,42 @@ To install the latest release:: The latest release of GWCS is also available as part of `astroconda `__. -.. _getting-started: - -Getting Started ---------------- -The WCS data model represents a pipeline of transformations between two -coordinate frames, the final one usually a physical coordinate system. -It is represented as a list of steps executed in order. Each step defines a -starting coordinate frame and the transform to the next frame in the pipeline. -The last step has no transform, only a frame which is the output frame of -the total transform. As a minimum a WCS object has an ``input_frame`` (defaults to "detector"), -an ``output_frame`` and the transform between them. +.. _getting-started: -The WCS is validated using the `ASDF Standard `__ -and serialized to file using the `asdf `__ package. -There are two ways to save the WCS to a file: +Basic Structure of a GWCS Object +-------------------------------- + +The key concept to be aware of is that a GWCS Object consists of a pipeline +of steps; each step contains a transform (i.e., an Astropy model) that +converts the input coordinates of the step to the output coordinates of +the step. Furthermore, each step has an optional coordinate frame associated +with the step. The coordinate frame represents the input coordinate frame, not +the output coordinates. Most typically, the first step coordinate frame is +the detector pixel coordinates (the default). Since no step has a coordinate +frame for the output coordinates, it is necessary to append a step with no +transform to the end of the pipeline to represent the output coordinate frame. +For imaging, this frame typically references one of the Astropy standard +Sky Coordinate Frames of Reference. The GWCS frames also serve to hold the +units on the axes, the names of the axes and the physical type of the axis +(e.g., wavelength). + +Since it is often useful to obtain coordinates in an intermediate frame of +reference, GWCS allows the pipeline to consist of more than one transform. +For example, for spectrographs, it is useful to have access to coordinates +in the slit plane, and in such a case, the first step would transform from +the detector to the slit plane, and the second step from the slit plane to +sky coordinates and a wavelength. Constructed this way, it is possible to +extract from the GWCS the needed transforms between identified frames of +reference. + +The GWCS object can be saved to the ASDF format using the +`asdf `__ package and validated +using `ASDF Standard `__ + +There are two ways to save the GWCS object to a files: + +- `Save a WCS object as a pure ASDF file`_ - `Save a WCS object as a pure ASDF file`_ @@ -126,10 +146,10 @@ A step-by-step example of constructing an imaging GWCS object. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ The following example shows how to construct a GWCS object that maps -input pixel coordinates to sky coordinates. This example -involves 4 sequential transformations: +input pixel coordinates to sky coordinates. This example +involves 4 sequential transformations: -- Adjusting pixel coordinates such that the center of the array has +- Adjusting pixel coordinates such that the center of the array has (0, 0) value (typical of most WCS definitions, but any pixel may be the reference that is tied to the sky reference, even the (0, 0) pixel, or even pixels outside of the detector). @@ -138,7 +158,7 @@ involves 4 sequential transformations: - Projecting the resultant coordinates onto the sky using the tangent projection. If the field of view is small, the inaccuracies resulting leaving this out will be small; however, this is generally applied. -- Transforming the center pixel to the appropriate celestial coordinate +- Transforming the center pixel to the appropriate celestial coordinate with the approprate orientation on the sky. For simplicity's sake, we assume the detector array is already oriented with north up, and that the array has the appropriate parity as the sky coordinates. @@ -159,7 +179,7 @@ The following imports are generally useful: >>> from gwcs import wcs >>> from gwcs import coordinate_frames as cf -In the following transformation definitions, angular units are in degrees by +In the following transformation definitions, angular units are in degrees by default. .. doctest-skip:: @@ -171,8 +191,8 @@ default. For the last transformation, the three arguments are, respectively: -- Celestial longitude (i.e., RA) of the fiducial point (e.g., (0, 0) in the input - spherical coordinates). +- Celestial longitude (i.e., RA) of the fiducial point (e.g., (0, 0) in the input + spherical coordinates). In this case we put the detector center at 30 degrees (RA = 2 hours) - Celestial latitude (i.e., Dec) of the fiducial point. Here Dec = 45 degrees. - Longitude of celestial pole in input coordinate system. With north up, this