Skip to content

Commit 568cb79

Browse files
committed
Multiple Updates:
- Added MERRA data bias corrections - Added individual Biomass quantity maps - CSP works again - Changed the masking for RoofTop (still needs extra work) - Shapefile location is updated
1 parent c97cd47 commit 568cb79

8 files changed

Lines changed: 260 additions & 161 deletions

File tree

code/config.py

Lines changed: 31 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ def general_settings():
6767
param["author"] = "Thushara Addanki" # the name of the person running the script
6868
param["comment"] = "Potential Analysis"
6969
param["path_database_windows"] = "..\..\pyGRETA\Database_KS" # specify the relative (from the runme.py file) or the absolute path to the database folder
70-
param["path_database_linux"] = os.path.expanduser("~") + fs + "database_ks" # specify path to database on linux
70+
param["path_database_linux"] = os.path.expanduser("~") + fs + "pygreta" + fs + "0_database" # specify path to database on linux
7171

7272
if sys.platform.startswith("win"):
7373
root = param["path_database_windows"] # use windows location of database folder
@@ -123,10 +123,11 @@ def scope_paths_and_parameters(paths, param, config_file):
123123
skip_blank_lines=True, ) # Import parameters from config_files in folder 'configs'
124124
input_dict = input_df[1].to_dict() # Convert dataframe to dict with values from the first column
125125

126-
paths["subregions"] = PathTemp + input_dict["regions"].replace(" ", "")
127126
param["region_name"] = input_dict["region_name"].replace(" ", "") # Name tag of the spatial scope
128127
param["subregions_name"] = input_dict["subregions_name"] .replace(" ", "") # Name tag of the subregions
129128
param["country_code"] = input_dict["country_code"].replace(" ", "")
129+
paths["subregions"] = PathTemp + "gadm40_" + param["country_code"] + "_shp" + fs + input_dict["regions"].replace(
130+
" ", "")
130131
param["year"] = int(input_dict["year"].replace(" ", "")) # Convert string 'xxxx' to int
131132
param["technology"] = input_dict["technology"].replace(" ", "").split(',') # Creat array by comma separated string
132133
param["gid"] = input_dict["gid"].replace(" ", "") # Define spatial level according to GID
@@ -148,7 +149,7 @@ def computation_parameters(param):
148149
:return param: The updated dictionary param.
149150
:rtype: dict
150151
"""
151-
param["nproc"] = 6
152+
param["nproc"] = 10
152153
param["CPU_limit"] = True
153154
return param
154155

@@ -426,27 +427,27 @@ def osm_areas(param):
426427
def buffers(param):
427428

428429
buffer = {
429-
"snow": 4,
430-
"water": 1,
431-
"wetland": 1,
430+
"snow": 4, #Landuse
431+
"water": 1, #Landuse
432+
"wetland": 1, #Landuse
432433

433-
"protected_areas_pv": 1,
434-
"protected_areas_windon": 2,
435-
"protected_areas_windoff": 4,
434+
"protected_areas_pv": 1, #ProtectedAreas
435+
"protected_areas_windon": 2, #ProtectedAreas
436+
"protected_areas_windoff": 4, #ProtectedAreas
436437

437-
"airport_windon": 16,
438-
"boarder": 2,
438+
"airport_windon": 16, #Airports
439+
"boarder": 2, #gadm
439440

440-
"commercial_windon" : 2,
441-
"industrial_windon" : 1,
442-
"mining" : 1,
443-
"military_windon" : 2,
444-
"park_pv" : 1,
445-
"park_windon" : 3,
446-
"recreation_windon" : 1,
441+
"commercial_windon" : 2, #osm
442+
"industrial_windon" : 1, #osm
443+
"mining" : 1, #osm
444+
"military_windon" : 2, #osm
445+
"park_pv" : 1, #osm
446+
"park_windon" : 3, #osm
447+
"recreation_windon" : 1, #osm
447448

448-
"settlement_pv": 1,
449-
"settlement_windon" : 4,
449+
"settlement_pv": 1, #WSF
450+
"settlement_windon" : 4, #WSF
450451

451452
"hydrolakes" : 1,
452453
"hydrorivers_pv" : 1,
@@ -649,7 +650,7 @@ def csp_parameters(param):
649650
}
650651
csp["mask"] = {
651652
"slope": 20,
652-
"lu_suitability": np.array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0]),
653+
"lu_suitability": np.array([1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,1,1,1,1,1,0,0,0,0,1,1,1,0,0]),
653654
"pa_suitability": np.array([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
654655
}
655656
csp["weight"] = {
@@ -992,7 +993,7 @@ def output_folders(paths, param):
992993

993994
# Main output folder
994995
# paths["region"] = root + "03 Intermediate files" + fs + "Files " + region + fs # old structure of database
995-
paths["region"] = os.path.join(root, "..", "1_results", "Files" + region, "")
996+
paths["region"] = os.path.join(root, "..", "1_results", "Files " + region, "")
996997

997998
# Output folder for weather data
998999
paths["weather_data"] = paths["region"] + "Weather data" + fs
@@ -1049,6 +1050,9 @@ def weather_output_paths(paths, param):
10491050
year = str(param["year"])
10501051
paths["W50M"] = paths["weather_data"] + "w50m_" + year + ".mat"
10511052
paths["CLEARNESS"] = paths["weather_data"] + "clearness_" + year + ".mat"
1053+
paths["SWGDN"] = paths["weather_data"] + "SWGDN_" + year + ".mat"
1054+
paths["SWTDN"] = paths["weather_data"] + "SWTDN_" + year + ".mat"
1055+
paths["SWGDN_real"] = paths["weather_data"] + "SWGDN_real_" + year + ".mat"
10521056
paths["T2M"] = paths["weather_data"] + "t2m_" + year + ".mat"
10531057
paths["W50M_offshore"] = paths["weather_data"] + "w50m_offshore" + year + ".mat"
10541058

@@ -1101,6 +1105,7 @@ def local_maps_paths(paths, param):
11011105
paths["AREA"] = PathTemp + "_Area.mat" # Area per pixel in m²
11021106
paths["AREA_offshore"] = PathTemp + "_Area_offshore.mat" # Area per pixel in m²
11031107
paths["TOPO"] = PathTemp + "_Topography.mat" # Topography
1108+
paths["TOPO_low"] = PathTemp + "_Topography_low.mat"
11041109
paths["SLOPE"] = PathTemp + "_Slope.mat" # Slope
11051110
paths["BATH"] = PathTemp + "_Bathymetry.mat" # Bathymetry
11061111

@@ -1283,6 +1288,9 @@ def potential_output_paths(paths, param, tech):
12831288

12841289
# File name for Biomass
12851290
if tech in ["Biomass"]:
1291+
paths[tech]["BIOMASS_CROPS"] = PathTemp + "_Biomass_Crops.mat"
1292+
paths[tech]["BIOMASS_WOOD"] = PathTemp + "_Biomass_Wood.mat"
1293+
paths[tech]["BIOMASS_MANURE"] = PathTemp + "_Biomass_Manure.mat"
12861294
paths[tech]["BIOMASS_ENERGY"] = PathTemp + "_Biomass_Energy.mat"
12871295
paths[tech]["BIOMASS_CO2"] = PathTemp + "_Biomass_CO2.mat"
12881296
# File name for all other tech
@@ -1339,7 +1347,7 @@ def regional_analysis_output_paths(paths, param, tech):
13391347
paths[tech]["Region_Stats"] = PathTemp + "_Region_stats_" + year + ".csv"
13401348

13411349
if tech != "Biomass":
1342-
paths[tech]["Locations"] = PathTemp + "_Locations.shp"
1350+
paths[tech]["Locations"] = PathTemp + "_Locations_" + year + ".shp"
13431351
paths[tech]["TS"] = PathTemp + "_TS_" + year + ".csv"
13441352
paths[tech]["Sorted_FLH"] = PathTemp + "_sorted_FLH_sampled_" + year + ".mat"
13451353
paths[tech]["Regression_coefficients"] = paths["regression_out"] + subregions + "_" + tech + "_reg_coefficients_"

code/initialization.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
from lib.log import logger
44
import geopandas as gpd
55
import numpy as np
6+
import urllib.request
7+
import os
8+
import zipfile
69
import shapely
710
# import matplotlib.pyplot as plt
811

@@ -81,7 +84,7 @@ def read_EEZ(paths, param, scope_shp):
8184
eez_shp = gpd.read_file(paths["EEZ_global"]) # Import all exclusive economic zones worldwide
8285
eez_shp = eez_shp.to_crs(epsg=4326) # In case it is not already in this format
8386

84-
countries = scope_shp['GID_0'].drop_duplicates() # Obtain the countries out of the regions shapefile
87+
countries = scope_shp['ID_0'].drop_duplicates() # Obtain the countries out of the regions shapefile
8588
eez_shp = eez_shp[eez_shp['ISO_Ter1'].isin(countries)].reset_index() # Remain only eez areas of countries involved
8689

8790
param["offshore_scope"] = sf.define_spatial_scope(eez_shp)

code/lib/input_maps.py

Lines changed: 34 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,15 @@ def generate_maps_for_scope(paths, param, multiprocessing):
5252
"""
5353

5454
generate_land(paths, param) # Subregions
55-
generate_sea(paths, param) # Sea
55+
# generate_sea(paths, param) # Sea
56+
generate_topography(paths, param)
5657
generate_weather_files(paths, param) # MERRA Weather data for land
57-
generate_weather_offshore_files(paths, param) # MERRA Weather data for offshore # comment out if no offshore
58+
# generate_weather_offshore_files(paths, param) # MERRA Weather data for offshore # comment out if no offshore
5859

5960
if multiprocessing:
6061
processes = []
6162

6263
processes.append(mp.Process(target=generate_area, args=(paths, param)))
63-
processes.append(mp.Process(target=generate_topography, args=(paths, param)))
6464
processes.append(mp.Process(target=generate_landuse, args=(paths, param)))
6565
processes.append(mp.Process(target=generate_protected_areas, args=(paths, param)))
6666
processes.append(mp.Process(target=generate_airports, args=(paths, param)))
@@ -244,8 +244,30 @@ def generate_weather_files(paths, param): #ToDo: Multiprocessing?
244244

245245
# Create the overall wind speed
246246
W50M = abs(U50M + (1j * V50M))
247+
hdf5storage.writes({"SWTDN": SWTDN}, paths["SWTDN"], store_python_metadata=True,
248+
matlab_compatible=True)
249+
hdf5storage.writes({"SWGDN": SWGDN}, paths["SWGDN"], store_python_metadata=True,
250+
matlab_compatible=True)
247251
# Calculate the clearness index
248-
CLEARNESS = np.divide(SWGDN, SWTDN, out=np.zeros_like(SWGDN), where=SWTDN != 0)
252+
# MERRA bias corrections
253+
TOPO_low = hdf5storage.read("TOPO_low", paths["TOPO_low"]).astype(float)
254+
TOPO_low = TOPO_low / 1000 #in km
255+
SWGDN = hdf5storage.read("SWGDN", paths["SWGDN"]).astype(float)
256+
SWTDN = hdf5storage.read("SWTDN", paths["SWTDN"]).astype(float)
257+
numfactor1 = 1 + 0.087 * np.multiply(TOPO_low, TOPO_low) - 0.065 * TOPO_low - 0.51
258+
# numfactor2 = np.multiply(SWGDN, SWTDN)
259+
num = np.zeros([param["m_low"],param["n_low"],8760])
260+
for hour in range(8760):
261+
num[:,:,hour] = np.multiply(numfactor1, SWGDN[:,:,hour])
262+
den = -0.82 * SWGDN + SWTDN
263+
CLEARNESS = np.divide(num, den, out=np.zeros_like(num), where=den != 0)
264+
for i in range(param["m_low"]):
265+
for j in range(param["n_low"]):
266+
for k in range(8760):
267+
if CLEARNESS[i,j,k] > 0.7:
268+
CLEARNESS[i,j,k] = SWGDN[i,j,k] / SWTDN[i,j,k]
269+
# Clearness without corrections
270+
# CLEARNESS = np.divide(SWGDN, SWTDN, out=np.zeros_like(SWGDN), where=SWTDN != 0)
249271

250272
sys.stdout.write("\n")
251273
logger.info("Writing Files: T2M, W50M, CLEARNESS")
@@ -640,55 +662,27 @@ def generate_topography(paths, param):
640662
logger.info('Skip') # Skip generation if files are already there
641663

642664
else:
665+
# if 1==1:
643666
logger.info("Start")
644667
Crd_all = param["Crd_all"]
645-
# Ind = sf.ind_global(Crd_all, param["res_topography"])[0]
646668
Ind = sf.ind_global(Crd_all, param["res_desired"])[0]
647669
GeoRef = param["GeoRef"]
648-
# Topo = np.zeros((int(180 / param["res_topography"][0]), int(360 / param["res_topography"][1])))
649-
# tile_extents = np.zeros((24, 4), dtype=int)
650-
# i = 1
651-
# j = 1
652-
# for letter in ul.char_range("A", "X"):
653-
# north = (i - 1) * 45 / param["res_topography"][0] + 1
654-
# east = j * 60 / param["res_topography"][1]
655-
# south = i * 45 / param["res_topography"][0]
656-
# west = (j - 1) * 60 / param["res_topography"][1] + 1
657-
# tile_extents[ord(letter) - ord("A"), :] = [north, east, south, west]
658-
# j = j + 1
659-
# if j == 7:
660-
# i = i + 1
661-
# j = 1
662-
# n_min = (Ind[0] // (45 * 240)) * 45 / param["res_topography"][0] + 1
663-
# e_max = (Ind[1] // (60 * 240) + 1) * 60 / param["res_topography"][1]
664-
# s_max = (Ind[2] // (45 * 240) + 1) * 45 / param["res_topography"][0]
665-
# w_min = (Ind[3] // (60 * 240)) * 60 / param["res_topography"][1] + 1
666-
#
667-
# need = np.logical_and(
668-
# (np.logical_and((tile_extents[:, 0] >= n_min), (tile_extents[:, 1] <= e_max))),
669-
# np.logical_and((tile_extents[:, 2] <= s_max), (tile_extents[:, 3] >= w_min)),
670-
# )
671-
#
672-
# for letter in ul.char_range("A", "X"):
673-
# index = ord(letter) - ord("A")
674-
# if need[index]:
675-
# with rasterio.open(paths["Topo_tiles"] + "15-" + letter + ".tif") as src:
676-
# tile = src.read()
677-
# Topo[tile_extents[index, 0] - 1 : tile_extents[index, 2], tile_extents[index, 3] - 1 : tile_extents[index, 1]] = tile[0, 0:-1, 0:-1]
678-
#
679-
# A_TOPO = np.flipud(Topo[Ind[0] - 1 : Ind[2], Ind[3] - 1 : Ind[1]])
680-
# A_TOPO = sf.adjust_resolution(A_TOPO, param["res_topography"], param["res_desired"], "mean")
681-
# A_TOPO = sf.recalc_topo_resolution(A_TOPO, param["res_topography"], param["res_desired"])
670+
m_low = param ["m_low"]
671+
n_low = param ["n_low"]
682672

683673
with rasterio.open(paths["Topo_global"]) as src:
684674
A_TOPO = src.read(1, window=rasterio.windows.Window.from_slices(slice(Ind[0] - 1, Ind[2]),
685675
slice(Ind[3] - 1, Ind[1])))
686676
A_TOPO = np.flipud(A_TOPO)
687677

678+
A_TOPO_low = np.zeros([m_low,n_low])
679+
for i in range(m_low):
680+
for j in range(n_low):
681+
A_TOPO_low[i,j] = np.sum(A_TOPO[i:i+200,j:j+250])/(200*250)
688682

689683
hdf5storage.writes({"TOPO": A_TOPO}, paths["TOPO"], store_python_metadata=True, matlab_compatible=True)
684+
hdf5storage.writes({"TOPO_low": A_TOPO_low}, paths["TOPO_low"], store_python_metadata=True, matlab_compatible=True)
690685
logger.info("files saved: " + paths["TOPO"])
691-
# ul.create_json(paths["TOPO"], param, ["region_name", "Crd_all", "res_topography", "res_desired", "GeoRef"], paths, ["Topo_tiles", "TOPO"])
692686
ul.create_json(paths["TOPO"], param, ["region_name", "Crd_all", "res_desired", "GeoRef"],
693687
paths, ["Topo_global", "TOPO"])
694688
if param["savetiff_inputmaps"]:
@@ -1408,7 +1402,6 @@ def generate_livestock(paths, param):
14081402
:rtype: None
14091403
"""
14101404
logger.info("Start")
1411-
res_desired = param["res_desired"]
14121405
Crd_all = param["Crd_all"]
14131406
Ind = sf.ind_global(Crd_all, param["res_livestock"])[0]
14141407
GeoRef = param["GeoRef"]
@@ -1421,7 +1414,6 @@ def generate_livestock(paths, param):
14211414
slice(Ind[3] - 1, Ind[1])))
14221415
A_LS = np.flipud(A_LS)
14231416
A_LS = sf.recalc_livestock_resolution(A_LS, param["res_livestock"], param["res_desired"])
1424-
# print (np.size(A_LS))
14251417
A_LS[A_LS < 0] = float(0)
14261418
A_LS = np.multiply(A_LS, A_area) / (10 ** 6)
14271419

code/lib/physical_models.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,10 @@ def calc_CF_solar(hour, reg_ind, param, merraData, rasterData, tech):
203203

204204
if tech == "CSP":
205205
# Wind Speed Corrected at 2m
206-
w2m_h = ul.resizem(merraData["W50M"][:, :, hour], m_high, n_high)
207-
w2m_h = w2m_h[reg_ind] * rasterData["A_WindSpeed_Corr"][reg_ind]
206+
# w2m_h = ul.resizem(merraData["W50M"][:, :, hour], m_high, n_high)
207+
w2m_h = merraData["W50M"][:, :, hour]
208+
# w2m_h = w2m_h[reg_ind] * rasterData["A_WindSpeed_Corr"][reg_ind]
209+
w2m_h = w2m_h[reg_ind_h] * rasterData["A_WindSpeed_Corr"][reg_ind_h]
208210

209211
# Wind Speed cutoff filter:
210212
windfilter = w2m_h >= csp["Wind_cutoff"]

0 commit comments

Comments
 (0)