Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,7 @@ config.log
tests/.tests/
*__pycache__/
_build.*
*.pickle
*.ecsv
*cache/*

11 changes: 11 additions & 0 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from setuptools import setup
import os
import shutil
import re

reqs = []
Expand All @@ -14,6 +15,16 @@
with open('README.md') as file:
long_description = file.read()

try:
import astropy
astropy_cache_dir = astropy.config.get_cache_dir()
except ImportError:
astropy_cache_dir = os.path.join(f"{os.path.expanduser('~')}", ".astropy", "cache")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sorry. When I said "copy the file to the cache in setup" I meant in the test code just before the test runs. Not having setup.py copy the file -- For tests with unittest there is a setUp method that is called that can do things that the tests need. I'm not sure what the equivalent would be for your tests since you aren't using unittest. I didn't even realize you were using the deprecated setup.py to build the package. There is no guarantee that when test code runs that that cache file written during package installation would still exist.

PS I saw recently that Astropy cache tooling does allow you to name the cache directory so you can call it "spectractor", just like astroquery calls it "astroquery".

os.makedirs(os.path.join(astropy_cache_dir, "astroquery", "Simbad"), exist_ok=True)
shutil.copytree("./tests/data/cache/astropy/astroquery/Simbad",
os.path.join(astropy_cache_dir, "astroquery", "Simbad"),
dirs_exist_ok=True)

# cf. http://stackoverflow.com/questions/458550/standard-way-to-embed-version-into-python-package
version_file = os.path.join('spectractor', '_version.py')
verstrline = open(version_file, "rt").read()
Expand Down
75 changes: 53 additions & 22 deletions spectractor/extractor/targets.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@
import astropy.units as u
from astropy.time import Time
from astroquery.simbad import SimbadClass
from astropy.io import ascii
import astropy.config

import matplotlib.pyplot as plt
from scipy.interpolate import interp1d
import numpy as np
import os
import shutil

from spectractor import parameters
from spectractor.config import set_logger
Expand All @@ -24,6 +28,22 @@
_USE_NEW_SIMBAD = True


def _get_cache_dir():
cache = os.path.join(astropy.config.get_cache_dir(), "astroquery", "Simbad")
os.makedirs(cache, exist_ok=True)
return cache


def _get_cache_file(tag):
filename = tag.replace("*", "").replace(" ", "_").replace(".", "_")
return filename


def _clean_cache_dir():
cache = _get_cache_dir()
shutil.rmtree(cache)


def load_target(label, verbose=False):
"""Load the target properties according to the type set by parameters.OBS_OBJECT_TYPE.

Expand Down Expand Up @@ -265,33 +285,44 @@ def load(self):
# ``Simbad...`` methods secretly makes an instance, which stays around,
# has a connection go stale, and then raises an exception seemingly
# at some random time later
simbadQuerier = SimbadClass()
patchSimbadURL(simbadQuerier)
if not getCalspec.is_calspec(self.label) and getCalspec.is_calspec(self.label.replace(".", " ")):
self.label = self.label.replace(".", " ")
astroquery_label = self.label
if getCalspec.is_calspec(self.label):
calspec = getCalspec.Calspec(self.label)
astroquery_label = calspec.Astroquery_Name

cache_location = _get_cache_dir()
cache_file = _get_cache_file(astroquery_label)
if os.path.exists(os.path.join(cache_location, f"{cache_file}.ecsv")):
self.my_logger.debug(f"\n\tLoad {self.label} coordinates from cached file {cache_file}.ecsv")
self.simbad_table = ascii.read(os.path.join(cache_location, f"{cache_file}.ecsv"))
else:
simbadQuerier = SimbadClass()
patchSimbadURL(simbadQuerier)

if _USE_NEW_SIMBAD:
simbadQuerier.add_votable_fields('U', 'B', 'V', 'R', 'I', 'J', 'sp_type',
'parallax', 'propermotions', 'rvz_redshift')
if _USE_NEW_SIMBAD:
simbadQuerier.add_votable_fields('U', 'B', 'V', 'R', 'I', 'J', 'sp_type',
'parallax', 'propermotions', 'rvz_redshift')
else:
simbadQuerier.add_votable_fields(
'flux(U)', 'flux(B)', 'flux(V)', 'flux(R)', 'flux(I)', 'flux(J)', 'sptype',
'parallax', 'pm', 'z_value'
)
self.my_logger.debug(f"\n\tDownload {self.label} coordinates from Simbad...")
self.simbad_table = simbadQuerier.query_object(astroquery_label)
self.simbad_table.write(os.path.join(cache_location,f"{cache_file}.ecsv"), overwrite=True)

if "ra" in self.simbad_table.keys():
ra_key = "ra"
dec_key = "dec"
redshift_key = "rvz_redshift"
else:
simbadQuerier.add_votable_fields(
'flux(U)', 'flux(B)', 'flux(V)', 'flux(R)', 'flux(I)', 'flux(J)', 'sptype',
'parallax', 'pm', 'z_value'
)
ra_key = "RA"
dec_key = "DEC"
redshift_key = "Z_VALUE"
if not getCalspec.is_calspec(self.label) and getCalspec.is_calspec(self.label.replace(".", " ")):
self.label = self.label.replace(".", " ")
astroquery_label = self.label
if getCalspec.is_calspec(self.label):
calspec = getCalspec.Calspec(self.label)
astroquery_label = calspec.Astroquery_Name
self.simbad_table = simbadQuerier.query_object(astroquery_label)

if self.simbad_table is not None:
if self.verbose or True:
if self.verbose:
self.my_logger.info(f'\n\tSimbad:\n{self.simbad_table}')
if _USE_NEW_SIMBAD:
self.radec_position = SkyCoord(self.simbad_table[ra_key][0], self.simbad_table[dec_key][0], unit="deg")
Expand All @@ -301,11 +332,11 @@ def load(self):
)
else:
raise RuntimeError(f"Target {self.label} not found in Simbad")
self.get_radec_position_after_pm(date_obs="J2000")
if not np.ma.is_masked(self.simbad_table[redshift_key]):
self.redshift = float(self.simbad_table[redshift_key])
if not np.ma.is_masked(self.simbad_table[redshift_key][0]):
self.redshift = float(self.simbad_table[redshift_key][0])
else:
self.redshift = 0
self.get_radec_position_after_pm(date_obs="J2000")
self.load_spectra()

def load_spectra(self):
Expand Down Expand Up @@ -405,7 +436,7 @@ def load_spectra(self):

def get_radec_position_after_pm(self, date_obs):
if self.simbad_table is not None:
if _USE_NEW_SIMBAD:
if "pmra" in self.simbad_table[0].keys():
pmra_key = 'pmra'
pmdec_key = 'pmdec'
plx_value_key = 'plx_value'
Expand Down
242 changes: 242 additions & 0 deletions tests/data/cache/astropy/astroquery/Simbad/HD_111980.ecsv
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
# %ECSV 1.0
# ---
# datatype:
# - name: MAIN_ID
# datatype: string
# description: Main identifier for an object
# meta: !!omap
# - {ucd: meta.id;meta.main}
# - {width: 22}
# - links:
# - {href: 'http://simbad.u-strasbg.fr/simbad/sim-id?Ident=${MAIN_ID}&NbIdent=1', value: '${MAIN_ID}'}
# - {_votable_string_dtype: char}
# subtype: json
# - name: RA
# unit: '"h:m:s"'
# datatype: string
# description: Right ascension
# meta: !!omap
# - {ucd: pos.eq.ra;meta.main}
# - {width: 13}
# - {precision: '8'}
# - {_votable_string_dtype: char}
# - name: DEC
# unit: '"d:m:s"'
# datatype: string
# description: Declination
# meta: !!omap
# - {ucd: pos.eq.dec;meta.main}
# - {width: 13}
# - {precision: '8'}
# - {_votable_string_dtype: char}
# - name: RA_PREC
# datatype: int16
# description: Right ascension precision
# meta: !!omap
# - {width: 2}
# - name: DEC_PREC
# datatype: int16
# description: Declination precision
# meta: !!omap
# - {width: 2}
# - name: COO_ERR_MAJA
# unit: mas
# datatype: float32
# format: '{:6.3f}'
# description: Coordinate error major axis
# meta: !!omap
# - {ucd: phys.angSize.smajAxis;pos.errorEllipse;pos.eq}
# - {width: 6}
# - {precision: '3'}
# - name: COO_ERR_MINA
# unit: mas
# datatype: float32
# format: '{:6.3f}'
# description: Coordinate error minor axis
# meta: !!omap
# - {ucd: phys.angSize.sminAxis;pos.errorEllipse;pos.eq}
# - {width: 6}
# - {precision: '3'}
# - name: COO_ERR_ANGLE
# unit: deg
# datatype: int16
# description: Coordinate error angle
# meta: !!omap
# - {ucd: pos.posAng;pos.errorEllipse;pos.eq}
# - {width: 3}
# - name: COO_QUAL
# datatype: string
# description: Coordinate quality
# meta: !!omap
# - {ucd: meta.code.qual;pos.eq}
# - {width: 1}
# - {_votable_string_dtype: char}
# - name: COO_WAVELENGTH
# datatype: string
# description: Wavelength class for the origin of the coordinates (R,I,V,U,X,G)
# meta: !!omap
# - {ucd: instr.bandpass;pos.eq}
# - {width: 1}
# - {_votable_string_dtype: char}
# - name: COO_BIBCODE
# datatype: string
# description: Coordinate reference
# meta: !!omap
# - {ucd: meta.bib.bibcode;pos.eq}
# - {width: 19}
# - {_votable_string_dtype: char}
# subtype: json
# - name: FLUX_U
# unit: mag
# datatype: float32
# description: Magnitude U
# meta: !!omap
# - {ucd: phot.mag;em.opt.U}
# - name: FLUX_B
# unit: mag
# datatype: float32
# description: Magnitude B
# meta: !!omap
# - {ucd: phot.mag;em.opt.B}
# - name: FLUX_V
# unit: mag
# datatype: float32
# description: Magnitude V
# meta: !!omap
# - {ucd: phot.mag;em.opt.V}
# - name: FLUX_R
# unit: mag
# datatype: float32
# description: Magnitude R
# meta: !!omap
# - {ucd: phot.mag;em.opt.R}
# - name: FLUX_I
# unit: mag
# datatype: float32
# description: Magnitude I
# meta: !!omap
# - {ucd: phot.mag;em.opt.I}
# - name: FLUX_J
# unit: mag
# datatype: float32
# description: Magnitude J
# meta: !!omap
# - {ucd: phot.mag;em.IR.J}
# - name: SP_TYPE
# datatype: string
# description: MK spectral type
# meta: !!omap
# - {ucd: src.spType}
# - {width: 6}
# - {_votable_string_dtype: char}
# subtype: json
# - name: SP_QUAL
# datatype: string
# description: Spectral type quality
# meta: !!omap
# - {ucd: meta.code.qual;src.spType}
# - {width: 1}
# - {_votable_string_dtype: char}
# - name: SP_BIBCODE
# datatype: string
# description: spectral type reference
# meta: !!omap
# - {ucd: meta.bib.bibcode;src.spType}
# - {width: 19}
# - {_votable_string_dtype: char}
# subtype: json
# - name: PLX_VALUE
# unit: mas
# datatype: float64
# format: '{:9.3f}'
# description: Parallax
# meta: !!omap
# - {ucd: pos.parallax.trig}
# - {width: 9}
# - {precision: '3'}
# - name: PLX_PREC
# datatype: int16
# description: Parallax precision
# meta: !!omap
# - {width: 1}
# - name: PLX_ERROR
# unit: mas
# datatype: float32
# description: Parallax error
# meta: !!omap
# - {ucd: stat.error;pos.parallax.trig}
# - name: PLX_QUAL
# datatype: string
# description: Parallax quality
# meta: !!omap
# - {ucd: meta.code.qual;pos.parallax.trig}
# - {width: 1}
# - {_votable_string_dtype: char}
# - name: PLX_BIBCODE
# datatype: string
# description: Parallax reference
# meta: !!omap
# - {ucd: meta.bib.bibcode;pos.parallax.trig}
# - {width: 19}
# - {_votable_string_dtype: char}
# subtype: json
# - name: PMRA
# unit: mas / yr
# datatype: float64
# format: '{:9.3f}'
# description: Proper motion in RA
# meta: !!omap
# - {ucd: pos.pm;pos.eq.ra}
# - {width: 9}
# - {precision: '3'}
# - name: PMDEC
# unit: mas / yr
# datatype: float64
# format: '{:9.3f}'
# description: Proper motion in DEC
# meta: !!omap
# - {ucd: pos.pm;pos.eq.dec}
# - {width: 9}
# - {precision: '3'}
# - name: PM_ERR_MAJA
# unit: mas / yr
# datatype: float32
# format: '{:5.3f}'
# description: Proper motion error major axis
# meta: !!omap
# - {ucd: phys.angSize.smajAxis;pos.errorEllipse;pos.pm}
# - {width: 5}
# - {precision: '3'}
# - name: PM_ERR_MINA
# unit: mas / yr
# datatype: float32
# format: '{:5.3f}'
# description: Proper motion error minor axis
# meta: !!omap
# - {ucd: phys.angSize.sminAxis;pos.errorEllipse;pos.pm}
# - {width: 5}
# - {precision: '3'}
# - name: PM_ERR_ANGLE
# unit: deg
# datatype: int16
# description: Proper motion error angle
# meta: !!omap
# - {ucd: pos.posAng;pos.errorEllipse;pos.pm}
# - {width: 3}
# - name: Z_VALUE
# datatype: float64
# format: '{:.7f}'
# description: Redshift
# meta: !!omap
# - {ucd: src.redshift}
# - {precision: '7'}
# - name: SCRIPT_NUMBER_ID
# datatype: int32
# meta: !!omap
# - {ucd: meta.number}
# - {width: 2}
# - {precision: '1'}
# meta: {ID: SimbadScript, description: 'Simbad script executed on 2025.03.13CET16:08:13', name: default}
# schema: astropy-2.0
MAIN_ID RA DEC RA_PREC DEC_PREC COO_ERR_MAJA COO_ERR_MINA COO_ERR_ANGLE COO_QUAL COO_WAVELENGTH COO_BIBCODE FLUX_U FLUX_B FLUX_V FLUX_R FLUX_I FLUX_J SP_TYPE SP_QUAL SP_BIBCODE PLX_VALUE PLX_PREC PLX_ERROR PLX_QUAL PLX_BIBCODE PMRA PMDEC PM_ERR_MAJA PM_ERR_MINA PM_ERR_ANGLE Z_VALUE SCRIPT_NUMBER_ID
"""HD 111980""" "12 53 15.0529" "-18 31 20.013" 14 14 0.0225 0.0183 90 A O """2020yCat.1350....0G""" 8.8 8.91 8.38 "" "" 7.176 """F7V""" C """1988MSS...C04....0H""" 12.9277 4 0.0261 A """2020yCat.1350....0G""" 299.359 -795.843 0.032 0.026 90 0.000517 1
Loading