Skip to content

Commit

Permalink
improved standard star names and sources resolution.
Browse files Browse the repository at this point in the history
  • Loading branch information
cylammarco committed Apr 25, 2023
1 parent cb55004 commit f1c67be
Showing 1 changed file with 81 additions and 43 deletions.
124 changes: 81 additions & 43 deletions src/aspired/flux_calibration.py
Expand Up @@ -129,6 +129,10 @@ def __init__(
self.ftype = "flux"
self.cutoff = 0.4

self.designation_to_filename = None
self.lib_to_filename = None
self.filename_to_lib = None

self.spectrum_oned_imported = False

self._load_standard_dictionary()
Expand All @@ -139,6 +143,14 @@ def _load_standard_dictionary(self):
"""

self.designation_to_filename = json.load(
open(
pkg_resources.resource_filename(
"aspired", "standards/designation_to_filename.json"
),
encoding="ascii",
)
)
self.lib_to_filename = json.load(
open(
pkg_resources.resource_filename(
Expand All @@ -156,6 +168,10 @@ def _load_standard_dictionary(self):
)
)

self.designation_list = self.designation_to_filename.keys()
self.lib_list = self.lib_to_filename.keys()
self.filename_list = self.filename_to_lib.keys()

def _get_eso_standard(self):
"""
Formatter for reading the ESO standards.
Expand Down Expand Up @@ -312,79 +328,103 @@ def lookup_standard_libraries(self, target: str, cutoff: float = 0.4):
https://docs.python.org/3.7/library/difflib.html
This method tries to match the designation of the standard star
that is available on SIMBAD or as named by the Isaac Newton Group of
Telescopes. All comparisons are performed in lower case, all space
and special symbols (expect ".", "+", "-", "_") are stripped.
Parameters
----------
target: str
Name of the standard star
Name/designation of the standard star
cutoff: float (Default: 0.4)
The similarity toleranceold
[0 (completely different) - 1 (identical)]
"""

# Load the list of targets in the requested library
# Only works in case of exact match
try:
libraries = self.filename_to_lib[target.lower()]
return libraries, True
library_list = []
filename_list = []

if not isinstance(target, str):
error_msg = f"Target name has to be of type str, {type(target)} is provided."
self.logger.critical(error_msg)

except Exception as _warn:
self.logger.warning(str(_warn))
# If the provided designation exists
if target.lower() in self.designation_list:
_filename_list = self.designation_to_filename[target.lower()]

exact_match = True

else:
# If the requested target is not in any library, suggest the
# closest match, Top 5 are returned.
# difflib uses Gestalt pattern matching.
target_list = difflib.get_close_matches(
designation_list = difflib.get_close_matches(
target.lower(),
list(self.filename_to_lib.keys()),
list(self.designation_to_filename.keys()),
n=5,
cutoff=cutoff,
)

if len(target_list) > 0:
self.logger.warning(
f"Requested standard star cannot be found, a list of"
f" the closest matching names are returned:"
f" {{target_list}}."
)
for designation in designation_list:
_filename_list = self.designation_to_filename[designation]

return target_list, False
exact_match = False

else:
error_msg = (
(
"Please check the name of your standard star, nothing "
f"share a similarity above {cutoff}."
),
)
self.logger.critical(error_msg)
raise ValueError(error_msg)
for filename in _filename_list:
_library_list = self.filename_to_lib[filename]
for l in _library_list:
filename_list.append(filename)
library_list.append(l)

if len(filename_list) > 0:
self.logger.warning(
f"Requested standard star cannot be found, a list of"
f" the closest matching names are returned:"
f" {filename_list}."
)
else:
error_msg = (
(
"Please check the name of your standard star, nothing "
f"share a similarity above {cutoff}."
),
)
self.logger.critical(error_msg)
raise ValueError(error_msg)

return [
(f, l) for l, f in zip(library_list, filename_list)
], exact_match

def lookup_closet_match_in_library(self, target: str, library: str):
def lookup_closet_match_in_library(
self, target: str, library: str, cutoff: float = 0.2
):
"""
Check if the requested standard and library exist. Only if the
similarity is better than 0.5 a target name will be returned. See
similarity is better than (by default) 0.2 a target name will be returned. See
https://docs.python.org/3.7/library/difflib.html
https://docs.python.org/3.11/library/difflib.html
Parameters
----------
target: str
Name of the standard star
library: str
Name of the library
cutoff: float (Default: 0.4)
The toleranceold for the word similarity in the range of [0, 1].
Return:
-------
The closest names to the target in that (closet) library.
"""

# Load the list of targets in the requested library
# Load the list of libraries
library_name = difflib.get_close_matches(
library,
list(self.lib_to_filename.keys()),
n=1,
library, list(self.lib_to_filename.keys()), n=1, cutoff=cutoff
)

if library_name == []:
Expand All @@ -395,7 +435,10 @@ def lookup_closet_match_in_library(self, target: str, library: str):

# difflib uses Gestalt pattern matching.
target_name = difflib.get_close_matches(
target.lower(), self.lib_to_filename[library_name], n=1, cutoff=0.3
target.lower(),
self.lib_to_filename[library_name],
n=1,
cutoff=cutoff,
)
if target_name == []:
target_name = None
Expand Down Expand Up @@ -439,7 +482,7 @@ def load_standard(

# If there is a close match from the user-provided library, use
# that first, it will only accept the library and target if the
# similarity is above 0.5
# cutoff is above 0.4
self.library = library
if self.library is not None:
(
Expand All @@ -456,12 +499,9 @@ def load_standard(
libraries, success = self.lookup_standard_libraries(self.target)

if success:
if np.in1d([library], libraries):
self.library = library

else:
self.library = libraries[0]
self.target, self.library = libraries[0]

if not np.in1d([library], libraries):
self.logger.warning(
"The requested standard star cannot be found in the"
" given library, or the library is not specified."
Expand All @@ -470,9 +510,7 @@ def load_standard(

else:
# When success is Flase, the libraries is a list of standards
self.target = libraries[0]
libraries, _ = self.lookup_standard_libraries(self.target)
self.library = libraries[0]
self.target, self.library = libraries[0]

self.logger.warning(
f"The requested library does not exist, {self.library} "
Expand Down

0 comments on commit f1c67be

Please sign in to comment.