diff --git a/README.md b/README.md index e40cd7d..da280d5 100644 --- a/README.md +++ b/README.md @@ -3,12 +3,14 @@ Galaxy Surveys cheatsheet [![Python package][gh-workflow-badge]][gh-workflow] [![License][license-badge]](LICENSE) +![Python supported versions][pyversion-badge] [![PyPI][pypi-badge]][pypi] [gh-workflow]: https://github.com/aboucaud/galcheat/actions/workflows/python-package.yml [gh-workflow-badge]: https://github.com/aboucaud/galcheat/actions/workflows/python-package.yml/badge.svg [license-badge]: https://img.shields.io/github/license/aboucaud/galcheat?color=blue -[pypi-badge]: https://img.shields.io/pypi/pyversions/galcheat?color=yellow&logo=pypi +[pyversion-badge]: https://img.shields.io/pypi/pyversions/galcheat?color=yellow&logo=pypi +[pypi-badge]: https://badge.fury.io/py/galcheat.svg [pypi]: https://pypi.org/project/galcheat/ @@ -43,9 +45,14 @@ from galcheat import available_surveys from galcheat import get_survey, get_filter Rubin = get_survey("Rubin") -u_band = get_filter("u", Rubin) +u_band = get_filter("u", "Rubin") +# which is a proxy for +u_band = Rubin.get_filter("u") -# Get a dictionary of all available filters +# Get the list of available filters +Rubin.available_filters + +# or as a dictionary with all `Filter` objects Rubin.get_filters() # Both Survey and Filter classes have physical attributes diff --git a/galcheat/__init__.py b/galcheat/__init__.py index 490478f..77fdae5 100644 --- a/galcheat/__init__.py +++ b/galcheat/__init__.py @@ -21,18 +21,27 @@ >>> Rubin.mirror_diameter -Each `Survey` contains its own `Filter` list -accessible from the `Survey` +Each `Survey` contains a list of filters +whose names can be obtained as + + >>> Rubin.available_filters + +Each `Filter` class is then accessible either +as an attribute from the `Survey` >>> u_filter = Rubin.filters.u -or as a dictionary +or through a method + + >>> u_filter = Rubin.get_filter('u') - >>> filters = Rubin.get_filters() - >>> u_filter = filters['u'] +For a given survey, a dictionary of the available +filters is returned by -And parameter values can be converted to any -physical units using the `astropy.units` scheme + >>> Rubin.get_filters() + +Parameter values can be converted to any physical +units using the `astropy.units` scheme >>> u_filter.psf_fwhm @@ -55,56 +64,11 @@ from galcheat.survey import Survey +__all__ = ["available_surveys", "get_filter", "get_survey"] + _BASEDIR = Path(__file__).parent.resolve() _survey_info = { path.stem: Survey.from_yaml(path) for path in _BASEDIR.glob("data/*.yaml") } -available_surveys = list(_survey_info.keys()) - - -def get_survey(survey_name: str): - """Get the dataclass corresponding to the survey - - Raises - ------ - ValueError: when the input survey is not (currently) available - - """ - if survey_name not in available_surveys: - raise ValueError( - "Please check the survey name. " - f"The available surveys are {available_surveys}" - ) - - return _survey_info[survey_name] - - -def get_filter(filter_name: str, survey: Survey): - """ - Parameters - ---------- - filter_name: str - Name of a filter - - - Returns - ------- - a filter dataclass - - Raises - ------ - ValueError: when the input filter is not available - - """ - filter_dict = survey.get_filters() - available_filters = list(filter_dict.keys()) - - if filter_name not in available_filters: - raise ValueError( - "Please check the filter name. " - f"The available filters for {survey.name} " - f"are {available_filters}" - ) - - return filter_dict[filter_name] +from galcheat.helpers import available_surveys, get_filter, get_survey # noqa diff --git a/galcheat/__main__.py b/galcheat/__main__.py index e399c86..f57d9be 100644 --- a/galcheat/__main__.py +++ b/galcheat/__main__.py @@ -1,4 +1,4 @@ -from galcheat import available_surveys, get_survey +from galcheat.helpers import available_surveys, get_survey def main(): diff --git a/galcheat/helpers.py b/galcheat/helpers.py new file mode 100644 index 0000000..7c4a73b --- /dev/null +++ b/galcheat/helpers.py @@ -0,0 +1,55 @@ +from galcheat import _survey_info +from galcheat.filter import Filter +from galcheat.survey import Survey + +available_surveys = list(_survey_info.keys()) + + +def get_survey(survey_name: str) -> Survey: + """Get the dataclass corresponding to the survey + + Parameters + ---------- + survey_name: str + Name of a survey among the `available_surveys` + + Returns + ------- + a Survey dataclass + + Raises + ------ + ValueError: when the input survey is not (currently) available + + """ + if survey_name not in available_surveys: + raise ValueError( + "Please check the survey name. " + f"The available surveys are {available_surveys}" + ) + + return _survey_info[survey_name] + + +def get_filter(filter_name: str, survey_name: str) -> Filter: + """Get the filter class from the corresponding survey + + Parameters + ---------- + filter_name: str + Name of a filter belonging to `survey_name` + survey_name: str + Name of a survey among the `available_surveys` + + Returns + ------- + a Filter dataclass + + Raises + ------ + ValueError: when the survey or filter is not available + + """ + survey = get_survey(survey_name) + + return survey.get_filter(filter_name) diff --git a/galcheat/survey.py b/galcheat/survey.py index 2720912..a3e6c8f 100644 --- a/galcheat/survey.py +++ b/galcheat/survey.py @@ -1,5 +1,5 @@ -from dataclasses import dataclass, make_dataclass -from typing import Any, Optional +from dataclasses import dataclass, field, make_dataclass +from typing import Any, List, Optional import astropy.units as u import yaml @@ -17,6 +17,7 @@ class Survey: mirror_diameter: Quantity airmass: Optional[Quantity] = None zeropoint_airmass: Optional[Quantity] = None + available_filters: List[str] = field(init=False) @classmethod def from_yaml(cls, yaml_file): @@ -69,7 +70,7 @@ def _construct_filter_list(survey_dict): Returns ------- - Dynamically created dataclass whose attributes are the survey filter + Dynamically created dataclass whose attributes are the survey filters """ filter_data = { @@ -81,13 +82,27 @@ def _construct_filter_list(survey_dict): [(filter_name, Filter) for filter_name in filter_data.keys()], namespace={ "__repr__": lambda self: "(" - + ",".join([filt for filt in self.__dict__.keys()]) + + ", ".join([filt for filt in self.__dict__.keys()]) + ")" }, ) return FList(**filter_data) + def __post_init__(self): + self.available_filters = list(self.filters.__dict__.keys()) + def get_filters(self): """Getter method to retrieve the filters as a dictionary""" return self.filters.__dict__ + + def get_filter(self, filter_name): + """Getter method to retrieve a Filter object""" + if filter_name not in self.available_filters: + raise ValueError( + "Please check the filter name. " + f"The available filters for {self.name} " + f"are {self.available_filters}" + ) + + return self.filters.__dict__[filter_name] diff --git a/setup.py b/setup.py index b7d9396..a29bfd3 100644 --- a/setup.py +++ b/setup.py @@ -4,7 +4,7 @@ setup( name="galcheat", - version="0.1.1", + version="0.1.2", url="https://github.com/aboucaud/galcheat/", description="Tiny library of galaxy surveys most useful parameters (with units)", long_description=open("README.md").read(),