Skip to content

Commit 503ae3b

Browse files
Fixed coverage map output
1 parent 5e3a3ae commit 503ae3b

File tree

14 files changed

+3852
-28
lines changed

14 files changed

+3852
-28
lines changed

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,7 @@ docs/_build/
7171
# Pyenv
7272
.python-version
7373

74-
*.sh
74+
*.sh
75+
76+
**/ipynb_checkpoints
77+
*.ipynb

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

data/mask.npy

6.14 MB
Binary file not shown.

day_integration_test.yaml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ modules:
6262
mask_filepath: "data/mask.npy"
6363
sun_apparent_size: 0.54
6464
cloud_map:
65-
threshold: 3.5
65+
threshold: 3.0
6666

6767
comm:
6868
class: pyobs.comm.local.LocalComm
@@ -71,10 +71,10 @@ modules:
7171
tester:
7272
class: pyobs_cloudcover.testing.TestModule
7373
image_path: "data/test_day_image.fits"
74-
total_fraction: 0.7
74+
total_fraction: 0.3
7575
zenith_fraction: 0.02
76-
zenith_value: False
77-
zenith_average: 2.3
76+
zenith_value: True
77+
zenith_average: 5.8
7878

7979
comm:
8080
class: pyobs.comm.local.LocalComm

poetry.lock

Lines changed: 1419 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyobs_cloudcover/cloud_coverage_info.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55

66

77
class CloudCoverageInfo(object):
8-
def __init__(self, cloud_cover_query: SkyPixelQuery, change: Optional[float], obs_time: datetime.datetime) -> None:
8+
def __init__(self, cloud_cover_query: SkyPixelQuery, change: Optional[float], cloud_plot: bytes, obs_time: datetime.datetime) -> None:
99
self.cloud_cover_query = cloud_cover_query
1010
self.change = change
11+
self.cloud_plot = cloud_plot
1112
self.obs_time = obs_time
Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
11
import datetime
22

33
import numpy as np
4-
from cloudmap_rs import AltAzCoord, SkyPixelQuery
4+
import numpy.typing as npt
5+
from cloudmap_rs import SkyPixelQuery
56

67
from pyobs_cloudcover.cloud_coverage_info import CloudCoverageInfo
78
from pyobs_cloudcover.cloud_info_calculator.coverage_change_calculator import \
89
CoverageChangeCalculator
9-
from pyobs_cloudcover.measurement_log.field_evaluators.zenith_cloud_coverage_calculator import \
10-
ZenithCloudCoverageCalculator
1110

1211

1312
class CoverageInfoCalculator:
1413
def __init__(self, coverage_change_calculator: CoverageChangeCalculator) -> None:
1514
self._coverage_change_calculator = coverage_change_calculator
1615

17-
def __call__(self, sky_query: SkyPixelQuery, obs_time: datetime.datetime) -> CloudCoverageInfo:
16+
def __call__(self, sky_query: SkyPixelQuery, cloud_plot: bytes, obs_time: datetime.datetime) -> CloudCoverageInfo:
1817
change = self._coverage_change_calculator(sky_query.get_pixels())
1918

20-
return CloudCoverageInfo(sky_query, change, obs_time)
19+
return CloudCoverageInfo(sky_query, change, cloud_plot, obs_time)

pyobs_cloudcover/cloud_plot/__init__.py

Whitespace-only changes.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import io
2+
from typing import List
3+
4+
import matplotlib.pyplot as plt
5+
import numpy as np
6+
7+
from cloudmap_rs import AltAzCoord
8+
9+
10+
def plot_clouds(coordinates: List[AltAzCoord], clouds: List[bool]) -> bytes:
11+
'''
12+
z = 90 - np.rad2deg([coord.alt for coord in coordinates])
13+
az = np.rad2deg([coord.az for coord in coordinates])
14+
plt.polar()
15+
plt.scatter(az, z, c=clouds, s=1)
16+
plt.colorbar()
17+
'''
18+
19+
lon, lat = [coord.az for coord in coordinates], [coord.alt for coord in coordinates]
20+
plt.polar()
21+
plt.scatter(lon, 90 - np.rad2deg(lat), c=clouds, s=1)
22+
plt.colorbar()
23+
24+
return render_plot()
25+
26+
def render_plot() -> bytes:
27+
buffer = io.BytesIO()
28+
plt.savefig(buffer, format='png')
29+
buffer.seek(0)
30+
plt.close()
31+
32+
return buffer.read()

pyobs_cloudcover/pipeline/day/pipeline.py

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
11
import datetime
2+
from copy import copy
23
from itertools import compress
34
from typing import List, Any, Optional
45

6+
import matplotlib.pyplot as plt
57
import numpy as np
68
from numpy import typing as npt
79

810
from cloudmap_rs import SkyPixelQuery
911

1012
from pyobs_cloudcover.cloud_coverage_info import CloudCoverageInfo
1113
from pyobs_cloudcover.cloud_info_calculator import CoverageInfoCalculator
14+
from pyobs_cloudcover.cloud_plot.cloud_plotter import plot_clouds, render_plot
1215
from pyobs_cloudcover.pipeline.day.color_ratio_calculation import calc_color_ratio
1316
from pyobs_cloudcover.pipeline.day.debayer_image import debayer_image
1417
from pyobs_cloudcover.pipeline.day.sun_masker import SunMasker
1518
from pyobs_cloudcover.pipeline.day.altaz_map_generator import AltAzMapGenerator
1619
from pyobs_cloudcover.pipeline.night.cloud_map_generator.cloud_map_generator import CloudMapGenerator
20+
from pyobs_cloudcover.pipeline.night.preprocessor.image_binner import ImageBinner
1721
from pyobs_cloudcover.pipeline.pipeline import Pipeline
1822

1923

@@ -28,22 +32,34 @@ def __init__(self, mask: npt.NDArray[np.bool_], alt_az_generator: AltAzMapGenera
2832
self._sky_query: Optional[SkyPixelQuery] = None
2933
self._alt_az_mask: Optional[npt.NDArray[np.bool_]] = None
3034

35+
self._image_binner = ImageBinner(2)
36+
3137
def __call__(self, image: npt.NDArray[np.float_], obs_time: datetime.datetime) -> CloudCoverageInfo:
3238
debayered_image = debayer_image(image)
33-
color_ratio_image = calc_color_ratio(debayered_image).flatten()
34-
cloud_map = self._cloud_map_generator(color_ratio_image)
39+
color_ratio_image = calc_color_ratio(debayered_image)#.flatten()
40+
cloud_map = self._image_binner(self._cloud_map_generator(color_ratio_image))
3541

36-
if self._sky_query is None or self._alt_az_mask is None:
37-
alt_az_points = self.flatten(self._alt_az_generator(*image.shape))
38-
self._alt_az_mask = self._mask.flatten() & np.array([x is not None for x in alt_az_points])
3942

40-
self._sky_query = SkyPixelQuery(self.filter(alt_az_points, self._alt_az_mask), cloud_map[self._alt_az_mask]) # type: ignore
43+
if self._sky_query is None or self._alt_az_mask is None:
44+
alt_az_points = self.flatten(self._alt_az_generator(*cloud_map.shape))
45+
self._alt_az_mask = self._mask.flatten().astype(np.bool_) & np.array([x is not None for x in alt_az_points]).astype(np.bool_)
46+
flat_cloud_map = self._to_python_type(cloud_map)
47+
self._sky_query = SkyPixelQuery(self.filter(alt_az_points, self._alt_az_mask), self.filter(flat_cloud_map, self._alt_az_mask)) # type: ignore
4148
else:
4249
self._sky_query.set_pixels(cloud_map[self._alt_az_mask])
4350

4451
sky_query = self._sun_masker(self._sky_query, obs_time)
4552

46-
return self._coverage_info_calculator(sky_query, obs_time)
53+
cloud_plot = cloud_map.astype(np.float_).flatten()
54+
cloud_plot[~self._alt_az_mask] = np.nan
55+
plt.imshow(cloud_plot.reshape(cloud_map.shape))
56+
57+
return self._coverage_info_calculator(sky_query, render_plot(),obs_time)
58+
59+
60+
def _to_python_type(self, cloud_map: npt.NDArray[np.float_]) -> List[bool]:
61+
flat_map = self.flatten(list(cloud_map > 0.5))
62+
return list(map(bool, flat_map))
4763

4864
@staticmethod
4965
def flatten(map_2d: List[List[Any]]) -> List[Any]:

0 commit comments

Comments
 (0)