From 5c89870aa83c0a1fdae9c04b9c5155183ba4e8e8 Mon Sep 17 00:00:00 2001 From: weiqi-tori Date: Thu, 20 Jun 2024 17:15:03 +0800 Subject: [PATCH 01/29] add ERA 5 highest temperature layer --- city_metrix/layers/__init__.py | 1 + city_metrix/layers/era_5_high_temperature.py | 39 ++++++++++++++++++++ tests/layers.py | 6 ++- 3 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 city_metrix/layers/era_5_high_temperature.py diff --git a/city_metrix/layers/__init__.py b/city_metrix/layers/__init__.py index bef56c3..307b219 100644 --- a/city_metrix/layers/__init__.py +++ b/city_metrix/layers/__init__.py @@ -16,3 +16,4 @@ from .open_buildings import OpenBuildings from .tree_canopy_hight import TreeCanopyHeight from .alos_dsm import AlosDSM +from .era_5_high_temperature import Era5HighTemperature diff --git a/city_metrix/layers/era_5_high_temperature.py b/city_metrix/layers/era_5_high_temperature.py new file mode 100644 index 0000000..dac8b62 --- /dev/null +++ b/city_metrix/layers/era_5_high_temperature.py @@ -0,0 +1,39 @@ +import ee + +from .layer import Layer, get_image_collection + + +class Era5HighTemperature(Layer): + def __init__(self, start_date="2023-01-01", end_date="2024-01-01", **kwargs): + super().__init__(**kwargs) + self.start_date = start_date + self.end_date = end_date + + def get_data(self, bbox): + dataset = ee.ImageCollection("ECMWF/ERA5_LAND/HOURLY") + + # Function to find the maximum value - highest temperature - pixel in each image + def highest_temperature_image(image): + max_pixel = image.reduceRegion( + reducer=ee.Reducer.max(), + geometry=ee.Geometry.BBox(*bbox), + scale=11132, + bestEffort=True + ).values().get(0) + + return image.set('highest_temperature', max_pixel) + + era5 = ee.ImageCollection(dataset + .filterBounds(ee.Geometry.BBox(*bbox)) + .filterDate(self.start_date, self.end_date) + .select('temperature_2m') + ) + + era5_highest = era5.map(highest_temperature_image) + + # Sort the collection based on the highest temperature and get the first image + highest_temperature_day = ee.ImageCollection(era5_highest.sort('highest_temperature', False).first()) + + data = get_image_collection(highest_temperature_day, bbox, 11132, "ERA 5 Temperature").temperature_2m + + return data diff --git a/tests/layers.py b/tests/layers.py index adf01ea..05b6351 100644 --- a/tests/layers.py +++ b/tests/layers.py @@ -1,6 +1,6 @@ import ee -from city_metrix.layers import LandsatCollection2, Albedo, LandSurfaceTemperature, EsaWorldCover, EsaWorldCoverClass, TreeCover, AverageNetBuildingHeight, OpenStreetMap, OpenStreetMapClass, UrbanLandUse, OpenBuildings, TreeCanopyHeight, AlosDSM +from city_metrix.layers import LandsatCollection2, Albedo, LandSurfaceTemperature, EsaWorldCover, EsaWorldCoverClass, TreeCover, AverageNetBuildingHeight, OpenStreetMap, OpenStreetMapClass, UrbanLandUse, OpenBuildings, TreeCanopyHeight, AlosDSM, Era5HighTemperature from city_metrix.layers.layer import get_image_collection from .conftest import MockLayer, MockMaskLayer, ZONES, LARGE_ZONES, MockLargeLayer, MockGroupByLayer, \ MockLargeGroupByLayer @@ -108,3 +108,7 @@ def test_tree_canopy_hight(): def test_AlosDSM(): mean = AlosDSM().get_data(SAMPLE_BBOX).mean() assert mean + +def test_era_5_high_temperature(): + mean = Era5HighTemperature().get_data(SAMPLE_BBOX).mean() + assert mean From 1cb786736109f213960ee417ea91822c42d0fbac Mon Sep 17 00:00:00 2001 From: weiqi-tori Date: Mon, 24 Jun 2024 16:38:57 +0800 Subject: [PATCH 02/29] find the hottest day use gee asset then pull data use api --- city_metrix/layers/era_5_high_temperature.py | 75 ++++++++++++++++++-- 1 file changed, 71 insertions(+), 4 deletions(-) diff --git a/city_metrix/layers/era_5_high_temperature.py b/city_metrix/layers/era_5_high_temperature.py index dac8b62..c73447f 100644 --- a/city_metrix/layers/era_5_high_temperature.py +++ b/city_metrix/layers/era_5_high_temperature.py @@ -1,6 +1,13 @@ import ee +from timezonefinder import TimezoneFinder +from pytz import timezone +from datetime import datetime +import pytz +import cdsapi +import xarray as xr +import pandas as pd -from .layer import Layer, get_image_collection +from .layer import Layer class Era5HighTemperature(Layer): @@ -14,7 +21,7 @@ def get_data(self, bbox): # Function to find the maximum value - highest temperature - pixel in each image def highest_temperature_image(image): - max_pixel = image.reduceRegion( + max_pixel = image.select('temperature_2m').reduceRegion( reducer=ee.Reducer.max(), geometry=ee.Geometry.BBox(*bbox), scale=11132, @@ -32,8 +39,68 @@ def highest_temperature_image(image): era5_highest = era5.map(highest_temperature_image) # Sort the collection based on the highest temperature and get the first image - highest_temperature_day = ee.ImageCollection(era5_highest.sort('highest_temperature', False).first()) + highest_temperature_day = era5_highest.sort('highest_temperature', False).first() + highest_temperature_day = highest_temperature_day.get('system:index').getInfo() - data = get_image_collection(highest_temperature_day, bbox, 11132, "ERA 5 Temperature").temperature_2m + year = highest_temperature_day[0:4] + month = highest_temperature_day[4:6] + day = highest_temperature_day[6:8] + time = highest_temperature_day[-2:] + + min_lon, min_lat, max_lon, max_lat = bbox + center_lon = (min_lon + max_lon) / 2 + center_lat = (min_lat + max_lat) / 2 + + # Initialize TimezoneFinder + tf = TimezoneFinder() + # Find the timezone of the center point + tz_name = tf.timezone_at(lng=center_lon, lat=center_lat) + # Get the timezone object + local_tz = timezone(tz_name) + # Define the UTC time + utc_time = datetime.strptime( + f'{year}-{month}-{day} {time}:00:00', "%Y-%m-%d %H:%M:%S") + + # Convert UTC time to local time + local_time = utc_time.replace(tzinfo=pytz.utc).astimezone(local_tz) + local_date = local_time.date() + + utc_times = [] + for i in range(0, 24): + local_time_hourly = local_tz.localize( + datetime(local_date.year, local_date.month, local_date.day, i, 0)) + utc_time_hourly = local_time_hourly.astimezone(pytz.utc) + utc_times.append(utc_time_hourly) + + data = pd.DataFrame() + + c = cdsapi.Client() + for i in range(0, 24): + c.retrieve( + 'reanalysis-era5-single-levels', + { + 'product_type': 'reanalysis', + 'variable': [ + '10m_u_component_of_wind', '10m_v_component_of_wind', '2m_dewpoint_temperature', + '2m_temperature', 'clear_sky_direct_solar_radiation_at_surface', 'mean_surface_direct_short_wave_radiation_flux_clear_sky', + 'mean_surface_downward_long_wave_radiation_flux_clear_sky', 'sea_surface_temperature', 'total_precipitation', + ], + 'year': utc_times[i].year, + 'month': utc_times[i].month, + 'day': utc_times[i].day, + 'time': utc_times[i].strftime("%H:00"), + 'area': [max_lat, min_lon, min_lat, max_lon], + 'format': 'netcdf', + }, + f'download_{i}.nc') + + dataset = xr.open_dataset(f'download_{i}.nc') + + data.loc[i, 'utc_date'] = utc_times[i].strftime("%Y-%m-%d") + data.loc[i, 'utc_time'] = utc_times[i].strftime("%H:00") + + variables = list(dataset.data_vars.keys()) + for variable in variables: + data.loc[i, variable] = float(dataset[variable].mean().values) return data From d63561914be95066bd9e5d1966b6c7fedf600cc2 Mon Sep 17 00:00:00 2001 From: weiqi-tori Date: Wed, 26 Jun 2024 18:12:36 +0800 Subject: [PATCH 03/29] update post request processing --- city_metrix/layers/era_5_high_temperature.py | 95 +++++++++++++++----- tests/layers.py | 2 +- 2 files changed, 74 insertions(+), 23 deletions(-) diff --git a/city_metrix/layers/era_5_high_temperature.py b/city_metrix/layers/era_5_high_temperature.py index c73447f..89030cb 100644 --- a/city_metrix/layers/era_5_high_temperature.py +++ b/city_metrix/layers/era_5_high_temperature.py @@ -4,8 +4,11 @@ from datetime import datetime import pytz import cdsapi -import xarray as xr import pandas as pd +import os +from netCDF4 import num2date +import numpy as np +import netCDF4 from .layer import Layer @@ -19,16 +22,16 @@ def __init__(self, start_date="2023-01-01", end_date="2024-01-01", **kwargs): def get_data(self, bbox): dataset = ee.ImageCollection("ECMWF/ERA5_LAND/HOURLY") - # Function to find the maximum value - highest temperature - pixel in each image - def highest_temperature_image(image): - max_pixel = image.select('temperature_2m').reduceRegion( - reducer=ee.Reducer.max(), + # Function to find the city mean temperature of each hour + def hourly_mean_temperature(image): + hourly_mean = image.select('temperature_2m').reduceRegion( + reducer=ee.Reducer.mean(), geometry=ee.Geometry.BBox(*bbox), scale=11132, bestEffort=True ).values().get(0) - return image.set('highest_temperature', max_pixel) + return image.set('hourly_mean_temperature', hourly_mean) era5 = ee.ImageCollection(dataset .filterBounds(ee.Geometry.BBox(*bbox)) @@ -36,10 +39,10 @@ def highest_temperature_image(image): .select('temperature_2m') ) - era5_highest = era5.map(highest_temperature_image) + era5_hourly_mean = era5.map(hourly_mean_temperature) # Sort the collection based on the highest temperature and get the first image - highest_temperature_day = era5_highest.sort('highest_temperature', False).first() + highest_temperature_day = era5_hourly_mean.sort('hourly_mean_temperature', False).first() highest_temperature_day = highest_temperature_day.get('system:index').getInfo() year = highest_temperature_day[0:4] @@ -58,8 +61,7 @@ def highest_temperature_image(image): # Get the timezone object local_tz = timezone(tz_name) # Define the UTC time - utc_time = datetime.strptime( - f'{year}-{month}-{day} {time}:00:00', "%Y-%m-%d %H:%M:%S") + utc_time = datetime.strptime(f'{year}-{month}-{day} {time}:00:00', "%Y-%m-%d %H:%M:%S") # Convert UTC time to local time local_time = utc_time.replace(tzinfo=pytz.utc).astimezone(local_tz) @@ -67,13 +69,11 @@ def highest_temperature_image(image): utc_times = [] for i in range(0, 24): - local_time_hourly = local_tz.localize( - datetime(local_date.year, local_date.month, local_date.day, i, 0)) + local_time_hourly = local_tz.localize(datetime(local_date.year, local_date.month, local_date.day, i, 0)) utc_time_hourly = local_time_hourly.astimezone(pytz.utc) utc_times.append(utc_time_hourly) - data = pd.DataFrame() - + df_list = [] c = cdsapi.Client() for i in range(0, 24): c.retrieve( @@ -94,13 +94,64 @@ def highest_temperature_image(image): }, f'download_{i}.nc') - dataset = xr.open_dataset(f'download_{i}.nc') - - data.loc[i, 'utc_date'] = utc_times[i].strftime("%Y-%m-%d") - data.loc[i, 'utc_time'] = utc_times[i].strftime("%H:00") - - variables = list(dataset.data_vars.keys()) - for variable in variables: - data.loc[i, variable] = float(dataset[variable].mean().values) + dataset = netCDF4.Dataset(f'download_{i}.nc') + + t2m_var = dataset.variables['t2m'] + u10_var = dataset.variables['u10'] + v10_var = dataset.variables['v10'] + sst_var = dataset.variables['sst'] + cdir_var = dataset.variables['cdir'] + sw_var = dataset.variables['msdrswrfcs'] + lw_var = dataset.variables['msdwlwrfcs'] + d2m_var = dataset.variables['d2m'] + time_var = dataset.variables['time'] + lat_var = dataset.variables['latitude'] + lon_var = dataset.variables['longitude'] + + # temps go from K to C; global rad (cdir) goes from /hour to /second; wind speed from vectors (pythagorean) + # rh calculated from temp and dew point; vpd calculated from tepm and rh + times = num2date(time_var[:], units=time_var.units) + t2m_vals = (t2m_var[:]-273.15) + d2m_vals = (d2m_var[:]-273.15) + rh_vals = (100*(np.exp((17.625*d2m_vals)/(243.04+d2m_vals))/np.exp((17.625*t2m_vals)/(243.04+t2m_vals)))) + grad_vals = (cdir_var[:]/3600) + dir_vals = (sw_var[:]) + dif_vals = (lw_var[:]) + wtemp_vals = (sst_var[:]-273.15) + wind_vals = (np.sqrt(((np.square(u10_var[:]))+(np.square(v10_var[:]))))) + # calc vapor pressure deficit in hPa for future utci conversion. first, get svp in pascals and then get vpd + svp_vals = (0.61078*np.exp(t2m_vals/(t2m_vals+237.3)*17.2694)) + vpd_vals = ((svp_vals*(1-(rh_vals/100))))*10 + + # make lat/lon grid + latitudes = lat_var[:] + longitudes = lon_var[:] + latitudes_2d, longitudes_2d = np.meshgrid( + latitudes, longitudes, indexing='ij') + latitudes_flat = latitudes_2d.flatten() + longitudes_flat = longitudes_2d.flatten() + + # create pandas dataframe + df = pd.DataFrame({ + 'time': np.repeat(times, len(latitudes_flat)), + 'lat': np.tile(latitudes_flat, len(times)), + 'lon': np.tile(longitudes_flat, len(times)), + 'temp': t2m_vals.flatten(), + 'rh': rh_vals.flatten(), + 'global_rad': grad_vals.flatten(), + 'direct_rad': dir_vals.flatten(), + 'diffuse_rad': dif_vals.flatten(), + 'water_temp': wtemp_vals.flatten(), + 'wind': wind_vals.flatten(), + 'vpd': vpd_vals.flatten() + }) + # round all numbers to two decimal places, which is the precision needed by the model + df = df.round(2) + + df_list.append(df) + + os.remove(f'download_{i}.nc') + + data = pd.concat(df_list, ignore_index=True) return data diff --git a/tests/layers.py b/tests/layers.py index 05b6351..2e45a21 100644 --- a/tests/layers.py +++ b/tests/layers.py @@ -110,5 +110,5 @@ def test_AlosDSM(): assert mean def test_era_5_high_temperature(): - mean = Era5HighTemperature().get_data(SAMPLE_BBOX).mean() + mean = Era5HighTemperature().get_data(SAMPLE_BBOX).count().sum() assert mean From 09331048302adf5fb934b63dadcdc60ff99a3fb2 Mon Sep 17 00:00:00 2001 From: weiqi-tori Date: Thu, 4 Jul 2024 15:27:28 +0800 Subject: [PATCH 04/29] update environment.yml --- city_metrix/layers/era_5_high_temperature.py | 2 +- environment.yml | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/city_metrix/layers/era_5_high_temperature.py b/city_metrix/layers/era_5_high_temperature.py index 89030cb..bf92f15 100644 --- a/city_metrix/layers/era_5_high_temperature.py +++ b/city_metrix/layers/era_5_high_temperature.py @@ -45,6 +45,7 @@ def hourly_mean_temperature(image): highest_temperature_day = era5_hourly_mean.sort('hourly_mean_temperature', False).first() highest_temperature_day = highest_temperature_day.get('system:index').getInfo() + # system:index in format 20230101T00 year = highest_temperature_day[0:4] month = highest_temperature_day[4:6] day = highest_temperature_day[6:8] @@ -149,7 +150,6 @@ def hourly_mean_temperature(image): df = df.round(2) df_list.append(df) - os.remove(f'download_{i}.nc') data = pd.concat(df_list, ignore_index=True) diff --git a/environment.yml b/environment.yml index 18f95f4..640d5a5 100644 --- a/environment.yml +++ b/environment.yml @@ -22,6 +22,10 @@ dependencies: - pip=23.3.1 - boto3=1.34.124 - scikit-learn=1.5.0 + - netcdf4==1.7.1 + - cdsapi=0.7.0 + - pytz=2024.1 + - timezonefinder=6.5.2 - pip: - cartoframes==1.2.5 - git+https://github.com/isciences/exactextract From 18012c93ed037ed1356e420eb808768b3b2bf877 Mon Sep 17 00:00:00 2001 From: weiqi-tori Date: Thu, 4 Jul 2024 18:03:34 +0800 Subject: [PATCH 05/29] pull twice instead of 24 times from api --- city_metrix/layers/era_5_high_temperature.py | 39 ++++++++++++-------- tests/layers.py | 4 ++ 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/city_metrix/layers/era_5_high_temperature.py b/city_metrix/layers/era_5_high_temperature.py index bf92f15..4266128 100644 --- a/city_metrix/layers/era_5_high_temperature.py +++ b/city_metrix/layers/era_5_high_temperature.py @@ -74,9 +74,11 @@ def hourly_mean_temperature(image): utc_time_hourly = local_time_hourly.astimezone(pytz.utc) utc_times.append(utc_time_hourly) + utc_dates = list(set([dt.date() for dt in utc_times])) + df_list = [] c = cdsapi.Client() - for i in range(0, 24): + for i in range(len(utc_dates)): c.retrieve( 'reanalysis-era5-single-levels', { @@ -86,15 +88,17 @@ def hourly_mean_temperature(image): '2m_temperature', 'clear_sky_direct_solar_radiation_at_surface', 'mean_surface_direct_short_wave_radiation_flux_clear_sky', 'mean_surface_downward_long_wave_radiation_flux_clear_sky', 'sea_surface_temperature', 'total_precipitation', ], - 'year': utc_times[i].year, - 'month': utc_times[i].month, - 'day': utc_times[i].day, - 'time': utc_times[i].strftime("%H:00"), + 'year': utc_dates[i].year, + 'month': utc_dates[i].month, + 'day': utc_dates[i].day, + 'time': ['00:00', '01:00', '02:00', '03:00', '04:00', '05:00', '06:00', '07:00', '08:00', '09:00', + '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00', '19:00', + '20:00', '21:00', '22:00', '23:00'], 'area': [max_lat, min_lon, min_lat, max_lon], 'format': 'netcdf', }, f'download_{i}.nc') - + dataset = netCDF4.Dataset(f'download_{i}.nc') t2m_var = dataset.variables['t2m'] @@ -109,17 +113,21 @@ def hourly_mean_temperature(image): lat_var = dataset.variables['latitude'] lon_var = dataset.variables['longitude'] + # Subset times for the day + times = num2date(time_var[:], units=time_var.units) + indices = [i for i, value in enumerate(times) if value in utc_times] + # temps go from K to C; global rad (cdir) goes from /hour to /second; wind speed from vectors (pythagorean) # rh calculated from temp and dew point; vpd calculated from tepm and rh - times = num2date(time_var[:], units=time_var.units) - t2m_vals = (t2m_var[:]-273.15) - d2m_vals = (d2m_var[:]-273.15) + times = num2date(time_var[indices], units=time_var.units) + t2m_vals = (t2m_var[indices]-273.15) + d2m_vals = (d2m_var[indices]-273.15) rh_vals = (100*(np.exp((17.625*d2m_vals)/(243.04+d2m_vals))/np.exp((17.625*t2m_vals)/(243.04+t2m_vals)))) - grad_vals = (cdir_var[:]/3600) - dir_vals = (sw_var[:]) - dif_vals = (lw_var[:]) - wtemp_vals = (sst_var[:]-273.15) - wind_vals = (np.sqrt(((np.square(u10_var[:]))+(np.square(v10_var[:]))))) + grad_vals = (cdir_var[indices]/3600) + dir_vals = (sw_var[indices]) + dif_vals = (lw_var[indices]) + wtemp_vals = (sst_var[indices]-273.15) + wind_vals = (np.sqrt(((np.square(u10_var[indices]))+(np.square(v10_var[indices]))))) # calc vapor pressure deficit in hPa for future utci conversion. first, get svp in pascals and then get vpd svp_vals = (0.61078*np.exp(t2m_vals/(t2m_vals+237.3)*17.2694)) vpd_vals = ((svp_vals*(1-(rh_vals/100))))*10 @@ -127,8 +135,7 @@ def hourly_mean_temperature(image): # make lat/lon grid latitudes = lat_var[:] longitudes = lon_var[:] - latitudes_2d, longitudes_2d = np.meshgrid( - latitudes, longitudes, indexing='ij') + latitudes_2d, longitudes_2d = np.meshgrid(latitudes, longitudes, indexing='ij') latitudes_flat = latitudes_2d.flatten() longitudes_flat = longitudes_2d.flatten() diff --git a/tests/layers.py b/tests/layers.py index 34018ef..e81ca61 100644 --- a/tests/layers.py +++ b/tests/layers.py @@ -120,3 +120,7 @@ def test_overture_buildings(): def test_nasa_dem(): mean = NasaDEM().get_data(SAMPLE_BBOX).mean() assert mean + +def test_era_5_high_temperature(): + count = Era5HighTemperature().get_data(SAMPLE_BBOX).count().sum() + assert count From fa33ea23e8f640468eff0bad26163e474b44f611 Mon Sep 17 00:00:00 2001 From: weiqi-tori Date: Sat, 13 Jul 2024 18:09:33 +0800 Subject: [PATCH 06/29] separate layer and metrix --- city_metrix/layers/__init__.py | 2 +- ...gh_temperature.py => era_5_hottest_day.py} | 72 +++---------------- .../metrics/era_5_met_preprocessing.py | 69 ++++++++++++++++++ environment.yml | 1 - tests/layers.py | 10 +-- 5 files changed, 86 insertions(+), 68 deletions(-) rename city_metrix/layers/{era_5_high_temperature.py => era_5_hottest_day.py} (58%) create mode 100644 city_metrix/metrics/era_5_met_preprocessing.py diff --git a/city_metrix/layers/__init__.py b/city_metrix/layers/__init__.py index b7273cb..073f995 100644 --- a/city_metrix/layers/__init__.py +++ b/city_metrix/layers/__init__.py @@ -18,4 +18,4 @@ from .alos_dsm import AlosDSM from .overture_buildings import OvertureBuildings from .nasa_dem import NasaDEM -from .era_5_high_temperature import Era5HighTemperature +from .era_5_hottest_day import Era5HottestDay diff --git a/city_metrix/layers/era_5_high_temperature.py b/city_metrix/layers/era_5_hottest_day.py similarity index 58% rename from city_metrix/layers/era_5_high_temperature.py rename to city_metrix/layers/era_5_hottest_day.py index 4266128..48bf502 100644 --- a/city_metrix/layers/era_5_high_temperature.py +++ b/city_metrix/layers/era_5_hottest_day.py @@ -4,16 +4,12 @@ from datetime import datetime import pytz import cdsapi -import pandas as pd import os -from netCDF4 import num2date -import numpy as np -import netCDF4 +import xarray as xr from .layer import Layer - -class Era5HighTemperature(Layer): +class Era5HottestDay(Layer): def __init__(self, start_date="2023-01-01", end_date="2024-01-01", **kwargs): super().__init__(**kwargs) self.start_date = start_date @@ -76,7 +72,7 @@ def hourly_mean_temperature(image): utc_dates = list(set([dt.date() for dt in utc_times])) - df_list = [] + dataarray_list = [] c = cdsapi.Client() for i in range(len(utc_dates)): c.retrieve( @@ -99,66 +95,18 @@ def hourly_mean_temperature(image): }, f'download_{i}.nc') - dataset = netCDF4.Dataset(f'download_{i}.nc') - - t2m_var = dataset.variables['t2m'] - u10_var = dataset.variables['u10'] - v10_var = dataset.variables['v10'] - sst_var = dataset.variables['sst'] - cdir_var = dataset.variables['cdir'] - sw_var = dataset.variables['msdrswrfcs'] - lw_var = dataset.variables['msdwlwrfcs'] - d2m_var = dataset.variables['d2m'] - time_var = dataset.variables['time'] - lat_var = dataset.variables['latitude'] - lon_var = dataset.variables['longitude'] + dataarray = xr.open_dataset(f'download_{i}.nc') # Subset times for the day - times = num2date(time_var[:], units=time_var.units) + times = [time.astype('datetime64[s]').astype(datetime).replace(tzinfo=pytz.UTC) for time in dataarray['time'].values] indices = [i for i, value in enumerate(times) if value in utc_times] + subset_dataarray = dataarray.isel(time=indices) + + dataarray_list.append(subset_dataarray) - # temps go from K to C; global rad (cdir) goes from /hour to /second; wind speed from vectors (pythagorean) - # rh calculated from temp and dew point; vpd calculated from tepm and rh - times = num2date(time_var[indices], units=time_var.units) - t2m_vals = (t2m_var[indices]-273.15) - d2m_vals = (d2m_var[indices]-273.15) - rh_vals = (100*(np.exp((17.625*d2m_vals)/(243.04+d2m_vals))/np.exp((17.625*t2m_vals)/(243.04+t2m_vals)))) - grad_vals = (cdir_var[indices]/3600) - dir_vals = (sw_var[indices]) - dif_vals = (lw_var[indices]) - wtemp_vals = (sst_var[indices]-273.15) - wind_vals = (np.sqrt(((np.square(u10_var[indices]))+(np.square(v10_var[indices]))))) - # calc vapor pressure deficit in hPa for future utci conversion. first, get svp in pascals and then get vpd - svp_vals = (0.61078*np.exp(t2m_vals/(t2m_vals+237.3)*17.2694)) - vpd_vals = ((svp_vals*(1-(rh_vals/100))))*10 - - # make lat/lon grid - latitudes = lat_var[:] - longitudes = lon_var[:] - latitudes_2d, longitudes_2d = np.meshgrid(latitudes, longitudes, indexing='ij') - latitudes_flat = latitudes_2d.flatten() - longitudes_flat = longitudes_2d.flatten() - - # create pandas dataframe - df = pd.DataFrame({ - 'time': np.repeat(times, len(latitudes_flat)), - 'lat': np.tile(latitudes_flat, len(times)), - 'lon': np.tile(longitudes_flat, len(times)), - 'temp': t2m_vals.flatten(), - 'rh': rh_vals.flatten(), - 'global_rad': grad_vals.flatten(), - 'direct_rad': dir_vals.flatten(), - 'diffuse_rad': dif_vals.flatten(), - 'water_temp': wtemp_vals.flatten(), - 'wind': wind_vals.flatten(), - 'vpd': vpd_vals.flatten() - }) - # round all numbers to two decimal places, which is the precision needed by the model - df = df.round(2) - - df_list.append(df) + # Remove local file os.remove(f'download_{i}.nc') - data = pd.concat(df_list, ignore_index=True) + data = xr.concat(dataarray_list, dim='time') return data diff --git a/city_metrix/metrics/era_5_met_preprocessing.py b/city_metrix/metrics/era_5_met_preprocessing.py new file mode 100644 index 0000000..f97d019 --- /dev/null +++ b/city_metrix/metrics/era_5_met_preprocessing.py @@ -0,0 +1,69 @@ + +from datetime import datetime +import pandas as pd +import numpy as np +from geopandas import GeoDataFrame, GeoSeries + +from city_metrix.layers import Era5HottestDay + + +def era_5_met_preprocessing(zones: GeoDataFrame) -> GeoSeries: + """ + Get ERA 5 data for the hottest day + :param zones: GeoDataFrame with geometries to collect zonal stats on + :return: Pandas Dataframe of data + """ + era_5_data = Era5HottestDay().get_data(zones.total_bounds) + + t2m_var = era_5_data['t2m'].values + u10_var = era_5_data['u10'].values + v10_var = era_5_data['v10'].values + sst_var = era_5_data['sst'].values + cdir_var = era_5_data['cdir'].values + sw_var = era_5_data['msdrswrfcs'].values + lw_var = era_5_data['msdwlwrfcs'].values + d2m_var = era_5_data['d2m'].values + time_var = era_5_data['time'].values + lat_var = era_5_data['latitude'].values + lon_var = era_5_data['longitude'].values + + # temps go from K to C; global rad (cdir) goes from /hour to /second; wind speed from vectors (pythagorean) + # rh calculated from temp and dew point; vpd calculated from tepm and rh + times = [time.astype('datetime64[s]').astype(datetime) for time in time_var] + t2m_vals = (t2m_var[:]-273.15) + d2m_vals = (d2m_var[:]-273.15) + rh_vals = (100*(np.exp((17.625*d2m_vals)/(243.04+d2m_vals))/np.exp((17.625*t2m_vals)/(243.04+t2m_vals)))) + grad_vals = (cdir_var[:]/3600) + dir_vals = (sw_var[:]) + dif_vals = (lw_var[:]) + wtemp_vals = (sst_var[:]-273.15) + wind_vals = (np.sqrt(((np.square(u10_var[:]))+(np.square(v10_var[:]))))) + # calc vapor pressure deficit in hPa for future utci conversion. first, get svp in pascals and then get vpd + svp_vals = (0.61078*np.exp(t2m_vals/(t2m_vals+237.3)*17.2694)) + vpd_vals = ((svp_vals*(1-(rh_vals/100))))*10 + + # make lat/lon grid + latitudes = lat_var[:] + longitudes = lon_var[:] + latitudes_2d, longitudes_2d = np.meshgrid(latitudes, longitudes, indexing='ij') + latitudes_flat = latitudes_2d.flatten() + longitudes_flat = longitudes_2d.flatten() + + # create pandas dataframe + df = pd.DataFrame({ + 'time': np.repeat(times, len(latitudes_flat)), + 'lat': np.tile(latitudes_flat, len(times)), + 'lon': np.tile(longitudes_flat, len(times)), + 'temp': t2m_vals.flatten(), + 'rh': rh_vals.flatten(), + 'global_rad': grad_vals.flatten(), + 'direct_rad': dir_vals.flatten(), + 'diffuse_rad': dif_vals.flatten(), + 'water_temp': wtemp_vals.flatten(), + 'wind': wind_vals.flatten(), + 'vpd': vpd_vals.flatten() + }) + # round all numbers to two decimal places, which is the precision needed by the model + df = df.round(2) + + return df diff --git a/environment.yml b/environment.yml index 640d5a5..60e6f83 100644 --- a/environment.yml +++ b/environment.yml @@ -22,7 +22,6 @@ dependencies: - pip=23.3.1 - boto3=1.34.124 - scikit-learn=1.5.0 - - netcdf4==1.7.1 - cdsapi=0.7.0 - pytz=2024.1 - timezonefinder=6.5.2 diff --git a/tests/layers.py b/tests/layers.py index e81ca61..bf46e01 100644 --- a/tests/layers.py +++ b/tests/layers.py @@ -1,6 +1,8 @@ import ee -from city_metrix.layers import LandsatCollection2, Albedo, LandSurfaceTemperature, EsaWorldCover, EsaWorldCoverClass, TreeCover, AverageNetBuildingHeight, OpenStreetMap, OpenStreetMapClass, UrbanLandUse, OpenBuildings, TreeCanopyHeight, AlosDSM, SmartSurfaceLULC, OvertureBuildings, NasaDEM, Era5HighTemperature +from city_metrix.layers import LandsatCollection2, Albedo, LandSurfaceTemperature, EsaWorldCover, EsaWorldCoverClass, TreeCover, \ + AverageNetBuildingHeight, OpenStreetMap, OpenStreetMapClass, UrbanLandUse, OpenBuildings, TreeCanopyHeight, AlosDSM, SmartSurfaceLULC, \ + OvertureBuildings, NasaDEM, Era5HottestDay from city_metrix.layers.layer import get_image_collection from .conftest import MockLayer, MockMaskLayer, ZONES, LARGE_ZONES, MockLargeLayer, MockGroupByLayer, \ MockLargeGroupByLayer @@ -121,6 +123,6 @@ def test_nasa_dem(): mean = NasaDEM().get_data(SAMPLE_BBOX).mean() assert mean -def test_era_5_high_temperature(): - count = Era5HighTemperature().get_data(SAMPLE_BBOX).count().sum() - assert count +def test_era_5_hottest_day(): + mean = Era5HottestDay().get_data(SAMPLE_BBOX).mean() + assert mean From 4ebac4d9c6d8c26ef9bc789e3b53caadd79e27c7 Mon Sep 17 00:00:00 2001 From: weiqi-tori Date: Wed, 31 Jul 2024 17:46:42 +0800 Subject: [PATCH 07/29] add cds api requirement --- README.md | 1 + setup.py | 2 ++ 2 files changed, 3 insertions(+) diff --git a/README.md b/README.md index be0888c..276952d 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ NOTE: If you are using this method you may want to use something like pyenv to m To run the module, 1. You need access to Google Earth Engine 2. Install https://cloud.google.com/sdk/docs/install + 3. If you want to use the ERA5 layer, you need to install the [Climate Data Store (CDS) Application Program Interface (API)](https://cds.climate.copernicus.eu/api-how-to) ### Interactive development For most people working in a notebook or IDE the script should walk you thourgh an interactive authentication process. You will just need to be logged in to your Google account that has access to GEE in your browser. diff --git a/setup.py b/setup.py index cc94eb4..841f6db 100644 --- a/setup.py +++ b/setup.py @@ -31,5 +31,7 @@ "exactextract", "overturemaps", "scikit-learn>=1.5.0", + "cdsapi", + "timezonefinder" ], ) From 5ce1b04f697c0ca126c1942093d0ce49b18d1f19 Mon Sep 17 00:00:00 2001 From: weiqi-tori Date: Thu, 8 Aug 2024 14:41:24 +0800 Subject: [PATCH 08/29] add tests for era 5 layer and metric --- city_metrix/metrics/__init__.py | 3 +- notebooks/layers/era_5_hottest_day.ipynb | 332 +++++++++++++++++++++++ tests/test_layers.py | 5 + tests/test_metrics.py | 3 + 4 files changed, 342 insertions(+), 1 deletion(-) create mode 100644 notebooks/layers/era_5_hottest_day.ipynb diff --git a/city_metrix/metrics/__init__.py b/city_metrix/metrics/__init__.py index 10b559c..d95cfa5 100644 --- a/city_metrix/metrics/__init__.py +++ b/city_metrix/metrics/__init__.py @@ -3,4 +3,5 @@ from .built_land_with_high_land_surface_temperature import built_land_with_high_land_surface_temperature from .mean_tree_cover import mean_tree_cover from .urban_open_space import urban_open_space -from .natural_areas import natural_areas \ No newline at end of file +from .natural_areas import natural_areas +from .era_5_met_preprocessing import era_5_met_preprocessing diff --git a/notebooks/layers/era_5_hottest_day.ipynb b/notebooks/layers/era_5_hottest_day.ipynb new file mode 100644 index 0000000..71e7596 --- /dev/null +++ b/notebooks/layers/era_5_hottest_day.ipynb @@ -0,0 +1,332 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Setup" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import geopandas as gpd" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "'/home/weiqi_tori/GitHub/wri/cities-cif'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# # update the wd path to be able to laod the module\n", + "os.chdir('../..')\n", + "os.getcwd()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Get Area of Interest" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/weiqi_tori/anaconda3/envs/fenv/lib/python3.10/site-packages/pyogrio/raw.py:196: RuntimeWarning: driver GeoJSON does not support open option DRIVER\n", + " return ogr_read(\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
geo_idgeo_levelgeo_namegeo_parent_namecreation_dategeometry
0BRA-Salvador_ADM4-union_1ADM4-unionBRA-SalvadorBRA-Salvador2022-08-03MULTIPOLYGON (((-38.50135 -13.01134, -38.5014 ...
\n", + "
" + ], + "text/plain": [ + " geo_id geo_level geo_name geo_parent_name \\\n", + "0 BRA-Salvador_ADM4-union_1 ADM4-union BRA-Salvador BRA-Salvador \n", + "\n", + " creation_date geometry \n", + "0 2022-08-03 MULTIPOLYGON (((-38.50135 -13.01134, -38.5014 ... " + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "# load boundary from s3\n", + "boundary_path = 'https://cities-indicators.s3.eu-west-3.amazonaws.com/data/boundaries/boundary-BRA-Salvador-ADM4union.geojson'\n", + "city_gdf = gpd.read_file(boundary_path, driver='GeoJSON')\n", + "city_gdf.head()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Get Layer" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Get Layer\n", + "from city_metrix.layers import Era5HottestDay\n", + "era_5_hottest_day = Era5HottestDay().get_data(city_gdf.total_bounds)" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Find the time step with the maximum temperature\n", + "max_temp_index = era_5_hottest_day['t2m'].argmax(dim='time')\n", + "max_time = era_5_hottest_day['t2m']['time'].isel(time=max_temp_index)\n", + "\n", + "# Select the data corresponding to the maximum time and plot\n", + "era_5_hottest_day['t2m'].sel(time=max_time).plot(cmap='Reds')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Save to file" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Create a data folder if it does not exist\n", + "if not os.path.exists('data'):\n", + " os.makedirs('data')" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# Save the era_5_hottest_day temperature to a tif file\n", + "era_5_hottest_day['t2m'].rio.to_raster(raster_path='data/era_5_hottest_day_t2m.tif', driver=\"COG\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "cities-cif", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.14" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/tests/test_layers.py b/tests/test_layers.py index 989c147..5f7ce78 100644 --- a/tests/test_layers.py +++ b/tests/test_layers.py @@ -18,6 +18,7 @@ TreeCanopyHeight, TreeCover, UrbanLandUse, + Era5HottestDay, ) from city_metrix.layers.layer import get_image_collection @@ -170,3 +171,7 @@ def test_overture_buildings(): def test_nasa_dem(): mean = NasaDEM().get_data(BBOX_BRAZIL_LAURO_DE_FREITAS_1).mean() assert mean + +def test_era_5_hottest_day(): + mean = Era5HottestDay().get_data(BBOX_BRAZIL_LAURO_DE_FREITAS_1).mean() + assert mean diff --git a/tests/test_metrics.py b/tests/test_metrics.py index eb2c440..1601633 100644 --- a/tests/test_metrics.py +++ b/tests/test_metrics.py @@ -16,3 +16,6 @@ def test_high_lst(): indicator = built_land_with_high_land_surface_temperature(ZONES) assert indicator.size == 100 +def test_era_5_met_preprocess(): + indicator = era_5_met_preprocessing(ZONES) + assert len(indicator) == 24 From 26750a241f1c979741c76958ee00ddd72fd6efe9 Mon Sep 17 00:00:00 2001 From: weiqi-tori Date: Wed, 14 Aug 2024 14:51:34 +0800 Subject: [PATCH 09/29] update requirements.txt for auto check --- .github/requirements.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/requirements.txt b/.github/requirements.txt index 9928a46..b7140d6 100644 --- a/.github/requirements.txt +++ b/.github/requirements.txt @@ -16,5 +16,7 @@ geemap==0.32.0 pip==23.3.1 boto3==1.34.124 scikit-learn==1.5.0 +cdsapi=0.7.0 +timezonefinder=6.5.2 overturemaps==0.6.0 git+https://github.com/isciences/exactextract \ No newline at end of file From 6962f27ee93c497dca80e95128b6870bab7db7d4 Mon Sep 17 00:00:00 2001 From: weiqi-tori Date: Wed, 14 Aug 2024 14:59:08 +0800 Subject: [PATCH 10/29] typo --- .github/requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/requirements.txt b/.github/requirements.txt index b7140d6..2ffc983 100644 --- a/.github/requirements.txt +++ b/.github/requirements.txt @@ -16,7 +16,7 @@ geemap==0.32.0 pip==23.3.1 boto3==1.34.124 scikit-learn==1.5.0 -cdsapi=0.7.0 -timezonefinder=6.5.2 +cdsapi==0.7.0 +timezonefinder==6.5.2 overturemaps==0.6.0 git+https://github.com/isciences/exactextract \ No newline at end of file From 6506f7f880470712a1a4a4b4d40ada3d0cdd5ac2 Mon Sep 17 00:00:00 2001 From: Chris Rowe Date: Wed, 4 Sep 2024 17:00:07 -0400 Subject: [PATCH 11/29] Add ERA5 api key to GH --- .github/workflows/dev_ci_cd.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.github/workflows/dev_ci_cd.yml b/.github/workflows/dev_ci_cd.yml index 6d55444..016d68b 100644 --- a/.github/workflows/dev_ci_cd.yml +++ b/.github/workflows/dev_ci_cd.yml @@ -14,6 +14,13 @@ jobs: python-version: ["3.10"] steps: + - name: Add ERA5 API key + run: | + cat < $HOME/.cdsapirc + url: ${{ secrets.ERA5_URL }} + key: ${{ secrets.ERA5_KEY }} + EOF + - uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v3 From a35b9254e08b7cc219726b6ae860ae1a63e71929 Mon Sep 17 00:00:00 2001 From: Chris Rowe Date: Wed, 4 Sep 2024 17:07:51 -0400 Subject: [PATCH 12/29] add workflow_dispatch GH Actions option --- .github/workflows/dev_ci_cd.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/dev_ci_cd.yml b/.github/workflows/dev_ci_cd.yml index 016d68b..88f38e2 100644 --- a/.github/workflows/dev_ci_cd.yml +++ b/.github/workflows/dev_ci_cd.yml @@ -2,6 +2,7 @@ name: Dev CIF API CI/CD on: pull_request: + workflow_dispatch: permissions: contents: read From 21e8d45242faa1a082a9eff386fb07d1893d9b62 Mon Sep 17 00:00:00 2001 From: Chris Rowe Date: Thu, 19 Sep 2024 10:16:41 -0400 Subject: [PATCH 13/29] Update to bata api and add notebook --- city_metrix/layers/era_5_hottest_day.py | 9 +- environment.yml | 3 +- notebooks/layers/era5.ipynb | 124 ++++++++++++++++++++++++ tests/test_layers.py | 2 +- 4 files changed, 132 insertions(+), 6 deletions(-) create mode 100644 notebooks/layers/era5.ipynb diff --git a/city_metrix/layers/era_5_hottest_day.py b/city_metrix/layers/era_5_hottest_day.py index 48bf502..39a0b6d 100644 --- a/city_metrix/layers/era_5_hottest_day.py +++ b/city_metrix/layers/era_5_hottest_day.py @@ -91,22 +91,23 @@ def hourly_mean_temperature(image): '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00', '19:00', '20:00', '21:00', '22:00', '23:00'], 'area': [max_lat, min_lon, min_lat, max_lon], - 'format': 'netcdf', + 'data_format': 'netcdf', + 'download_format': 'unarchived' }, f'download_{i}.nc') dataarray = xr.open_dataset(f'download_{i}.nc') # Subset times for the day - times = [time.astype('datetime64[s]').astype(datetime).replace(tzinfo=pytz.UTC) for time in dataarray['time'].values] + times = [valid_time.astype('datetime64[s]').astype(datetime).replace(tzinfo=pytz.UTC) for valid_time in dataarray['valid_time'].values] indices = [i for i, value in enumerate(times) if value in utc_times] - subset_dataarray = dataarray.isel(time=indices) + subset_dataarray = dataarray.isel(valid_time=indices) dataarray_list.append(subset_dataarray) # Remove local file os.remove(f'download_{i}.nc') - data = xr.concat(dataarray_list, dim='time') + data = xr.concat(dataarray_list, dim='valid_time') return data diff --git a/environment.yml b/environment.yml index 0ed4db7..eb71a05 100644 --- a/environment.yml +++ b/environment.yml @@ -21,11 +21,12 @@ dependencies: - geemap=0.32.0 - pip=23.3.1 - boto3=1.34.124 - - cdsapi=0.7.0 + - cdsapi=0.7.3 - pytz=2024.1 - timezonefinder=6.5.2 - scikit-learn=1.5.1 - scikit-image=0.24.0 - exactextract=0.2.0 + - netcdf4=1.6.2 - pip: - overturemaps==0.6.0 diff --git a/notebooks/layers/era5.ipynb b/notebooks/layers/era5.ipynb new file mode 100644 index 0000000..8ac57ac --- /dev/null +++ b/notebooks/layers/era5.ipynb @@ -0,0 +1,124 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Setup" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "sys.dont_write_bytecode=True\n", + "\n", + "%load_ext autoreload\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import os\n", + "import geopandas as gpd" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# # update the wd path to be able to laod the module\n", + "os.chdir('../..')\n", + "os.getcwd()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Get Area of Interest" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# load boundary from s3\n", + "boundary_path = 'https://cities-indicators.s3.eu-west-3.amazonaws.com/data/boundaries/boundary-BRA-Salvador-ADM4union.geojson'\n", + "city_gdf = gpd.read_file(boundary_path, driver='GeoJSON')\n", + "city_gdf.head()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Get area in sqare km\n", + "city_gdf.to_crs(epsg=3857).area / 10**6" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# Get Layer" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%autoreload\n", + "from city_metrix.layers import Era5HottestDay\n", + "\n", + "hottest_day = Era5HottestDay().get_data(city_gdf.total_bounds)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "hottest_day" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "cities-cif", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.14" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/tests/test_layers.py b/tests/test_layers.py index 48ec3d2..6bd8fe2 100644 --- a/tests/test_layers.py +++ b/tests/test_layers.py @@ -48,7 +48,7 @@ def test_average_net_building_height(): def test_era_5_hottest_day(): - mean = Era5HottestDay().get_data(BBOX_BRAZIL_LAURO_DE_FREITAS_1).mean() + mean = Era5HottestDay().get_data(BBOX).mean() assert mean From 287cb9b9c5abdff334975f21f9832b3529fbf01f Mon Sep 17 00:00:00 2001 From: weiqi-tori Date: Fri, 20 Sep 2024 17:27:58 +0800 Subject: [PATCH 14/29] update for the new api --- city_metrix/layers/era_5_hottest_day.py | 2 + .../metrics/era_5_met_preprocessing.py | 19 ++--- notebooks/layers/era5.ipynb | 2 +- notebooks/layers/era_5_hottest_day.ipynb | 83 +++++++++++++++---- 4 files changed, 80 insertions(+), 26 deletions(-) diff --git a/city_metrix/layers/era_5_hottest_day.py b/city_metrix/layers/era_5_hottest_day.py index 39a0b6d..92c2982 100644 --- a/city_metrix/layers/era_5_hottest_day.py +++ b/city_metrix/layers/era_5_hottest_day.py @@ -109,5 +109,7 @@ def hourly_mean_temperature(image): os.remove(f'download_{i}.nc') data = xr.concat(dataarray_list, dim='valid_time') + # xarray.Dataset to xarray.DataArray + data = data.to_array() return data diff --git a/city_metrix/metrics/era_5_met_preprocessing.py b/city_metrix/metrics/era_5_met_preprocessing.py index f97d019..513aca5 100644 --- a/city_metrix/metrics/era_5_met_preprocessing.py +++ b/city_metrix/metrics/era_5_met_preprocessing.py @@ -1,4 +1,3 @@ - from datetime import datetime import pandas as pd import numpy as np @@ -15,15 +14,15 @@ def era_5_met_preprocessing(zones: GeoDataFrame) -> GeoSeries: """ era_5_data = Era5HottestDay().get_data(zones.total_bounds) - t2m_var = era_5_data['t2m'].values - u10_var = era_5_data['u10'].values - v10_var = era_5_data['v10'].values - sst_var = era_5_data['sst'].values - cdir_var = era_5_data['cdir'].values - sw_var = era_5_data['msdrswrfcs'].values - lw_var = era_5_data['msdwlwrfcs'].values - d2m_var = era_5_data['d2m'].values - time_var = era_5_data['time'].values + t2m_var = era_5_data.sel(variable='t2m').values + u10_var = era_5_data.sel(variable='u10').values + v10_var = era_5_data.sel(variable='v10').values + sst_var = era_5_data.sel(variable='sst').values + cdir_var = era_5_data.sel(variable='cdir').values + sw_var = era_5_data.sel(variable='msdrswrfcs').values + lw_var = era_5_data.sel(variable='msdwlwrfcs').values + d2m_var = era_5_data.sel(variable='d2m').values + time_var = era_5_data['valid_time'].values lat_var = era_5_data['latitude'].values lon_var = era_5_data['longitude'].values diff --git a/notebooks/layers/era5.ipynb b/notebooks/layers/era5.ipynb index 8ac57ac..05b3b28 100644 --- a/notebooks/layers/era5.ipynb +++ b/notebooks/layers/era5.ipynb @@ -21,7 +21,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, "outputs": [], "source": [ diff --git a/notebooks/layers/era_5_hottest_day.ipynb b/notebooks/layers/era_5_hottest_day.ipynb index 71e7596..fee05e5 100644 --- a/notebooks/layers/era_5_hottest_day.ipynb +++ b/notebooks/layers/era_5_hottest_day.ipynb @@ -9,7 +9,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -48,7 +48,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 3, "metadata": {}, "outputs": [ { @@ -110,7 +110,7 @@ "0 2022-08-03 MULTIPOLYGON (((-38.50135 -13.01134, -38.5014 ... " ] }, - "execution_count": 4, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" } @@ -131,9 +131,63 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Authenticating to GEE with configured credentials file.\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "2024-09-20 17:16:16,081 INFO Request ID is 2b411663-6790-42c7-ab4d-f3ae38c99678\n", + "2024-09-20 17:16:16,431 INFO status has been updated to accepted\n", + "2024-09-20 17:16:38,041 INFO status has been updated to successful\n" + ] + }, + { + "data": { + "application/vnd.jupyter.widget-view+json": { + "model_id": "550d881c31b540dcbb82290f7e9323c8", + "version_major": 2, + "version_minor": 0 + }, + "text/plain": [ + "f4e4b5329c3eea8496d48601d058dbae.nc: 0%| | 0.00/100k [00:00" + "" ] }, - "execution_count": 14, + "execution_count": 15, "metadata": {}, "output_type": "execute_result" }, { "data": { - "image/png": "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", + "image/png": "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Y8fw1FNPAbg3AnPixAn07dtX6pNcLkdmZiY8PT3V6kNNXFxccOzYMZW0B8/79u2L1NRUdOrUqdoyunXrhszMTFy5cgU2NjYAgISEhDrrtrGxQbt27fDnn3/i+eefrzZP3759sWPHDlhbW0OhUNRYVp8+fdCnTx8sXLgQ7u7u2L59e52BU139SkxMxN27d7Fq1SoYGNxbRvrVV19Vyefo6IgZM2ZgxowZWLhwITZu3IhXXnkFRkZGAFDlZ4CImgcGTkTV6Ny5M/z9/REYGIiPP/4YFhYWeOONN9CuXTv4+/urXc4rr7yC5cuXo1OnTujWrRvef/993Lhxo9aRFmdnZ/z8888YP3485HI5rKys4OXlhatXr2LlypV49tlnERMTg3379qkEBa+++ipWrFiBzp07o3v37li9erXKXkAWFhaYN28e5s6di4qKCgwcOBCFhYU4cuQIzM3NERAQoHa/5syZAw8PD6xcuRIjR47E/v37VabpAGDJkiX4z3/+A0dHR4wdOxYGBgb4/fffkZycjHfeeQc+Pj7o2LEjAgICsHLlShQVFUmLw+saiQoLC8OcOXOgUCjg5+eHkpISJCYm4saNGwgJCcHzzz+P//73v/D398eyZcvg4OCAzMxM7Nq1C6+//jrKysrwySefYMSIEbC3t0dqairOnz+PyZMn19n3uvrVsWNH3L17F++//z6GDx+OX3/9FR999JFKGcHBwfDz80OXLl1w48YNHDx4UArInZycIJPJ8P3332PYsGEwMTGBubm52n83RNTAmmx1FVEz8+Ai7evXr4tJkyYJpVIpTExMxJAhQ8T58+el65GRkSqLoYUQIjo6Wtz/z6qsrEwEBQUJhUIhWrduLRYsWCDGjh0rxo8fX2O9R48eFa6urkIul6uUtWHDBuHo6CjMzMzE5MmTRXh4uMri8LKyMvHqq68KhUIhWrVqJUJCQsTkyZNVFqJXVFSIdevWia5du4qWLVuKtm3biiFDhoj4+Pgan0t1i8OFuLcA28HBQZiYmIjhw4eL9957r8rziImJER4eHsLExEQoFArx+OOPi08++US6fu7cOfHEE08IIyMj0a1bN/Hdd98JACImJkYI8f+Lw0+dOlWl/m3btolHH31UGBkZidatW4unnnpK7Nq1S7qenZ0tJk+eLKysrIRcLhePPPKICAwMFAUFBSInJ0eMHDlS2NnZCSMjI+Hk5CSWLFkiysvLa3wOmvRr9erVws7OTvq52bp1q8qC76CgINGxY0chl8tF27ZtxaRJk0ReXp50/7Jly4Stra2QyWQiICBApW5wcThRk5IJUY8FF0RULxUVFejevTuee+45ld3CmzNnZ2cEBwc3yudofv31VwwcOBAXL15UWXRP/08mkyE6OlrrT+kQUf1wHyeiBnTp0iVs3LgR58+fR3JyMmbOnIn09HRMnDixqZumkQULFsDc3BwFBQU6LTc6OhqxsbHIyMjAgQMH8PLLL+OJJ55g0FSNGTNmcMqOqBngiBNRA8rKysL48eNx5swZCCHQs2dPrFixQlrA/TC4dOmS9DbYI488Ii141oWtW7fi7bffRlZWFqysrPD0009j1apVaNOmjc7q0FSPHj1q3EH8448/rnFBekPLzc1FYWEhgHvbXtz/piERNR4GTkRE97k/UHyQjY1Nlb2hiOjfhYETERERkZq4xomIiIhITQyciIiIiNTEwImIiIhITQyciIiIiNTEwImIiIhITQyciIiIiNTEwImIiIhITQyciIiIiNT0f/c2ATvrPb4nAAAAAElFTkSuQmCC", "text/plain": [ "
" ] @@ -202,11 +256,10 @@ ], "source": [ "# Find the time step with the maximum temperature\n", - "max_temp_index = era_5_hottest_day['t2m'].argmax(dim='time')\n", - "max_time = era_5_hottest_day['t2m']['time'].isel(time=max_temp_index)\n", + "max_temp_index = era_5_hottest_day.sel(variable='t2m').argmax(dim='valid_time')\n", "\n", - "# Select the data corresponding to the maximum time and plot\n", - "era_5_hottest_day['t2m'].sel(time=max_time).plot(cmap='Reds')" + "# # Select the data corresponding to the maximum time and plot\n", + "era_5_hottest_day.sel(variable='t2m').isel(valid_time=max_temp_index).plot(cmap='Reds')" ] }, { @@ -264,7 +317,7 @@ }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 17, "metadata": {}, "outputs": [ { @@ -304,7 +357,7 @@ ], "source": [ "# Save the era_5_hottest_day temperature to a tif file\n", - "era_5_hottest_day['t2m'].rio.to_raster(raster_path='data/era_5_hottest_day_t2m.tif', driver=\"COG\")" + "era_5_hottest_day.sel(variable='t2m').rio.to_raster(raster_path='data/era_5_hottest_day_t2m.tif', driver=\"COG\")" ] } ], From be9802044ed8a265b11f4d12acd79d079f4175df Mon Sep 17 00:00:00 2001 From: Chris Rowe Date: Tue, 24 Sep 2024 11:57:57 -0400 Subject: [PATCH 15/29] Preserve $HOME --- .github/workflows/dev_ci_cd_conda.yml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dev_ci_cd_conda.yml b/.github/workflows/dev_ci_cd_conda.yml index 76818e4..5b2b1b1 100644 --- a/.github/workflows/dev_ci_cd_conda.yml +++ b/.github/workflows/dev_ci_cd_conda.yml @@ -17,15 +17,16 @@ jobs: matrix: python-version: ["3.10"] steps: + - name: Preserve $HOME set in the container + run: echo HOME=/root >> "$GITHUB_ENV" - name: Add ERA5 API key run: | cat < $HOME/.cdsapirc url: ${{ secrets.ERA5_URL }} key: ${{ secrets.ERA5_KEY }} EOF - - uses: actions/checkout@v4 - - uses: conda-incubator/setup-miniconda@v2 + - uses: conda-incubator/setup-miniconda@v3 with: activate-environment: cities-cif environment-file: environment.yml @@ -40,4 +41,4 @@ jobs: GOOGLE_APPLICATION_USER: ${{ secrets.GOOGLE_APPLICATION_USER }} GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }} run: | - pytest tests \ No newline at end of file + pytest From 11a6603861e48e292afbf6e06485bf1f3fae4f82 Mon Sep 17 00:00:00 2001 From: Chris Rowe Date: Tue, 24 Sep 2024 12:03:49 -0400 Subject: [PATCH 16/29] try again --- .github/workflows/dev_ci_cd_conda.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/dev_ci_cd_conda.yml b/.github/workflows/dev_ci_cd_conda.yml index 5b2b1b1..5355cb7 100644 --- a/.github/workflows/dev_ci_cd_conda.yml +++ b/.github/workflows/dev_ci_cd_conda.yml @@ -18,7 +18,9 @@ jobs: python-version: ["3.10"] steps: - name: Preserve $HOME set in the container - run: echo HOME=/root >> "$GITHUB_ENV" + run: | + echo $HOME + echo HOME=/home/runner >> "$GITHUB_ENV" - name: Add ERA5 API key run: | cat < $HOME/.cdsapirc From dbff5cbc65369b435948162b2903f899a6cc9238 Mon Sep 17 00:00:00 2001 From: Chris Rowe Date: Tue, 24 Sep 2024 16:34:23 -0400 Subject: [PATCH 17/29] v2 --- .github/workflows/dev_ci_cd_conda.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dev_ci_cd_conda.yml b/.github/workflows/dev_ci_cd_conda.yml index 5355cb7..ab80d3f 100644 --- a/.github/workflows/dev_ci_cd_conda.yml +++ b/.github/workflows/dev_ci_cd_conda.yml @@ -20,7 +20,7 @@ jobs: - name: Preserve $HOME set in the container run: | echo $HOME - echo HOME=/home/runner >> "$GITHUB_ENV" + echo HOME=$HOME >> "$GITHUB_ENV" - name: Add ERA5 API key run: | cat < $HOME/.cdsapirc @@ -28,7 +28,7 @@ jobs: key: ${{ secrets.ERA5_KEY }} EOF - uses: actions/checkout@v4 - - uses: conda-incubator/setup-miniconda@v3 + - uses: conda-incubator/setup-miniconda@v2 with: activate-environment: cities-cif environment-file: environment.yml From 5cebf7235205f0640354d9012fac25cb8abe4b6b Mon Sep 17 00:00:00 2001 From: weiqi-tori Date: Fri, 27 Sep 2024 18:07:37 +0800 Subject: [PATCH 18/29] try update github action --- .github/workflows/dev_ci_cd_conda.yml | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/.github/workflows/dev_ci_cd_conda.yml b/.github/workflows/dev_ci_cd_conda.yml index ab80d3f..4a45463 100644 --- a/.github/workflows/dev_ci_cd_conda.yml +++ b/.github/workflows/dev_ci_cd_conda.yml @@ -17,16 +17,20 @@ jobs: matrix: python-version: ["3.10"] steps: - - name: Preserve $HOME set in the container + - name: Set up .cdsapirc run: | - echo $HOME - echo HOME=$HOME >> "$GITHUB_ENV" - - name: Add ERA5 API key - run: | - cat < $HOME/.cdsapirc - url: ${{ secrets.ERA5_URL }} - key: ${{ secrets.ERA5_KEY }} - EOF + echo "url: ${{ secrets.ERA5_URL }}" > ~/.cdsapirc + echo "key: ${{ secrets.ERA5_KEY }}" >> ~/.cdsapirc + # - name: Preserve $HOME set in the container + # run: | + # echo $HOME + # echo HOME=$HOME >> "$GITHUB_ENV" + # - name: Add ERA5 API key + # run: | + # cat < $HOME/.cdsapirc + # url: ${{ secrets.ERA5_URL }} + # key: ${{ secrets.ERA5_KEY }} + # EOF - uses: actions/checkout@v4 - uses: conda-incubator/setup-miniconda@v2 with: @@ -43,4 +47,4 @@ jobs: GOOGLE_APPLICATION_USER: ${{ secrets.GOOGLE_APPLICATION_USER }} GOOGLE_APPLICATION_CREDENTIALS: ${{ secrets.GOOGLE_APPLICATION_CREDENTIALS }} run: | - pytest + pytest tests From 2c15d7b7950ce5ce9fc68a1baa6ae0421738bf73 Mon Sep 17 00:00:00 2001 From: weiqi-tori <79890935+weiqi-tori@users.noreply.github.com> Date: Sun, 29 Sep 2024 16:03:54 +0800 Subject: [PATCH 19/29] Update dev_ci_cd_conda.yml --- .github/workflows/dev_ci_cd_conda.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dev_ci_cd_conda.yml b/.github/workflows/dev_ci_cd_conda.yml index 4a45463..b975227 100644 --- a/.github/workflows/dev_ci_cd_conda.yml +++ b/.github/workflows/dev_ci_cd_conda.yml @@ -19,8 +19,8 @@ jobs: steps: - name: Set up .cdsapirc run: | - echo "url: ${{ secrets.ERA5_URL }}" > ~/.cdsapirc - echo "key: ${{ secrets.ERA5_KEY }}" >> ~/.cdsapirc + echo "url: ${{ secrets.ERA5_URL }}" > $HOME/.cdsapirc + echo "key: ${{ secrets.ERA5_KEY }}" >> $HOME/.cdsapirc # - name: Preserve $HOME set in the container # run: | # echo $HOME From 6cc023f9bfdc86e81b44ad85636797d210f2d482 Mon Sep 17 00:00:00 2001 From: Chris Rowe Date: Fri, 4 Oct 2024 10:08:10 -0400 Subject: [PATCH 20/29] missing , --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index c2814a7..1cb51f1 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ "boto3", "overturemaps", "cdsapi", - "timezonefinder" + "timezonefinder", "scikit-learn>=1.5.1", "scikit-image>=0.24.0", "exactextract>=0.2.0" From cd5de4e1489a98822f133ac227c9fdf73dd7ceaf Mon Sep 17 00:00:00 2001 From: weiqi-tori Date: Thu, 10 Oct 2024 18:15:58 +0800 Subject: [PATCH 21/29] skip tests for era5 layer and metrix --- .github/workflows/dev_ci_cd_conda.yml | 14 -------------- tests/test_layers.py | 1 + tests/test_metrics.py | 2 ++ 3 files changed, 3 insertions(+), 14 deletions(-) diff --git a/.github/workflows/dev_ci_cd_conda.yml b/.github/workflows/dev_ci_cd_conda.yml index b975227..c8b81f6 100644 --- a/.github/workflows/dev_ci_cd_conda.yml +++ b/.github/workflows/dev_ci_cd_conda.yml @@ -17,20 +17,6 @@ jobs: matrix: python-version: ["3.10"] steps: - - name: Set up .cdsapirc - run: | - echo "url: ${{ secrets.ERA5_URL }}" > $HOME/.cdsapirc - echo "key: ${{ secrets.ERA5_KEY }}" >> $HOME/.cdsapirc - # - name: Preserve $HOME set in the container - # run: | - # echo $HOME - # echo HOME=$HOME >> "$GITHUB_ENV" - # - name: Add ERA5 API key - # run: | - # cat < $HOME/.cdsapirc - # url: ${{ secrets.ERA5_URL }} - # key: ${{ secrets.ERA5_KEY }} - # EOF - uses: actions/checkout@v4 - uses: conda-incubator/setup-miniconda@v2 with: diff --git a/tests/test_layers.py b/tests/test_layers.py index 917fc55..f8e1fe2 100644 --- a/tests/test_layers.py +++ b/tests/test_layers.py @@ -48,6 +48,7 @@ def test_built_up_height(): data = BuiltUpHeight().get_data(BBOX) assert np.size(data) > 0 +@pytest.mark.skip(reason="CDS API needs personal access token file to run") def test_era_5_hottest_day(): data = Era5HottestDay().get_data(BBOX) assert np.size(data) > 0 diff --git a/tests/test_metrics.py b/tests/test_metrics.py index bcdde74..8fd42cc 100644 --- a/tests/test_metrics.py +++ b/tests/test_metrics.py @@ -1,5 +1,6 @@ from city_metrix import * from .conftest import ZONES +import pytest def test_built_land_with_high_lst(): @@ -23,6 +24,7 @@ def test_built_land_without_tree_cover(): assert expected_zone_size == actual_indicator_size +@pytest.mark.skip(reason="CDS API needs personal access token file to run") def test_era_5_met_preprocess(): indicator = era_5_met_preprocessing(ZONES) assert len(indicator) == 24 From 676fb84813c2b3136a4f5ec565daba783e47cab7 Mon Sep 17 00:00:00 2001 From: weiqi-tori Date: Fri, 11 Oct 2024 15:43:31 +0800 Subject: [PATCH 22/29] remove pytz --- environment.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/environment.yml b/environment.yml index eb71a05..30bbb00 100644 --- a/environment.yml +++ b/environment.yml @@ -22,7 +22,6 @@ dependencies: - pip=23.3.1 - boto3=1.34.124 - cdsapi=0.7.3 - - pytz=2024.1 - timezonefinder=6.5.2 - scikit-learn=1.5.1 - scikit-image=0.24.0 From a70abcedcd108203480a53a5a31dbd77a402f41b Mon Sep 17 00:00:00 2001 From: weiqi-tori Date: Fri, 11 Oct 2024 16:27:10 +0800 Subject: [PATCH 23/29] remove sklearn --- environment.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/environment.yml b/environment.yml index 30bbb00..53ce12b 100644 --- a/environment.yml +++ b/environment.yml @@ -23,8 +23,6 @@ dependencies: - boto3=1.34.124 - cdsapi=0.7.3 - timezonefinder=6.5.2 - - scikit-learn=1.5.1 - - scikit-image=0.24.0 - exactextract=0.2.0 - netcdf4=1.6.2 - pip: From cd5e367d4fefe84d516c40e1ea9308ffd1071b95 Mon Sep 17 00:00:00 2001 From: weiqi-tori Date: Fri, 11 Oct 2024 17:19:45 +0800 Subject: [PATCH 24/29] remove netcdf --- environment.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/environment.yml b/environment.yml index 53ce12b..8afde98 100644 --- a/environment.yml +++ b/environment.yml @@ -24,6 +24,5 @@ dependencies: - cdsapi=0.7.3 - timezonefinder=6.5.2 - exactextract=0.2.0 - - netcdf4=1.6.2 - pip: - overturemaps==0.6.0 From 9b777ed27ad35c2df5186c3696f825b91a033ec9 Mon Sep 17 00:00:00 2001 From: weiqi-tori Date: Fri, 11 Oct 2024 17:33:03 +0800 Subject: [PATCH 25/29] add back skimage --- environment.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/environment.yml b/environment.yml index 8afde98..0350113 100644 --- a/environment.yml +++ b/environment.yml @@ -23,6 +23,7 @@ dependencies: - boto3=1.34.124 - cdsapi=0.7.3 - timezonefinder=6.5.2 + - scikit-image=0.24.0 - exactextract=0.2.0 - pip: - overturemaps==0.6.0 From 765cdf209b7f699b224ee7f57628cce3b9566e57 Mon Sep 17 00:00:00 2001 From: weiqi-tori Date: Fri, 11 Oct 2024 17:50:33 +0800 Subject: [PATCH 26/29] try add era5 test back --- .github/workflows/dev_ci_cd_conda.yml | 4 ++++ setup.py | 1 - tests/test_layers.py | 2 +- tests/test_metrics.py | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dev_ci_cd_conda.yml b/.github/workflows/dev_ci_cd_conda.yml index c8b81f6..65566ea 100644 --- a/.github/workflows/dev_ci_cd_conda.yml +++ b/.github/workflows/dev_ci_cd_conda.yml @@ -17,6 +17,10 @@ jobs: matrix: python-version: ["3.10"] steps: + - name: Set up .cdsapirc + run: | + echo "url: ${{ secrets.ERA5_URL }}" > $HOME/.cdsapirc + echo "key: ${{ secrets.ERA5_KEY }}" >> $HOME/.cdsapirc - uses: actions/checkout@v4 - uses: conda-incubator/setup-miniconda@v2 with: diff --git a/setup.py b/setup.py index 1cb51f1..a46fcde 100644 --- a/setup.py +++ b/setup.py @@ -25,7 +25,6 @@ "overturemaps", "cdsapi", "timezonefinder", - "scikit-learn>=1.5.1", "scikit-image>=0.24.0", "exactextract>=0.2.0" ], diff --git a/tests/test_layers.py b/tests/test_layers.py index f8e1fe2..e6ca71d 100644 --- a/tests/test_layers.py +++ b/tests/test_layers.py @@ -48,7 +48,7 @@ def test_built_up_height(): data = BuiltUpHeight().get_data(BBOX) assert np.size(data) > 0 -@pytest.mark.skip(reason="CDS API needs personal access token file to run") +# @pytest.mark.skip(reason="CDS API needs personal access token file to run") def test_era_5_hottest_day(): data = Era5HottestDay().get_data(BBOX) assert np.size(data) > 0 diff --git a/tests/test_metrics.py b/tests/test_metrics.py index 8fd42cc..946a6e2 100644 --- a/tests/test_metrics.py +++ b/tests/test_metrics.py @@ -24,7 +24,7 @@ def test_built_land_without_tree_cover(): assert expected_zone_size == actual_indicator_size -@pytest.mark.skip(reason="CDS API needs personal access token file to run") +# @pytest.mark.skip(reason="CDS API needs personal access token file to run") def test_era_5_met_preprocess(): indicator = era_5_met_preprocessing(ZONES) assert len(indicator) == 24 From e77ff39af78d5dc064b05ea1d867784be0e31359 Mon Sep 17 00:00:00 2001 From: weiqi-tori Date: Fri, 11 Oct 2024 18:08:40 +0800 Subject: [PATCH 27/29] replace home directory --- .github/workflows/dev_ci_cd_conda.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/dev_ci_cd_conda.yml b/.github/workflows/dev_ci_cd_conda.yml index 65566ea..d33de04 100644 --- a/.github/workflows/dev_ci_cd_conda.yml +++ b/.github/workflows/dev_ci_cd_conda.yml @@ -19,8 +19,8 @@ jobs: steps: - name: Set up .cdsapirc run: | - echo "url: ${{ secrets.ERA5_URL }}" > $HOME/.cdsapirc - echo "key: ${{ secrets.ERA5_KEY }}" >> $HOME/.cdsapirc + echo "url: ${{ secrets.ERA5_URL }}" > ~/.cdsapirc + echo "key: ${{ secrets.ERA5_KEY }}" >> ~/.cdsapirc - uses: actions/checkout@v4 - uses: conda-incubator/setup-miniconda@v2 with: From 40fa6759cc52a2f3ed453871afacba6ae58f468d Mon Sep 17 00:00:00 2001 From: weiqi-tori Date: Fri, 11 Oct 2024 18:23:11 +0800 Subject: [PATCH 28/29] try again --- .github/workflows/dev_ci_cd_conda.yml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/dev_ci_cd_conda.yml b/.github/workflows/dev_ci_cd_conda.yml index d33de04..7c4c28f 100644 --- a/.github/workflows/dev_ci_cd_conda.yml +++ b/.github/workflows/dev_ci_cd_conda.yml @@ -17,10 +17,16 @@ jobs: matrix: python-version: ["3.10"] steps: - - name: Set up .cdsapirc + - name: Preserve $HOME set in the container run: | - echo "url: ${{ secrets.ERA5_URL }}" > ~/.cdsapirc - echo "key: ${{ secrets.ERA5_KEY }}" >> ~/.cdsapirc + echo $HOME + echo HOME=$HOME >> "$GITHUB_ENV" + - name: Add ERA5 API key + run: | + cat < $HOME/.cdsapirc + url: ${{ secrets.ERA5_URL }} + key: ${{ secrets.ERA5_KEY }} + EOF - uses: actions/checkout@v4 - uses: conda-incubator/setup-miniconda@v2 with: From 34a549fd5223e2e300d888a0ecdf9774c432973e Mon Sep 17 00:00:00 2001 From: weiqi-tori Date: Fri, 11 Oct 2024 18:33:22 +0800 Subject: [PATCH 29/29] skip era5 test --- .github/workflows/dev_ci_cd_conda.yml | 10 ---------- tests/test_layers.py | 2 +- tests/test_metrics.py | 2 +- 3 files changed, 2 insertions(+), 12 deletions(-) diff --git a/.github/workflows/dev_ci_cd_conda.yml b/.github/workflows/dev_ci_cd_conda.yml index 7c4c28f..c8b81f6 100644 --- a/.github/workflows/dev_ci_cd_conda.yml +++ b/.github/workflows/dev_ci_cd_conda.yml @@ -17,16 +17,6 @@ jobs: matrix: python-version: ["3.10"] steps: - - name: Preserve $HOME set in the container - run: | - echo $HOME - echo HOME=$HOME >> "$GITHUB_ENV" - - name: Add ERA5 API key - run: | - cat < $HOME/.cdsapirc - url: ${{ secrets.ERA5_URL }} - key: ${{ secrets.ERA5_KEY }} - EOF - uses: actions/checkout@v4 - uses: conda-incubator/setup-miniconda@v2 with: diff --git a/tests/test_layers.py b/tests/test_layers.py index e6ca71d..f8e1fe2 100644 --- a/tests/test_layers.py +++ b/tests/test_layers.py @@ -48,7 +48,7 @@ def test_built_up_height(): data = BuiltUpHeight().get_data(BBOX) assert np.size(data) > 0 -# @pytest.mark.skip(reason="CDS API needs personal access token file to run") +@pytest.mark.skip(reason="CDS API needs personal access token file to run") def test_era_5_hottest_day(): data = Era5HottestDay().get_data(BBOX) assert np.size(data) > 0 diff --git a/tests/test_metrics.py b/tests/test_metrics.py index 946a6e2..8fd42cc 100644 --- a/tests/test_metrics.py +++ b/tests/test_metrics.py @@ -24,7 +24,7 @@ def test_built_land_without_tree_cover(): assert expected_zone_size == actual_indicator_size -# @pytest.mark.skip(reason="CDS API needs personal access token file to run") +@pytest.mark.skip(reason="CDS API needs personal access token file to run") def test_era_5_met_preprocess(): indicator = era_5_met_preprocessing(ZONES) assert len(indicator) == 24