Commit d38ea91c authored by Roelofsen, Hans's avatar Roelofsen, Hans
Browse files

Merge branch 'workingHans' into 'master'

Working hans

See merge request !9
parents 6499858e 284ec736
import pandas as pd
import os
import pathlib
import sys
class TabularSpecies:
Class holding pandas data frame and helper dicts on all MNP species
def __init__(self):
filepath = pathlib.Path(__file__)
# De volledige Species tabel als Pandas dataframe
benb_dir = os.path.dirname(os.path.dirname(filepath))
self.df = pd.read_csv(os.path.join(benb_dir, r'resources\mnp_species.csv'), sep=',', comment='#')
# Dictionaries tussen code, lokale naam, wetenschappelijke naam
self.code2local = dict(zip(self.df.Species_code, self.df.Local_name))
self.local2code = dict(zip(self.df.Local_name, self.df.Species_code))
self.code2scientific = dict(zip(self.df.Species_code, self.df.Scientific_name))
self.scientific2code = dict(zip(self.df.Scientific_name, self.df.Species_code))
self.local2scientific = dict(zip(self.df.Local_name, self.df.Scientific_name))
self.scientific2local = dict(zip(self.df.Scientific_name, self.df.Local_name))
self.code2taxon = dict(zip(self.df.Species_code, self.df.taxon))
# Dictionaries to self, is usefull sometimes. Trust me...
self.local2local = dict(zip(self.df.Local_name, self.df.Local_name))
self.code2code = dict(zip(self.df.Species_code, self.df.Species_code))
self.scientific2scientific = dict(zip(self.df.Scientific_name, self.df.Scientific_name))
# Dict between species code and boolean species list
self.code2sel468 = dict(zip(self.df.Species_code,{1: True, 0: False})))
self.code2selall = dict(zip(self.df.Species_code,{1: True, 0: False})))
self.code2sel281 = dict(zip(self.df.Species_code,{1: True, 0: False})))
self.code2sel146 = dict(zip(self.df.Species_code,{1: True, 0: False})))
class IndividualSpecies:
Class for holding properties of a single species instance.
Hans Roelofsen, WEnR, 12 jan 2022
def __init__(self, x):
Initiate for a species.
:param x: species code, local name or scientific name
species_tab = TabularSpecies()
species_identifiers_full = ['Species_code', 'Local_name', 'Scientific_name']
species_identifiers_brief = ['code', 'local', 'scientific']
# Determine if X is a species code, local name, scientific name or not-existing
isin = [x in getattr(species_tab.df, col).values for col
in species_identifiers_full].index(True)
typer = species_identifiers_brief[isin]
except ValueError:
print('{} is not a recognized species'.format(x))
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.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.groupinfo = '146:{0} - 281:{1} - 468:{2}'.format(self.sel146, self.sel281, self.sel468)
\ No newline at end of file
python program for quering MNP draagkracht file
Hans Roelofsen, jan 2022
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
species_table = species.TabularSpecies()
class DraagKracht:
def __init__(self):
self.dkdir = r'W:\PROJECTS\QMAR\MNP-SNL-ParameterSet\Parameters_v05_2021_04_08'
self.defaultdk = r'03_MNP_versie5_par_density_factors_BT2021_v3.csv'
self.snl_bt = get_snl_beheertypen_list(of='full')
self.use_default = True
self.bt_column = 'Land_type_code' = None
def read_dk(self, dk_file='default', bt_column=None):
Read a draagkrachten file
:param dk_file: name of a draagrkachten file
:param bt_column: name of column in non-default file with BT codes
:return: pd dataframe
if dk_file != 'default':
self.use_default = False
self.bt_column = bt_column
target = dk_file
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'):
query the draagkrachten for a specific beheertype
:param bt_lst: beheertype code
:param of: output format
:param sp_sel: use which species list? 1018, 468 or 281?
:return: str to stdout
for bt in bt_lst:
query = '({0} in {1}) and selection == True'.format(self.bt_column, [fix_bt(bt, as_mnp=True)])
sel =, 'code2sel{}'.format(sp_sel)))) \
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':
.sort_values(by=['taxon', 'local']) \
.loc[:, ['Species_code', 'taxon', 'Land_type_quality', 'local']] \
.to_csv(sep='\t', index=False, header=False))
def query4species(self, species_lst: list, of):
query draagkrachten for one or more species
:param species_lst:
:param of:
for x in species_lst:
sp = species.IndividualSpecies(x)
query = 'Species_code in ["{0}"]'.format(sp.code)
sel =
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)) \
.loc[:, ['Land_type_quality', self.bt_column, 'desc']] \
.sort_values(by=self.bt_column) \
.to_csv(sep='\t', index=False, header=False))
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('--qbt', nargs='+', type=str)
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)
args = parser.parse_args()
hans = DraagKracht()
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)
import numbers
def fix_bt(code_in, as_mnp=False):
def fix_bt(code_in, as_mnp=False, verbose=False, strict=True):
Parser for Beheertype codes to repair abbreviated codes and/or MNP extension
eg. 02.01 --> N02.01 if as_mnp==False
......@@ -17,44 +18,61 @@ def fix_bt(code_in, as_mnp=False):
N04.02.00 is equivalent to N04.02
:param code_in: beheertypecode in any format
:param as_mnp: return MNP style beheertypecode, default=False
:param verbose: verbose feedback
:param strict: raise error if bt code is unexpected
:return: beheertypecode
if verbose:
print('from {}'.format(code_in), end=' ')
if isinstance(code_in, numbers.Number):
code_in = str(code_in)
# Identify parts of code
parts = code_in.split(".")
if len(parts) == 1:
raise AssertionError("Unexpected BT code: {}".format(code_in))
if strict:
raise AssertionError("1. Unexpected BT code: {}".format(code_in))
return None
elif len(parts) == 2:
top, sub = parts
neer = None
elif len(parts) == 3:
top, sub, neer = parts
raise AssertionError("Unexpected BT code: {}".format(code_in))
if strict:
raise AssertionError("2. Unexpected BT code: {}".format(code_in))
return None
# Verify TOP and add "N" is required
if top.isdigit():
top = "N{0}".format(top.zfill(2))
assert top[0].isupper(), "Unexpected BT Code format: {}".format(code_in)
assert top[0].upper() in ['N', 'W', 'S', 'T', 'A', 'L'], "3. Unexpected BT Code: {}".format(code_in)
if top[0].islower():
top = top.capitalize()
assert top[1].isdigit(), '3. Unexpected BT code: {}'.format(code_in)
assert top[2].isdigit(), '3. Unexpected BT code: {}'.format(code_in)
assert len(top) == 3, "3. Unexpected BT Code: {}".format(code_in)
# Verify SUB
assert sub.isdigit and len(sub) == 2, "Unexpected BT Code format: {}".format(code_in)
assert sub.isdigit and len(sub) == 2, "4. Unexpected BT Code: {}".format(code_in)
# Verify NEER and check if it is neergeschaald or not
keep_neer = False
if neer:
assert neer.isdigit and len(neer) == 2, "Unexpected BT Code format: {}".format(code_in)
assert neer.isdigit and len(neer) == 2, "5. Unexpected BT Code: {}".format(code_in)
if int(neer) > 0:
keep_neer = True
# Construct output
head = "{}.{}".format(top, sub)
if keep_neer:
return "{}.{}".format(head, neer)
output = "{}.{}".format(head, neer)
elif as_mnp:
return "{}.00".format(head)
output = "{}.00".format(head)
return head
output = head
if verbose:
print('to {}'.format(output))
return output
\ No newline at end of file
Module to read MNP species CSV tab and provide several helper dictionaries
import pandas as pd
import os
import pathlib
filepath = pathlib.Path(__file__)
# De volledige Species tabel als Pandas dataframe
species_tab = pd.read_csv(os.path.join(os.path.dirname(filepath), r'resources\mnp_species.csv'), sep=',', comment='#')
# Dictionaries tussen code, lokale naam, wetenschappelijke naam
code2local = dict(zip(species_tab.Species_code, species_tab.Local_name))
local2code = dict(zip(species_tab.Local_name, species_tab.Species_code))
code2scientific = dict(zip(species_tab.Species_code, species_tab.Scientific_name))
scientific2code = dict(zip(species_tab.Scientific_name, species_tab.Species_code))
local2scientific = dict(zip(species_tab.Local_name, species_tab.Scientific_name))
scientific2local = dict(zip(species_tab.Scientific_name, species_tab.Local_name))
code2taxon = dict(zip(species_tab.Species_code, species_tab.taxon))
# Dictionaries to self, is usefull sometimes. Trust me...
local2local = dict(zip(species_tab.Local_name, species_tab.Local_name))
code2code = dict(zip(species_tab.Species_code, species_tab.Species_code))
scientific2scientific = dict(zip(species_tab.Scientific_name, species_tab.Scientific_name))
# Dict between species code and boolean species list
code2sel468 = dict(zip(species_tab.Species_code,{1: True, 0: False})))
code2sel281 = dict(zip(species_tab.Species_code,{1: True, 0: False})))
code2sel146 = dict(zip(species_tab.Species_code,{1: True, 0: False})))
code2selall = dict(zip(species_tab.Species_code,{1: True, 0: False})))
This diff is collapsed.
......@@ -4,14 +4,31 @@ Hans Roelofsen, 14/07/2021
import os
from pathlib import Path
import pathlib
import pandas as pd
import sys
from fix_bt import fix_bt # this only works if the dir containing benb_utils has already been appended to
# sys.path
filepath = pathlib.Path(__file__)
def get_snl_beheertypen_list(benb_dir):
df = pd.read_csv(os.path.join(os.path.dirname(filepath), r'resources/snl_beheertypen.csv'), sep=',', comment='#', quotechar='"')
def get_snl_beheertypen_list(df=df, of='sparse'):
return snl beheertypen list as pandas df
:param benb_dir: directory of benb_utils
:return: pandas dataframe
return pd.read_csv(r'./resources/snl_beheertypen.csv', sep=',', comment='#', quotechar='"')
\ No newline at end of file
mnp_codes = df.LAND_TYPE_CODE.apply(fix_bt, as_mnp=True)
return {'full': df.assign(mnp_code=mnp_codes),
'sparse': df}[of]
def btcode2description(code):
# Note: dit hoeft niet perse in een functie te staan.
return dict(zip(df.LAND_TYPE_CODE.apply(fix_bt, as_mnp=True),
df.LST_NAME))[fix_bt(code, as_mnp=True)]
except KeyError as e:
print('\n{} is not a valid beheertype\n'.format(code))
\ No newline at end of file
Markdown is supported
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