Source: Korea Times (Dec 30, 2024), citing Ministry of Land, Infrastructure and Transport. Period: 2019 - August 2024.
airport_data <- data.frame(
Airport = c("Muan", "Gimpo", "Jeju", "Gimhae", "Daegu", "Cheongju"),
BirdStrikes = c(10, 140, 119, 147, 38, 33),
TotalFlights = c(11004, 757479, 926699, NA, NA, NA)
)
airports_with_flights <- airport_data[!is.na(airport_data$TotalFlights), ]
airports_with_flights$StrikeRate_pct <- airports_with_flights$BirdStrikes /
airports_with_flights$TotalFlights * 100
knitr::kable(airports_with_flights, digits = 4,
col.names = c("Airport", "Bird Strikes", "Total Flights", "Rate (%)"),
caption = "Bird strike data for Korean airports (2019-Aug 2024)")
| Airport | Bird Strikes | Total Flights | Rate (%) |
|---|---|---|---|
| Muan | 10 | 11004 | 0.0909 |
| Gimpo | 140 | 757479 | 0.0185 |
| Jeju | 119 | 926699 | 0.0128 |
muan_strikes <- 10
muan_flights <- 11004
muan_no_strikes <- muan_flights - muan_strikes
other_strikes <- 140 + 119
other_flights <- 757479 + 926699
other_no_strikes <- other_flights - other_strikes
contingency <- matrix(
c(muan_strikes, muan_no_strikes,
other_strikes, other_no_strikes),
nrow = 2, byrow = TRUE,
dimnames = list(
Airport = c("Muan", "Gimpo + Jeju"),
Outcome = c("Bird Strike", "No Bird Strike")
)
)
knitr::kable(contingency, format.args = list(big.mark = ","),
caption = "2 x 2 contingency table")
| Bird Strike | No Bird Strike | |
|---|---|---|
| Muan | 10 | 10,994 |
| Gimpo + Jeju | 259 | 1,683,919 |
R’s chisq.test() applies Yates’ continuity correction by
default for 2x2 tables.
chi_result <- chisq.test(contingency)
chi_result
##
## Pearson's Chi-squared test with Yates' continuity correction
##
## data: contingency
## X-squared = 34.661, df = 1, p-value = 3.924e-09
Manuscript values: \(\chi^2 = 34.66\), \(df = 1\), \(p < 0.001\).
print(paste0("Computed chi-square: ", round(chi_result$statistic, 2), " (manuscript: 34.66)"))
## [1] "Computed chi-square: 34.66 (manuscript: 34.66)"
print(paste0("P-value: ", format(chi_result$p.value, scientific = TRUE, digits = 2), " (manuscript: < 0.001)"))
## [1] "P-value: 3.9e-09 (manuscript: < 0.001)"
odds_muan <- muan_strikes / muan_no_strikes
odds_other <- other_strikes / other_no_strikes
OR <- odds_muan / odds_other
se_log_OR <- sqrt(1/muan_strikes + 1/muan_no_strikes +
1/other_strikes + 1/other_no_strikes)
CI_lower <- exp(log(OR) - 1.96 * se_log_OR)
CI_upper <- exp(log(OR) + 1.96 * se_log_OR)
print(paste0("Odds Ratio: ", round(OR, 2)))
## [1] "Odds Ratio: 5.91"
print(paste0("95% CI: [", round(CI_lower, 2), ", ", round(CI_upper, 2), "]"))
## [1] "95% CI: [3.14, 11.13]"
Manuscript values: OR = 5.91, 95% CI: 3.14-11.13.
muan_rate <- muan_strikes / muan_flights * 100
other_rate <- other_strikes / other_flights * 100
rate_ratio <- muan_rate / other_rate
print(paste0("Muan rate: ", round(muan_rate, 4), "%"))
## [1] "Muan rate: 0.0909%"
print(paste0("Combined rate: ", round(other_rate, 4), "%"))
## [1] "Combined rate: 0.0154%"
print(paste0("Rate ratio: ", round(rate_ratio, 1), "x"))
## [1] "Rate ratio: 5.9x"
How the combined rate is calculated: \[\text{Combined rate} = \frac{140 + 119}{757{,}479 + 926{,}699} = \frac{259}{1{,}684{,}178} = 0.0154\% \approx 0.015\%\]
expected_muan <- muan_flights * (other_strikes / other_flights)
print(paste0("Observed strikes at Muan: ", muan_strikes))
## [1] "Observed strikes at Muan: 10"
print(paste0("Expected at comparison rate: ", round(expected_muan, 1)))
## [1] "Expected at comparison rate: 1.7"
print(paste0("Excess: ", round((muan_strikes - expected_muan) / expected_muan * 100, 0), "%"))
## [1] "Excess: 491%"
Data from 2022-2024, sourced from Seou1. Values extracted from the published figure.
bird_data <- data.frame(
Year = rep(2022:2024, each = 5),
Airport = rep(c("Gimhae", "Gimpo", "Incheon", "Jeju", "Muan"), 3),
Rate_per_10k = c(
4.2, 7.8, 3.0, 2.8, 14.3,
3.9, 6.3, 3.8, 2.5, 10.3,
3.5, 5.7, 3.0, 2.3, 22.0
),
Incidents = c(
58, 47, 35, 48, 1,
50, 50, 55, 42, 2,
53, 103, 42, 38, 7
),
stringsAsFactors = FALSE
)
knitr::kable(bird_data, digits = 1,
caption = "Bird strike data by airport and year (2022-2024)")
| Year | Airport | Rate_per_10k | Incidents |
|---|---|---|---|
| 2022 | Gimhae | 4.2 | 58 |
| 2022 | Gimpo | 7.8 | 47 |
| 2022 | Incheon | 3.0 | 35 |
| 2022 | Jeju | 2.8 | 48 |
| 2022 | Muan | 14.3 | 1 |
| 2023 | Gimhae | 3.9 | 50 |
| 2023 | Gimpo | 6.3 | 50 |
| 2023 | Incheon | 3.8 | 55 |
| 2023 | Jeju | 2.5 | 42 |
| 2023 | Muan | 10.3 | 2 |
| 2024 | Gimhae | 3.5 | 53 |
| 2024 | Gimpo | 5.7 | 103 |
| 2024 | Incheon | 3.0 | 42 |
| 2024 | Jeju | 2.3 | 38 |
| 2024 | Muan | 22.0 | 7 |
airport_colors <- c(
"Gimhae" = "#2B5F5F",
"Gimpo" = "#5C7A3A",
"Incheon" = "#8CA63A",
"Jeju" = "#C4CC70",
"Muan" = "#1B2A4A"
)
airports <- c("Gimhae", "Gimpo", "Incheon", "Jeju", "Muan")
years <- 2022:2024
pch_val <- 8
par(mfrow = c(1, 2), mar = c(4, 5, 3, 1), oma = c(0, 0, 0, 8), xpd = FALSE)
plot(NULL, xlim = c(2021.8, 2024.2), ylim = c(0, 24),
xlab = "Year", ylab = "Incidents per 10k Operations",
main = "A Bird-Strike Incidents per 10,000\n Operations by Airport",
xaxt = "n", las = 1, cex.main = 1.0)
axis(1, at = years, labels = years)
abline(h = seq(0, 20, 5), col = "grey90", lty = 1)
for (ap in airports) {
sub <- bird_data[bird_data$Airport == ap, ]
lwd_val <- if (ap == "Muan") 2.5 else 1.5
lines(sub$Year, sub$Rate_per_10k, col = airport_colors[ap], lwd = lwd_val)
points(sub$Year, sub$Rate_per_10k, col = airport_colors[ap], pch = pch_val, cex = 1.2)
}
plot(NULL, xlim = c(2021.8, 2024.2), ylim = c(0, 110),
xlab = "Year", ylab = "Incidents",
main = "B Bird-Strike Incidents by Airport",
xaxt = "n", las = 1, cex.main = 1.0)
axis(1, at = years, labels = years)
abline(h = seq(0, 100, 25), col = "grey90", lty = 1)
for (ap in airports) {
sub <- bird_data[bird_data$Airport == ap, ]
lwd_val <- if (ap == "Muan") 2.5 else 1.5
lines(sub$Year, sub$Incidents, col = airport_colors[ap], lwd = lwd_val)
points(sub$Year, sub$Incidents, col = airport_colors[ap], pch = pch_val, cex = 1.2)
}
par(xpd = NA)
legend("right", inset = c(-0.45, 0),
legend = airports,
col = airport_colors[airports],
lwd = c(1.5, 1.5, 1.5, 1.5, 2.5),
pch = pch_val,
cex = 0.85, bty = "n",
title = "Airport", title.font = 2)
From published aviation safety literature (see Table 1 in manuscript).
event_names <- c(
"Hydraulic failure",
"Pilot reaction delay",
"High touchdown speed",
"Low runway friction",
"Initiating go around",
"Unavailable thrust"
)
probs <- c(7e-7, 0.145, 0.0227, 0, 0.03, 0.09)
names(probs) <- event_names
knitr::kable(
data.frame(Event = event_names, Probability = probs),
caption = "Basic event probabilities (Table 1 in manuscript)"
)
| Event | Probability | |
|---|---|---|
| Hydraulic failure | Hydraulic failure | 7.00e-07 |
| Pilot reaction delay | Pilot reaction delay | 1.45e-01 |
| High touchdown speed | High touchdown speed | 2.27e-02 |
| Low runway friction | Low runway friction | 0.00e+00 |
| Initiating go around | Initiating go around | 3.00e-02 |
| Unavailable thrust | Unavailable thrust | 9.00e-02 |
Top Event: Collision with ILS Antenna Structure (OR gate, Q = 0.0253)
+-- Runway Overrun on Landing (OR gate, Q = 0.0227)
| +-- Ineffective Braking (AND gate, Q = 1.015e-07)
| | +-- [1] Hydraulic Failure (p = 7e-7)
| | +-- [2] Pilot Reaction Delay (p = 0.145)
| +-- Needing Extra Distance (OR gate, Q = 0.0227)
| +-- [3] High Touchdown Speed (p = 0.0227)
| +-- [4] Low Runway Friction (p = 0)
+-- Inadequate Pilot Performance (AND gate, Q = 0.0027)
+-- [5] Initiating Go-Around (p = 0.03)
+-- Inadequate Climb Performance (OR gate, Q = 0.09)
+-- [6] Unavailable Engine/Thrust (p = 0.09)
+-- [1] Hydraulic Failure (p = 7e-7) <- shared event
Computed using the closed-form gate equations.
calculate_top_event_prob <- function(q_hf, q_prd, q_hts, q_lrf, q_iga, q_uet) {
q_ib <- q_hf * q_prd
q_ned <- 1 - (1 - q_hts) * (1 - q_lrf)
q_rol <- 1 - (1 - q_ib) * (1 - q_ned)
q_icp <- 1 - (1 - q_uet) * (1 - q_hf)
q_ipp <- q_iga * q_icp
q_top <- 1 - (1 - q_rol) * (1 - q_ipp)
return(q_top)
}
Q_top <- calculate_top_event_prob(
q_hf = probs[1], q_prd = probs[2], q_hts = probs[3],
q_lrf = probs[4], q_iga = probs[5], q_uet = probs[6]
)
print(paste0("Top event probability: ", round(Q_top, 8)))
## [1] "Top event probability: 0.02533883"
print(paste0("Ineffective Braking = ", format(probs[1] * probs[2], scientific = TRUE, digits = 4), " (Figure 6: 1.015e-07)"))
## [1] "Ineffective Braking = 1.015e-07 (Figure 6: 1.015e-07)"
print(paste0("Needing Extra Distance = ", round(1 - (1 - probs[3]) * (1 - probs[4]), 4), " (Figure 6: 0.0227)"))
## [1] "Needing Extra Distance = 0.0227 (Figure 6: 0.0227)"
q_icp <- 1 - (1 - probs[6]) * (1 - probs[1])
print(paste0("Inadequate Climb Perf = ", round(q_icp, 6), " (Figure 6: 0.09)"))
## [1] "Inadequate Climb Perf = 0.090001 (Figure 6: 0.09)"
print(paste0("Inadequate Pilot Perf = ", round(probs[5] * q_icp, 6), " (Figure 6: 0.0027)"))
## [1] "Inadequate Pilot Perf = 0.0027 (Figure 6: 0.0027)"
print(paste0("Runway Overrun on Landing = ", round(1 - (1 - probs[1] * probs[2]) * (1 - 1 + (1 - probs[3]) * (1 - probs[4])), 6), " (Figure 6: 0.0227)"))
## [1] "Runway Overrun on Landing = 0.0227 (Figure 6: 0.0227)"
print(paste0("Top Event = ", round(Q_top, 6), " (Figure 6: 0.0253)"))
## [1] "Top Event = 0.025339 (Figure 6: 0.0253)"
mcs_list <- list(
list(events = c(3), label = "{High touchdown speed}"),
list(events = c(4), label = "{Low runway friction}"),
list(events = c(1, 2), label = "{Hydraulic failure, Pilot reaction delay}"),
list(events = c(5, 6), label = "{Initiating go-around, Unavailable thrust}"),
list(events = c(5, 1), label = "{Initiating go-around, Hydraulic failure}")
)
mcs_df <- data.frame(
MCS = paste0("MCS", seq_along(mcs_list)),
Events = sapply(mcs_list, `[[`, "label"),
Probability = sapply(mcs_list, function(m) prod(probs[m$events]))
)
knitr::kable(mcs_df, caption = "Minimal cut sets and their probabilities")
| MCS | Events | Probability |
|---|---|---|
| MCS1 | {High touchdown speed} | 2.27e-02 |
| MCS2 | {Low runway friction} | 0.00e+00 |
| MCS3 | {Hydraulic failure, Pilot reaction delay} | 1.00e-07 |
| MCS4 | {Initiating go-around, Unavailable thrust} | 2.70e-03 |
| MCS5 | {Initiating go-around, Hydraulic failure} | 0.00e+00 |
The importance measures use the following definitions:
where \(Q_1 = P(\text{top} \mid p_i = 1)\) and \(Q_0 = P(\text{top} \mid p_i = 0)\).
calc_Q <- function(p) {
calculate_top_event_prob(
q_hf = p[1], q_prd = p[2], q_hts = p[3],
q_lrf = p[4], q_iga = p[5], q_uet = p[6]
)
}
plot_events <- c("Initiating go around", "Hydraulic failure",
"Pilot reaction delay", "Unavailable thrust",
"High touchdown speed")
n_ev <- length(probs)
Q1 <- Q0 <- numeric(n_ev)
names(Q1) <- names(Q0) <- event_names
for (i in 1:n_ev) {
p_tmp <- probs; p_tmp[i] <- 1; Q1[i] <- calc_Q(p_tmp)
p_tmp <- probs; p_tmp[i] <- 0; Q0[i] <- calc_Q(p_tmp)
}
birnbaum <- Q1 - Q0
fv <- (Q_top - Q0) / Q_top
raw_diff <- Q1 - Q_top
rrw_diff <- Q_top - Q0
importance_df <- data.frame(
Event = event_names,
FV = fv,
RRW = rrw_diff,
RAW = raw_diff,
Birnbaum = birnbaum
)
idx <- match(plot_events, event_names)
knitr::kable(importance_df[idx, ], digits = 6, row.names = FALSE,
caption = "Importance measures for basic events (difference-based RAW/RRW)")
| Event | FV | RRW | RAW | Birnbaum |
|---|---|---|---|---|
| Initiating go around | 0.104138 | 0.002639 | 0.085319 | 0.087958 |
| Hydraulic failure | 0.000005 | 0.000000 | 0.164137 | 0.164138 |
| Pilot reaction delay | 0.000004 | 0.000000 | 0.000001 | 0.000001 |
| Unavailable thrust | 0.104137 | 0.002639 | 0.026680 | 0.029319 |
| High touchdown speed | 0.893439 | 0.022639 | 0.974661 | 0.997300 |
q_detail <- data.frame(
Event = event_names[idx],
p_i = probs[idx],
Q1 = Q1[idx],
Q0 = Q0[idx],
`Q1 - Q_top` = (Q1 - Q_top)[idx],
`Q_top - Q0` = (Q_top - Q0)[idx],
check.names = FALSE
)
knitr::kable(q_detail, digits = 8, row.names = FALSE,
caption = "Detailed Q values for each event")
| Event | p_i | Q1 | Q0 | Q1 - Q_top | Q_top - Q0 |
|---|---|---|---|---|---|
| Initiating go around | 3.00e-02 | 0.11065771 | 0.02270010 | 0.08531889 | 0.00263873 |
| Hydraulic failure | 7.00e-07 | 0.18947625 | 0.02533871 | 0.16413742 | 0.00000012 |
| Pilot reaction delay | 1.45e-01 | 0.02533941 | 0.02533873 | 0.00000058 | 0.00000010 |
| Unavailable thrust | 9.00e-02 | 0.05201910 | 0.02270012 | 0.02668027 | 0.00263871 |
| High touchdown speed | 2.27e-02 | 1.00000000 | 0.00270012 | 0.97466117 | 0.02263871 |
rank_df <- data.frame(
Event = event_names[idx],
FV = rank(-fv[idx]),
Birnbaum = rank(-birnbaum[idx]),
RAW = rank(-raw_diff[idx]),
RRW = rank(-rrw_diff[idx])
)
knitr::kable(rank_df, row.names = FALSE,
caption = "Importance rankings among the 5 plotted events (1 = most important)")
| Event | FV | Birnbaum | RAW | RRW |
|---|---|---|---|---|
| Initiating go around | 2 | 3 | 3 | 2 |
| Hydraulic failure | 4 | 2 | 2 | 4 |
| Pilot reaction delay | 5 | 5 | 5 | 5 |
| Unavailable thrust | 3 | 4 | 4 | 3 |
| High touchdown speed | 1 | 1 | 1 | 1 |
data_matrix <- matrix(c(
fv[idx], birnbaum[idx], raw_diff[idx], rrw_diff[idx]
), nrow = length(idx), ncol = 4)
rownames(data_matrix) <- plot_events
colnames(data_matrix) <- c("FV", "Birnbaum", "RAW", "RRW")
base_angles <- c(pi/2, 0, -pi/2, pi)
color_map <- list(
"Initiating go around" = list(line = "#5C1010", fill = "#8B1A1A", lty = 1, lwd = 1.5),
"Hydraulic failure" = list(line = "#2B3260", fill = "#555588", lty = 1, lwd = 1.5),
"Pilot reaction delay" = list(line = "#5C2060", fill = "#886688", lty = 1, lwd = 1.5),
"Unavailable thrust" = list(line = "#6090B8", fill = "#8AB8D8", lty = 1, lwd = 1.5),
"High touchdown speed" = list(line = "#1A6B25", fill = "#2D8B3D", lty = 2, lwd = 2.2)
)
val_to_r <- function(v) (v + 0.25) / 1.25
par(mar = c(1, 2, 3, 8), xpd = TRUE)
plot(NULL, xlim = c(-1.15, 1.15), ylim = c(-1.15, 1.15), asp = 1,
axes = FALSE, xlab = "", ylab = "")
grid_vals <- c(0, 0.25, 0.5, 0.75, 1.0)
for (gv in grid_vals) {
r <- val_to_r(gv)
vx <- r * cos(base_angles)
vy <- r * sin(base_angles)
polygon(vx, vy, border = "#888888", lwd = 0.6, col = NA)
}
for (a in base_angles) {
lines(c(0, 1.05 * cos(a)), c(0, 1.05 * sin(a)), col = "#888888", lwd = 0.6)
}
for (gv in grid_vals) {
r <- val_to_r(gv)
text(-0.04, r - 0.01, format(gv, nsmall = 2), cex = 0.8, col = "#555555",
adj = c(1, 0))
}
off <- 1.16
text(0, off, "FV", cex = 1.3, font = 2, col = "#1B1B1B")
text(off + 0.02, 0, "Birnbaum", cex = 1.3, font = 2, col = "#1B1B1B", adj = c(0, 0.5))
text(0, -off, "RAW", cex = 1.3, font = 2, col = "#1B1B1B")
text(-off - 0.02, 0, "RRW", cex = 1.3, font = 2, col = "#1B1B1B", adj = c(1, 0.5))
hts_i <- which(plot_events == "High touchdown speed")
draw_order <- c(hts_i, setdiff(seq_along(plot_events), hts_i))
for (di in draw_order) {
ev <- plot_events[di]
cm <- color_map[[ev]]
vals <- data_matrix[di, ]
r_vals <- val_to_r(vals)
xs <- r_vals * cos(base_angles)
ys <- r_vals * sin(base_angles)
fill_alpha <- if (ev == "High touchdown speed") 0.10 else 0.07
polygon(xs, ys, col = adjustcolor(cm$fill, alpha.f = fill_alpha), border = NA)
lines(c(xs, xs[1]), c(ys, ys[1]), col = cm$line, lwd = cm$lwd, lty = cm$lty)
points(xs, ys, col = cm$line, pch = 16, cex = 0.8)
}
title("FTA Importance Measures", cex.main = 1.4, font.main = 2, col.main = "#1B1B1B")
legend("right", inset = c(-0.32, 0),
legend = plot_events,
col = sapply(plot_events, function(e) color_map[[e]]$line),
lwd = sapply(plot_events, function(e) color_map[[e]]$lwd),
lty = sapply(plot_events, function(e) color_map[[e]]$lty),
cex = 0.75, bty = "n")
The manuscript states: “Varying probability estimates by +/-50% did not change the relative ranking of importance measures.”
compute_all_measures <- function(p) {
Q <- calc_Q(p)
n <- length(p)
q1 <- q0 <- numeric(n)
for (i in 1:n) {
pt <- p; pt[i] <- 1; q1[i] <- calc_Q(pt)
pt <- p; pt[i] <- 0; q0[i] <- calc_Q(pt)
}
list(
Q_top = Q,
Birnbaum = q1 - q0,
FV = (Q - q0) / Q,
RAW = q1 - Q,
RRW = Q - q0
)
}
get_top1 <- function(m, idx) {
sapply(list(m$Birnbaum[idx], m$FV[idx], m$RAW[idx], m$RRW[idx]),
function(x) plot_events[which.max(x)])
}
baseline <- compute_all_measures(probs)
baseline_top1 <- get_top1(baseline, idx)
results <- data.frame(
Perturbation = character(),
Q_top = numeric(),
Top1_Stable = character(),
stringsAsFactors = FALSE
)
for (i in 1:n_ev) {
if (probs[i] == 0) next
for (mult in c(0.5, 1.5)) {
p_v <- probs
p_v[i] <- min(1, max(0, probs[i] * mult))
res <- compute_all_measures(p_v)
tops <- get_top1(res, idx)
stable <- ifelse(identical(tops, baseline_top1), "Yes", "CHANGED")
results <- rbind(results, data.frame(
Perturbation = paste0(event_names[i], " x", mult),
Q_top = round(res$Q_top, 6),
Top1_Stable = stable,
stringsAsFactors = FALSE
))
}
}
knitr::kable(results,
col.names = c("Perturbation", "Q_top", "#1 Rank Stable?"),
caption = "Sensitivity of top-ranked event to +/-50% perturbations (among 5 plotted events)")
| Perturbation | Q_top | #1 Rank Stable? | |
|---|---|---|---|
| Hydraulic failure | Hydraulic failure x0.5 | 0.025339 | Yes |
| Hydraulic failure1 | Hydraulic failure x1.5 | 0.025339 | Yes |
| Hydraulic failure2 | Pilot reaction delay x0.5 | 0.025339 | Yes |
| Hydraulic failure3 | Pilot reaction delay x1.5 | 0.025339 | Yes |
| Hydraulic failure4 | High touchdown speed x0.5 | 0.014019 | Yes |
| Hydraulic failure5 | High touchdown speed x1.5 | 0.036658 | Yes |
| Hydraulic failure6 | Initiating go around x0.5 | 0.024019 | Yes |
| Hydraulic failure7 | Initiating go around x1.5 | 0.026658 | Yes |
| Hydraulic failure8 | Unavailable thrust x0.5 | 0.024019 | Yes |
| Hydraulic failure9 | Unavailable thrust x1.5 | 0.026658 | Yes |
tornado <- data.frame(Event = character(), Q_low = numeric(),
Q_high = numeric(), stringsAsFactors = FALSE)
for (i in 1:n_ev) {
if (probs[i] == 0) next
p_lo <- probs; p_lo[i] <- probs[i] * 0.5
p_hi <- probs; p_hi[i] <- probs[i] * 1.5
tornado <- rbind(tornado, data.frame(
Event = event_names[i],
Q_low = calc_Q(p_lo),
Q_high = calc_Q(p_hi),
stringsAsFactors = FALSE
))
}
tornado$Swing <- tornado$Q_high - tornado$Q_low
tornado <- tornado[order(tornado$Swing, decreasing = TRUE), ]
par(mar = c(5, 12, 4, 2))
bp <- barplot(
tornado$Swing, horiz = TRUE, names.arg = tornado$Event,
las = 1, col = "steelblue", border = "white",
main = expression("Sensitivity of Q"[top]*" to "*pm*"50% Variation"),
xlab = expression(Delta * " Q"[top]),
xlim = c(0, max(tornado$Swing) * 1.15)
)
text(tornado$Swing, bp, labels = round(tornado$Swing, 5), pos = 4, cex = 0.8)
hts_idx_local <- which(plot_events == "High touchdown speed")
detail_rows <- list()
detail_rows[[1]] <- data.frame(
Scenario = "Baseline",
Q_top = round(baseline$Q_top, 6),
`Birn(HTS)` = round(baseline$Birnbaum[idx[hts_idx_local]], 6),
`FV(HTS)` = round(baseline$FV[idx[hts_idx_local]], 6),
`RAW(HTS)` = round(baseline$RAW[idx[hts_idx_local]], 6),
`RRW(HTS)` = round(baseline$RRW[idx[hts_idx_local]], 6),
check.names = FALSE, stringsAsFactors = FALSE
)
k <- 2
for (i in 1:n_ev) {
if (probs[i] == 0) next
for (mult in c(0.5, 1.5)) {
p_v <- probs
p_v[i] <- min(1, max(0, probs[i] * mult))
res <- compute_all_measures(p_v)
detail_rows[[k]] <- data.frame(
Scenario = paste0(event_names[i], " x", mult),
Q_top = round(res$Q_top, 6),
`Birn(HTS)` = round(res$Birnbaum[idx[hts_idx_local]], 6),
`FV(HTS)` = round(res$FV[idx[hts_idx_local]], 6),
`RAW(HTS)` = round(res$RAW[idx[hts_idx_local]], 6),
`RRW(HTS)` = round(res$RRW[idx[hts_idx_local]], 6),
check.names = FALSE, stringsAsFactors = FALSE
)
k <- k + 1
}
}
detail_df <- do.call(rbind, detail_rows)
knitr::kable(detail_df, row.names = FALSE,
caption = "High touchdown speed measures under each perturbation")
| Scenario | Q_top | Birn(HTS) | FV(HTS) | RAW(HTS) | RRW(HTS) |
|---|---|---|---|---|---|
| Baseline | 0.025339 | 0.99730 | 0.893439 | 0.974661 | 0.022639 |
| Hydraulic failure x0.5 | 0.025339 | 0.99730 | 0.893442 | 0.974661 | 0.022639 |
| Hydraulic failure x1.5 | 0.025339 | 0.99730 | 0.893437 | 0.974661 | 0.022639 |
| Pilot reaction delay x0.5 | 0.025339 | 0.99730 | 0.893441 | 0.974661 | 0.022639 |
| Pilot reaction delay x1.5 | 0.025339 | 0.99730 | 0.893438 | 0.974661 | 0.022639 |
| High touchdown speed x0.5 | 0.014019 | 0.99730 | 0.807402 | 0.985981 | 0.011319 |
| High touchdown speed x1.5 | 0.036658 | 0.99730 | 0.926343 | 0.963342 | 0.033958 |
| Initiating go around x0.5 | 0.024019 | 0.99865 | 0.943791 | 0.975981 | 0.022669 |
| Initiating go around x1.5 | 0.026658 | 0.99595 | 0.848072 | 0.973342 | 0.022608 |
| Unavailable thrust x0.5 | 0.024019 | 0.99865 | 0.943791 | 0.975981 | 0.022669 |
| Unavailable thrust x1.5 | 0.026658 | 0.99595 | 0.848072 | 0.973342 | 0.022608 |
sessionInfo()
## R version 4.5.1 (2025-06-13 ucrt)
## Platform: x86_64-w64-mingw32/x64
## Running under: Windows 11 x64 (build 26200)
##
## Matrix products: default
## LAPACK version 3.12.1
##
## locale:
## [1] LC_COLLATE=English_United Kingdom.utf8
## [2] LC_CTYPE=English_United Kingdom.utf8
## [3] LC_MONETARY=English_United Kingdom.utf8
## [4] LC_NUMERIC=C
## [5] LC_TIME=English_United Kingdom.utf8
##
## time zone: America/Los_Angeles
## tzcode source: internal
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## loaded via a namespace (and not attached):
## [1] digest_0.6.37 R6_2.6.1 fastmap_1.2.0 xfun_0.52
## [5] cachem_1.1.0 knitr_1.50 htmltools_0.5.8.1 rmarkdown_2.30
## [9] lifecycle_1.0.4 cli_3.6.5 sass_0.4.10 jquerylib_0.1.4
## [13] compiler_4.5.1 tools_4.5.1 evaluate_1.0.5 bslib_0.9.0
## [17] yaml_2.3.10 rlang_1.1.6 jsonlite_2.0.0