Commit 756bc7de authored by Roelofsen, Hans's avatar Roelofsen, Hans
Browse files

Merge branch 'stuff_hans' into 'master'

Stuff hans

See merge request !11
parents 694dbb38 117b4031
import pandas as pd
import os
import pathlib
import numpy as np
import sys
sys.path.append('..')
class TabularSpecies:
"""
Class holding pandas data frame and helper dicts on all MNP species
......@@ -14,7 +16,7 @@ class TabularSpecies:
filepath = pathlib.Path(__file__)
# De volledige Species tabel als Pandas dataframe
benb_dir = os.path.dirname(os.path.dirname(filepath))
benb_dir = pathlib.Path(filepath.parents[1])
self.df = pd.read_csv(os.path.join(benb_dir, r'resources\mnp_species.csv'), sep=',', comment='#')
# Dictionaries tussen code, lokale naam, wetenschappelijke naam
......@@ -40,6 +42,11 @@ class TabularSpecies:
self.code2sel281 = dict(zip(self.df.Species_code, self.df.sel281.map({1: True, 0: False})))
self.code2sel146 = dict(zip(self.df.Species_code, self.df.sel146.map({1: True, 0: False})))
# Additional data sources
self.pop_factors_src = r'W:\PROJECTS\QMAR\MNP-SNL-ParameterSet\Parameters_v05_2021_04_08\07_MNP_versie4_par_population_factors.csv'
self.pop_factors = pd.read_csv(self.pop_factors_src, sep=',')
self.code2local_distance = dict(zip(self.pop_factors.Species_code, self.pop_factors.Local_distance))
self.code2key_area = dict(zip(self.pop_factors.Species_code, self.pop_factors.Key_area))
class IndividualSpecies:
"""
......@@ -47,7 +54,7 @@ class IndividualSpecies:
Hans Roelofsen, WEnR, 12 jan 2022
"""
def __init__(self, x):
def __init__(self, x, brief=False):
"""
Initiate for a species.
:param x: species code, local name or scientific name
......@@ -67,16 +74,53 @@ class IndividualSpecies:
print('{} is not a recognized species'.format(x))
raise
self.taxondict = {'S02': 'V', 'S06': 'E', 'S09': 'P'}
# Set all relevant attributes
self.code = getattr(species_tab, '{}2code'.format(typer))[x] # Species code
self.local = getattr(species_tab, '{}2local'.format(typer))[x] # Species local name
self.scientific = getattr(species_tab, '{}2scientific'.format(typer))[x] # Species Scientific name
self.taxondict = {'S02': 'V', 'S06': 'E', 'S09': 'P'}
self.taxon = self.taxondict[self.code[:3]]
self.sel281 = species_tab.code2sel281[self.code] # boolean, species is part of 281 selection?
self.sel468 = species_tab.code2sel468[self.code] # idem for 468 selection
self.sel146 = species_tab.code2sel146[self.code] # idem foo 146 selection
self.selall = species_tab.code2selall[self.code] # catch all
self.key_area = species_tab.code2key_area[self.code]
self.local_distance = species_tab.code2local_distance[self.code]
if not brief:
# Set all relevant attributes
self.sel281 = species_tab.code2sel281[self.code] # boolean, species is part of 281 selection?
self.sel468 = species_tab.code2sel468[self.code] # idem for 468 selection
self.sel146 = species_tab.code2sel146[self.code] # idem foo 146 selection
self.selall = species_tab.code2selall[self.code] # catch all
self.groupinfo = '146:{0} - 281:{1} - 468:{2}'.format(self.sel146, self.sel281, self.sel468)
def response_to_abiotic(self, abiotic_limits, x):
"""
return response to a given Abiotic value
:param abiotic_limits: array with 4 values [L20, L80, H80, H20] in MNP speak
:param x: the abiotic value
:return: response {0, 0.5, 1}
_____
1| | |
| | |
0.5| _____| |_____
| | |
| | |
0 __|________________|__
L20 L80 H80 H20
"""
# limits = np.array(getattr(self, '{}_response_src'.format(abiotic)).loc[self.code])
return [0, 0.5, 1, 0.5, 0][int(np.digitize(x, abiotic_limits))]
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('species', help='Species local name, scientific name or code.')
parser.add_argument('what', help='any property of the species')
args = parser.parse_args()
sp = IndividualSpecies(args.species)
try:
print(getattr(sp, args.what))
except AttributeError:
print('{0} does not have a {1}'.format(sp.local, args.what))
sys.exit(1)
self.groupinfo = '146:{0} - 281:{1} - 468:{2}'.format(self.sel146, self.sel281, self.sel468)
\ No newline at end of file
"""
Find value of Abiotic Condition (AC) to accomodate as many species as possible based on species response to the AC
Hans Roelofsen, 24-01-2022
"""
import os
import rasterio as rio
import pandas as pd
import pathlib
import sys
import datetime
from Classes.Species import IndividualSpecies as Species
import dkq
import read_sources as src
# Append one level up to sys path and import mrt module from there.
# See: https://git.wur.nl/roelo008/mrt
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'
self.gvg_response = pd.read_csv(self.gvg_response_src, index_col='Species_code')
self.ndep_response = pd.read_csv(self.ndep_response_src, index_col='Species_code')
self.ph_response = pd.read_csv(self.ph_response_src, index_col='Species_code')
def get_abiotic_limits(self, sp_code, abiotic):
"""
Return abiotic limits for a species
:param sp_code: species code as formatted in MNP
:param abiotic: {ph, ndep, ph}
"""
# TODO: dit past misschien beter bij Classes.Species.IndividualSpecies
tab = getattr(self, '{}_response'.format(abiotic))
return tab.loc[sp_code]
def optimum_for_bt(self, bt, abiotic_condition, sp_list, of='tuple', verbose=False):
"""
return optimum value of a abiotic condition given a Beheertype and species list
:param bt: Beheertype
:param abiotic_condition: {gvg, ph, ndep}
:param sp_list: {146, 281}
:param of: output format
:return: float
"""
# 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)
# Empty dataframe for results
response_df = pd.DataFrame(data={'response_sum': 0, 'n_species': 0},
index=getattr(self, '{}_range'.format(abiotic_condition)))
# Loop over species in ht especies list
for c in species_lst:
sp = Species(c, brief=True)
species_abiotic_limits = self.get_abiotic_limits(sp.code, abiotic_condition)
# Loop over each abiotic value in the provided range
for i in response_df.index:
# Species response to this abiotic value {0, 0.5, 1}
species_response = sp.response_to_abiotic(species_abiotic_limits, i)
# Add tot summed species response
response_df.loc[i, 'response_sum'] = response_df.loc[i, 'response_sum'] + species_response
# Add 1 to number of species with response > 0
if species_response > 0:
response_df.loc[i, 'n_species'] = response_df.loc[i, 'n_species'] + 1
# The optimal abiotic condition is where:
# first the response_sum is highest
# then the n_species is highest
# then the lowest abiotic value
# Note: dit is zoals gesuggereerd door Marlies Sanders, 7 mrt 2022
top_score = response_df.response_sum.max()
abiotic_optimum = response_df.loc[response_df.response_sum == top_score, 'n_species'].idxmax()
n_with_optimum = response_df.loc[response_df.response_sum ==top_score].shape[0]
# Score is the summed species response PLUS number of species with response > 0
# Dit is een alternatieve methode.
# response_df['score'] = response_df.sum(axis=1)
# Determine top score and corresponding abiotic condition value
# top_score = response_df.score.max()
# abiotic_optimum = response_df.score.idxmax() # First occurence of maximum
# n_with_optimum = response_df.loc[response_df.score == top_score].shape[0]
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, outdir, outname, mapping='from_species',
**kwargs):
"""
Remap a Beheertypen map to the abiotic optimum corresponding to each beheertype
:param abiotic: {gvg, ph, ndep}
:param sp_list: which species list?
:param bt_raster: path to template beheertypen raster
: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
"""
abiotic = abiotic.lower()
# Open template beheertypen raster
bt = rio.open(bt_raster)
bt_arr = bt.read(1)
# 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(' ')]
bt_vat['optimum'] = None
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:
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()
assert bt.shape == (prof['height'], prof['width'])
assert bt.transform == prof['transform']
# Set non-compatible beheertypen and otherwise to Nodata
bt_vat.optimum.fillna(prof['nodata'], inplace=True)
# Apply mapping between BT map pixel value and optimum
d = dict(zip(bt_vat['Value'], bt_vat['optimum']))
d[bt.nodata] = prof['nodata']
out = mrt.vec_translate(bt_arr, d).astype(prof['dtype'])
# Write to file
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,
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)
if os.path.isfile(destination):
print('...succes, see {}'.format(destination))
if __name__ == '__main__':
def query4bt(**kwargs):
foo = AbioticOptimum()
out = foo.optimum_for_bt(bt=kwargs.get('bt'), abiotic_condition=kwargs.get('abiotic'),
sp_list=kwargs.get('sp_list'), of=kwargs.get('of'))
print(out)
def remap_bt(**kwargs):
foo = AbioticOptimum()
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()
sp = Species(kwargs.get('species'))
response_values = foo.get_abiotic_limits(sp.code, kwargs.get('abiotic'))
d = dict(zip(['L20', 'L80', 'H80', 'H20'], response_values))
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')])
import argparse
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest='subparser_name')
# 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_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=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')
parser_b.add_argument('abiotic', help='abiotic condition', type=str, choices=['gvg', 'ph', 'ndep'])
parser_b.add_argument('bt', help='Beheertype code', type=str)
parser_b.add_argument('--of', help='output format', type=str, choices=['tuple', 'df', 'dict', 'single', 'str'],
default='str')
parser_b.add_argument('--sp_list', help='which species list', type=int, choices=[146, 281, 468], default=281)
parser_b.set_defaults(func=query4bt)
# Subparser for abiotic range of a Species
parser_c = subparsers.add_parser('query4Species', help='get Abiotic limit values for a species')
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='csv')
parser_c.set_defaults(func=query4sp)
try:
args = parser.parse_args()
args.func(**vars(args))
except AssertionError as e:
print('\nError! {0}.'.format(e))
sys.exit(1)
......@@ -3,14 +3,14 @@ python program for quering MNP draagkracht file
Hans Roelofsen, jan 2022
"""
import sys
import pandas as pd
import os
from fix_bt import fix_bt
from snl_beheertypen import get_snl_beheertypen_list
from snl_beheertypen import btcode2description
from Classes import Species as species
# from Classes.Species import TabSpeciesInstance as mnps
from fix_bt import fix_bt # imports a function
from snl_beheertypen import get_snl_beheertypen_list # imports a function
from snl_beheertypen import code2name # imports a dictionary
from Classes import Species as species # imports a module with two classes
species_table = species.TabularSpecies()
......@@ -24,6 +24,8 @@ class DraagKracht:
self.bt_column = 'Land_type_code'
self.dk = None
self.read_dk()
def read_dk(self, dk_file='default', bt_column=None):
"""
Read a draagkrachten file
......@@ -40,7 +42,7 @@ class DraagKracht:
target = self.defaultdk
setattr(self, "dk", pd.read_csv(os.path.join(self.dkdir, target)))
def query4bt(self, bt_lst: list, of, sp_sel='281'):
def query4bt(self, bt_lst: list, of='brief', sp_sel='281'):
"""
query the draagkrachten for a specific beheertype
:param bt_lst: beheertype code
......@@ -49,21 +51,33 @@ class DraagKracht:
:return: str to stdout
"""
if isinstance(bt_lst, str):
bt_lst = [bt_lst]
for bt in bt_lst:
query = '({0} in {1}) and selection == True'.format(self.bt_column, [fix_bt(bt, as_mnp=True)])
sel = self.dk.assign(selection=self.dk.Species_code.map(getattr(species_table, 'code2sel{}'.format(sp_sel)))) \
.query(query)
counts = sel.Species_code.map(species_table.code2taxon).value_counts()
print('{0}-{1}: {2} vogel, {3} vlinder {4} plant. {5} total (out of {6}).'\
.format(bt, btcode2description(bt), counts.get('V', 0), counts.get('E', 0), counts.get('P', 0),
sel.shape[0], sp_sel if sp_sel != 'all' else '1081'))
if of == 'full':
print(sel.assign(local=sel.Species_code.map(species_table.code2local),
taxon=sel.Species_code.map(species_table.code2taxon))\
.sort_values(by=['taxon', 'local']) \
.loc[:, ['Species_code', 'taxon', 'Land_type_quality', 'local']] \
.to_csv(sep='\t', index=False, header=False))
message_brief = '{0}-{1}: {2} vogel, {3} vlinder {4} plant. {5} total (out of {6}).' \
.format(bt, code2name[fix_bt(bt, as_mnp=True)],
counts.get('V', 0), counts.get('E', 0), counts.get('P', 0),
sel.shape[0], sp_sel if sp_sel != 'all' else '1081')
message_full = sel.assign(local=sel.Species_code.map(species_table.code2local),
taxon=sel.Species_code.map(species_table.code2taxon)) \
.sort_values(by=['taxon', 'local']) \
.loc[:, ['Species_code', 'taxon', 'Land_type_quality', 'local']] \
.to_csv(sep='\t', index=False, header=False)
dict_out = dict(zip(sel['Species_code'], sel['Land_type_quality']))
if of == 'brief':
print(message_brief)
elif of == 'full':
print(message_brief)
print(message_full)
elif of == 'dict':
return dict_out
def query4species(self, species_lst: list, of):
"""
......@@ -80,10 +94,11 @@ class DraagKracht:
print("{0} ({1}-{2}. Listed in: {3}): {4} beheertypen".format(sp.local, sp.scientific, sp.code,
sp.groupinfo, sel.shape[0]))
if of == 'full':
print(sel.assign(desc=getattr(sel, self.bt_column).map(btcode2description)) \
df = sel.assign(desc=getattr(sel, self.bt_column).map(code2name)) \
.loc[:, ['Land_type_quality', self.bt_column, 'desc']] \
.sort_values(by=self.bt_column) \
.to_csv(sep='\t', index=False, header=False))
.sort_values(by=self.bt_column)
df.to_clipboard(sep='\t', index=False)
print(df.to_csv(sep='\t', index=False, header=False))
if __name__ == '__main__':
......@@ -94,35 +109,40 @@ if __name__ == '__main__':
parser.add_argument('--qsp', nargs='+', type=str)
parser.add_argument('--of', choices=['full', 'sparse'], default='full')
parser.add_argument('--sp_list', choices=['281', '468', '146', 'all'], default='281', type=str)
# parser.add_argument('--dk_file', help='draagrkachten file', default=)
args = parser.parse_args()
hans = DraagKracht()
hans.read_dk()
if args.qbt:
hans.query4bt(bt_lst=args.qbt, of=args.of, sp_sel=args.sp_list)
if args.qsp:
hans.query4species(species_lst=args.qsp, of=args.of)
d = {'S02': 'V',
'S06': 'E',
'S09': 'P'}
full = pd.read_csv(r'w:\PROJECTS\QMAR\MNP-SNL-ParameterSet\Parameters_v06_2019_12_09\01_Base_species_name.csv', sep=',', comment='#')
full.set_index(keys='Species_code', drop=False, inplace=True)
full['taxon'] = full.index.str.slice(0,3).map(d)
sel468 = pd.read_csv(r'W:\PROJECTS\QMAR\MNP-SNL-ParameterSet\Parameters_v05_2021_04_08\09_MNP_versie4_Group_Species_valid model_468.csv', sep=',', index_col='Species_code')
sel281 = pd.read_csv(r'W:\PROJECTS\QMAR\MNP-SNL-ParameterSet\Parameters_v05_2021_04_08\09_MNP_versie4_Species_group_valid_model_280.csv', sep=',', index_col='Species_code')
sel146 = pd.read_csv(r'W:\PROJECTS\QMAR\MNP-SNL-ParameterSet\Parameters_v06_2019_12_09\09_MNP_versie4_Species_group_valid_model_typisch_146.csv', sep=',', index_col='Species_code')
in468 = full.index.intersection(sel468.index)
in281 = full.index.intersection(sel281.index)
in146 = full.index.intersection(sel146.index)
full.loc[:, 'sel468'] = 0
full.loc[in468, 'sel468'] = 1
full.loc[:, 'sel281'] = 0
full.loc[in281, 'sel281'] = 1
full.loc[:, 'sel146'] = 0
full.loc[in146, 'sel146'] = 1
full.loc[:, 'sel1018'] = 1
full.loc[:, 'selall'] = 1
full.to_clipboard(sep=',', index=False)
try:
if args.qbt:
hans.query4bt(bt_lst=args.qbt, of=args.of, sp_sel=args.sp_list)
if args.qsp:
hans.query4species(species_lst=args.qsp, of=args.of)
except AssertionError as e:
print(e)
sys.exit(1)
#
# d = {'S02': 'V',
# 'S06': 'E',
# 'S09': 'P'}
# full = pd.read_csv(r'w:\PROJECTS\QMAR\MNP-SNL-ParameterSet\Parameters_v06_2019_12_09\01_Base_species_name.csv', sep=',', comment='#')
# full.set_index(keys='Species_code', drop=False, inplace=True)
# full['taxon'] = full.index.str.slice(0,3).map(d)
# sel468 = pd.read_csv(r'W:\PROJECTS\QMAR\MNP-SNL-ParameterSet\Parameters_v05_2021_04_08\09_MNP_versie4_Group_Species_valid model_468.csv', sep=',', index_col='Species_code')
# sel281 = pd.read_csv(r'W:\PROJECTS\QMAR\MNP-SNL-ParameterSet\Parameters_v05_2021_04_08\09_MNP_versie4_Species_group_valid_model_280.csv', sep=',', index_col='Species_code')
# sel146 = pd.read_csv(r'W:\PROJECTS\QMAR\MNP-SNL-ParameterSet\Parameters_v06_2019_12_09\09_MNP_versie4_Species_group_valid_model_typisch_146.csv', sep=',', index_col='Species_code')
# in468 = full.index.intersection(sel468.index)
# in281 = full.index.intersection(sel281.index)
# in146 = full.index.intersection(sel146.index)
# full.loc[:, 'sel468'] = 0
# full.loc[in468, 'sel468'] = 1
# full.loc[:, 'sel281'] = 0
# full.loc[in281, 'sel281'] = 1
# full.loc[:, 'sel146'] = 0
# full.loc[in146, 'sel146'] = 1
# full.loc[:, 'sel1018'] = 1
# full.loc[:, 'selall'] = 1
# full.to_clipboard(sep=',', index=False)
"""
Function to retrieve default MNP draagkracht for species/bt combination
"""
import pandas as pd
import numpy as np
# Get default mnp draagkracht values
mnp_dk_src = r'w:\PROJECTS\qmar\MNP-SNL-ParameterSet\Parameters_v06_2019_12_09\03_MNP_versie6_par_density_factors_BT2019_v2.csv'
mnp_dk = pd.read_csv(mnp_dk_src, sep=',',usecols=['Species_code', 'Land_type_code', 'Land_type_quality'])
def get_mnp_dk(species_code, bt_code, tab=mnp_dk):
"""
:param species_code: MNP species code starting with S02, S06, S09
:param bt_code: BT code NXX.YY.ZZ
:param tab: source table
:return: float draagrkacht
"""
dk = mnp_dk.loc[(mnp_dk.Species_code == species_code) & (mnp_dk.Land_type_code == bt_code), 'Land_type_quality']
if not dk.empty:
return float(dk)
else:
return np.nan
import os
import pandas as pd
import geopandas as gp
import sys
def read_gis(dir, lyr):
"""
Read either shapefile from disk or layer from Geopacakge
:param dir: file directory or GeoPackage
:param lyr: shapefile name within file dir or GPKG layer name
:return: geopandas geodataframe
"""
try:
if dir.endswith('gpkg'):
params = {'filename': dir, 'layer': lyr}
else:
params = {'filename': os.path.join(dir, lyr)}
foo = gp.read_file(**params)
# add hectare
foo['area_ha'] = foo.area/10000
return foo
except ValueError as e:
print('Incorrect layer source or name: '.format(e))
raise
def read_src(src, **kwargs):
"""Extract relevant lambda function to read a file and execute"""
return {
'.csv': lambda inner_src, **inner_kwargs: pd.read_csv(inner_src, inner_kwargs.get('sep')),
'.dbf': lambda inner_src: gp.read_file(inner_src),