Commit 55ae73d410663e52d3632f3d1c550cab84ddf5ae
1 parent
ad2b1e4a
Exists in
master
Ameliorations WCS
Showing
5 changed files
with
180 additions
and
9 deletions
Show diff stats
.gitignore
No preview for this file type
... | ... | @@ -0,0 +1 @@ |
1 | +de421.bsp | ... | ... |
src/guitastro/ephemeris.py
... | ... | @@ -1980,10 +1980,10 @@ if __name__ == "__main__": |
1980 | 1980 | |
1981 | 1981 | if example == 16: |
1982 | 1982 | """ |
1983 | - Load a matrix file generated by PyROS | |
1983 | + Load a matrix file schedule generated by PyROS | |
1984 | 1984 | """ |
1985 | 1985 | eph = Ephemeris() |
1986 | - fname = r"C:\srv\develop\pyros_soft\pyros\data\sequence\P001\20230831\scheduler_schedule.txt" | |
1986 | + fname = r"C:\srv\develop\pyros_soft\DATA\PRODUCTS\TESTS\LONGSTORE\sequences\P001\20230925\scheduler_schedule.txt" | |
1987 | 1987 | eph.skdl_plot_schedule(fname) |
1988 | 1988 | |
1989 | 1989 | ... | ... |
src/guitastro/wcs.py
... | ... | @@ -800,6 +800,134 @@ class Wcs(WcsException, GuitastroTools): |
800 | 800 | self.wcs2skyfield(naxis1, naxis2) |
801 | 801 | return self._skyfield; |
802 | 802 | |
803 | + def skyfield2fov(self, skyfield:dict) ->tuple: | |
804 | + """ Compute the image field of view profected on R.A., Dec. from a skyfield. | |
805 | + | |
806 | + Args: | |
807 | + skyfield: Input values. | |
808 | + | |
809 | + Returns: | |
810 | + Two elements defining the field of view: | |
811 | + | |
812 | + * fovra: (float) Field of view along Right Ascension (unit degrees) | |
813 | + * fovdec: (float) Field of view along Declination (unit degrees) | |
814 | + """ | |
815 | + cd11 = math.degrees(skyfield["cd11rad"]) | |
816 | + cd12 = math.degrees(skyfield["cd12rad"]) | |
817 | + cd21 = math.degrees(skyfield["cd21rad"]) | |
818 | + cd22 = math.degrees(skyfield["cd22rad"]) | |
819 | + naxis1 = skyfield["naxis1"] | |
820 | + naxis2 = skyfield["naxis2"] | |
821 | + cdelt1, cdelt2, crota2 = self.cd2cdelt(cd11, cd12, cd21, cd22) | |
822 | + crota2r = math.radians(crota2) | |
823 | + cosrota = math.cos(crota2r) | |
824 | + sinrota = math.sin(crota2r) | |
825 | + fov1 = cdelt1*naxis1 | |
826 | + fov2 = cdelt2*naxis2 | |
827 | + fovra = abs(fov1*cosrota) + abs(fov2*sinrota) | |
828 | + fovdec = abs(fov1*sinrota) + abs(fov2*cosrota) | |
829 | + return fovra, fovdec | |
830 | + | |
831 | + def is_skyfield_in_radecfov(self, ra:float, dec:float, fovra:float, fovdec:float, coscrval1:float, sincrval1: float, coscrval2:float, sincrval2: float) ->bool: | |
832 | + """Check if (ra,dec) target is perhaps inside a skyfields. | |
833 | + | |
834 | + Skyfield is defined by 12 elements. | |
835 | + Four of them are required as input of this method: coscrval1, sincrval1, coscrval2, sincrval2. | |
836 | + (ra, dec) target must be related to the same equinox than crval1, crval2 coordinates. | |
837 | + The code of this method can be adapted in programs that manage a SQL database. | |
838 | + The algorithm is rapid but not rigourous. | |
839 | + The goal is to exclude skyfields well outside the field of view. | |
840 | + Before using is_skyfield_in_radecfov() use skyfield2fov(). | |
841 | + After using is_skyfield_in_radecfov() use skyfields2indexes(). | |
842 | + | |
843 | + Args: | |
844 | + ra: Right ascension (degrees) of the target | |
845 | + dec: Declination (degrees) of the target | |
846 | + fov: Field of view (degrees) of the images stored in skyfield | |
847 | + coscrval1: cosinus of the CRVAL1 coordinate (degrees) of the skyfield | |
848 | + sincrval1: sinus of the CRVAL1 coordinate (degrees) of the skyfield | |
849 | + coscrval2: cosinus of the CRVAL2 coordinate (degrees) of the skyfield | |
850 | + sincrval2: sinus of the CRVAL2 coordinate (degrees) of the skyfield | |
851 | + | |
852 | + Returns: | |
853 | + Bolean value is True if the target should be inside the field of view. | |
854 | + """ | |
855 | + decr = math.radians(dec) | |
856 | + fovracos = fovra/math.cos(decr) | |
857 | + if fovracos > 180: | |
858 | + fovracos = 180 | |
859 | + # --- ra | |
860 | + rar = math.radians(ra+fovracos/2) | |
861 | + cosrap= math.cos(rar) | |
862 | + sinrap= math.sin(rar) | |
863 | + rar = math.radians(ra-fovracos/2) | |
864 | + cosram= math.cos(rar) | |
865 | + sinram= math.sin(rar) | |
866 | + if cosrap < cosram: | |
867 | + cosrap , cosram = cosram , cosrap | |
868 | + if sinrap < sinram: | |
869 | + sinrap , sinram = sinram , sinrap | |
870 | + if sinram < 0 and sinrap >= 0: | |
871 | + if cosram > 0: | |
872 | + cosrap = 1 | |
873 | + else: | |
874 | + cosrap = -1 | |
875 | + if cosram < 0 and cosrap >= 0: | |
876 | + if sinram > 0: | |
877 | + sinrap = 1 | |
878 | + else: | |
879 | + sinrap = -1 | |
880 | + # --- dec | |
881 | + decr = math.radians(dec+fovdec/2) | |
882 | + cosdecp= math.cos(decr) | |
883 | + sindecp= math.sin(decr) | |
884 | + decr = math.radians(dec-fovdec/2) | |
885 | + cosdecm= math.cos(decr) | |
886 | + sindecm= math.sin(decr) | |
887 | + # --- re-arange min, max | |
888 | + if cosdecp < cosdecm: | |
889 | + cosdecp , cosdecm = cosdecm , cosdecp | |
890 | + if sindecp < sindecm: | |
891 | + sindecp , sindecm = sindecm , sindecp | |
892 | + if sindecm < 0 and sindecp >= 0: | |
893 | + if cosdecm > 0: | |
894 | + cosdecp = 1 | |
895 | + else: | |
896 | + cosdecp = -1 | |
897 | + if cosdecm < 0 and cosdecp >= 0: | |
898 | + if sindecm > 0: | |
899 | + sindecp = 1 | |
900 | + else: | |
901 | + sindecp = -1 | |
902 | + # --- SQL request | |
903 | + # sql_query = "WHERE" | |
904 | + # sql_query += f" `coscrval1` >= {cosram}" | |
905 | + # sql_query += f" AND `coscrval1` <= {cosrap}" | |
906 | + # sql_query += f" AND `sincrval1` >= {sinram}" | |
907 | + # sql_query += f" AND `sincrval1` <= {sinrap}" | |
908 | + # sql_query += f" AND `coscrval2` >= {cosdecm}" | |
909 | + # sql_query += f" AND `coscrval2` <= {cosdecp}" | |
910 | + # sql_query += f" AND `sincrval2` >= {sindecm}" | |
911 | + # sql_query += f" AND `sincrval2` <= {sindecp}" | |
912 | + # --- test is true only if 4 crval* are inside the limits | |
913 | + if coscrval1 < cosram: | |
914 | + return False | |
915 | + if coscrval1 > cosrap: | |
916 | + return False | |
917 | + if sincrval1 < sinram: | |
918 | + return False | |
919 | + if sincrval1 > sinrap: | |
920 | + return False | |
921 | + if coscrval2 < cosdecm: | |
922 | + return False | |
923 | + if coscrval2 > cosdecp: | |
924 | + return False | |
925 | + if sincrval2 < sindecm: | |
926 | + return False | |
927 | + if sincrval2 > sindecp: | |
928 | + return False | |
929 | + return True | |
930 | + | |
803 | 931 | def skyfields2indexes(self, ra:float, dec:float, skyfields:list): |
804 | 932 | """Check if (ra,dec) is inside a list of skyfields. |
805 | 933 | |
... | ... | @@ -846,7 +974,7 @@ class Wcs(WcsException, GuitastroTools): |
846 | 974 | cd22 = skyfield["cd22rad"] |
847 | 975 | crp1 = skyfield["crpix1"] |
848 | 976 | crp2 = skyfield["crpix2"] |
849 | - naxis1 = skyfield["naxis2"] | |
977 | + naxis1 = skyfield["naxis1"] | |
850 | 978 | naxis2 = skyfield["naxis2"] |
851 | 979 | ccca = cc*ca # cos(dec)*cos(ra) * cos(ra0) |
852 | 980 | cssa = cs*sa # cos(dec)*sin(ra) * sin(ra0) |
... | ... | @@ -878,8 +1006,8 @@ class Wcs(WcsException, GuitastroTools): |
878 | 1006 | |
879 | 1007 | if __name__ == "__main__": |
880 | 1008 | |
881 | - default = 3 | |
882 | - example = input(f"Select the example (0 to 3) ({default}) ") | |
1009 | + default = 4 | |
1010 | + example = input(f"Select the example (0 to 4) ({default}) ") | |
883 | 1011 | try: |
884 | 1012 | example = int(example) |
885 | 1013 | except: |
... | ... | @@ -912,14 +1040,57 @@ if __name__ == "__main__": |
912 | 1040 | |
913 | 1041 | if example == 3: |
914 | 1042 | """ |
915 | - Use of skyfield | |
1043 | + Use of skyfields2indexes | |
916 | 1044 | """ |
917 | 1045 | skyfields = [] |
918 | 1046 | wcs = Wcs() |
919 | - wcs.optic(512, 512, "6h00m", "+30d", 9, 9, 1, 0) | |
1047 | + wcs.optic(512, 512, "8h00m", "+34d", 9, 9, 1, 0) | |
920 | 1048 | skyfield = wcs.skyfield_get(1024, 1024) |
921 | 1049 | skyfields.append(skyfield) |
922 | - wcs.optic(512, 512, "8h00m", "+34d", 9, 9, 1, 0) | |
1050 | + wcs.optic(512, 512, "6h00m", "+30d", 9, 9, 1, 0) | |
923 | 1051 | skyfield = wcs.skyfield_get(1024, 1024) |
924 | 1052 | skyfields.append(skyfield) |
925 | 1053 | indexes = wcs.skyfields2indexes(90.2, 30.04, skyfields) |
1054 | + for index in indexes: | |
1055 | + i, x, y = index | |
1056 | + ra, dec = wcs.xy2radec(x, y) | |
1057 | + print(f"Target {i} position in the image {x=:.2f} {y=:.2f}. R.A.={ra:.2f} Dec.={dec:.2f}") | |
1058 | + | |
1059 | + if example == 4: | |
1060 | + """ | |
1061 | + Use of is_skyfield_in_radecfov | |
1062 | + """ | |
1063 | + wcs = Wcs() | |
1064 | + # - Skyfield definition for the test | |
1065 | + wcs.optic(512, 512, "0h00m", "+31d", 9, 9, 1, 0) | |
1066 | + skyfield = wcs.skyfield_get(1024, 1024) | |
1067 | + fovra, fovdec = wcs.skyfield2fov(skyfield) | |
1068 | + print("=== Skyfield characteristics:") | |
1069 | + print(f"Image field of view {fovra:.2f} x {fovdec:.2f} degrees") | |
1070 | + crval1 = wcs.getval('CRVAL1')[0] | |
1071 | + crval2 = wcs.getval('CRVAL2')[0] | |
1072 | + print(f"Image center R.A.={crval1:.2f} Dec.={crval2:.2f} degrees") | |
1073 | + # - Get the four elements | |
1074 | + coscrval1 = skyfield['coscrval1'] | |
1075 | + sincrval1 = skyfield['sincrval1'] | |
1076 | + coscrval2 = skyfield['coscrval2'] | |
1077 | + sincrval2 = skyfield['sincrval2'] | |
1078 | + # - Target to check if inside the image defined by skyfield | |
1079 | + print("=== Target characteristics:") | |
1080 | + ra = 0.3 | |
1081 | + dec = 31.22 | |
1082 | + res = wcs.is_skyfield_in_radecfov(ra, dec, fovra, fovdec, coscrval1, sincrval1, coscrval2, sincrval2) | |
1083 | + resp = f"Target R.A.={ra:.2f} Dec.={dec:.2f} is " | |
1084 | + if res: | |
1085 | + resp += "inside the image." | |
1086 | + else: | |
1087 | + resp += "outside the image." | |
1088 | + print(f"{resp}") | |
1089 | + if res: | |
1090 | + skyfields = [] | |
1091 | + skyfields.append(skyfield) | |
1092 | + indexes = wcs.skyfields2indexes(ra, dec, skyfields) | |
1093 | + for index in indexes: | |
1094 | + i, x, y = index | |
1095 | + print(f"Target position in the image {x=:.2f} {y=:.2f}") | |
1096 | + | ... | ... |