Commit 72560278a3e377dd973c64334ba7d82db355bd93

Authored by Alain Klotz
1 parent d1b0d799
Exists in master

Update of Ima class + fix some bugs.

gui/tp_audine_elec/tp_audine_elec.py 0 → 100644
... ... @@ -0,0 +1,107 @@
  1 +# -*- coding: utf-8 -*-
  2 +"""
  3 +Created on Thu Mar 11 15:39:17 2021
  4 +
  5 +@author: alain
  6 +"""
  7 +
  8 +import os
  9 +import sys
  10 +import yaml
  11 +
  12 +import tkinter as tk
  13 +
  14 +path = os.path.abspath("../../src")
  15 +if path not in sys.path:
  16 + sys.path.insert(0,path)
  17 +import guitastro
  18 +
  19 +# #####################################################################
  20 +# #####################################################################
  21 +# #####################################################################
  22 +# Main
  23 +# #####################################################################
  24 +# #####################################################################
  25 +# #####################################################################
  26 +
  27 +if __name__ == "__main__":
  28 +
  29 + # --- Get path_images for examples
  30 + ima = guitastro.Ima()
  31 + path_products = ima.copy_data2products()
  32 + fconfig = os.path.join(path_products,"tp_audine_elec.yml")
  33 + if not os.path.exists(fconfig):
  34 + config = {}
  35 + conf = {}
  36 + conf["fits_path"] = path_products
  37 + config["visu1"] = conf
  38 + else:
  39 + with open(fconfig, 'r') as stream:
  40 + try:
  41 + config = yaml.safe_load(stream)
  42 + except yaml.YAMLError as exc:
  43 + print(exc)
  44 +
  45 + def save_config():
  46 + global fconfig
  47 + with open(fconfig, 'w') as yaml_file:
  48 + yaml.dump(config, yaml_file, default_flow_style=False)
  49 +
  50 + def ima1_load():
  51 + global widgets
  52 + path_cur = config["visu1"]["fits_path"]
  53 + ima1.rootdir = path_cur
  54 + fullfile = ima1.load()
  55 + if fullfile != "":
  56 + path_new = os.path.dirname(fullfile)
  57 + if path_cur != path_new and path_new != "":
  58 + config["visu1"]["fits_path"] = path_new
  59 + save_config()
  60 + visu1.autocuts()
  61 + visu1.disp()
  62 + widgets["button_saveima_1"].configure(state= tk.NORMAL)
  63 +
  64 + def ima1_save():
  65 + ima1.save()
  66 +
  67 + # --- load an image from a FITS file
  68 + ima1 = guitastro.Ima()
  69 + ima1.extension = ".fit"
  70 +
  71 + # --- Create a simple Tk interface
  72 + tkroot = tk.Tk()
  73 + tkroot.geometry("800x600+120+80")
  74 + tkroot.title("TP Audine Electronique")
  75 + # ---
  76 + frame1 = tk.Frame(tkroot)
  77 + frame1.pack(side = tk.LEFT, fill=tk.BOTH, expand=tk.YES)
  78 + # ---
  79 + widgets = {}
  80 + # ---
  81 + frame1m = tk.Frame(frame1)
  82 + widgets["button_loadima_1"] = tk.Button(frame1m, text="Load FITS", command=ima1_load)
  83 + widgets["button_loadima_1"].pack(side=tk.LEFT, padx = 2)
  84 + widgets["button_saveima_1"] = tk.Button(frame1m, text="Save FITS", command=ima1_save, state= tk.DISABLED)
  85 + widgets["button_saveima_1"].pack(side=tk.LEFT, padx = 2)
  86 + frame1m.pack(fill=tk.BOTH, expand=tk.NO)
  87 + # ---
  88 + tkroot.pack_propagate(0)
  89 + tkroot.update()
  90 +
  91 + # --- Create and use a visu
  92 + try:
  93 + frame1i = tk.Frame(frame1)
  94 + frame1i.pack(side = tk.TOP, fill=tk.BOTH, expand=tk.YES)
  95 + visu1 = guitastro.Visu(frame1i)
  96 + visu1.ima(ima1)
  97 + #visu1.autocuts()
  98 + #visu1.disp()
  99 +
  100 + except:
  101 + msg = "{}".format(sys.exc_info())
  102 + print(msg)
  103 +
  104 + # --- Launch the event loop of the user interface
  105 + tkroot.update()
  106 + tkroot.mainloop()
  107 +
... ...
gui/visu_double/visu_double.py
... ... @@ -53,7 +53,7 @@ if __name__ == "__main__":
53 53 def ima1_load():
54 54 global widgets
55 55 path_cur = config["visu1"]["fits_path"]
56   - ima1.path(path_cur)
  56 + ima1.rootdir = path_cur
57 57 fullfile = ima1.load()
58 58 if fullfile != "":
59 59 path_new = os.path.dirname(fullfile)
... ... @@ -70,7 +70,7 @@ if __name__ == "__main__":
70 70 def ima2_load():
71 71 global widgets
72 72 path_cur = config["visu2"]["fits_path"]
73   - ima2.path(path_cur)
  73 + ima2.rootdir = path_cur
74 74 fullfile = ima2.load()
75 75 if fullfile != "":
76 76 path_new = os.path.dirname(fullfile)
... ...
src/guitastro/astrotables.py
... ... @@ -415,7 +415,7 @@ class AstroTable(AstroTableException, GuitastroTools):
415 415 self._verify_table()
416 416 return self.t.keys()
417 417  
418   - def getcol(self, colname: str):
  418 + def getcol(self, colname: str, unit: bool=False):
419 419 """Return the values of a column of a given name
420 420  
421 421 Example:
... ... @@ -439,6 +439,9 @@ class AstroTable(AstroTableException, GuitastroTools):
439 439 """
440 440 self._verify_table()
441 441 col = self.t[colname]
  442 + if str(type(col)) == "<class 'astropy.utils.masked.core.MaskedQuantity'>" or str(type(col)) == "<class 'astropy.units.quantity.Quantity'>":
  443 + if unit == False:
  444 + col = col.value
442 445 return col
443 446  
444 447 def setcol(self, colname: str, colvalues: Any, **kwargs):
... ... @@ -836,6 +839,59 @@ class AstroTable(AstroTableException, GuitastroTools):
836 839 nrow, ncol = self.shape()
837 840 self.t.remove_rows(indexes)
838 841  
  842 + def keepvalidrows(self, colnames: list):
  843 + """Keep only rows where data of colnames are valids.
  844 +
  845 + Example:
  846 +
  847 + To delete rows from an index to another one:
  848 +
  849 + ::
  850 +
  851 + at = AstroTable()
  852 + at.table(None)
  853 + col = at.getcol('x').copy()
  854 + col[2] = np.nan
  855 + at.setcol("z", col * u.mag)
  856 + at.keepvalidrows(["x", "y", "z"])
  857 + at
  858 +
  859 + The result is:
  860 +
  861 + ::
  862 +
  863 + ====================
  864 + Metadata:
  865 + DATE-OBS = 2020-02-22T02:20:22
  866 + AUTHOR = Guitastro
  867 + ====================
  868 + Table:
  869 + x y z
  870 + mag
  871 + --- --- ---
  872 + 0.0 0.0 0.0
  873 + 1.0 1.0 1.0
  874 + 3.0 9.0 3.0
  875 +
  876 + """
  877 + self._verify_table()
  878 + nrow, ncol = self.shape()
  879 + bad_indexes = set()
  880 + for colname in colnames:
  881 + col = self.getcol(colname, False)
  882 + print(f"{colname=} {str(type(col))=} {col=}")
  883 + if str(type(col)) == "<class 'astropy.utils.masked.core.MaskedNDArray'>":
  884 + idxs = set(np.where(col.mask == True)[0])
  885 + print(f"{colname=} {idxs=}")
  886 + bad_indexes.update(idxs)
  887 + if str(type(col)) == "<class 'numpy.ndarray'>":
  888 + idxs = set(np.where(np.isnan(col))[0])
  889 + print(f"{colname=} {idxs=}")
  890 + bad_indexes.update(idxs)
  891 + bad_indexes = list(bad_indexes)
  892 + print(f"{bad_indexes=}")
  893 + self.t.remove_rows(bad_indexes)
  894 +
839 895 # =============================================
840 896 # Manage table metadata
841 897 # =============================================
... ... @@ -1704,7 +1760,7 @@ class AstroTable(AstroTableException, GuitastroTools):
1704 1760 except IndexError:
1705 1761 raise AstroTableException(AstroTableException.NO_OBJECT_FOUND)
1706 1762 except:
1707   - msg = sys.exc_info()[0]
  1763 + msg = repr(sys.exc_info()[0])
1708 1764 raise AstroTableException(AstroTableException.ERROR_NOT_REFERENCED, msg)
1709 1765  
1710 1766 if table is not None:
... ... @@ -1746,8 +1802,8 @@ class AstroTable(AstroTableException, GuitastroTools):
1746 1802  
1747 1803 if __name__ == "__main__":
1748 1804  
1749   - default = 7
1750   - example = input(f"Select the example (0 to 7) ({default}) ")
  1805 + default = 8
  1806 + example = input(f"Select the example (0 to 8) ({default}) ")
1751 1807 try:
1752 1808 example = int(example)
1753 1809 except:
... ... @@ -1940,3 +1996,15 @@ if __name__ == &quot;__main__&quot;:
1940 1996 plt.ylabel('T sky')
1941 1997 plt.show()
1942 1998  
  1999 + if example == 8:
  2000 + at = AstroTable()
  2001 + at.table(None)
  2002 + col = at.getcol('x').copy()
  2003 + col[2] = np.nan
  2004 + at.setcol("z", col * u.mag)
  2005 + at.keepvalidrows(["x", "y", "z"])
  2006 +
  2007 + if example == 9:
  2008 + at = AstroTable()
  2009 + at.catalog("1h5m13s", "+13d56m32s", "0.5d", "0.5d", "GAIA", "IDRADECMAGS", column_filters = {"gmag": "<16"})
  2010 +
... ...
src/guitastro/filenames.py
... ... @@ -2975,7 +2975,7 @@ class FileNames(FileNamesException, GuitastroTools):
2975 2975 def _askopenfilename(self, title="", filetypes=""):
2976 2976 root = tk.Tk()
2977 2977 root.withdraw() # To avoid display of the Tk window
2978   - initialdir = self._image_dir
  2978 + initialdir = self.rootdir
2979 2979 if filetypes == "":
2980 2980 filetypes = [("FITS","*.fit;*.fits;*.fts;*.gz"),("All", "*")]
2981 2981 fitsname = askopenfilename(title=title, initialdir=initialdir, filetypes = filetypes)
... ... @@ -2983,14 +2983,14 @@ class FileNames(FileNamesException, GuitastroTools):
2983 2983 filename, file_extension = os.path.splitext(fitsname)
2984 2984 if file_extension=="":
2985 2985 fitsname += self._fits_extension
2986   - self._image_dir = os.path.dirname(fitsname)
  2986 + self.rootdir = os.path.dirname(fitsname)
2987 2987 root.destroy()
2988 2988 return fitsname
2989 2989  
2990 2990 def _asksaveasfilename(self, title="", filetypes=""):
2991 2991 root = tk.Tk()
2992 2992 root.withdraw() # To avoid display of the Tk window
2993   - initialdir = self._image_dir
  2993 + initialdir = self.rootdir
2994 2994 if filetypes == "":
2995 2995 filetypes = [("FITS","*.fit;*.fits;*.fts;*.gz"),("All", "*")]
2996 2996 fitsname = asksaveasfilename(title=title, initialdir=initialdir, filetypes = filetypes)
... ... @@ -2998,7 +2998,7 @@ class FileNames(FileNamesException, GuitastroTools):
2998 2998 filename, file_extension = os.path.splitext(fitsname)
2999 2999 if file_extension=="":
3000 3000 fitsname += self._fits_extension
3001   - self._image_dir = os.path.dirname(fitsname)
  3001 + self.rootdir = os.path.dirname(fitsname)
3002 3002 root.destroy()
3003 3003 return fitsname
3004 3004  
... ...
src/guitastro/ima.py
... ... @@ -1994,7 +1994,8 @@ class Ima(ImaException, FileNames):
1994 1994 for lstdo in lstdos:
1995 1995 print(lstdo)
1996 1996 # --- On charge tmp.wcs
1997   - wcsname = os.path.join(ima1.path(), "tmp.wcs")
  1997 + #wcsname = os.path.join(self.rootdir, "tmp.wcs")
  1998 + wcsname = self.join("tmp.wcs")
1998 1999 wcs_header = []
1999 2000 if os.path.exists(wcsname)==False:
2000 2001 # Code to execute when solve fails
... ... @@ -2006,7 +2007,8 @@ class Ima(ImaException, FileNames):
2006 2007 wcs_header = False
2007 2008 else:
2008 2009 # --- On charge tmp.new comme image calibrée
2009   - newname = os.path.join(ima1.path(), "tmp.new")
  2010 + #newname = os.path.join(ima1.rootdir = ), "tmp.new")
  2011 + newname = self.join("tmp.new")
2010 2012 self.load(newname)
2011 2013 with open(wcsname,"rt") as fid:
2012 2014 while True:
... ... @@ -3130,7 +3132,7 @@ class Ima(ImaException, FileNames):
3130 3132 tot_sigs = []
3131 3133 sig2fwhm = 2*math.sqrt(2*math.log(2))
3132 3134 for x, y, mag in zip(xs, ys, mags):
3133   - self.etc.inputs("m", mag.value)
  3135 + self.etc.inputs("m", float(mag))
3134 3136 self.etc.t2snr_computations()
3135 3137 res = self.etc.simu_star_params(unit="adu")
3136 3138 amplitudes.append(res["max_sig"][0])
... ... @@ -3546,8 +3548,7 @@ if __name__ == &quot;__main__&quot;:
3546 3548 Just a visu
3547 3549 """
3548 3550 ima1 = Ima()
3549   - ima1.extension(".fit")
3550   - ima1.path(path_products)
  3551 + ima1.fcontext = "image_in"
3551 3552 ima1.load("m57")
3552 3553 ima1.visu()
3553 3554  
... ... @@ -3556,8 +3557,7 @@ if __name__ == &quot;__main__&quot;:
3556 3557 A call of sextractor
3557 3558 """
3558 3559 ima1 = Ima()
3559   - ima1.extension(".fit")
3560   - ima1.path(path_products)
  3560 + ima1.fcontext = "image_in"
3561 3561 ima1.load("m57")
3562 3562 stars = ima1.sextractor(kappa_sigma = 0.2, pixel_radius=3.5)
3563 3563 stars.xy2radec()
... ... @@ -3588,8 +3588,7 @@ if __name__ == &quot;__main__&quot;:
3588 3588 A call of DAOphot
3589 3589 """
3590 3590 ima1 = Ima()
3591   - ima1.extension(".fit")
3592   - ima1.path(path_products)
  3591 + ima1.fcontext = "image_in"
3593 3592 ima1.load("m57")
3594 3593 radii = np.linspace(2,10,(10-2+1))
3595 3594 stars = ima1.daophot(kappa_sigma = 1, phot_radii=radii)
... ... @@ -3642,8 +3641,7 @@ if __name__ == &quot;__main__&quot;:
3642 3641 Subsky
3643 3642 """
3644 3643 ima1 = Ima()
3645   - ima1.extension(".fit")
3646   - ima1.path(path_products)
  3644 + ima1.fcontext = "image_in"
3647 3645 ima1.load("m57")
3648 3646 res = ima1.subsky()
3649 3647 ima1.visu()
... ... @@ -3653,23 +3651,24 @@ if __name__ == &quot;__main__&quot;:
3653 3651 Mult
3654 3652 """
3655 3653 ima1 = Ima()
3656   - ima1.extension(".fit")
3657   - ima1.path(path_products)
  3654 + ima1.fcontext = "image_in"
3658 3655 ima1.load("m57")
3659 3656 ima1.stat()
3660 3657 ima1.mult(.2)
3661   - ima1.stat()
  3658 + stat = ima1.stat()
  3659 + print(f"{stat=}")
3662 3660  
3663 3661 if example == 7:
3664 3662 """
3665 3663 A call of sextractor + match ra,dec with a catalog
3666 3664 """
3667 3665 ima1 = Ima()
3668   - ima1.extension(".fit")
3669   - ima1.path(path_products)
  3666 + ima1.fcontext = "image_in"
3670 3667 ima1.load("m57")
3671 3668 infos = ima1.wcs_infos()
3672   - if False:
  3669 + # --- File name of the Astrotable
  3670 + filename = os.path.join(path_products,"image_sources.txt")
  3671 + if not os.path.exists(filename):
3673 3672 # === Case the AstroTable need to be written in the disk
3674 3673 # --- Create an AstroTable of sources in the image (x,y,flux,etc.)
3675 3674 stars = ima1.sextractor(kappa_sigma = 0.2, pixel_radius=3.5)
... ... @@ -3678,7 +3677,6 @@ if __name__ == &quot;__main__&quot;:
3678 3677 # --- Keep only interesting columns in the AstroTable
3679 3678 stars.keepcols(['x','y','app_flux', 'app_fluxerr', 'ra','dec'])
3680 3679 # --- Save the AstroTable on disk
3681   - filename = os.path.join(path_products,"image_sources.txt")
3682 3680 stars.write(filename, format='astrotable', overwrite=True)
3683 3681 # ===
3684 3682 # --- Create an AstroTable of cataloged sources in the image (ra,dec,mag,etc.)
... ... @@ -3690,7 +3688,6 @@ if __name__ == &quot;__main__&quot;:
3690 3688 else:
3691 3689 # === Case the AstroTable are read from the disk
3692 3690 # --- Load the AstroTables
3693   - filename = os.path.join(path_products,"image_sources.txt")
3694 3691 stars = AstroTable()
3695 3692 stars.read(filename, format='astrotable')
3696 3693 catstars = AstroTable()
... ... @@ -3704,36 +3701,42 @@ if __name__ == &quot;__main__&quot;:
3704 3701 flux = stars.getcol('app_flux')
3705 3702 maginst = -2.5*np.log10(flux)
3706 3703 stars.setcol("maginst", maginst * u.mag)
  3704 + # --- Keep only rows with valid values in given columns
  3705 + stars.keepvalidrows(['maginst', 'magABg', 'magABr'])
3707 3706 # --- Get the catalog magnitudes
3708 3707 magABg = stars.getcol('magABg')
3709 3708 magABr = stars.getcol('magABr')
3710 3709 magABgr = magABg - magABr
3711 3710 maginst = stars.getcol('maginst')
3712 3711 zeromags = magABr - maginst
  3712 + # --- plots
  3713 + # import matplotlib.pyplot as plt
3713 3714 plt.plot(magABgr, zeromags, 'ob')
  3715 + plt.xlabel('(g-r) AB')
  3716 + plt.ylabel('zeromag r AB')
  3717 + plt.show()
3714 3718 zeromag = np.nanmean(zeromags)
3715 3719 zeromag_std = np.nanstd(zeromags)
3716 3720 print(f"zeromag = {zeromag:.2f} +/- {zeromag_std:.2f}")
  3721 + plt.plot(magABr, zeromags, 'or')
  3722 + plt.xlabel('r AB')
  3723 + plt.ylabel('zeromag r AB')
  3724 + plt.show()
3717 3725  
3718 3726 if example == 8:
3719 3727 from astropy.nddata import CCDData
3720 3728 ima1 = Ima()
3721   - ima1.extension(".fit")
3722   - ima1.path(path_products)
3723   - image_file_path = ima1.load("i")
3724   - #image_file_path = 'D:\\srv\\develop\\astromeccadev\\astromecca_data\\images\\i.fit'
  3729 + ima1.fcontext = "image_in"
  3730 + image_file_path = ima1.join("m57")
3725 3731 ccd = CCDData.read(image_file_path, unit='adu')
3726 3732 data = ccd.data
3727   - ima1.save("i")
3728   - ima1.load("i")
3729 3733  
3730 3734 if example == 9:
3731 3735 """
3732 3736 Calibwcs examples
3733 3737 """
3734 3738 ima1 = Ima()
3735   - ima1.extension(".fit")
3736   - ima1.path(path_products)
  3739 + ima1.fcontext = "image_in"
3737 3740 ima1.load("m57")
3738 3741 # --- Delete all previous WCS header cards
3739 3742 success, comment, detail = ima1.calibwcs("delete")
... ... @@ -3780,6 +3783,7 @@ if __name__ == &quot;__main__&quot;:
3780 3783  
3781 3784 if example == 10:
3782 3785 ima1 = Ima()
  3786 + ima1.fcontext = "image_in"
3783 3787 fitsname = "m57"
3784 3788 ima1.load(fitsname)
3785 3789 ima1.sortx(50)
... ... @@ -3793,8 +3797,7 @@ if __name__ == &quot;__main__&quot;:
3793 3797  
3794 3798 if example == 11:
3795 3799 ima1 = Ima()
3796   - ima1.extension(".fit")
3797   - ima1.path(path_products)
  3800 + ima1.fcontext = "image_in"
3798 3801 ima1.load("m57")
3799 3802 sources, phot_table = ima1.daophot()
3800 3803 # stars.colnames
... ... @@ -3830,8 +3833,7 @@ if __name__ == &quot;__main__&quot;:
3830 3833 fitgauss
3831 3834 """
3832 3835 ima1 = Ima()
3833   - ima1.extension(".fit")
3834   - ima1.path(path_products)
  3836 + ima1.fcontext = "image_in"
3835 3837 ima1.load("m57")
3836 3838 box = [200,40,220,60]
3837 3839 #ima1.window(box)
... ... @@ -3857,6 +3859,10 @@ if __name__ == &quot;__main__&quot;:
3857 3859 print(resultx.fit_report())
3858 3860 print("="*15)
3859 3861 print(resulty.fit_report())
  3862 + print("="*15)
  3863 + print(f"{flux=:.2f} +/- {dflux:.2f} adu")
  3864 + print(f"{fwhm=:.2f} +/- {dfwhm:.2f} pix")
  3865 + print(f"{bg=:.2f} +/- {dbg:.2f} adu")
3860 3866  
3861 3867 if example == 13:
3862 3868 """
... ... @@ -3866,10 +3872,10 @@ if __name__ == &quot;__main__&quot;:
3866 3872  
3867 3873 if example == 14:
3868 3874 ima1 = Ima()
3869   - ima1.extension(".fit")
3870   - ima1.path(path_products)
  3875 + ima1.fcontext = "image_in"
3871 3876 ima1.load("m57")
3872   - ima1.corners(34,50)
  3877 + ima1.corners(20,20)
  3878 + ima1.visu()
3873 3879  
3874 3880 if example == 15:
3875 3881 """
... ... @@ -3888,13 +3894,13 @@ if __name__ == &quot;__main__&quot;:
3888 3894 Simulation
3889 3895 """
3890 3896 ima1 = Ima()
  3897 + ima1.fcontext = "image_in"
3891 3898 ima1.etc.camera("Kepler 4040")
3892 3899 ima1.etc.optics("Takahashi_180ED")
3893 3900 ima1.etc.params("msky",18)
3894 3901 ra = 132.84583
3895 3902 dec = 11.81333
3896 3903 at = ima1.simulation("GAIA", "PHOTOM", shutter_mode="opened", t=50, ra=ra, dec=dec, column_filters = {"Gmag": "<15"})
3897   - ima1.path(path_products)
3898 3904 ima1.save("test_simulation")
3899 3905  
3900 3906 # --- Create a simple Tk interface
... ... @@ -3934,7 +3940,7 @@ if __name__ == &quot;__main__&quot;:
3934 3940 # --- Load the image
3935 3941 ima1 = Ima()
3936 3942 ima1.extension(".fit")
3937   - ima1.path(path_ima)
  3943 + ima1.rootdir = path_ima
3938 3944 ima1.load(file_ima)
3939 3945 # --- Crop the image to eliminate borders
3940 3946 if len(crop_box) > 0:
... ...