Introduction

This document is for the course Fisheries Technology and Evaluation of Resources (Univ. Algarve).

We will:

  1. Loads functions for various selectivity curves
  2. Logistic selectivity (e.g., trawls)
  3. Dome-shaped selectivity – normal model (e.g, gillnets/hooks)
  4. Dome-shaped selectivity – double-normal (e.g, gillnets/hooks)
  5. Exercises

R Code

Load needed libraries

library(ggplot2)
library(dplyr)
library(tidyr)
  1. Loads functions for various selectivity curves
#-----------------------------------------------------------
# 1. Helper functions for selectivity curves
#-----------------------------------------------------------

# 1.1 Logistic selectivity
#     Typical for trawl codend, increasing to an asymptote at 1
#     Parameters:
#       L50 = length at 50% retention
#       SR  = selection range = L75 - L25
logistic_sel <- function(L, L50, SR) {
  # For the logistic curve:
  #   SR = 2*log(3) / b   =>   b = 2*log(3) / SR
  b <- 2 * log(3) / SR
  a <- -b * L50
  1 / (1 + exp(-(a + b * L)))
}

# 1.2 Normal dome-shaped selectivity
#     Typical for gillnets/hooks: catches peak at an optimal size, then drop
#     Parameters:
#       mu    = mode (peak length)
#       sigma = spread (standard deviation)
normal_sel <- function(L, mu, sigma) {
  s <- exp(-0.5 * ((L - mu) / sigma)^2)
  s / max(s)  # scale so max = 1 for easier comparison
}

# 1.3 Double-normal (bi-normal) dome-shaped selectivity
#     More flexible dome-shaped form (can be skewed, bimodal, etc.)
#     Parameters:
#       mu1, sigma1 = first mode
#       mu2, sigma2 = second mode
#       w           = weight of first mode (0–1)
double_normal_sel <- function(L, mu1, sigma1, mu2, sigma2, w = 0.5) {
  s1 <- exp(-0.5 * ((L - mu1) / sigma1)^2)
  s2 <- exp(-0.5 * ((L - mu2) / sigma2)^2)
  s  <- w * s1 + (1 - w) * s2
  s / max(s)  # scale so max = 1
}

# Length grid used for all plots
L_grid <- seq(20, 160, by = 1)
  1. Logistic selectivity (e.g., trawls)
# Example 1: Different L50, same SR
# Imagine three codends with increasing L50 (selective for larger fish)
codends <- data.frame(
  gear = c("Codend A", "Codend B", "Codend C"),
  L50  = c(30, 40, 50),  # increases
  SR   = c(8, 8, 8)      # same SR
)

logistic_df <- codends |>
  crossing(length = L_grid) |>
  mutate(selectivity = logistic_sel(length, L50, SR))

ggplot(logistic_df, aes(x = length, y = selectivity, colour = gear)) +
  geom_line(linewidth = 1.1) +
  labs(
    x = "Length (cm)",
    y = "Retention probability",
    colour = "Codend",
    title = "Logistic selectivity – different L50, same SR"
  ) +
  theme_minimal(base_size = 13)

# ----------------------------------------------------------
# Example 2: Same L50, different SR
# Narrow SR = steeper curve; Wide SR = more gradual transition
codends_SR <- data.frame(
  gear = c("Narrow SR", "Medium SR", "Wide SR"),
  L50  = c(40, 40, 40),       # same L50
  SR   = c(6, 10, 16)         # different SR
)

logistic_SR_df <- codends_SR |>
  crossing(length = L_grid) |>
  mutate(selectivity = logistic_sel(length, L50, SR))

ggplot(logistic_SR_df, aes(x = length, y = selectivity, colour = gear)) +
  geom_line(linewidth = 1.1) +
  labs(
    x = "Length (cm)",
    y = "Retention probability",
    colour = "Codend",
    title = "Logistic selectivity – same L50, different SR"
  ) +
  theme_minimal(base_size = 13)

  1. Dome-shaped selectivity – normal model (e.g, gillnets/hooks)
# Think of mesh size (or hook size) as controlling the "target" fish size.
# Simplified assumption: mean length caught ≈ k * mesh size.

mesh <- c(5, 7.5, 10, 12.5, 15)  # e.g., mesh or hook sizes
k_mu   <- 8                       # scaling factor from mesh to length
sigmaN <- 10                      # common spread

normal_df <- data.frame(mesh = mesh) |>
  crossing(length = L_grid) |>
  mutate(
    mu = k_mu * mesh,
    selectivity = normal_sel(length, mu, sigmaN)
  )

ggplot(normal_df, aes(x = length, y = selectivity, colour = factor(mesh))) +
  geom_line(linewidth = 1.1) +
  labs(
    x = "Length (cm)",
    y = "Relative selectivity (scaled to 1)",
    colour = "Mesh size",
    title = "Normal dome-shaped selectivity – multi-mesh gears"
  ) +
  theme_minimal(base_size = 13)

  1. Dome-shaped selectivity – double-normal (e.g, gillnets/hooks)
# Here we allow a more flexible shape:
# e.g., main peak at k*mesh, with a second broader component at larger sizes.

double_df <- data.frame(mesh = mesh) |>
  crossing(length = L_grid) |>
  mutate(
    mu1 = k_mu * mesh,          # main mode
    mu2 = k_mu * mesh + 20,     # second mode
    selectivity = double_normal_sel(
      length,
      mu1    = mu1,
      sigma1 = 10,
      mu2    = mu2,
      sigma2 = 20,
      w      = 0.7
    )
  )

ggplot(double_df, aes(x = length, y = selectivity, colour = factor(mesh))) +
  geom_line(linewidth = 1.1) +
  labs(
    x = "Length (cm)",
    y = "Relative selectivity (scaled to 1)",
    colour = "Mesh size",
    title = "Double-normal dome-shaped selectivity – flexible curves"
  ) +
  theme_minimal(base_size = 13)

Class EXERCISES:

Exercise 1:

  1. Change L50 in the logistic examples and see how the curve moves.
  2. For example, try L50 = c(25, 35, 45, 55).

Exercise 2:

  • Change SR (selection range) and see how steep or flat the curve becomes.

Exercise 3:

  • In the normal dome-shaped example, change k_mu or sigmaN:
  • k_mu <- 6 # what happens to the curves?
  • sigmaN <- 15 # what happens to the width?

Exercise 4:

  • In the double-normal example, change w (0.3, 0.5, 0.9) and see how much the second mode influences the shape.

Class DISCUSSION

For which gears in real fisheries would you expect:

    1. logistic selectivity?
    1. dome-shaped normal?
    1. strongly asymmetric or double-normal shapes?