Skip to content

Commit

Permalink
WCRP functions (#455)
Browse files Browse the repository at this point in the history
* draft wcrp barrier count view and func

* tidy

* add wcrp connectivity status view and func, renaming to habitat connectivity status

* coalesce null rearing vals

* add co/sk rearing wb factors to wcrp crossings summary

* fix wcrp upstream habitat table

* of course, all_spawning is required

* update wcrp_extent function

* add updated wcrp barrier severity query

* conditional function drops
  • Loading branch information
smnorris authored Feb 13, 2024
1 parent 406517b commit cf9444f
Show file tree
Hide file tree
Showing 10 changed files with 704 additions and 14 deletions.
91 changes: 91 additions & 0 deletions db/functions/wcrp_barrier_count.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
-- function to query the view (so it is visible in pgfs)
DROP FUNCTION IF EXISTS postgisftw.wcrp_barrier_count;
CREATE FUNCTION postgisftw.wcrp_barrier_count(
watershed_group_code TEXT,
model_status TEXT default 'ALL'
)
-- watershed_group_code: BULK, LNIC, HORS, BOWR, QUES, CARR, ELKR
-- model_status : HABITAT, ACCESSIBLE, ALL (default)

RETURNS TABLE (
crossing_feature_type TEXT,
n_passable bigint,
n_barrier bigint,
n_potential bigint,
n_unknown bigint,
total bigint
)
LANGUAGE 'plpgsql'
IMMUTABLE PARALLEL SAFE

AS $$

DECLARE
v_wsg text := watershed_group_code;
v_model_status text := model_status;

BEGIN

IF (v_model_status = 'ALL')
then return query

SELECT
v.crossing_feature_type,
sum(v.n_passable)::bigint as n_passable,
sum(v.n_barrier)::bigint as n_barrier,
sum(v.n_potential)::bigint as n_potential,
sum(v.n_unknown)::bigint as n_unknown,
(sum(v.n_passable) + sum(v.n_barrier) + sum(v.n_potential) + sum(v.n_unknown))::bigint as total
FROM bcfishpass.wcrp_barrier_count_vw v
WHERE v.watershed_group_code = v_wsg
GROUP BY v.crossing_feature_type;

ELSIF (v_model_status = 'ACCESSIBLE')
then return query
SELECT
v.crossing_feature_type,
sum(v.n_passable)::bigint as n_passable,
sum(v.n_barrier)::bigint as n_barrier,
sum(v.n_potential)::bigint as n_potential,
sum(v.n_unknown)::bigint as n_unknown,
(sum(v.n_passable) + sum(v.n_barrier) + sum(v.n_potential) + sum(v.n_unknown))::bigint as total
FROM bcfishpass.wcrp_barrier_count_vw v
WHERE
v.watershed_group_code = v_wsg and
v.model_status in ('ACCESSIBLE', 'HABITAT')
group by v.crossing_feature_type;

ELSIF (v_model_status = 'HABITAT')
then return query
SELECT
v.crossing_feature_type,
v.n_passable::bigint as n_passable,
v.n_barrier::bigint as n_barrier,
v.n_potential::bigint as n_potential,
v.n_unknown::bigint as n_unknown,
(v.n_passable + v.n_barrier + v.n_potential + v.n_unknown)::bigint as total
FROM bcfishpass.wcrp_barrier_count_vw v
WHERE
v.watershed_group_code = v_wsg and
v.model_status = 'HABITAT';

END IF;

END


$$;

COMMENT ON FUNCTION postgisftw.wcrp_barrier_count IS
'Return count of crossings per crossing_feature_type within specified watershed group.
Returns count of crossings accessible to target species if model_status=ACCESSIBLE is specified,
Returns count of crossings below modelled habitat if model_status=HABITAT is specified
Returns count of all crossings if model_status=ALL is specified (default)';

REVOKE EXECUTE ON FUNCTION postgisftw.wcrp_barrier_count FROM public;

-- test
--select * from postgisftw.wcrp_barrier_count('QUES');
--select * from postgisftw.wcrp_barrier_count('QUES','ALL');
--select * from postgisftw.wcrp_barrier_count('QUES','ACCESSIBLE');
--select * from postgisftw.wcrp_barrier_count('QUES','HABITAT');
69 changes: 69 additions & 0 deletions db/functions/wcrp_barrier_extent.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
DROP FUNCTION IF EXISTS postgisftw.wcrp_barrier_extent(TEXT);

CREATE FUNCTION postgisftw.wcrp_barrier_extent(watershed_group_code TEXT)

-- watershed_group_code: BULK, LNIC, HORS, BOWR, QUES, CARR, ELKR

RETURNS TABLE(
crossing_feature_type TEXT,
all_habitat_blocked_km numeric,
total_habitat_km numeric,
extent_pct numeric
)

LANGUAGE 'plpgsql'
IMMUTABLE PARALLEL SAFE

AS $$

DECLARE
v_wsg text := watershed_group_code;

BEGIN

RETURN query

with barriers as (
select
c.watershed_group_code,
ft.crossing_feature_type,
ROUND(SUM(h_wcrp.all_spawningrearing_belowupstrbarriers_km)::numeric, 2) as all_spawningrearing_blocked_km
FROM bcfishpass.crossings c
inner join bcfishpass.crossings_upstream_habitat uh using (aggregated_crossings_id)
inner join bcfishpass.crossings_feature_type_vw ft using (aggregated_crossings_id)
inner join bcfishpass.crossings_upstream_habitat_wcrp h_wcrp using (aggregated_crossings_id)
WHERE c.barrier_status IN ('POTENTIAL', 'BARRIER')
AND c.aggregated_crossings_id != '1100002536' -- don't count the Elko Dam in ELKR
AND c.watershed_group_code = v_wsg
GROUP BY c.watershed_group_code, ft.crossing_feature_type
ORDER BY c.watershed_group_code, ft.crossing_feature_type
),

total AS (
SELECT
b.crossing_feature_type,
b.all_spawningrearing_blocked_km,
(SELECT all_habitat FROM postgisftw.wcrp_habitat_connectivity_status(v_wsg)) as total_habitat_km
FROM barriers b
)

SELECT
t.crossing_feature_type,
t.all_spawningrearing_blocked_km,
t.total_habitat_km,
round((t.all_spawningrearing_blocked_km / t.total_habitat_km) * 100, 2) as extent_pct
FROM total t;

END


$$;

COMMENT ON FUNCTION postgisftw.wcrp_barrier_extent IS
'Return km of all blocked spawning and rearing by barrier type, and the percentage of
total spawning and rearing within given watershed group that this blocked habitat represents.';


REVOKE EXECUTE ON FUNCTION postgisftw.wcrp_barrier_extent FROM public;

-- select * from postgisftw.wcrp_barrier_extent('QUES');
63 changes: 63 additions & 0 deletions db/functions/wcrp_barrier_severity.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
DROP FUNCTION IF EXISTS postgisftw.wcrp_barrier_severity(text);

CREATE FUNCTION postgisftw.wcrp_barrier_severity(watershed_group_code TEXT)

-- watershed_group_code: BULK, LNIC, HORS, BOWR, QUES, CARR, ELKR

RETURNS TABLE(
structure_type TEXT,
n_assessed_barrier bigint,
n_assess_total bigint,
pct_assessed_barrier numeric
)
LANGUAGE 'plpgsql'
IMMUTABLE PARALLEL SAFE

AS $$

DECLARE
v_wsg text := watershed_group_code;

BEGIN

RETURN query

-- dams and assessed crossings on potentially accessible streams (to target spp)
-- - n total
-- - n barriers
-- - pct barriers
SELECT
cft.crossing_feature_type,
count(*) filter (where c.barrier_status in ('BARRIER', 'POTENTIAL')) as n_barrier,
count(*) as n_total,
round((count(*) filter (where c.barrier_status in ('BARRIER', 'POTENTIAL'))::numeric / count(*)::numeric) * 100, 1) as pct_barrier
from bcfishpass.crossings c
inner join bcfishpass.crossings_feature_type_vw cft using (aggregated_crossings_id)
inner join bcfishpass.crossings_upstream_access a using (aggregated_crossings_id)
where c.watershed_group_code = v_wsg
-- do not include flathead in ELKR
and c.wscode_ltree <@ '300.602565.854327.993941.902282.132363'::ltree is false
-- pscis crossing downstream or dam downstream
and (c.stream_crossing_id is not null or c.dam_id is not null)
-- potentially accessible to target species
and (
cardinality(a.barriers_ch_cm_co_pk_sk_dnstr) = 0 or
cardinality(a.barriers_st_dnstr) = 0 or
cardinality(a.barriers_wct_dnstr) = 0
)
group by c.watershed_group_code, cft.crossing_feature_type
order by c.watershed_group_code, cft.crossing_feature_type;

END

$$;

COMMENT ON FUNCTION postgisftw.wcrp_barrier_severity IS
'For given watershed group, returns count of dams/pscis crossings on potentially accessible streams
- n total
- n barrier
- pct that are barrier';

REVOKE EXECUTE ON FUNCTION postgisftw.wcrp_barrier_severity FROM public;

-- select * from postgisftw.wcrp_barrier_severity('QUES')
49 changes: 49 additions & 0 deletions db/functions/wcrp_habitat_connectivity_status.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
-- report on total modelled habitat vs accessible modelled habitat

DROP FUNCTION IF EXISTS postgisftw.wcrp_habitat_connectivity_status(TEXT,TEXT);

CREATE OR REPLACE FUNCTION postgisftw.wcrp_habitat_connectivity_status(
watershed_group_code TEXT,
habitat_type TEXT default 'ALL'
)

-- watershed_group_code: BULK, LNIC, HORS, BOWR, QUES, CARR, ELKR
-- habitat_type: SPAWNING, REARING, ALL (default)

RETURNS TABLE(
connectivity_status NUMERIC,
all_habitat NUMERIC,
all_habitat_accessible NUMERIC
)
LANGUAGE 'plpgsql'
IMMUTABLE PARALLEL SAFE

AS $$

DECLARE
v_wsg text := watershed_group_code;
v_hab text := habitat_type;

BEGIN
RETURN QUERY
select
pct_accessible as connectivity_status,
total_km as all_habitat,
accessible_km as all_habitat_accessible
from bcfishpass.wcrp_habitat_connectivity_status_vw v
where v.watershed_group_code = v_wsg
and v.habitat_type = v_hab;

END
$$;

COMMENT ON FUNCTION postgisftw.wcrp_habitat_connectivity_status IS
'Return pct habitat accessible, total km habitat, and km habitat accessible
for the habitat type and watershed group specified.';

REVOKE EXECUTE ON FUNCTION postgisftw.wcrp_habitat_connectivity_status FROM public;

-- select * from postgisftw.wcrp_habitat_connectivity_status('QUES')
-- select * from postgisftw.wcrp_habitat_connectivity_status('QUES', 'ALL')
-- select * from postgisftw.wcrp_habitat_connectivity_status('QUES', 'SPAWNING')
-- select * from postgisftw.wcrp_habitat_connectivity_status('QUES', 'REARING')
22 changes: 22 additions & 0 deletions db/tables/crossings_upstream_habitat.sql
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,26 @@ create table bcfishpass.crossings_upstream_habitat (
wct_rearing_km double precision DEFAULT 0,
wct_spawning_belowupstrbarriers_km double precision DEFAULT 0,
wct_rearing_belowupstrbarriers_km double precision DEFAULT 0
);


-- wcrp 'all species' upstream habitat reporting (for columns where it differs from above table)
-- - barriers only
-- - currently ch/co/sk/st/wct where they exist in watersheds of interest
-- - apply 1.5x multiplier to co rearing in wetlands and all sk rearing
drop table if exists bcfishpass.crossings_upstream_habitat_wcrp cascade;

create table bcfishpass.crossings_upstream_habitat_wcrp (
aggregated_crossings_id text primary key,
watershed_group_code character varying (4),
co_rearing_km double precision DEFAULT 0,
co_rearing_belowupstrbarriers_km double precision DEFAULT 0,
sk_rearing_km double precision DEFAULT 0,
sk_rearing_belowupstrbarriers_km double precision DEFAULT 0,
all_spawning_km double precision DEFAULT 0,
all_spawning_belowupstrbarriers_km double precision DEFAULT 0,
all_rearing_km double precision DEFAULT 0,
all_rearing_belowupstrbarriers_km double precision DEFAULT 0,
all_spawningrearing_km double precision DEFAULT 0,
all_spawningrearing_belowupstrbarriers_km double precision DEFAULT 0
);
47 changes: 47 additions & 0 deletions db/views/wcrp_barrier_count_vw.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
drop view if exists bcfishpass.wcrp_barrier_count_vw;
create view bcfishpass.wcrp_barrier_count_vw as
with model_status as (
select
c.aggregated_crossings_id,
case
when
h.ch_spawning_km > 0 or h.ch_rearing_km > 0 or
h.co_spawning_km > 0 or h.co_rearing_km > 0 or
h.sk_spawning_km > 0 or h.sk_rearing_km > 0 or
h.st_spawning_km > 0 or h.st_rearing_km > 0 or
h.wct_spawning_km > 0 or h.wct_rearing_km > 0
then 'HABITAT'
when
cardinality(a.barriers_ch_cm_co_pk_sk_dnstr) = 0 or
cardinality(a.barriers_st_dnstr) = 0 or
cardinality(a.barriers_wct_dnstr) = 0
then 'ACCESSIBLE'
else 'NATURAL_BARRIER'
end as model_status
FROM bcfishpass.crossings c
left outer join bcfishpass.crossings_upstream_access a
on c.aggregated_crossings_id = a.aggregated_crossings_id
left outer join bcfishpass.crossings_upstream_habitat h
on c.aggregated_crossings_id = h.aggregated_crossings_id
)

SELECT
c.watershed_group_code,
ms.model_status,
ft.crossing_feature_type,
count(*) filter (where c.barrier_status = 'PASSABLE') as n_passable,
count(*) filter (where c.barrier_status = 'BARRIER') as n_barrier,
count(*) filter (where c.barrier_status = 'POTENTIAL') as n_potential,
count(*) filter (where c.barrier_status = 'UNKNOWN') as n_unknown,
count(*) as total
FROM bcfishpass.crossings c
inner join bcfishpass.crossings_feature_type_vw ft
on c.aggregated_crossings_id = ft.aggregated_crossings_id
left outer join model_status ms
on c.aggregated_crossings_id = ms.aggregated_crossings_id
-- WCRP watersheds only
WHERE c.watershed_group_code in ('BULK','LNIC','HORS','BOWR','QUES','CARR','ELKR')
-- do not include flathead
AND c.wscode_ltree <@ '300.602565.854327.993941.902282.132363'::ltree IS FALSE
GROUP BY c.watershed_group_code, ms.model_status, ft.crossing_feature_type
ORDER BY c.watershed_group_code, ms.model_status, ft.crossing_feature_type;
Loading

0 comments on commit cf9444f

Please sign in to comment.