Commit 9a51fc60 authored by Roelofsen, Hans's avatar Roelofsen, Hans
Browse files

option for remapping BT to Abiotic based on file

parent e4f1d8c0
......@@ -20,14 +20,27 @@ fp = pathlib.Path(__file__)
sys.path.append(str(pathlib.Path(fp).parents[1]))
from mrt.sample import mrt_helpers as mrt
class AbioticOptimum:
"""
Class for holding and calculating abiotic optima for a Beheertype
Hans Roelofsen, WEnR, mrt 2022
"""
def __init__(self):
"""
Initiate
"""
# Set ranges of abiotic values
self.ph_range = [i/10 for i in range(0, 140, 1)]
self.gvg_range = [i for i in range(-50, 150, 5)]
self.ndep_range = [i for i in range(410, 3680, 5)]
# Get draagkracht class instance
self.dk = dkq.DraagKracht()
# Paths to default files with species response towards abiotic conditions
self.gvg_response_src = r'w:\PROJECTS\QMAR\MNP-SNL-ParameterSet\Parameters_v05_2021_04_08\04_MNP_versie4_par_response_GVG.csv'
self.ndep_response_src = r'w:\PROJECTS\QMAR\MNP-SNL-ParameterSet\Parameters_v05_2021_04_08\05_MNP_versie4_par_response_Ndep.csv'
self.ph_response_src = r'w:\PROJECTS\QMAR\MNP-SNL-ParameterSet\Parameters_v05_2021_04_08\06_MNP_versie4_par_response_PH.csv'
......@@ -58,7 +71,7 @@ class AbioticOptimum:
:return: float
"""
# Species list corresponding to this beheertype
# Get species list corresponding to this beheertype
species_lst = [x for x, _ in self.dk.query4bt(bt, of='dict', sp_sel=str(sp_list)).items()]
assert species_lst, "no species found for {}".format(bt)
......@@ -92,17 +105,24 @@ class AbioticOptimum:
abiotic_optimum = response_df.score.idxmax() # First occurence of maximum
n_with_optimum = response_df.loc[response_df.score == top_score].shape[0]
# TODO: alternatieve manier voor optimum bepalen, suggestie Marlies S, 20220307
# eerst hoogste response_sum, daarbinnen hoogste n_species. Bij gelijkspel: laagste abiotiek
msg = '{0} optimum for {1} is {2}'.format(abiotic_condition, bt, abiotic_optimum)
if verbose:
print(msg)
if of == 'df':
response_df.to_clipboard(index=True)
return {'tuple': (len(species_lst), top_score, n_with_optimum, abiotic_optimum),
'df': response_df,
'dict': {bt: abiotic_optimum},
'single': abiotic_optimum,
'str': msg}[of]
def remap_from_bts(self, abiotic, sp_list, bt_raster, bt_vat_file, out_dir, out_name):
def remap_from_bts(self, abiotic, sp_list, bt_raster, bt_vat_file, outdir, outname, mapping='from_species',
**kwargs):
"""
Remap a Beheertypen map to the abiotic optimum corresponding to each beheertype
:param abiotic: {gvg, ph, ndep}
......@@ -111,6 +131,10 @@ class AbioticOptimum:
:param bt_vat_file: path to corresponding raster vat (*.tif.vat.dbf OR *.csv)
:param out_dir: output directory
:param out_name: output name
:param mapping: mapping bteen beheertype and optima {from_species, from_file}
:kwargs: mapping file: path to table file if mapping == from_file
key: key column
val: value column
:return: raster file on disk
"""
......@@ -120,7 +144,7 @@ class AbioticOptimum:
bt = rio.open(bt_raster)
bt_arr = bt.read(1)
# Read Beheertypen map VAT, identify beheertypen and add already columns
# Read mapping between beheertypen and abiotic optima
bt_vat = pd.DataFrame.from_dict(src.mapping_from_file(bt_vat_file, key_col='Value', value_col='Descriptio'),
orient='index', columns=['Description'])
bt_vat['code'] = [x[0] for x in bt_vat.Description.str.split(' ')]
......@@ -128,12 +152,26 @@ class AbioticOptimum:
bt_vat['Value'] = bt_vat.index
# Gather abiotic optimum for beheertype
if mapping == 'from_file':
print(' reading {0} optima from file: {1}'.format(abiotic, kwargs.get('mapping_file')))
bt2opt = src.mapping_from_file(src=kwargs.get('mapping_file'),
key_col=kwargs.get('key'),
value_col=kwargs.get('val'),
sep=kwargs.get('sep'))
origin = 'read from file: {0}'.format(kwargs.get('mapping_file'))
else:
origin = 'optimisation for {0} species list, based on {1}'.format(sp_list,
getattr(self, '{}_response_src'.format(abiotic)))
for code in bt_vat.code.values:
try:
bt_vat.loc[bt_vat.code == code, 'optimum'] = self.optimum_for_bt(code, abiotic, sp_list, 'single',
verbose=True)
except AssertionError as e:
optimum = {'from_file': lambda x: bt2opt[x],
'from_species': lambda x: self.optimum_for_bt(x, abiotic, sp_list, 'single',
verbose=True)}[mapping](code)
except (AssertionError, KeyError) as e:
print(e)
continue
bt_vat.loc[bt_vat.code == code, 'optimum'] = optimum
# Build output profile
prof = mrt.mnp_abiotiek_raster_profile()
......@@ -149,13 +187,12 @@ class AbioticOptimum:
out = mrt.vec_translate(bt_arr, d).astype(prof['dtype'])
# Write to file
destination = os.path.join(out_dir, out_name)
destination = os.path.join(outdir, outname)
with rio.open(destination, 'w', **prof) as dest:
dest.update_tags(creation_date=datetime.datetime.now().strftime('%d-%b-%Y_%H:%M:%S'),
created_by=os.environ.get('USERNAME'),
beheertypen_src_file=bt_raster,
species_response_src_file=getattr(self, '{}_response_src'.format(abiotic)),
content='{0} optimized for Beheertypen based on {1} species list'.format(abiotic, sp_list),
content='{0} based on {1}'.format(abiotic, origin),
created_with=os.path.basename(__file__))
dest.update_tags(**dict(zip(bt_vat.Description, bt_vat.optimum)))
dest.write(out, 1)
......@@ -171,11 +208,15 @@ if __name__ == '__main__':
sp_list=kwargs.get('sp_list'), of=kwargs.get('of'))
print(out)
def remapBT(**kwargs):
def remap_bt(**kwargs):
foo = AbioticOptimum()
foo.remap_from_bts(abiotic=kwargs.get('abiotic'), sp_list=kwargs.get('sp_list'), bt_raster=kwargs.get('bt_rast'),
bt_vat_file=kwargs.get('bt_vat'), out_dir=kwargs.get('outdir'),
out_name=kwargs.get('outname'))
kwargs['mapping'] = 'from_file' if all(kwargs.get('fromfile')) else 'from_species'
kwargs['mapping_file'], kwargs['key'], kwargs['val'], kwargs['sep'] = kwargs.get('fromfile')
try:
foo.remap_from_bts(**kwargs)
except (KeyError, AssertionError) as e:
print(e)
sys.exit(0)
def query4sp(**kwargs):
foo = AbioticOptimum()
......@@ -185,7 +226,7 @@ if __name__ == '__main__':
df = pd.DataFrame.from_dict(d, orient='index', columns=[kwargs.get('abiotic')])
df.T.to_clipboard(sep='\t')
print({'dict': d,
'csv': df.to_csv(sep='\t')}[kwargs.get('of')])
'csv': df.to_csv(sep='\t')}[kwargs.get('of')])
import argparse
parser = argparse.ArgumentParser()
......@@ -194,12 +235,14 @@ if __name__ == '__main__':
# Subparser for remapping a Beheertypen map to Abiotic Optima
parser_a = subparsers.add_parser('remapBT', help='Remap a Beheertypen map to abiotic optima')
parser_a.add_argument('abiotic', help='abiotic condition', type=str, choices=['gvg', 'ph', 'ndep'])
parser_a.add_argument('bt_rast', help='beheertypen raster @ 25m', type=str)
parser_a.add_argument('bt_vat', help='corresponding vat', type=str)
parser_a.add_argument('bt_raster', help='beheertypen raster @ 25m', type=str)
parser_a.add_argument('bt_vat_file', help='corresponding vat', type=str)
parser_a.add_argument('outdir', help='output dir', type=str)
parser_a.add_argument('outname', help='output name', type=str)
parser_a.add_argument('--sp_list', help='which species list', type=int, choices=[146, 281, 468], default=146)
parser_a.set_defaults(func=remapBT)
parser_a.add_argument('--sp_list', help='which species list', type=int, choices=[146, 281, 468], default=281)
parser_a.add_argument('--fromfile', help='src_file key_col val_col seperator when reading mapping from file',
nargs=4, default=[None, None, None, None])
parser_a.set_defaults(func=remap_bt)
# Subparser for querying a beheertype
parser_b = subparsers.add_parser('query4BT', help='Get information on the abtiotic optimum for a Beheertype')
......@@ -215,7 +258,7 @@ if __name__ == '__main__':
parser_c.add_argument('species', help='Species local name, scientific name or code.')
parser_c.add_argument('abiotic', help='abiotic condition', type=str, choices=['gvg', 'ph', 'ndep'])
parser_c.add_argument('--of', help='output format', type=str, choices=['dict', 'csv'],
default='str')
default='csv')
parser_c.set_defaults(func=query4sp)
try:
......
......@@ -53,3 +53,4 @@ def btcode2description(code):
print('\n{} is not a valid beheertype\n'.format(code))
sys.exit(0)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment