Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
31451f5
Address Issue #44, added D0 as its own variable to ensure FBP reports…
BadgerOnABike Sep 18, 2024
29b8bfb
Update the FMC Min documentation. Kicking off a retest in the PR, tes…
BadgerOnABike Dec 31, 2024
a31c058
Longitudinal correction for values over 270, code uses Easting / Westing
BadgerOnABike Jan 2, 2025
d544695
FMC update
BadgerOnABike Jan 8, 2025
d292326
Work so far on FMC fixing D0 failures
BadgerOnABike Jun 19, 2025
08e22e9
Rebuilding Test Data
BadgerOnABike Oct 6, 2025
c10a39c
Address Issue #44, added D0 as its own variable to ensure FBP reports…
BadgerOnABike Sep 18, 2024
daa55d7
Update the FMC Min documentation. Kicking off a retest in the PR, tes…
BadgerOnABike Dec 31, 2024
ee6c35e
Longitudinal correction for values over 270, code uses Easting / Westing
BadgerOnABike Jan 2, 2025
90ec88f
FMC update
BadgerOnABike Jan 8, 2025
592f9d8
Work so far on FMC fixing D0 failures
BadgerOnABike Jun 19, 2025
58e84d9
Merge branch 'BadgerOnABike/issue44' of https://github.com/cffdrs/cff…
BadgerOnABike Oct 20, 2025
635663c
Work so far on FMC fixing D0 failures
BadgerOnABike Jun 19, 2025
5d66f75
Rebuilding Test Data
BadgerOnABike Oct 6, 2025
732d77c
Merge branch 'BadgerOnABike/issue44' of https://github.com/cffdrs/cff…
BadgerOnABike Oct 20, 2025
627c5ca
Update desc / test csvs
BadgerOnABike Oct 21, 2025
1f2a0c6
Continuing progress on foliar moisture content.
BadgerOnABike Oct 29, 2025
4c29b09
Ensure fueltypes that would not have a D0 are zeroed out prior to ret…
BadgerOnABike Oct 29, 2025
ff0f299
Comment as to why D0 is calculated within FMC when the FBP function c…
BadgerOnABike Oct 29, 2025
f705289
Updated test data to deal with non-0 FMC
BadgerOnABike May 4, 2026
11b454d
Updates to FMC to return D0 properly when 0.
BadgerOnABike May 6, 2026
a9d8271
Improve tests and provide updated test data now that FMC is appropria…
BadgerOnABike May 7, 2026
bd5c431
Increment version number to 1.10.0
BadgerOnABike May 7, 2026
6ebb547
Merge branch 'main' into BadgerOnABike/issue44
BadgerOnABike May 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Type: Package
Package: cffdrs
Title: Canadian Forest Fire Danger Rating System
Version: 1.9.2
Date: 2025-08-21
Version: 1.10.0
Date: 2026-05-07
Authors@R: c(
person("Xianli", "Wang", , "Xianli.Wang@nrcan-rncan.gc.ca", role = "aut"),
person("Alan", "Cantin", , "Alan.Cantin@nrcan-rncan.gc.ca", role = "aut"),
Expand Down
9 changes: 9 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
# cffdrs 1.10.0

## Enhancements

### Updated Foliar Moisture Content

Foliar moisture content now properly calculates the date of minimum moisture and
will append it to the output so allow the user to see the `D0` in the output.

# cffdrs 1.9.2

# version 1.9.2
Expand Down
12 changes: 9 additions & 3 deletions R/fire_behaviour_prediction.r
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,11 @@ fire_behaviour_prediction <- function(
LAT <- ifelse(LAT < -90 | LAT > 90, 0, LAT)
LAT <- ifelse(is.na(LAT), 55, LAT)
LONG <- ifelse(LONG < -180 | LONG > 360, 0, LONG)
LONG <- ifelse(LONG > 180, LONG - 180, LONG)
LONG <- ifelse(is.na(LONG), -120, LONG)
# Any negative longitudes (western hemisphere) are translated to positive
# longitudes
LONG <- ifelse(LONG < 0, -LONG, LONG)
THETA <- ifelse(is.na(THETA) | THETA < -2 * pi | THETA > 2 * pi, 0, THETA)
SD <- ifelse(SD < 0 | SD > 1e+05, -999, SD)
SD <- ifelse(is.na(SD), 0, SD)
Expand All @@ -247,9 +251,7 @@ fire_behaviour_prediction <- function(
WAZ <- ifelse(WAZ > 2 * pi, WAZ - 2 * pi, WAZ)
SAZ <- ASPECT + pi
SAZ <- ifelse(SAZ > 2 * pi, SAZ - 2 * pi, SAZ)
# Any negative longitudes (western hemisphere) are translated to positive
# longitudes
LONG <- ifelse(LONG < 0, -LONG, LONG)

############################################################################
# END
############################################################################
Expand All @@ -272,12 +274,16 @@ fire_behaviour_prediction <- function(
}
CBH <- crown_base_height(FUELTYPE, CBH, SD, SH)
CFL <- crown_fuel_load(FUELTYPE, CFL)
D0 <- ifelse(D0 <= 0, foliar_moisture_content_minimum(LAT, LONG, ELV, DJ, D0), D0)
FMC <- ifelse(
FMC <= 0 | FMC > 120 | is.na(FMC),
foliar_moisture_content(LAT, LONG, ELV, DJ, D0),
FMC
)

FMC <- ifelse(FUELTYPE %in% c("D1", "S1", "S2", "S3", "O1A", "O1B"), 0, FMC)
D0 <- ifelse(FUELTYPE %in% c("D1", "S1", "S2", "S3", "O1A", "O1B"), 0, D0)

############################################################################
# END
############################################################################
Expand Down
61 changes: 32 additions & 29 deletions R/foliar_moisture_content.r
Original file line number Diff line number Diff line change
Expand Up @@ -9,56 +9,59 @@
#' @param LAT Latitude (decimal degrees)
#' @param LONG Longitude (decimal degrees)
#' @param ELV Elevation (metres)
#' @param DJ Day of year (offeren referred to as julian date)
#' @param DJ Day of year (julian date)
#' @param D0 Date of minimum foliar moisture content. _If D0, date of min
#' FMC, is not known then D0 = NULL._
#' @param FMCo Foliar Moisture Content Override - For use when outside of North
#' America
#'
#' @return FMC: Foliar Moisture Content value
#' @noRd

foliar_moisture_content <- function(LAT, LONG, ELV, DJ, D0) {
# Initialize vectors
FMC <- rep(-1, length(LAT))
LATN <- rep(0, length(LAT))
# Calculate Normalized Latitude
# Eqs. 1 & 3 (FCFDG 1992)
LATN <- ifelse(
D0 <= 0,
ifelse(
ELV <= 0,
46 + 23.4 * exp(-0.0360 * (150 - LONG)),
43 + 33.7 * exp(-0.0351 * (150 - LONG))
),
LATN
)
# Calculate Date of minimum foliar moisture content
# Eqs. 2 & 4 (FCFDG 1992)
D0 <- ifelse(
D0 <= 0,
ifelse(
ELV <= 0,
151 * (LAT / LATN),
142.1 * (LAT / LATN) + 0.0172 * ELV
),
D0
)
# Round D0 to the nearest integer because it is a date
D0 <- round(D0, 0)
foliar_moisture_content <- function(LAT, LONG, ELV, DJ, D0=NA,FMCo=NULL) {

if(any(LAT < 7 | LONG > 140 | LONG < 52)){warning({"Location outside of North America. Please define an FMC override in the FMCo variable."})}
if(!is.null(FMCo)){
if(!is.na(FMCo)){FMC <- FMCo;
message("FMC Override provided, returning as FMC.");
return(FMC)
}}

## In the event a user wants to calculate the FMC outside of the FBP function this will ensure D0 gets calculated.

D0 <- if(any(D0 <= 0| is.na(D0))){foliar_moisture_content_minimum(LAT, LONG, ELV, DJ, D0)}else{D0}


# Number of days between day of year and date of min FMC

# Eq. 5 (FCFDG 1992)

ND <- abs(DJ - D0)

# Calculate final FMC

# Eqs. 6, 7, & 8 (FCFDG 1992)

FMC <- ifelse(

ND < 30,

85 + 0.0189 * ND^2,

ifelse(

ND >= 30 & ND < 50,

32.9 + 3.17 * ND - 0.0288 * ND^2,

120

)

)

return(FMC)

}

.FMCcalc <- function(...) {
Expand Down
59 changes: 59 additions & 0 deletions R/foliar_moisture_content_minimum.r
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#' Foliar Moisture Content Minimum Calculator
#'
#' @description Calculate date of Foliar Moisture Content Minimum.
#' All variables names are laid out in the same manner as Forestry Canada
#' Fire Danger Group (FCFDG) (1992). Development and Structure of the
#' Canadian Forest Fire Behavior Prediction System." Technical Report
#' ST-X-3, Forestry Canada, Ottawa, Ontario. This function returns the date of
#' minimum foliar moisture content.
#'
#' @param LAT Latitude (decimal degrees)
#' @param LONG Longitude (decimal degrees)
#' @param ELV Elevation (metres)
#' @param DJ Day of year (offeren referred to as julian date)
#' @param D0 Date of minimum foliar moisture content. _If D0, date of min
#' FMC, is not known then D0 = NULL._
#'
#' @return D0: Date of minimum foliar moisture content
#' @noRd

foliar_moisture_content_minimum <- function(LAT, LONG, ELV, DJ,D0) {

# Initialize vectors

FMC <- rep(-1, length(LAT))
LATN <- rep(0, length(LAT))

# Calculate Normalized Latitude

# Eqs. 1 & 3 (FCFDG 1992)

LATN <- ifelse(
D0 <= 0|is.na(D0),
ifelse(
ELV <= 0,
46 + 23.4 * exp(-0.0360 * (150 - LONG)),
43 + 33.7 * exp(-0.0351 * (150 - LONG))
),LATN)


# Calculate Date of minimum foliar moisture content

# Eqs. 2 & 4 (FCFDG 1992)

D0 <- ifelse(
D0 <= 0|is.na(D0),
ifelse(
ELV <= 0,
151 * (LAT / LATN),
142.1 * (LAT / LATN) + 0.0172 * ELV
),
D0
)

# Round D0 to the nearest integer because it is a date

D0 <- round(D0, 0)
return(D0)

}
Loading
Loading