Loading noche/headers/header_base_v1.ini +1 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ OBSTYPE = | Observation type [Detector] DETECTOR = | Detector identifier DETSIZE = | [px] Physical CCD dimensions DETROT = | [deg] Rotation offset of the detector XPIXSZ = | [um] Pixel X axis size YPIXSZ = | [um] Pixel Y axis size PIXSCALE = | [arcsec/px] Plate scale in binning 1 Loading noche/noche.py +112 −53 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ import configparser from pathlib import Path from configparser import DuplicateOptionError from ast import literal_eval import sys import numpy as np from astropy.coordinates import SkyCoord, EarthLocation Loading Loading @@ -48,6 +49,8 @@ class Noche: if debug: log.setLevel('DEBUG') log.debug(sys._getframe().f_code.co_name) self._coord = None self._location = None self._obstime = None Loading @@ -69,8 +72,11 @@ class Noche: Returns ------- list of str Names of available observatory configuration files (without .ini extension). Names of available observatory configuration files (without .ini extension). """ log.debug(sys._getframe().f_code.co_name) data_dir = Path(__file__).parent / self._obs_dir return [f.stem for f in data_dir.glob("*.ini")] Loading @@ -84,6 +90,7 @@ class Noche: path : str Configuration file in .ini format """ log.debug(sys._getframe().f_code.co_name) if not path: path = Path(__file__).parent / self._head_dir / "header_base_v1.ini" Loading Loading @@ -117,11 +124,11 @@ class Noche: name : str One of the supported observatories. """ log.debug(sys._getframe().f_code.co_name) data_dir = Path(__file__).parent / self._obs_dir ini_path = data_dir / f"{name}.ini" log.debug(ini_path) if not ini_path.exists(): msg = f"Observatory config '{ini_path}' not found." # raise FileNotFoundError(msg) Loading @@ -141,6 +148,7 @@ class Noche: path : str Configuration file in .ini format. """ log.debug(sys._getframe().f_code.co_name) config = self._load_config(path) Loading @@ -156,68 +164,105 @@ class Noche: if k in self.header: self.header[k] = val #self.header["DETSIZE"] = f'[1:{self.header["NAXIS1"]},1:{self.header["NAXIS2"]}]' if fits_file: self.fill_from_fits_file(path, fits_file) else: self._update() def fill_from_fits_file(self, path=None, fits_file=None): """ Load relevant header info from a fits file of the specific observatory. - [Mapping] section defines how the new keywords are related to the old ones. For example: FOCUSPOS = TELFOCUS - [Formula] section defines the formula to apply to a header value to match the specifics of the new one. For example: FOCUSPOS = (x)/1000 # Transforming mm in um. - [Mapping] defines how the new keywords are related to the old ones. - [Formula] defines formulas to apply *before* generating derived keywords. - [Tweak] defines formulas to apply *after* generating all keywords. Parameters ---------- path : str Configuration file in .ini format. fits_file : str FITS file position. FITS file path. """ log.debug(sys._getframe().f_code.co_name) config = self._load_config(path) filename = Path(fits_file) self.load_fits(filename) fits_file_header = self.hdu.header sections = config.sections() # Load formulas (if sections exist) pre_formulas = dict(config["Formula"]) if "Formula" in config else {} post_formulas = dict(config["Tweak"]) if "Tweak" in config else {} # Apply Mapping + PreFormula loc = config["Mapping"] for k in loc.keys(): if not (k in self.header): log.error(f"{k} not in header") continue fits_keyword = loc[k] fits_value = fits_file_header[fits_keyword] val = self._parse(fits_value) self.header[k] = val log.info(f"{k:<8} : {val}") loc = config["Formula"] for k in loc.keys(): fits_formula = loc[k] if k in pre_formulas: x = self.header[k] self.header[k] = eval(fits_formula) log.info(f"{k:<8} : from {x} to {self.header[k]}") del x try: self.header[k] = eval(pre_formulas[k]) log.warning(f"{k:<8} (Pre): from {x} to {self.header[k]}") except Exception as e: log.error(f"Failed to evaluate PreFormula for {k}: {e}") # # Apply Mapping # loc = config["Mapping"] # for k in loc.keys(): # if not (k in self.header): # log.error(f"{k} not in header") # continue # fits_keyword = loc[k] # fits_value = fits_file_header[fits_keyword] # val = self._parse(fits_value) # self.header[k] = val # log.info(f"{k:<8} : {val}") # # Apply PreFormula # for k, formula in pre_formulas.items(): # if k in self.header: # x = self.header[k] # try: # self.header[k] = eval(formula) # log.warning(f"{k:<8} (Pre): from {x} to {self.header[k]}") # except Exception as e: # log.error(f"Failed to evaluate PreFormula for {k}: {e}") # else: # log.debug(f"PreFormula skipped: {k} not in header") # Set coordinates (calls _update(), which triggers set_wcs and others) self.set_coordinates(self.header["RA"], self.header["DEC"], obstime=self.header["DATE-OBS"]) self._update() # Apply PostFormula for k, formula in post_formulas.items(): if k in self.header: x = self.header[k] try: self.header[k] = eval(formula) log.warning(f"{k:<8} (Post): from {x} to {self.header[k]}") except Exception as e: log.error(f"Failed to evaluate PostFormula for {k}: {e}") else: log.warning(f"PostFormula skipped: {k} not in header") self.header["FILEORIG"] = filename.name def set_location(self, lon, lat, alt): """ Location of the observatory, Separate so that it is Loading @@ -232,6 +277,7 @@ class Noche: alt : float Elevation in meters. """ log.debug(sys._getframe().f_code.co_name) self._location = EarthLocation(lon, lat, alt) Loading @@ -248,6 +294,7 @@ class Noche: obstime : str, astropy.time.Time Time of the observation. """ log.debug(sys._getframe().f_code.co_name) time = Time(obstime) self._obstime = time Loading @@ -259,7 +306,7 @@ class Noche: self.header['DATE-OBS'] = time.isot self.header['MJD-OBS'] = time.mjd self._update() #self._update() def set_object(self, objname, update_coord=False, obstime=None): Loading @@ -275,16 +322,17 @@ class Noche: obstime : str or astropy.time.Time, optional Observation time to associate with coordinates. """ log.debug(sys._getframe().f_code.co_name) if obstime: time = Time(obstime) self.set_obstime(time) if update_coord: try: coord = SkyCoord.from_name(objname) self._coord = coord if obstime: time = Time(obstime) self.set_obstime(time) log.info("Found catalog name") coorstr = coord.to_string(style='hmsdms', sep=' ', precision=1, pad=True) log.info(f"Corresponds to {coorstr}") Loading Loading @@ -315,6 +363,7 @@ class Noche: obstime : str or astropy.time.Time, optional Observation time. """ log.debug(sys._getframe().f_code.co_name) coord = SkyCoord(ra=ra, dec=dec, unit=(u.hourangle, u.deg)) self._coord = coord Loading @@ -325,8 +374,8 @@ class Noche: self.header['RA'] = coord.ra.to_string(unit=u.hourangle, sep=':', pad=True, precision=1) self.header['DEC'] = coord.dec.to_string(unit=u.deg, sep=':', pad=True, precision=1) self.header['DEC'] = coord.dec.to_string(unit=u.deg, sep=':', pad=True, precision=1) self.header['RA_DEG'] = coord.ra.deg self.header['DEC_DEG'] = coord.dec.deg Loading @@ -342,6 +391,7 @@ class Noche: ValueError If observation time or location is not set. """ log.debug(sys._getframe().f_code.co_name) if self._obstime == None or self._location == None: raise ValueError("Observation Time, Instrument parameters must be set.") Loading @@ -365,11 +415,11 @@ class Noche: # Position angle: with respect to Celestial North Pole north_celestial = SkyCoord(ra=0*u.deg, dec=90*u.deg, frame='icrs') posang = self._coord.position_angle(north_celestial).to(u.deg).value self.header['POSANGLE'] = round(posang, 2) posangle = self._coord.position_angle(north_celestial).to(u.deg).value self.header['POSANGLE'] = round(posangle, 2) # Parallactic angle: between local meridian and celestial axis parangle = (posang - altaz.az.deg + 360) % 360 parangle = (posangle - altaz.az.deg + 360) % 360 if parangle > 180: parangle -= 360 # Wrap to [-180, 180] Loading @@ -390,11 +440,11 @@ class Noche: ValueError If coordinates or location are not set. """ log.debug(sys._getframe().f_code.co_name) if self._coord == None or self._location == None: raise ValueError("Observation Coordinates, Instrument parameters must be set.") detsize = self.header['DETSIZE'].strip('[]') x_str, y_str = detsize.split(',') Loading @@ -407,20 +457,22 @@ class Noche: cdelt2 = round(self.header["PIXSCALE"]*self.header["YBINNING"]*u.arcsec.to(u.deg), 7) if not angle: angle = self.header["DEROTANG"] angle = self.header["DEROTANG"] + self.header["DETROT"] angle = np.deg2rad(angle) crval_ra = self._coord.ra.deg crval_dec = self._coord.dec.deg flip = -1 # East to the left self.header['CRPIX1'] = crpix[0] self.header['CRPIX2'] = crpix[1] self.header['CRVAL1'] = crval_ra self.header['CRVAL2'] = crval_dec self.header['CDELT1'] = cdelt1 self.header['CDELT1'] = cdelt1 * flip self.header['CDELT2'] = cdelt2 self.header["PC1_1"] = +np.cos(angle) *-1 # E to left self.header["PC1_1"] = +np.cos(angle) self.header["PC1_2"] = -np.sin(angle) self.header["PC2_1"] = +np.sin(angle) self.header["PC2_2"] = +np.cos(angle) Loading @@ -435,6 +487,7 @@ class Noche: ValueError If coordinates or location are not set. """ log.debug(sys._getframe().f_code.co_name) if self._coord == None or self._location == None: raise ValueError("Observation Time, Observing location must be set.") Loading Loading @@ -467,12 +520,14 @@ class Noche: """ List the header keywords that are still empty """ log.debug(sys._getframe().f_code.co_name) for k in self.header: if self.header[k] == None: print(k, self.header[k]) def load_fits(self, fits_file): log.debug(sys._getframe().f_code.co_name) filename = fits_file hdul = fits.open(filename) Loading @@ -487,6 +542,7 @@ class Noche: @staticmethod def _load_config(path): log.debug(sys._getframe().f_code.co_name) config = configparser.ConfigParser(inline_comment_prefixes=('#',)) Loading @@ -504,8 +560,10 @@ class Noche: If coordinates, observation and location are provided, then additional keywords can be filled """ log.debug(sys._getframe().f_code.co_name) if self._coord != None and self._obstime != None and self._location != None: self.set_altaz_and_parallactic() self.set_ambient() self.set_wcs() Loading @@ -525,6 +583,7 @@ class Noche: int, float, bool, or str Parsed value. """ # log.debug(sys._getframe().f_code.co_name) try: val = val.strip() Loading noche/observatories/abobservatory.ini +5 −2 Original line number Diff line number Diff line Loading @@ -5,14 +5,14 @@ FOCALLEN = 1170 # [mm] Telescope focal length OBS-LONG = -11.2430135 # [deg] Observatory longitude (East > 0) OBS-LAT = 43.5235203 # [deg] Observatory latitude (North > 0) OBS-ELEV = 1025 # [m] Observatory altitude above sea level DEROTANG = 0 # [deg] Rotator angle, if any INSTRUME = ABOb instrument # Instrument name OBSTYPE = Imaging # Observation type DETECTOR = Atik 383 L # Detector identifier DETSIZE = [1:3354,1:2529] # [px] [1:x,1:y] Physical CCD dimensions DETROT = -89.67 # [deg] Rotation offset of the detector XPIXSZ = 5.4 # [um] Pixel X axis size YPIXSZ = 5.4 # [um] Pixel Y axis size PIXSCALE = 36 # [arcsec/px] Plate scale in binning 1 PIXSCALE = 1.0 # [arcsec/px] Plate scale in binning 1 GAIN = # [e-/ADU] Gain RDNOISE = # [e- RMS] Readout noise Loading @@ -38,3 +38,6 @@ SWCREATE = SWCREATE # Software that created FILEORIG [Formula] [Tweak] CDELT2 = -1*x noche/observatories/grt.ini +6 −1 Original line number Diff line number Diff line Loading @@ -5,11 +5,11 @@ FOCALLEN = 1520 # [mm] Telescope focal length OBS-LONG = 14.020563 # [deg] Observatory longitude (East > 0) OBS-LAT = 37.9391183 # [deg] Observatory latitude (North > 0) OBS-ELEV = 606 # [m] Observatory altitude above sea level DEROTANG = 0 # [deg] Rotator angle, if any INSTRUME = GRT instrument # Instrument name OBSTYPE = Imaging # Observation type DETECTOR = Moravian CMOS C4-16000 # Detector identifier DETSIZE = [1:4096,1:4096] # [px] [1:x,1:y] Physical CCD dimensions DETROT = +5.0 # [deg] Rotation offset of the detector XPIXSZ = 9 # [um] Pixel X axis size YPIXSZ = 9 # [um] Pixel Y axis size PIXSCALE = 1.22 # [arcsec/px] Plate scale in binning 1 Loading Loading @@ -37,3 +37,8 @@ YBINNING = YBINNING # Binning factor in Y SWCREATE = SWCREATE # Software that created FILEORIG [Formula] [Tweak] CDELT2 = -1*x CRPIX1 = x+134 CRPIX2 = x-500 noche/observatories/oarpaf.ini +6 −2 Original line number Diff line number Diff line Loading @@ -5,11 +5,11 @@ FOCALLEN = 6400 # [mm] Telescope focal length OBS-LONG = 9.2034 # [deg] Observatory longitude (East > 0) OBS-LAT = 44.5912 # [deg] Observatory latitude (North > 0) OBS-ELEV = 1469 # [m] Observatory altitude above sea level DEROTANG = -89.67 # [deg] Rotator angle, if any INSTRUME = Cerbero # Instrument name OBSTYPE = Imaging # Observation type DETECTOR = SBIG STX-16081 # Detector identifier DETSIZE = [1:4144,1:4126] # [px] [1:x,1:y] Physical CCD dimensions DETROT = -89.67 # [deg] Rotation offset of the detector XPIXSZ = 9 # [um] Pixel X axis size YPIXSZ = 9 # [um] Pixel Y axis size PIXSCALE = 0.283 # [arcsec/px] Plate scale in binning 1 Loading Loading @@ -37,4 +37,8 @@ TEMPERAT = HIERARCH CAM AMBIENT # [C] Ambient temperature SWCREATE = SWCREATE # Software that created FILEORIG [Formula] RA = (x)/15 RA = x/15 [Tweak] CRPIX1 = x+234 CRPIX2 = x-100 Loading
noche/headers/header_base_v1.ini +1 −0 Original line number Diff line number Diff line Loading @@ -47,6 +47,7 @@ OBSTYPE = | Observation type [Detector] DETECTOR = | Detector identifier DETSIZE = | [px] Physical CCD dimensions DETROT = | [deg] Rotation offset of the detector XPIXSZ = | [um] Pixel X axis size YPIXSZ = | [um] Pixel Y axis size PIXSCALE = | [arcsec/px] Plate scale in binning 1 Loading
noche/noche.py +112 −53 Original line number Diff line number Diff line Loading @@ -2,6 +2,7 @@ import configparser from pathlib import Path from configparser import DuplicateOptionError from ast import literal_eval import sys import numpy as np from astropy.coordinates import SkyCoord, EarthLocation Loading Loading @@ -48,6 +49,8 @@ class Noche: if debug: log.setLevel('DEBUG') log.debug(sys._getframe().f_code.co_name) self._coord = None self._location = None self._obstime = None Loading @@ -69,8 +72,11 @@ class Noche: Returns ------- list of str Names of available observatory configuration files (without .ini extension). Names of available observatory configuration files (without .ini extension). """ log.debug(sys._getframe().f_code.co_name) data_dir = Path(__file__).parent / self._obs_dir return [f.stem for f in data_dir.glob("*.ini")] Loading @@ -84,6 +90,7 @@ class Noche: path : str Configuration file in .ini format """ log.debug(sys._getframe().f_code.co_name) if not path: path = Path(__file__).parent / self._head_dir / "header_base_v1.ini" Loading Loading @@ -117,11 +124,11 @@ class Noche: name : str One of the supported observatories. """ log.debug(sys._getframe().f_code.co_name) data_dir = Path(__file__).parent / self._obs_dir ini_path = data_dir / f"{name}.ini" log.debug(ini_path) if not ini_path.exists(): msg = f"Observatory config '{ini_path}' not found." # raise FileNotFoundError(msg) Loading @@ -141,6 +148,7 @@ class Noche: path : str Configuration file in .ini format. """ log.debug(sys._getframe().f_code.co_name) config = self._load_config(path) Loading @@ -156,68 +164,105 @@ class Noche: if k in self.header: self.header[k] = val #self.header["DETSIZE"] = f'[1:{self.header["NAXIS1"]},1:{self.header["NAXIS2"]}]' if fits_file: self.fill_from_fits_file(path, fits_file) else: self._update() def fill_from_fits_file(self, path=None, fits_file=None): """ Load relevant header info from a fits file of the specific observatory. - [Mapping] section defines how the new keywords are related to the old ones. For example: FOCUSPOS = TELFOCUS - [Formula] section defines the formula to apply to a header value to match the specifics of the new one. For example: FOCUSPOS = (x)/1000 # Transforming mm in um. - [Mapping] defines how the new keywords are related to the old ones. - [Formula] defines formulas to apply *before* generating derived keywords. - [Tweak] defines formulas to apply *after* generating all keywords. Parameters ---------- path : str Configuration file in .ini format. fits_file : str FITS file position. FITS file path. """ log.debug(sys._getframe().f_code.co_name) config = self._load_config(path) filename = Path(fits_file) self.load_fits(filename) fits_file_header = self.hdu.header sections = config.sections() # Load formulas (if sections exist) pre_formulas = dict(config["Formula"]) if "Formula" in config else {} post_formulas = dict(config["Tweak"]) if "Tweak" in config else {} # Apply Mapping + PreFormula loc = config["Mapping"] for k in loc.keys(): if not (k in self.header): log.error(f"{k} not in header") continue fits_keyword = loc[k] fits_value = fits_file_header[fits_keyword] val = self._parse(fits_value) self.header[k] = val log.info(f"{k:<8} : {val}") loc = config["Formula"] for k in loc.keys(): fits_formula = loc[k] if k in pre_formulas: x = self.header[k] self.header[k] = eval(fits_formula) log.info(f"{k:<8} : from {x} to {self.header[k]}") del x try: self.header[k] = eval(pre_formulas[k]) log.warning(f"{k:<8} (Pre): from {x} to {self.header[k]}") except Exception as e: log.error(f"Failed to evaluate PreFormula for {k}: {e}") # # Apply Mapping # loc = config["Mapping"] # for k in loc.keys(): # if not (k in self.header): # log.error(f"{k} not in header") # continue # fits_keyword = loc[k] # fits_value = fits_file_header[fits_keyword] # val = self._parse(fits_value) # self.header[k] = val # log.info(f"{k:<8} : {val}") # # Apply PreFormula # for k, formula in pre_formulas.items(): # if k in self.header: # x = self.header[k] # try: # self.header[k] = eval(formula) # log.warning(f"{k:<8} (Pre): from {x} to {self.header[k]}") # except Exception as e: # log.error(f"Failed to evaluate PreFormula for {k}: {e}") # else: # log.debug(f"PreFormula skipped: {k} not in header") # Set coordinates (calls _update(), which triggers set_wcs and others) self.set_coordinates(self.header["RA"], self.header["DEC"], obstime=self.header["DATE-OBS"]) self._update() # Apply PostFormula for k, formula in post_formulas.items(): if k in self.header: x = self.header[k] try: self.header[k] = eval(formula) log.warning(f"{k:<8} (Post): from {x} to {self.header[k]}") except Exception as e: log.error(f"Failed to evaluate PostFormula for {k}: {e}") else: log.warning(f"PostFormula skipped: {k} not in header") self.header["FILEORIG"] = filename.name def set_location(self, lon, lat, alt): """ Location of the observatory, Separate so that it is Loading @@ -232,6 +277,7 @@ class Noche: alt : float Elevation in meters. """ log.debug(sys._getframe().f_code.co_name) self._location = EarthLocation(lon, lat, alt) Loading @@ -248,6 +294,7 @@ class Noche: obstime : str, astropy.time.Time Time of the observation. """ log.debug(sys._getframe().f_code.co_name) time = Time(obstime) self._obstime = time Loading @@ -259,7 +306,7 @@ class Noche: self.header['DATE-OBS'] = time.isot self.header['MJD-OBS'] = time.mjd self._update() #self._update() def set_object(self, objname, update_coord=False, obstime=None): Loading @@ -275,16 +322,17 @@ class Noche: obstime : str or astropy.time.Time, optional Observation time to associate with coordinates. """ log.debug(sys._getframe().f_code.co_name) if obstime: time = Time(obstime) self.set_obstime(time) if update_coord: try: coord = SkyCoord.from_name(objname) self._coord = coord if obstime: time = Time(obstime) self.set_obstime(time) log.info("Found catalog name") coorstr = coord.to_string(style='hmsdms', sep=' ', precision=1, pad=True) log.info(f"Corresponds to {coorstr}") Loading Loading @@ -315,6 +363,7 @@ class Noche: obstime : str or astropy.time.Time, optional Observation time. """ log.debug(sys._getframe().f_code.co_name) coord = SkyCoord(ra=ra, dec=dec, unit=(u.hourangle, u.deg)) self._coord = coord Loading @@ -325,8 +374,8 @@ class Noche: self.header['RA'] = coord.ra.to_string(unit=u.hourangle, sep=':', pad=True, precision=1) self.header['DEC'] = coord.dec.to_string(unit=u.deg, sep=':', pad=True, precision=1) self.header['DEC'] = coord.dec.to_string(unit=u.deg, sep=':', pad=True, precision=1) self.header['RA_DEG'] = coord.ra.deg self.header['DEC_DEG'] = coord.dec.deg Loading @@ -342,6 +391,7 @@ class Noche: ValueError If observation time or location is not set. """ log.debug(sys._getframe().f_code.co_name) if self._obstime == None or self._location == None: raise ValueError("Observation Time, Instrument parameters must be set.") Loading @@ -365,11 +415,11 @@ class Noche: # Position angle: with respect to Celestial North Pole north_celestial = SkyCoord(ra=0*u.deg, dec=90*u.deg, frame='icrs') posang = self._coord.position_angle(north_celestial).to(u.deg).value self.header['POSANGLE'] = round(posang, 2) posangle = self._coord.position_angle(north_celestial).to(u.deg).value self.header['POSANGLE'] = round(posangle, 2) # Parallactic angle: between local meridian and celestial axis parangle = (posang - altaz.az.deg + 360) % 360 parangle = (posangle - altaz.az.deg + 360) % 360 if parangle > 180: parangle -= 360 # Wrap to [-180, 180] Loading @@ -390,11 +440,11 @@ class Noche: ValueError If coordinates or location are not set. """ log.debug(sys._getframe().f_code.co_name) if self._coord == None or self._location == None: raise ValueError("Observation Coordinates, Instrument parameters must be set.") detsize = self.header['DETSIZE'].strip('[]') x_str, y_str = detsize.split(',') Loading @@ -407,20 +457,22 @@ class Noche: cdelt2 = round(self.header["PIXSCALE"]*self.header["YBINNING"]*u.arcsec.to(u.deg), 7) if not angle: angle = self.header["DEROTANG"] angle = self.header["DEROTANG"] + self.header["DETROT"] angle = np.deg2rad(angle) crval_ra = self._coord.ra.deg crval_dec = self._coord.dec.deg flip = -1 # East to the left self.header['CRPIX1'] = crpix[0] self.header['CRPIX2'] = crpix[1] self.header['CRVAL1'] = crval_ra self.header['CRVAL2'] = crval_dec self.header['CDELT1'] = cdelt1 self.header['CDELT1'] = cdelt1 * flip self.header['CDELT2'] = cdelt2 self.header["PC1_1"] = +np.cos(angle) *-1 # E to left self.header["PC1_1"] = +np.cos(angle) self.header["PC1_2"] = -np.sin(angle) self.header["PC2_1"] = +np.sin(angle) self.header["PC2_2"] = +np.cos(angle) Loading @@ -435,6 +487,7 @@ class Noche: ValueError If coordinates or location are not set. """ log.debug(sys._getframe().f_code.co_name) if self._coord == None or self._location == None: raise ValueError("Observation Time, Observing location must be set.") Loading Loading @@ -467,12 +520,14 @@ class Noche: """ List the header keywords that are still empty """ log.debug(sys._getframe().f_code.co_name) for k in self.header: if self.header[k] == None: print(k, self.header[k]) def load_fits(self, fits_file): log.debug(sys._getframe().f_code.co_name) filename = fits_file hdul = fits.open(filename) Loading @@ -487,6 +542,7 @@ class Noche: @staticmethod def _load_config(path): log.debug(sys._getframe().f_code.co_name) config = configparser.ConfigParser(inline_comment_prefixes=('#',)) Loading @@ -504,8 +560,10 @@ class Noche: If coordinates, observation and location are provided, then additional keywords can be filled """ log.debug(sys._getframe().f_code.co_name) if self._coord != None and self._obstime != None and self._location != None: self.set_altaz_and_parallactic() self.set_ambient() self.set_wcs() Loading @@ -525,6 +583,7 @@ class Noche: int, float, bool, or str Parsed value. """ # log.debug(sys._getframe().f_code.co_name) try: val = val.strip() Loading
noche/observatories/abobservatory.ini +5 −2 Original line number Diff line number Diff line Loading @@ -5,14 +5,14 @@ FOCALLEN = 1170 # [mm] Telescope focal length OBS-LONG = -11.2430135 # [deg] Observatory longitude (East > 0) OBS-LAT = 43.5235203 # [deg] Observatory latitude (North > 0) OBS-ELEV = 1025 # [m] Observatory altitude above sea level DEROTANG = 0 # [deg] Rotator angle, if any INSTRUME = ABOb instrument # Instrument name OBSTYPE = Imaging # Observation type DETECTOR = Atik 383 L # Detector identifier DETSIZE = [1:3354,1:2529] # [px] [1:x,1:y] Physical CCD dimensions DETROT = -89.67 # [deg] Rotation offset of the detector XPIXSZ = 5.4 # [um] Pixel X axis size YPIXSZ = 5.4 # [um] Pixel Y axis size PIXSCALE = 36 # [arcsec/px] Plate scale in binning 1 PIXSCALE = 1.0 # [arcsec/px] Plate scale in binning 1 GAIN = # [e-/ADU] Gain RDNOISE = # [e- RMS] Readout noise Loading @@ -38,3 +38,6 @@ SWCREATE = SWCREATE # Software that created FILEORIG [Formula] [Tweak] CDELT2 = -1*x
noche/observatories/grt.ini +6 −1 Original line number Diff line number Diff line Loading @@ -5,11 +5,11 @@ FOCALLEN = 1520 # [mm] Telescope focal length OBS-LONG = 14.020563 # [deg] Observatory longitude (East > 0) OBS-LAT = 37.9391183 # [deg] Observatory latitude (North > 0) OBS-ELEV = 606 # [m] Observatory altitude above sea level DEROTANG = 0 # [deg] Rotator angle, if any INSTRUME = GRT instrument # Instrument name OBSTYPE = Imaging # Observation type DETECTOR = Moravian CMOS C4-16000 # Detector identifier DETSIZE = [1:4096,1:4096] # [px] [1:x,1:y] Physical CCD dimensions DETROT = +5.0 # [deg] Rotation offset of the detector XPIXSZ = 9 # [um] Pixel X axis size YPIXSZ = 9 # [um] Pixel Y axis size PIXSCALE = 1.22 # [arcsec/px] Plate scale in binning 1 Loading Loading @@ -37,3 +37,8 @@ YBINNING = YBINNING # Binning factor in Y SWCREATE = SWCREATE # Software that created FILEORIG [Formula] [Tweak] CDELT2 = -1*x CRPIX1 = x+134 CRPIX2 = x-500
noche/observatories/oarpaf.ini +6 −2 Original line number Diff line number Diff line Loading @@ -5,11 +5,11 @@ FOCALLEN = 6400 # [mm] Telescope focal length OBS-LONG = 9.2034 # [deg] Observatory longitude (East > 0) OBS-LAT = 44.5912 # [deg] Observatory latitude (North > 0) OBS-ELEV = 1469 # [m] Observatory altitude above sea level DEROTANG = -89.67 # [deg] Rotator angle, if any INSTRUME = Cerbero # Instrument name OBSTYPE = Imaging # Observation type DETECTOR = SBIG STX-16081 # Detector identifier DETSIZE = [1:4144,1:4126] # [px] [1:x,1:y] Physical CCD dimensions DETROT = -89.67 # [deg] Rotation offset of the detector XPIXSZ = 9 # [um] Pixel X axis size YPIXSZ = 9 # [um] Pixel Y axis size PIXSCALE = 0.283 # [arcsec/px] Plate scale in binning 1 Loading Loading @@ -37,4 +37,8 @@ TEMPERAT = HIERARCH CAM AMBIENT # [C] Ambient temperature SWCREATE = SWCREATE # Software that created FILEORIG [Formula] RA = (x)/15 RA = x/15 [Tweak] CRPIX1 = x+234 CRPIX2 = x-100