def _make_racmo_wind_speed() -> Layer: return Layer( id='racmo_wind_speed', title='Annual mean wind speed 1958-2019 (5km)', description= ("""Averaged annual mean wind speed in meters per second from RACMO2.3p2 for the period 1958-2019."""), tags=[], style='racmo_wind_speed', input=LayerInput( dataset=dataset, asset=dataset.assets['only'], ), steps=[ decompress_step( input_file='{input_dir}/RACMO_QGreenland_Jan2021.zip', decompress_contents_mask='magnitudes.nc', ), *warp_and_cut( input_file='{input_dir}/magnitudes.nc', output_file='{output_dir}/racmo_wind_speed.tif', cut_file=project.boundaries['data'].filepath, ), *compress_and_add_overviews( input_file='{input_dir}/racmo_wind_speed.tif', output_file='{output_dir}/racmo_wind_speed.tif', dtype_is_float=True, ), ], )
def _make_masked_racmo_layer( *, layer_id: str, title: str, description: str, style: str, input_filename: str, decompress_contents_mask: str, variable: str, nodata: int = -9999, gdal_edit_args=(), ) -> Layer: return Layer( id=layer_id, title=title, description=description, tags=[], style=style, input=LayerInput( dataset=dataset, asset=dataset.assets['only'], ), steps=[ decompress_step( input_file='{input_dir}/RACMO_QGreenland_Jan2021.zip', decompress_contents_mask=decompress_contents_mask, ), # Apply the promice mask. The `Promicemask` values are 3 = Greenland ice # sheet; 2,1 = Greenland peripheral ice caps; 0 = Ocean. This step masks # out the ocean as 'nodata'. CommandStep(args=[ 'gdal_calc.py', f'--calc="numpy.where((B != 0), A, {nodata})"', f'--NoDataValue={nodata}', '--outfile={output_dir}/' + f'{variable}.tif', '-A', 'NETCDF:{input_dir}/' + f'{input_filename}:{variable}', '-B', ('NETCDF:{input_dir}/' 'Icemask_Topo_Iceclasses_lon_lat_average_1km_GrIS.nc:Promicemask' ), ], ), *gdal_edit( input_file='{input_dir}/' + f'{variable}.tif', output_file='{output_dir}/edited.tif', gdal_edit_args=[ '-a_srs', project.crs, *gdal_edit_args, ], ), *compress_and_add_overviews( input_file='{input_dir}/edited.tif', output_file='{output_dir}/' + f'racmo_{variable}.tif', dtype_is_float=True, ), ], )
def sea_ice_age_layer(year: int, age_type: AgeType) -> Layer: layer_info = seaice_age_layers[year][age_type] return Layer( id=f'seaice_{age_type}_age_{year}', title=f"{layer_info['date_range']} {year}", description=( f"""Age of sea ice derived from weekly averaged ice motion vectors. A value of N indicates ice aged N-1 to N years. A value of 20 represents land; 21 represents ocean cells where ice age was not calculated. Week of {age_type} extent chosen based on NSDIC's Sea Ice Index 5-day average.""" ), tags=[], style='sea_ice_age', input=LayerInput( dataset=dataset, asset=dataset.assets[str(year)], ), steps=[ CommandStep( args=[ 'gdal_translate', '-b', layer_info['band_num'], ( 'NETCDF:{input_dir}/' f'iceage_nh_12.5km_{year}0101_{year}1231_v4.1.nc:age_of_sea_ice' ), '{output_dir}/age_of_sea_ice.tif', ], ), *gdal_edit( input_file='{input_dir}/age_of_sea_ice.tif', output_file='{output_dir}/edited.tif', gdal_edit_args=[ '-a_ullr', '-4518421 4518421 4506579 -4506579', ], ), *warp_and_cut( input_file='{input_dir}/edited.tif', output_file='{output_dir}/warped_and_cut.tif', cut_file=project.boundaries['background'].filepath, reproject_args=[ '-tr', '12500', '12500', ], ), *compress_and_add_overviews( input_file='{input_dir}/warped_and_cut.tif', output_file='{output_dir}/overviews.tif', dtype_is_float=False, ), ], )
def surface_elevation_layer( *, array_index: int, start_year: int, end_year: int, variable: SurfaceElevVar, ) -> Layer: if variable == 'SEC': description = 'Rate of surface elevation change in meters per year.' style = 'surface_elevation_change' else: description = 'Error of rate of surface elevation change in meters per year.' style = 'surface_elevation_change_errors' return Layer( id=f'surface_elevation_change_{variable.lower()}_{start_year}_{end_year}', title=f'Surface elevation change {start_year}-{end_year}', description=description, tags=[], style=style, input=LayerInput( dataset=dataset, asset=dataset.assets['only'], ), steps=[ CommandStep( args=[ 'gdalmdimtranslate', '-co', 'COMPRESS=DEFLATE', '-array', f'name={variable},view=[:,:,{array_index}]', '{input_dir}/Release/CCI_GrIS_RA_SEC_5km_Vers2.0_2020-08-26.nc', '{output_dir}/' + f'{variable.lower()}_{start_year}_{end_year}.tif', ], ), *compress_and_add_overviews( input_file=( '{input_dir}/' f'{variable.lower()}_{start_year}_{end_year}.tif' ), output_file='{output_dir}/overviews.tif', dtype_is_float=True, ), ], )
def _make_layer( *, layer_id: str, title: str, description: str, style: str, filename: str, dataset: Dataset, ) -> Layer: return Layer( id=layer_id, title=title, description=description, tags=[], style=style, input=LayerInput( dataset=dataset, asset=dataset.assets['only'], ), steps=[ decompress_step( input_file='{input_dir}/archive.zip', decompress_contents_mask=filename, ), *warp_and_cut( input_file='{input_dir}/' + filename, output_file='{output_dir}/' + filename, reproject_args=[ # Source data is 0.02x-0.02 degrees resolution. Rene noted in # his email to QGreenland on 2021-01-22 that the geoid and # gravity anomaly grids are 2km resolution. '-tr', '2000', '2000', ], cut_file=project.boundaries['data'].filepath, ), *compress_and_add_overviews( input_file='{input_dir}/' + filename, output_file='{output_dir}/' + filename, dtype_is_float=True, ), ], )
def _layer(year) -> Layer: month = conc_max_month(year) month_name = calendar.month_name[month] return Layer( id=f'seaice_maximum_concentration_{year}', title=f'{month_name} {year}', description=CONCENTRATION_DESCRIPTION, tags=[], style=CONCENTRATION_STYLE, input=LayerInput( dataset=dataset, asset=dataset.assets[f'maximum_concentration_{year}'], ), # TODO: Extract to helper steps=[ CommandStep( args=[ 'gdal_calc.py', '--calc', "'A / 10.0'", '-A', '{input_dir}/*.tif', '--outfile={output_dir}/downscaled.tif', ], ), *warp_and_cut( input_file='{input_dir}/downscaled.tif', output_file='{output_dir}/warped_and_cut.tif', cut_file=project.boundaries['background'].filepath, ), *compress_and_add_overviews( input_file='{input_dir}/warped_and_cut.tif', output_file='{output_dir}/overviews.tif', dtype_is_float=False, ), ], )
cut_file=project.boundaries['data'].filepath, ), CommandStep(args=[ 'gdal_calc.py', '--calc', '"A * 100.0"', '--NoDataValue', '-9999', '--type', 'Int32', '-A', '{input_dir}/arctic_dem.tif', '--outfile', '{output_dir}/arctic_dem_scaled.tif', ], ), *gdal_edit( input_file='{input_dir}/arctic_dem_scaled.tif', output_file='{output_dir}/arctic_dem.tif', gdal_edit_args=[ '-scale', '0.01', ], ), *compress_and_add_overviews( input_file='{input_dir}/arctic_dem.tif', output_file='{output_dir}/arctic_dem.tif', dtype_is_float=False, ), ], )
title=f'September {year}', description=CONCENTRATION_DESCRIPTION, tags=[], style=CONCENTRATION_STYLE, input=LayerInput( dataset=dataset, asset=dataset.assets[f'minimum_concentration_{year}'], ), steps=[ CommandStep(args=[ 'gdal_calc.py', '--calc', "'A / 10.0'", '-A', '{input_dir}/*.tif', '--outfile={output_dir}/downscaled.tif', ], ), *warp_and_cut( input_file='{input_dir}/downscaled.tif', output_file='{output_dir}/warped_and_cut.tif', cut_file=project.boundaries['background'].filepath, ), *compress_and_add_overviews( input_file='{input_dir}/warped_and_cut.tif', output_file='{output_dir}/overviews.tif', dtype_is_float=False, ), ], ) for year in MIN_CONCENTRATION_YEARS ]
the year 3007. Values less than or equal to 16% are masked."""), tags=[], style='future_ice_sheet_coverage', input=LayerInput( dataset=dataset, asset=dataset.assets[f'rcp_{rcp}'], ), steps=[ *warp( input_file=( 'NETCDF:{input_dir}/' f'percent_gris_g1800m_v3a_rcp_{rcp}_0_1000.nc:sftgif'), output_file='{output_dir}/extracted.tif', warp_args=( '-srcnodata', '0', '-tr', '1800', '1800', ), cut_file=project.boundaries['data'].filepath, ), *compress_and_add_overviews( input_file='{input_dir}/extracted.tif', output_file='{output_dir}/final.tif', dtype_is_float=True, ), ], ) for rcp in LAYER_RCPS ]
*warp( input_file='NETCDF:{input_dir}/IBCAO_v4_400m_ice.nc:z', output_file='{output_dir}/bathymetric_chart.tif', warp_args=( '-s_srs', '"+proj=stere +lat_0=90 +lat_ts=75 +datum=WGS84"', '-dstnodata', '-9999', '-tr', '400', '400', # This dataset does not contain CF-compliant fields or # geotransform array. Set # `GDAL_NETCDF_IGNORE_XY_AXIS_NAME_CHECKS` to `true` to use # the provided `x` and `y` dims as coordinate values so that # gdal can compute the transform on its own. See # https://github.com/OSGeo/gdal/issues/4075 '--config', 'GDAL_NETCDF_IGNORE_XY_AXIS_NAME_CHECKS', 'true', ), cut_file=project.boundaries['background'].filepath, ), *compress_and_add_overviews( input_file='{input_dir}/bathymetric_chart.tif', output_file='{output_dir}/bathymetric_chart.tif', dtype_is_float=True, ), ], ) bathymetric_contours = make_layer( layer_id=bathymetric_contours_params['id'], layer_params=bathymetric_contours_params, )
CommandStep( id='merge_bands', args=[ 'gdal_merge.py', '-o', '{output_dir}/merged.tif', '-co', 'COMPRESS=DEFLATE', '-separate', '{input_dir}/b1.tif', '{input_dir}/b2.tif', '{input_dir}/b3.tif', '{input_dir}/mask.tif', ], ), # Finally, add compression with overviews and use the newly added band 4 # as a mask. *compress_and_add_overviews( input_file='{input_dir}/merged.tif', output_file='{output_dir}/overviews.tif', compress_type='JPEG', compress_args=[ '-co', 'JPEG_QUALITY=90', '-co', 'PHOTOMETRIC=YCBCR', '-b', '1', '-b', '2', '-b', '3', # The `-mask 4` option sets band 4 as the mask. '-mask', '4', '--config', 'GDAL_TIFF_INTERNAL_MASK', 'YES', ], ), ], )
def make_racmo_supplemental_layers() -> list[Layer]: layers = [] _racmo_mask_layer_params = { 'racmo_promicemask': { 'title': 'PROMICE mask (1km)', 'description': ("""Mask of categorized Greenland ice. 3 = Greenland ice sheet; 2,1 = Greenland peripheral ice caps; 0 = Ocean."""), 'extract_filename': 'Icemask_Topo_Iceclasses_lon_lat_average_1km_GrIS.nc', 'variable': 'Promicemask', }, 'racmo_grounded_ice': { 'title': 'Grounded ice mask (1km)', 'description': 'Mask of grounded ice. 1 = grounded.', 'extract_filename': 'Icemask_Topo_Iceclasses_lon_lat_average_1km_Aug2020.nc', 'variable': 'grounded_ice', }, } for layer_id, params in _racmo_mask_layer_params.items(): layers.append( Layer( id=layer_id, title=params['title'], description=params['description'], tags=[], style='racmo_promicemask', input=LayerInput( dataset=dataset, asset=dataset.assets['only'], ), steps=[ decompress_step( input_file='{input_dir}/RACMO_QGreenland_Jan2021.zip', decompress_contents_mask=params['extract_filename'], ), CommandStep( args=[ 'gdal_translate', '-a_srs', project.crs, '-a_ullr', RACMO_ULLR, # Data is stored as Float32 but uses integers for mask values. '-ot', 'Byte', '-a_nodata', 'none', ('NETCDF:{input_dir}/' + f"{params['extract_filename']}:{params['variable']}" ), '{output_dir}/' + f"{params['variable']}.tif", ], ), *compress_and_add_overviews( input_file='{input_dir}/' + f"{params['variable']}.tif", output_file='{output_dir}/' + f'{layer_id}.tif', dtype_is_float=False, ), ], ), ) racmo_topography = _make_masked_racmo_layer( layer_id='racmo_topography', title='Ice surface topography (1km)', description= ("""Ice sheet surface elevation in meters upscaled from the Greenland Mapping Project (GIMP) Digital Elevation Model."""), style='racmo_topography', decompress_contents_mask= 'Icemask_Topo_Iceclasses_lon_lat_average_1km_GrIS.nc', input_filename='Icemask_Topo_Iceclasses_lon_lat_average_1km_GrIS.nc', variable='Topography', gdal_edit_args=[ '-a_ullr', RACMO_ULLR, ], ) layers.append(racmo_topography) return layers
native resolution)."""), tags=[], input=LayerInput( dataset=dataset, asset=dataset.assets['55km_map'], ), steps=[ *warp_and_cut( input_file= '{input_dir}/geothermal_heat_flow_map_55km_without_NGRIP.nc', output_file='{output_dir}/geothermal_heat_flow_map_55km.tif', cut_file=project.boundaries['data'].filepath, ), *compress_and_add_overviews( input_file='{input_dir}/geothermal_heat_flow_map_55km.tif', output_file='{output_dir}/geothermal_heat_flow_map_55km.tif', dtype_is_float=True, ), ], ) geothermal_heat_flow_measurements = Layer( id='geothermal_heat_flow_measurements', title='Flow measurement locations', description= ("""Heat flow measurement database used in the creation of the 'Geothermal heat flow map (10km)' layer."""), tags=[], input=LayerInput( dataset=dataset, asset=dataset.assets['heat_flow_measurements'],
id='vegetation_biomass_2010', title='Vegetation biomass 2010 (12.4km)', description=( """Estimated above ground plant biomass for the tundra biome in kilograms per square meter. Based on trans-Arctic field data and AVHRR NDVI. Data provided by ORNL DAAC."""), tags=[], style='vegetation_biomass', input=LayerInput( dataset=dataset, asset=dataset.assets['only'], ), steps=[ *warp( input_file='{input_dir}/aga_circumpolar_avhrr_biomass_2010.tif', output_file='{output_dir}/warped.tif', cut_file=project.boundaries['data'].filepath, warp_args=( '-tr', '12400', '12400', ), ), *compress_and_add_overviews( input_file='{input_dir}/warped.tif', output_file='{output_dir}/compressed.tif', dtype_is_float=True, ), ], )
'gdal_calc.py', '--type', 'Int16', # Set a nodata value of 3. This value does not occur in the data # (valid values are -1, 0, 1). '--NoDataValue', '3', # This dataset contains nans. Replace them with the nodata value (3) '--calc="nan_to_num(A, nan=3)"', '-A', '{input_dir}/basal_thermal_state.tif', '--outfile={output_dir}/basal_thermal_state.tif', ], ), *gdal_edit( input_file='{input_dir}/basal_thermal_state.tif', output_file='{output_dir}/basal_thermal_state.tif', gdal_edit_args=[ '-a_ullr', '-632500.0 -667500.0 847500.0 -3342500.0', '-a_srs', 'EPSG:3413', ], ), *compress_and_add_overviews( input_file='{input_dir}/basal_thermal_state.tif', output_file='{output_dir}/basal_thermal_state.tif', dtype_is_float=False, ), ], )
("""Error estimate for Greenland bed elevation and ice thickness in meters."""), }, } layers = [ Layer( id=f'bedmachine_{key}', title=f'{params["title"]} (150m)', description=params['description'], tags=['terrain_model'], style=f'bedmachine_{key}', input=LayerInput( dataset=bedmachine.bedmachine, asset=bedmachine.bedmachine.assets['only'], ), steps=[ *warp_and_cut( input_file='NETCDF:{input_dir}/' + f'{bedmachine_fn}:{key}', output_file='{output_dir}/warped_and_cut.tif', cut_file='{assets_dir}/greenland_rectangle.geojson', ), *compress_and_add_overviews( input_file='{input_dir}/warped_and_cut.tif', output_file='{output_dir}/overviews.tif', dtype_is_float=False if key == 'errbed' else True, ), ], ) for key, params in bed_datasets.items() ]
'gdal_calc.py', '--calc="A*B"', '--outfile={output_dir}/' + f'masked_{layer_id}.tif', '-A', 'NETCDF:{input_dir}/GRE_G0120_0000.nc:v', '-B', 'NETCDF:{input_dir}/GRE_G0120_0000.nc:ice', ], ), *warp_and_cut( input_file='{input_dir}/' + f'masked_{layer_id}.tif', output_file='{output_dir}/' + f'{layer_id}.tif', cut_file=project.boundaries['data'].filepath, ), *compress_and_add_overviews( input_file='{input_dir}/' + f'{layer_id}.tif', output_file='{output_dir}/' + f'{layer_id}.tif', dtype_is_float=True, ), ], ) for layer_id, params in _masked_velocity_mosaic_params.items() ] velocity_mosaic_ice_mask = Layer( id='velocity_mosaic_ice_mask', title='Ice mask (120m)', description=("""Ice mask used for ITS_LIVE velocity mosiac."""), in_package=False, tags=[], input=LayerInput( dataset=dataset, asset=dataset.assets['only'],
reproject_args=[ # Webpage for this data # (https://doi.pangaea.de/10.1594/PANGAEA.888600) notes All # files are provided in Arctic Polar Stereographic projection # (EPSG:3995 WGS 84) '-s_srs', 'EPSG:3995', '-tr', '10000', '10000', # This dataset does not contain CF-compliant fields or # geotransform array. Set # `GDAL_NETCDF_IGNORE_XY_AXIS_NAME_CHECKS` to `true` to use # the provided `x` and `y` dims as coordinate values so that # gdal can compute the transform on its own. See # https://github.com/OSGeo/gdal/issues/4075 '--config', 'GDAL_NETCDF_IGNORE_XY_AXIS_NAME_CHECKS', 'true', ], cut_file=project.boundaries['data'].filepath, ), *compress_and_add_overviews( input_file='{input_dir}/' + f'{layer_id}.tif', output_file='{output_dir}/' + f'{layer_id}.tif', dtype_is_float=True, ), ], ) for layer_id, params in _layer_params.items() ]
from qgreenland.config.datasets.dms_gtk import ( danish_agency_for_data_supply_and_efficiency_gtk_topo_map as dataset, ) from qgreenland.config.helpers.steps.compress_and_add_overviews import compress_and_add_overviews from qgreenland.models.config.layer import Layer, LayerInput dms_gtk_topo = Layer( id='dms_gtk_topo', title='Topographic map (1 to 500,000)', description=("""Digitized and geolocated topographic map of Greenland."""), tags=[], input=LayerInput( dataset=dataset, asset=dataset.assets['only'], ), steps=[ # NOTE: This layer is not reprojected. We had some issues in the distant # past reprojecting this layer correctly. Its internal CRS is # `EPSG:32624`. *compress_and_add_overviews( input_file='{input_dir}/dms_gtk_topo.tif', output_file='{output_dir}/final.tif', dtype_is_float=False, ), ], )
compress_and_add_overviews, ) from qgreenland.models.config.layer import Layer, LayerInput layers = [Layer( id=f'albedo_{year}_07', title=f'July {year} albedo (1km)', description=( f"""Average broadband planar albedo for July {year} derived from the Ocean and Land Colour Instrument (OLCI) on board the European Union Copernicus Sentinel-3A satellite. Albedo is a fractional value ranging from 0-1 representing the amount of incident solar radiation reflected from the surface.""" ), tags=[], style='albedo', input=LayerInput( dataset=dataset, asset=dataset.assets[f'{year}_07'], ), steps=[ *compress_and_add_overviews( input_file='{input_dir}/*.tif', output_file='{output_dir}/' + f'albedo_{year}_07.tif', dtype_is_float=True, ), ], ) for year in (2018, 2019)]