Skip to content

Commit 8ef43c1

Browse files
Merge branch 'alpha2-development' into documentation-start
2 parents d2a5026 + a9d67bf commit 8ef43c1

2 files changed

Lines changed: 131 additions & 3 deletions

File tree

plasticparcels/scripts/create_release_maps.py

Lines changed: 129 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import geopandas as gpd
1313
import glob
1414
from scipy import spatial
15+
from scipy.interpolate import RegularGridInterpolator
1516

1617
from utils import distance, get_coords_from_polygon
1718

@@ -394,6 +395,122 @@ def create_fisheries_gfwv2_release_map(fisheries_filepath, mask_land_filepath):
394395
return agg_data_fisheries_info, model_agg_data_fisheries_info
395396

396397

398+
def create_global_concentrations_kaandorp_release_map(mask_land_filepath, mask_coast_filepath, coords_filepath,
399+
kaandorp_filepath, distance_thresshold=50.):
400+
"""
401+
Description
402+
----------
403+
404+
A function to create a particle release map based on the global concentrations data produced by [@Kaandorp2023].
405+
We match this data to the model coastal and ocean cells for a better coverage release.
406+
We use only the 2020 data for all plastic class sizes, and for the ocean cells we only use the surface 0-5m depth.
407+
"""
408+
409+
# Load in the data and select year 2020, all plastic sizes, and for ocean concentrations take the surface layer
410+
ds = xr.open_dataset(kaandorp_filepath)
411+
beach = ds['concentration_beach_mass_log10'].sel({'size_nominal':'all', 'time':2020})
412+
ocean = ds['concentration_mass_log10'].sel({'size_nominal':'all', 'time':2020, 'depth':'0 - <5'})
413+
414+
# Load in coast mask and model coordinates
415+
data_mask_coast = xr.open_dataset(mask_coast_filepath)
416+
coords = xr.open_dataset(coords_filepath, decode_cf=False)
417+
418+
lats_coast = data_mask_coast['lat'].data[np.where(data_mask_coast['mask_coast'])]
419+
lons_coast = data_mask_coast['lon'].data[np.where(data_mask_coast['mask_coast'])]
420+
421+
# Tackle the beach concentrations first:
422+
# Create a list of lons, lats, concentration values
423+
lon_beach = beach.lon_beach.values
424+
lat_beach = beach.lat_beach.values
425+
conc_beach = np.power(10,beach.values) # beach.values are in log10 form
426+
427+
# Load Natural Earth dataset for attaching country information to beach source
428+
shpfilename = shpreader.natural_earth(resolution='50m',
429+
category='cultural',
430+
name='admin_0_countries')
431+
reader = shpreader.Reader(shpfilename)
432+
countries = reader.records()
433+
434+
countries_list = []
435+
for country in countries:
436+
continent = country.attributes['CONTINENT']
437+
region_un = country.attributes['REGION_UN']
438+
subregion = country.attributes['SUBREGION']
439+
country_name = country.attributes['NAME_LONG']
440+
441+
country_coords = get_coords_from_polygon(country.geometry)
442+
country_lons, country_lats = country_coords[:, 0], country_coords[:, 1]
443+
444+
country_df = pd.DataFrame({'Continent': np.repeat(continent, len(country_lons)),
445+
'Region': np.repeat(region_un, len(country_lons)),
446+
'Subregion': np.repeat(subregion, len(country_lons)),
447+
'Country': np.repeat(country_name, len(country_lons)),
448+
'Longitude': country_lons,
449+
'Latitude': country_lats})
450+
countries_list.append(country_df)
451+
coastal_df = pd.concat(countries_list)
452+
453+
# Create coastal concentrations dataset
454+
coast_concentration_list = []
455+
distance_threshhold=50.
456+
457+
for i, (lon, lat) in enumerate(zip(lons_coast,lats_coast)):
458+
# Find the closest beach concentration
459+
distances = distance(np.repeat(lon, len(lon_beach)), np.repeat(lat, len(lat_beach)), lon_beach, lat_beach)
460+
closest_beach_id = np.argmin(distances)
461+
if distances[closest_beach_id] > distance_threshhold: # skip coastal grid cells not within a threshhold from a littered beach
462+
continue
463+
else:
464+
# Find the closest country point to the coastal cell to assign country information
465+
distances_country = distance(np.repeat(lon, len(coastal_df['Longitude'])),
466+
np.repeat(lat, len(coastal_df['Latitude'])),
467+
coastal_df['Longitude'],
468+
coastal_df['Latitude'])
469+
closest_country_id = np.argmin(distances_country)
470+
471+
coast_concentration_list.append({'Continent': coastal_df['Continent'].iloc[closest_country_id],
472+
'Region': coastal_df['Region'].iloc[closest_country_id],
473+
'Subregion': coastal_df['Subregion'].iloc[closest_country_id],
474+
'Country': coastal_df['Country'].iloc[closest_country_id],
475+
'Longitude': lon,
476+
'Latitude': lat,
477+
'Concentration': conc_beach[closest_beach_id],
478+
'ConcentrationType': 'Beach'})
479+
480+
coast_concentration_df = pd.DataFrame.from_records(coast_concentration_list)
481+
482+
# Now tackle the surface ocean concentrations:
483+
conc_ocean = np.power(10,ocean.values) # Values are in log10 space
484+
485+
data_mask_land = xr.open_dataset(mask_land_filepath)
486+
lats_ocean = data_mask_land['lat'].data[np.where(~data_mask_land['mask_land'])]
487+
lons_ocean = data_mask_land['lon'].data[np.where(~data_mask_land['mask_land'])]
488+
489+
# Function to interpolate the ocean concentrations
490+
f_interp_conc_ocean = RegularGridInterpolator((ocean.lon, ocean.lat), conc_ocean.T, method='nearest', bounds_error=False, fill_value=None)
491+
492+
# Interpolate the ocean concentrations to the model grid cells
493+
interp_conc_ocean = f_interp_conc_ocean((lons_ocean, lats_ocean))
494+
495+
# Create ocean concentration dataset where values are non-NaN
496+
non_nan_id = ~np.isnan(interp_conc_ocean)
497+
ocean_concentration_list = []
498+
for i in np.where(non_nan_id)[0]:
499+
ocean_concentration_list.append({'Continent': 'N/A',
500+
'Region': 'N/A',
501+
'Subregion': 'N/A',
502+
'Country': 'N/A',
503+
'Longitude': lons_ocean[i],
504+
'Latitude': lats_ocean[i],
505+
'Concentration': interp_conc_ocean[i],
506+
'ConcentrationType': 'Ocean'})
507+
ocean_concentration_df = pd.DataFrame.from_records(ocean_concentration_list)
508+
509+
# Combine the two beach and ocean datasets
510+
concentration_df = pd.concat([ocean_concentration_df, coast_concentration_df])
511+
512+
return concentration_df
513+
397514
output_data = '/Users/denes001/Research/Projects/PlasticParcels/PlasticParcels/data/release/generated_files/'
398515
mask_land_filepath = '/Users/denes001/Research/Projects/PlasticParcels/PlasticParcels/data/output_data/masks/mask_land_NEMO0083.nc'
399516
mask_coast_filepath = '/Users/denes001/Research/Projects/PlasticParcels/PlasticParcels/data/output_data/masks/mask_coast_NEMO0083.nc'
@@ -420,7 +537,7 @@ def create_fisheries_gfwv2_release_map(fisheries_filepath, mask_land_filepath):
420537
if not os.path.isfile(output_name):
421538
river_dataset = create_rivers_meijer_release_map(mask_coast_filepath=mask_coast_filepath,
422539
river_filepath=river_filepath)
423-
river_dataset.to_csv(output_data+'river_emissions_NEMO0083.csv')
540+
river_dataset.to_csv(output_name)
424541
print("River mismanaged plastic waste file created:", output_name)
425542
else:
426543
print("River mismanaged plastic waste file already exists:", output_name)
@@ -438,3 +555,14 @@ def create_fisheries_gfwv2_release_map(fisheries_filepath, mask_land_filepath):
438555
print("Fishing related plastic waste file created:", output_name, 'and', output_on_model_name)
439556
else:
440557
print("Fishing related plastic waste file already exists:", output_name)
558+
559+
# Create current concentrations release data
560+
kaandorp_filepath = '/Users/denes001/Research/Projects/PlasticParcels/PlasticParcels/data/release/Kaandorp2023/AtlantECO-MAPS_Global_plastic_mass_budget_Kaandorp_etal_2023.nc'
561+
output_name = output_data+'global_concentrations_NEMO0083.csv'
562+
563+
if not os.path.isfile(output_name):
564+
concentration_dataset = create_global_concentrations_kaandorp_release_map(mask_land_filepath, mask_coast_filepath, coords_filepath, kaandorp_filepath, distance_thresshold=50.)
565+
concentration_dataset.to_csv(output_name)
566+
print("Concentration map file created:", output_name)
567+
else:
568+
print("Concentration map file already exists:", output_name)

tests/test_settings.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22

33

44
def test_settings():
5-
settings = pp.utils.load_settings('docs/examples/default_settings.json')
5+
settings = pp.utils.load_settings('docs/examples/example_Italy_coast_settings.json')
66
assert settings is not None
77

88

99
def test_download_script(tmpdir):
10-
settings = pp.utils.load_settings('docs/examples/default_settings.json')
10+
settings = pp.utils.load_settings('docs/examples/example_Italy_coast_settings.json')
1111
pp.utils.download_plasticparcels_dataset("NEMO0083", settings=settings, data_home=tmpdir)
1212
assert True

0 commit comments

Comments
 (0)