diff --git a/application.yaml b/application.yaml deleted file mode 100644 index 08a1319..0000000 --- a/application.yaml +++ /dev/null @@ -1 +0,0 @@ -class: pyobs_cloudcover.application.Application \ No newline at end of file diff --git a/example.yaml b/example.yaml new file mode 100644 index 0000000..16b59bf --- /dev/null +++ b/example.yaml @@ -0,0 +1,36 @@ +class: pyobs_cloudcover.application.Application + +model: + class: pyobs_cloudcover.world_model.SimpleModel + args: [4.81426598e-03, 2.00000000e+00, 1.06352627e+03, 7.57115607e+02, 5.11194838e+02] + +pipelines: + night: + alt_interval: + start: None + end: -18 + + options: + preprocessor: + mask_filepath: "" + bin_size: 2 + bkg_sigma_clip: 3.0 + bkg_box_size: (5, 5) + + catalog: + filepath: "" + filter: + alt: 30.0 + v_mag: 7.0 + distance: 0.0 + + reverse_matcher: + sigma_threshold: 3.0 + window_size: 6.0 + + cloud_map: + radius: 50.0 + + coverage_info: + cloud_threshold: 0.5 + zenith_radius: 20 diff --git a/pyobs_cloudcover/application_factory.py b/pyobs_cloudcover/application_factory.py new file mode 100644 index 0000000..0ce3e3f --- /dev/null +++ b/pyobs_cloudcover/application_factory.py @@ -0,0 +1,6 @@ + + +class ApplicationFactory(object): + def __init__(self) -> None: + ... + diff --git a/pyobs_cloudcover/pipeline/night/catalog/catalog_constructor_factory.py b/pyobs_cloudcover/pipeline/night/catalog/catalog_constructor_factory.py new file mode 100644 index 0000000..f9ceb3e --- /dev/null +++ b/pyobs_cloudcover/pipeline/night/catalog/catalog_constructor_factory.py @@ -0,0 +1,22 @@ +from astroplan import Observer + +from pyobs_cloudcover.pipeline.night.catalog.altaz_catalog_loader import AltAzCatalogLoader +from pyobs_cloudcover.pipeline.night.catalog.catalog_constructor import CatalogConstructor +from pyobs_cloudcover.pipeline.night.catalog.catalog_constructor_options import CatalogConstructorOptions +from pyobs_cloudcover.world_model import WorldModel + + +class CatalogConstructorFactory(object): + def __init__(self, options: CatalogConstructorOptions, model: WorldModel, observer: Observer) -> None: + self._options = options + self._model = model + self._observer = observer + + def __call__(self) -> CatalogConstructor: + altaz_catalog_loader = AltAzCatalogLoader.from_csv(self._options.filepath) + catalog_constructor = CatalogConstructor( + altaz_catalog_loader, self._model, self._observer, + self._options.alt_filter, self._options.v_mag_filter, self._options.distance_filter + ) + + return catalog_constructor diff --git a/pyobs_cloudcover/pipeline/night/catalog/catalog_constructor_options.py b/pyobs_cloudcover/pipeline/night/catalog/catalog_constructor_options.py new file mode 100644 index 0000000..4b342d5 --- /dev/null +++ b/pyobs_cloudcover/pipeline/night/catalog/catalog_constructor_options.py @@ -0,0 +1,32 @@ +from __future__ import annotations +from typing import Dict, Any, Optional + + +class CatalogConstructorOptions(object): + def __init__(self, filepath: str, alt_filter: float = 20.0, v_mag_filter: float = 7.5, distance_filter: float = 0.0) -> None: + self.filepath = filepath + self.alt_filter = alt_filter + self.v_mag_filter = v_mag_filter + self.distance_filter = distance_filter + + @classmethod + def from_dict(cls, options: Dict[str, Any]) -> CatalogConstructorOptions: + filepath: str = str(options["filepath"]) + + if "filter" not in options: + return cls(filepath) + + filter_options: Dict[str, Any] = options["filter"] + + filter_kwargs: Dict[str, float] = {} + + if "alt" in filter_options: + filter_kwargs["alt_filter"] = filter_options["alt"] + + if "v_mag" in filter_options: + filter_kwargs["v_mag_filter"] = filter_options["v_mag"] + + if "distance" in filter_options: + filter_kwargs["distance_filter"] = filter_options["distance"] + + return cls(filepath, **filter_kwargs) diff --git a/pyobs_cloudcover/pipeline/night/cloud_coverage_calculator/cloud_info_calculator_factory.py b/pyobs_cloudcover/pipeline/night/cloud_coverage_calculator/cloud_info_calculator_factory.py new file mode 100644 index 0000000..5bd1109 --- /dev/null +++ b/pyobs_cloudcover/pipeline/night/cloud_coverage_calculator/cloud_info_calculator_factory.py @@ -0,0 +1,23 @@ +from pyobs_cloudcover.pipeline.night.cloud_coverage_calculator.cloud_info_calculator_options import \ + CloudInfoCalculatorOptions +from pyobs_cloudcover.pipeline.night.cloud_coverage_calculator.coverage_calculator import CoverageCalculator +from pyobs_cloudcover.pipeline.night.cloud_coverage_calculator.coverage_change_calculator import \ + CoverageChangeCalculator +from pyobs_cloudcover.pipeline.night.cloud_coverage_calculator.coverage_info_calculator import CoverageInfoCalculator +from pyobs_cloudcover.pipeline.night.cloud_coverage_calculator.zenith_masker import ZenithMasker +from pyobs_cloudcover.world_model import WorldModel + + +class CloudInfoCalculatorFactory(object): + def __init__(self, options: CloudInfoCalculatorOptions, model: WorldModel): + self._options = options + self._model = model + + def __call__(self) -> CoverageInfoCalculator: + coverage_calculator = CoverageCalculator(self._options.cloud_threshold) + coverage_change_calculator = CoverageChangeCalculator() + zenith_masker = ZenithMasker(self._options.altitude_limit, self._model) + cloud_coverage_info_calculator = CoverageInfoCalculator(coverage_calculator, coverage_change_calculator, + zenith_masker) + + return cloud_coverage_info_calculator diff --git a/pyobs_cloudcover/pipeline/night/cloud_coverage_calculator/cloud_info_calculator_options.py b/pyobs_cloudcover/pipeline/night/cloud_coverage_calculator/cloud_info_calculator_options.py new file mode 100644 index 0000000..958a64d --- /dev/null +++ b/pyobs_cloudcover/pipeline/night/cloud_coverage_calculator/cloud_info_calculator_options.py @@ -0,0 +1,13 @@ +from __future__ import annotations + +from typing import Dict, Any + + +class CloudInfoCalculatorOptions(object): + def __init__(self, cloud_threshold: float, zenith_radius: float) -> None: + self.cloud_threshold = cloud_threshold + self.altitude_limit = 90 - zenith_radius + + @classmethod + def from_dict(cls, options: Dict[str, Any]) -> CloudInfoCalculatorOptions: + return CloudInfoCalculatorOptions(**options) diff --git a/pyobs_cloudcover/pipeline/night/cloud_map_generator/__init__.py b/pyobs_cloudcover/pipeline/night/cloud_map_generator/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pyobs_cloudcover/pipeline/night/cloud_map_generator.py b/pyobs_cloudcover/pipeline/night/cloud_map_generator/cloud_map_generator.py similarity index 100% rename from pyobs_cloudcover/pipeline/night/cloud_map_generator.py rename to pyobs_cloudcover/pipeline/night/cloud_map_generator/cloud_map_generator.py diff --git a/pyobs_cloudcover/pipeline/night/cloud_map_generator/cloud_map_generator_factory.py b/pyobs_cloudcover/pipeline/night/cloud_map_generator/cloud_map_generator_factory.py new file mode 100644 index 0000000..82f4603 --- /dev/null +++ b/pyobs_cloudcover/pipeline/night/cloud_map_generator/cloud_map_generator_factory.py @@ -0,0 +1,10 @@ +from pyobs_cloudcover.pipeline.night.cloud_map_generator.cloud_map_generator import CloudMapGenerator +from pyobs_cloudcover.pipeline.night.cloud_map_generator.cloud_map_generator_options import CloudMapGeneratorOptions + + +class CloudMapGeneratorFactory(object): + def __init__(self, options: CloudMapGeneratorOptions) -> None: + self._options = options + + def __call__(self) -> CloudMapGenerator: + return CloudMapGenerator(self._options.radius) diff --git a/pyobs_cloudcover/pipeline/night/cloud_map_generator/cloud_map_generator_options.py b/pyobs_cloudcover/pipeline/night/cloud_map_generator/cloud_map_generator_options.py new file mode 100644 index 0000000..ec84bd5 --- /dev/null +++ b/pyobs_cloudcover/pipeline/night/cloud_map_generator/cloud_map_generator_options.py @@ -0,0 +1,12 @@ +from __future__ import annotations + +from typing import Any, Dict + + +class CloudMapGeneratorOptions(object): + def __init__(self, radius: float = 5.0) -> None: + self.radius = radius + + @classmethod + def from_dict(cls, options: Dict[str, Any]) -> CloudMapGeneratorOptions: + return cls(**options) diff --git a/pyobs_cloudcover/pipeline/night/pipeline.py b/pyobs_cloudcover/pipeline/night/pipeline.py index c42458a..da6f1e3 100644 --- a/pyobs_cloudcover/pipeline/night/pipeline.py +++ b/pyobs_cloudcover/pipeline/night/pipeline.py @@ -6,16 +6,16 @@ from pyobs_cloudcover.cloud_coverage_info import CloudCoverageInfo from pyobs_cloudcover.pipeline.night.catalog.catalog_constructor import CatalogConstructor from pyobs_cloudcover.pipeline.night.cloud_coverage_calculator.coverage_info_calculator import CoverageInfoCalculator -from pyobs_cloudcover.pipeline.night.cloud_map_generator import CloudMapGenerator +from pyobs_cloudcover.pipeline.night.cloud_map_generator.cloud_map_generator import CloudMapGenerator from pyobs_cloudcover.pipeline.night.preprocessor.preprocessor import Preprocessor -from pyobs_cloudcover.pipeline.night.star_reverse_matcher.star_reverse_matcher import StareReverseMatcher +from pyobs_cloudcover.pipeline.night.star_reverse_matcher.star_reverse_matcher import StarReverseMatcher class NightPipeline(object): def __init__(self, preprocess: Preprocessor, catalog_constructor: CatalogConstructor, - star_reverse_matcher: StareReverseMatcher, + star_reverse_matcher: StarReverseMatcher, cloud_map_generator: CloudMapGenerator, coverage_info_calculator: CoverageInfoCalculator) -> None: diff --git a/pyobs_cloudcover/pipeline/night/pipeline_factory.py b/pyobs_cloudcover/pipeline/night/pipeline_factory.py new file mode 100644 index 0000000..fddfcd6 --- /dev/null +++ b/pyobs_cloudcover/pipeline/night/pipeline_factory.py @@ -0,0 +1,37 @@ +from astroplan import Observer + +from pyobs_cloudcover.pipeline.night.catalog.catalog_constructor_factory import CatalogConstructorFactory +from pyobs_cloudcover.pipeline.night.cloud_coverage_calculator.cloud_info_calculator_factory import \ + CloudInfoCalculatorFactory +from pyobs_cloudcover.pipeline.night.cloud_map_generator.cloud_map_generator_factory import CloudMapGeneratorFactory +from pyobs_cloudcover.pipeline.night.pipeline import NightPipeline +from pyobs_cloudcover.pipeline.night.pipeline_options import NightPipelineOptions +from pyobs_cloudcover.pipeline.night.preprocessor.preprocessor_factory import PreprocessorFactory +from pyobs_cloudcover.pipeline.night.star_reverse_matcher.star_reverse_matcher_factory import StarReverseMatcherFactory +from pyobs_cloudcover.world_model import WorldModel + + +class NightPipelineFactory(object): + def __init__(self, observer: Observer, model: WorldModel, options: NightPipelineOptions): + self._preprocessor_factory = PreprocessorFactory(options.preprocessor_options) + self._catalog_constructor_factory = CatalogConstructorFactory(options.catalog_options, model, observer) + self._reverse_matcher_factory = StarReverseMatcherFactory(options.star_matcher_options) + self._cloud_map_generator_factory = CloudMapGeneratorFactory(options.cloud_generator_options) + self._coverage_info_calculator_factory = CloudInfoCalculatorFactory(options.coverage_info_options, model) + + def __call__(self) -> NightPipeline: + preprocessor = self._preprocessor_factory() + catalog_constructor = self._catalog_constructor_factory() + star_reverse_matcher = self._reverse_matcher_factory() + cloud_map_generator = self._cloud_map_generator_factory() + coverage_info_calculator = self._coverage_info_calculator_factory() + + pipeline = NightPipeline( + preprocessor, + catalog_constructor, + star_reverse_matcher, + cloud_map_generator, + coverage_info_calculator + ) + + return pipeline diff --git a/pyobs_cloudcover/pipeline/night/pipeline_options.py b/pyobs_cloudcover/pipeline/night/pipeline_options.py new file mode 100644 index 0000000..fc9e291 --- /dev/null +++ b/pyobs_cloudcover/pipeline/night/pipeline_options.py @@ -0,0 +1,41 @@ +from __future__ import annotations + +from typing import Dict, Any + +from pyobs_cloudcover.pipeline.night.catalog.catalog_constructor_options import CatalogConstructorOptions +from pyobs_cloudcover.pipeline.night.cloud_coverage_calculator.cloud_info_calculator_options import \ + CloudInfoCalculatorOptions +from pyobs_cloudcover.pipeline.night.cloud_map_generator.cloud_map_generator_options import CloudMapGeneratorOptions +from pyobs_cloudcover.pipeline.night.preprocessor.preprocessor_options import PreprocessorOptions +from pyobs_cloudcover.pipeline.night.star_reverse_matcher.star_reverse_matcher_options import StarReverseMatcherOptions + + +class NightPipelineOptions(object): + def __init__(self, + preprocessor_options: PreprocessorOptions, + catalog_options: CatalogConstructorOptions, + star_matcher_options: StarReverseMatcherOptions, + cloud_generator_options: CloudMapGeneratorOptions, + coverage_info_options: CloudInfoCalculatorOptions + ) -> None: + + self.preprocessor_options = preprocessor_options + self.catalog_options = catalog_options + self.star_matcher_options = star_matcher_options + self.cloud_generator_options = cloud_generator_options + self.coverage_info_options = coverage_info_options + + @classmethod + def from_dict(cls, options: Dict[str, Any]) -> NightPipelineOptions: + preprocessor_options = PreprocessorOptions.from_dict(options.get("preprocessor", {})) + catalog_options = CatalogConstructorOptions.from_dict(options.get("catalog", {})) + star_matcher_options = StarReverseMatcherOptions.from_dict(options.get("reverse_matcher", {})) + cloud_generator_options = CloudMapGeneratorOptions.from_dict(options.get("cloud_map", {})) + coverage_info_options = CloudInfoCalculatorOptions.from_dict(options.get("coverage_info", {})) + + return cls(preprocessor_options, + catalog_options, + star_matcher_options, + cloud_generator_options, + coverage_info_options + ) diff --git a/pyobs_cloudcover/pipeline/night/preprocessor/background_remover.py b/pyobs_cloudcover/pipeline/night/preprocessor/background_remover.py index 11c2064..5be2e31 100644 --- a/pyobs_cloudcover/pipeline/night/preprocessor/background_remover.py +++ b/pyobs_cloudcover/pipeline/night/preprocessor/background_remover.py @@ -8,7 +8,7 @@ class BackgroundRemover(object): - def __init__(self, sigma_clip: float = 3.0, box_size: Tuple[int, int] = (5, 5)) -> None: + def __init__(self, sigma_clip: float, box_size: Tuple[int, int]) -> None: self._sigma_clip = sigma_clip self._box_size = box_size diff --git a/pyobs_cloudcover/pipeline/night/preprocessor/image_masker.py b/pyobs_cloudcover/pipeline/night/preprocessor/image_masker.py index f3dbd3b..9b26ac2 100644 --- a/pyobs_cloudcover/pipeline/night/preprocessor/image_masker.py +++ b/pyobs_cloudcover/pipeline/night/preprocessor/image_masker.py @@ -1,3 +1,4 @@ +from __future__ import annotations from copy import copy import numpy as np @@ -13,3 +14,8 @@ def __call__(self, image: npt.NDArray[np.float_]) -> npt.NDArray[np.float_]: masked_image *= self._mask return masked_image + + @classmethod + def from_npy_file(cls, file_path: str) -> ImageMasker: + mask = np.load(file_path) + return ImageMasker(mask) diff --git a/pyobs_cloudcover/pipeline/night/preprocessor/preprocessor_factory.py b/pyobs_cloudcover/pipeline/night/preprocessor/preprocessor_factory.py new file mode 100644 index 0000000..fdba2a9 --- /dev/null +++ b/pyobs_cloudcover/pipeline/night/preprocessor/preprocessor_factory.py @@ -0,0 +1,18 @@ +from pyobs_cloudcover.pipeline.night.preprocessor.background_remover import BackgroundRemover +from pyobs_cloudcover.pipeline.night.preprocessor.image_binner import ImageBinner +from pyobs_cloudcover.pipeline.night.preprocessor.image_masker import ImageMasker +from pyobs_cloudcover.pipeline.night.preprocessor.preprocessor import Preprocessor +from pyobs_cloudcover.pipeline.night.preprocessor.preprocessor_options import PreprocessorOptions + + +class PreprocessorFactory(object): + def __init__(self, options: PreprocessorOptions): + self._options = options + + def __call__(self) -> Preprocessor: + mask = ImageMasker.from_npy_file(self._options.mask_file_path) + binner = ImageBinner(self._options.bin_size) + background_remover = BackgroundRemover(self._options.bkg_sigma_clip, self._options.bkg_box_size) + preprocessor = Preprocessor(mask, binner, background_remover) + + return preprocessor diff --git a/pyobs_cloudcover/pipeline/night/preprocessor/preprocessor_options.py b/pyobs_cloudcover/pipeline/night/preprocessor/preprocessor_options.py new file mode 100644 index 0000000..cb13bb2 --- /dev/null +++ b/pyobs_cloudcover/pipeline/night/preprocessor/preprocessor_options.py @@ -0,0 +1,14 @@ +from __future__ import annotations +from typing import Tuple, Dict, Any + + +class PreprocessorOptions(object): + def __init__(self, mask_filepath: str, bin_size: int = 2, bkg_sigma_clip: float = 3.0, bkg_box_size: Tuple[int, int] = (5, 5)) -> None: + self.mask_file_path = mask_filepath + self.bin_size = bin_size + self.bkg_sigma_clip = bkg_sigma_clip + self.bkg_box_size = bkg_box_size + + @classmethod + def from_dict(cls, options: Dict[str, Any]) -> PreprocessorOptions: + return cls(**options) diff --git a/pyobs_cloudcover/pipeline/night/star_reverse_matcher/star_reverse_matcher.py b/pyobs_cloudcover/pipeline/night/star_reverse_matcher/star_reverse_matcher.py index 6f51429..72564ef 100644 --- a/pyobs_cloudcover/pipeline/night/star_reverse_matcher/star_reverse_matcher.py +++ b/pyobs_cloudcover/pipeline/night/star_reverse_matcher/star_reverse_matcher.py @@ -8,7 +8,7 @@ from pyobs_cloudcover.pipeline.night.star_reverse_matcher.window import ImageWindow -class StareReverseMatcher(object): +class StarReverseMatcher(object): def __init__(self, detector: StarDetector, window: ImageWindow): self._detector = detector self._window = window diff --git a/pyobs_cloudcover/pipeline/night/star_reverse_matcher/star_reverse_matcher_factory.py b/pyobs_cloudcover/pipeline/night/star_reverse_matcher/star_reverse_matcher_factory.py new file mode 100644 index 0000000..5747e24 --- /dev/null +++ b/pyobs_cloudcover/pipeline/night/star_reverse_matcher/star_reverse_matcher_factory.py @@ -0,0 +1,16 @@ +from pyobs_cloudcover.pipeline.night.star_reverse_matcher.detector.sigma_treshhold_detector import \ + SigmaThresholdDetector +from pyobs_cloudcover.pipeline.night.star_reverse_matcher.star_reverse_matcher import StarReverseMatcher +from pyobs_cloudcover.pipeline.night.star_reverse_matcher.star_reverse_matcher_options import StarReverseMatcherOptions +from pyobs_cloudcover.pipeline.night.star_reverse_matcher.window import ImageWindow + + +class StarReverseMatcherFactory(object): + def __init__(self, options: StarReverseMatcherOptions): + self._options = options + + def __call__(self) -> StarReverseMatcher: + detector = SigmaThresholdDetector(self._options.sigma_threshold) + window = ImageWindow(self._options.window_size) + reverse_matcher = StarReverseMatcher(detector, window) + return reverse_matcher diff --git a/pyobs_cloudcover/pipeline/night/star_reverse_matcher/star_reverse_matcher_options.py b/pyobs_cloudcover/pipeline/night/star_reverse_matcher/star_reverse_matcher_options.py new file mode 100644 index 0000000..401db99 --- /dev/null +++ b/pyobs_cloudcover/pipeline/night/star_reverse_matcher/star_reverse_matcher_options.py @@ -0,0 +1,13 @@ +from __future__ import annotations + +from typing import Dict, Any + + +class StarReverseMatcherOptions(object): + def __init__(self, sigma_threshold: float = 3.0, window_size: int = 6): + self.sigma_threshold = sigma_threshold + self.window_size = window_size + + @classmethod + def from_dict(cls, options: Dict[str, Any]) -> StarReverseMatcherOptions: + return StarReverseMatcherOptions(**options) diff --git a/tests/integration/mask.npy b/tests/integration/mask.npy new file mode 100644 index 0000000..ebe08ba Binary files /dev/null and b/tests/integration/mask.npy differ diff --git a/tests/integration/test_night_pipeline,.py b/tests/integration/test_night_pipeline.py similarity index 89% rename from tests/integration/test_night_pipeline,.py rename to tests/integration/test_night_pipeline.py index ec14353..e4f73b3 100644 --- a/tests/integration/test_night_pipeline,.py +++ b/tests/integration/test_night_pipeline.py @@ -12,7 +12,7 @@ CoverageChangeCalculator from pyobs_cloudcover.pipeline.night.cloud_coverage_calculator.coverage_info_calculator import CoverageInfoCalculator from pyobs_cloudcover.pipeline.night.cloud_coverage_calculator.zenith_masker import ZenithMasker -from pyobs_cloudcover.pipeline.night.cloud_map_generator import CloudMapGenerator +from pyobs_cloudcover.pipeline.night.cloud_map_generator.cloud_map_generator import CloudMapGenerator from pyobs_cloudcover.pipeline.night.pipeline import NightPipeline from pyobs_cloudcover.pipeline.night.preprocessor.image_masker import ImageMasker from pyobs_cloudcover.pipeline.night.preprocessor.preprocessor import Preprocessor @@ -20,12 +20,12 @@ from pyobs_cloudcover.pipeline.night.preprocessor.background_remover import BackgroundRemover from pyobs_cloudcover.pipeline.night.star_reverse_matcher.detector.sigma_treshhold_detector import \ SigmaThresholdDetector -from pyobs_cloudcover.pipeline.night.star_reverse_matcher.star_reverse_matcher import StareReverseMatcher +from pyobs_cloudcover.pipeline.night.star_reverse_matcher.star_reverse_matcher import StarReverseMatcher from pyobs_cloudcover.pipeline.night.star_reverse_matcher.window import ImageWindow from pyobs_cloudcover.world_model.simple_model import SimpleModel -def test_night_pipeline(): +def test_night_pipeline() -> None: observer = Observer(latitude=51.559299 * u.deg, longitude=9.945472 * u.deg, elevation=201 * u.m) obs_time = datetime.datetime(2024, 3, 9, 1, 48, 48, 297970) @@ -41,13 +41,13 @@ def test_night_pipeline(): mask = ImageMasker(np.ones((2*1040, 2*1548)).astype(np.bool_)) binner = ImageBinner(2) - background_remover = BackgroundRemover() + background_remover = BackgroundRemover(3.0, (5, 5)) preprocessor = Preprocessor(mask, binner, background_remover) altaz_catalog_loader = AltAzCatalogLoader.from_csv("tests/integration/catalog.csv") catalog_constructor = CatalogConstructor(altaz_catalog_loader, model, observer, 0.0, 3.0, 0.0) - reverse_matcher = StareReverseMatcher(SigmaThresholdDetector(3.0), ImageWindow(6.0)) + reverse_matcher = StarReverseMatcher(SigmaThresholdDetector(3.0), ImageWindow(6.0)) cloud_map_gem = CloudMapGenerator(50.0) diff --git a/tests/integration/test_night_pipeline_factory.py b/tests/integration/test_night_pipeline_factory.py new file mode 100644 index 0000000..0749db9 --- /dev/null +++ b/tests/integration/test_night_pipeline_factory.py @@ -0,0 +1,59 @@ +import datetime + +import numpy as np +from astroplan import Observer + +import astropy.units as u + +from pyobs_cloudcover.pipeline.night.pipeline import NightPipeline +from pyobs_cloudcover.pipeline.night.pipeline_factory import NightPipelineFactory +from pyobs_cloudcover.pipeline.night.pipeline_options import NightPipelineOptions +from pyobs_cloudcover.world_model import SimpleModel + + +def test_night_pipeline() -> None: + observer = Observer(latitude=51.559299 * u.deg, longitude=9.945472 * u.deg, elevation=201 * u.m) + obs_time = datetime.datetime(2024, 3, 9, 1, 48, 48, 297970) + + model_parameters = [4.81426598e-03, 2.00000000e+00, 1.06352627e+03, 7.57115607e+02, 5.11194838e+02] + model = SimpleModel(*model_parameters) + + stars = np.loadtxt('tests/integration/matches_small_20240308.csv', delimiter=",") + + image = np.zeros((2*1040, 2*1548)) + + for star in stars: + image[int(star[2]), int(star[1])] = 10 + + pipeline_kwargs = { + "preprocessor": { + "mask_filepath": "tests/integration/mask.npy", + "bin_size": 2, + "bkg_sigma_clip": 3.0, + "bkg_box_size": (5, 5), + }, + "catalog": { + "filepath": "tests/integration/catalog.csv", + "filter": { + "alt": 30.0, + "v_mag": 7.0, + "distance": 0.0 + } + }, + "reverse_matcher": { + "sigma_threshold": 3.0, + "window_size": 6.0 + }, + "cloud_map": { + "radius": 50.0 + }, + "coverage_info": { + "cloud_threshold": 0.5, + "zenith_radius": 20 + } + } + + pipeline_options = NightPipelineOptions.from_dict(pipeline_kwargs) + pipeline_factory = NightPipelineFactory(observer, model, pipeline_options) + pipeline = pipeline_factory() + pipeline(image, obs_time) diff --git a/tests/unit/pipeline/night/preprocessor/test_background_remover.py b/tests/unit/pipeline/night/preprocessor/test_background_remover.py index 491d269..fe94dc7 100644 --- a/tests/unit/pipeline/night/preprocessor/test_background_remover.py +++ b/tests/unit/pipeline/night/preprocessor/test_background_remover.py @@ -4,7 +4,7 @@ def test_background_remover(): - remover = BackgroundRemover() + remover = BackgroundRemover(3.0, (5, 5)) image = np.ones((10, 10)) corr_image = remover(image) diff --git a/tests/unit/pipeline/night/test_cloud_map_generator.py b/tests/unit/pipeline/night/test_cloud_map_generator.py index 905d302..9546347 100644 --- a/tests/unit/pipeline/night/test_cloud_map_generator.py +++ b/tests/unit/pipeline/night/test_cloud_map_generator.py @@ -1,10 +1,10 @@ import numpy as np from pyobs_cloudcover.pipeline.night.catalog.pixel_catalog import PixelCatalog -from pyobs_cloudcover.pipeline.night.cloud_map_generator import CloudMapGenerator +from pyobs_cloudcover.pipeline.night.cloud_map_generator.cloud_map_generator import CloudMapGenerator -def test_call(): +def test_call() -> None: cloud_map_generator = CloudMapGenerator(1) catalog = PixelCatalog(sao=np.array([0, 1]), px=np.array([1, 1]), py=np.array([1, 1]), v_mag=np.array([0, 1])) diff --git a/tests/unit/web_api/test_coverage_query_executor.py b/tests/unit/web_api/test_coverage_query_executor.py index 345c2fb..9ee1fb7 100644 --- a/tests/unit/web_api/test_coverage_query_executor.py +++ b/tests/unit/web_api/test_coverage_query_executor.py @@ -42,12 +42,12 @@ def test_call_map(observer, obs_time, model): executor = CoverageQueryExecutor(model, observer, window) executor._radec_to_altaz = Mock(return_value=(np.pi/2, 0)) - executor._model.altaz_to_pix = Mock(return_value=(1 , 1)) + executor._model.altaz_to_pix = Mock(return_value=(1, 1)) executor.set_measurement(CloudCoverageInfo(np.identity(3), 0, 0, 0, obs_time)) assert executor(10, 10) == 1/3 - executor._radec_to_altaz.assert_called_once_with(10, 10) + executor._radec_to_altaz.assert_called_once_with(10, 10, obs_time) executor._model.altaz_to_pix.assert_called_once_with(np.pi/2, 0)