Skip to content

Commit effaa04

Browse files
authored
Merge pull request #161 from NOAA-EDAB/detrital_fixes
fixed interdetrital flows (EEs and ecosim equilibrium), removed a det…
2 parents d93dfe7 + 5b566a6 commit effaa04

2 files changed

Lines changed: 61 additions & 45 deletions

File tree

R/ecopath.R

Lines changed: 47 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@ rpath <- function(Rpath.params, eco.name = NA, eco.area = 1) {
3636
set(model, j = logic.col[i], value = as.numeric(model[[logic.col[i]]]))
3737
}
3838
}
39-
39+
4040
#Remove first column if names (factor or character)
4141
if(sapply(diet, class)[1] == 'factor') diet[, 1 := NULL]
4242
if(sapply(diet, class)[1] == 'character') diet[, 1 := NULL]
43-
43+
4444
#Adjust diet comp of mixotrophs
4545
mixotrophs <- which(model[, Type] > 0 & model[, Type] < 1)
4646
mix.Q <- 1 - model[mixotrophs, Type]
@@ -57,10 +57,10 @@ rpath <- function(Rpath.params, eco.name = NA, eco.area = 1) {
5757
nliving <- nrow(model[Type < 2, ])
5858
ndead <- nrow(model[Type == 2, ])
5959
ngear <- nrow(model[Type == 3, ])
60-
60+
6161
nodetrdiet <- diet[1:nliving, ]
6262
model[is.na(DetInput), DetInput := 0]
63-
63+
6464
# fill in GE(PQ), QB, or PB from other inputs
6565
GE <- ifelse(is.na(model[, ProdCons]), model[, PB / QB], model[, ProdCons])
6666
QB.1 <- ifelse(is.na(model[, QB]), model[, PB / GE], model[, QB])
@@ -72,7 +72,7 @@ rpath <- function(Rpath.params, eco.name = NA, eco.area = 1) {
7272
landmat <- model[, (10 + ndead + 1):(10 + ndead + ngear), with = F]
7373
discardmat <- model[, (10 + ndead + 1 + ngear):(10 + ndead + (2 * ngear)), with = F]
7474
totcatchmat <- landmat + discardmat
75-
75+
7676
if (is.data.frame(totcatchmat)){
7777
totcatch <- rowSums(totcatchmat)
7878
landings <- rowSums(landmat)
@@ -91,7 +91,7 @@ rpath <- function(Rpath.params, eco.name = NA, eco.area = 1) {
9191
model[, landings := landings]
9292
model[, discards := discards]
9393
model[, totcatch := totcatch]
94-
94+
9595
# flag missing pars and subset for estimation
9696
model[, noB := 0]
9797
model[, noEE := 0]
@@ -104,7 +104,8 @@ rpath <- function(Rpath.params, eco.name = NA, eco.area = 1) {
104104

105105
# define detritus fate matrix
106106
detfate <- model[, (10 + 1):(10 + ndead), with = F]
107-
107+
detdetfate <- model[Type==2, (10 + 1):(10 + ndead), with = F]
108+
108109
# set up and solve the system of equations for living group B or EE
109110
living <- model[alive == 1, ]
110111

@@ -133,7 +134,7 @@ rpath <- function(Rpath.params, eco.name = NA, eco.area = 1) {
133134
A <- A - QBDCa
134135
#Switch flag back
135136
#living[BEE == 1, noB := 0]
136-
137+
137138
# Generalized inverse does the actual solving
138139
#Invert A and multiple by b to get x (unknowns)
139140
x <- MASS::ginv(A, tol = .Machine$double.eps) %*% living[, b]
@@ -144,22 +145,32 @@ rpath <- function(Rpath.params, eco.name = NA, eco.area = 1) {
144145

145146
living[, B := x * noB]
146147
living[is.na(Biomass), Biomass := B]
147-
148+
148149
# detritus EE calcs
149150
living[, M0 := PB * (1 - EE)]
150151
living[, QBloss := QB]
151152
living[is.na(QBloss), QBloss := 0]
153+
#KYA fix Aug 2025
154+
#loss <- c((living[, M0] * living[, Biomass]) +
155+
# (living[, Biomass] * living[, QBloss] * living[, Unassim]),
156+
# model[Type ==2, DetInput],
157+
# geardisc)
158+
#detinputs1 <- colSums(loss * detfate)
159+
#detinputs1 is "first pass" at det inputs, final detinputs is after initial EE
152160
loss <- c((living[, M0] * living[, Biomass]) +
153161
(living[, Biomass] * living[, QBloss] * living[, Unassim]),
154-
model[Type ==2, DetInput],
155-
geardisc)
156-
detinputs <- colSums(loss * detfate)
162+
rep(0,ndead),
163+
geardisc)
164+
detinputs1 <- colSums(loss * detfate + model[, DetInput])
165+
## end fix
157166
detdiet <- diet[(nliving + 1):(nliving + ndead), ]
158167
BQB <- living[, Biomass * QB]
159168
detcons <- as.matrix(detdiet) * BQB[col(as.matrix(detdiet))]
160169
detoutputs <- rowSums(detcons, na.rm = T)
170+
det_unused <- ifelse(detinputs1>detoutputs, detinputs1-detoutputs, 0.0)
171+
detinputs <- detinputs1 + colSums(det_unused*detdetfate)
161172
EE <- c(living[, EE], as.vector(detoutputs / detinputs))
162-
173+
163174
# added by kya
164175
# if a detritus biomass is put into the spreadsheet, use that and
165176
# calculate PB. If no biomass, but a PB, use that pb with inflow to
@@ -172,7 +183,7 @@ rpath <- function(Rpath.params, eco.name = NA, eco.area = 1) {
172183
DetPB <- ifelse(is.na(inDetPB), Default_Detrital_PB, inDetPB)
173184
DetB <- ifelse(is.na(inDetB), detinputs / DetPB, inDetB)
174185
DetPB <- detinputs / DetB
175-
186+
176187
# Trophic Level calcs
177188
b <- rep(1, ngroups)
178189
TLcoeff <- matrix(0, ngroups, ngroups)
@@ -182,7 +193,7 @@ rpath <- function(Rpath.params, eco.name = NA, eco.area = 1) {
182193
gearcons[is.na(gearcons)] <- 0
183194
dietplus <- as.matrix(diet)
184195
dimnames(dietplus) <- list(NULL, NULL)
185-
196+
186197
#Adjust for mixotrophs (partial primary producers) - #Moved this code up so that
187198
#it also impacted the EE calculation
188199
# mixotrophs <- which(model[, Type] > 0 & model[, Type] < 1)
@@ -201,7 +212,7 @@ rpath <- function(Rpath.params, eco.name = NA, eco.area = 1) {
201212
dietplus <- cbind(dietplus, matrix(0, ngroups, ndead), gearcons)
202213
TLcoeffA <- TLcoeff - dietplus
203214
TL <- solve(t(TLcoeffA), b)
204-
215+
205216
#kya changed these following four lines for detritus, and removing NAs
206217
#to match header file format (replacing NAs with 0.0s)
207218
Bplus <- c(living[, Biomass], DetB, rep(0.0, ngear))
@@ -228,7 +239,7 @@ rpath <- function(Rpath.params, eco.name = NA, eco.area = 1) {
228239
EE = EEplus,
229240
GE = GE,
230241
Removals = RemPlus)
231-
242+
232243
M0plus <- c(living[, M0], as.vector(detoutputs / detinputs))
233244
gearF <- as.matrix(totcatchmat) / living[, Biomass][row(as.matrix(totcatchmat))]
234245
newcons <- as.matrix(nodetrdiet) * BQB[col(as.matrix(nodetrdiet))]
@@ -263,19 +274,19 @@ rpath <- function(Rpath.params, eco.name = NA, eco.area = 1) {
263274
detfatem <- as.matrix(detfate)
264275
dimnames(detfatem) <- list(gnames, gnames[(nliving+1):(nliving+ndead)])
265276
detfatem[is.na(detfatem)] <- 0
266-
277+
267278
# Add names for output list
268-
out.Group <- gnames; names(out.Group) <- gnames
269-
out.type <- model[, Type]; names(out.type) <- gnames
270-
out.TL <- TL; names(out.TL) <- gnames
271-
out.Biomass <- balanced$Biomass; names(out.Biomass) <- gnames
272-
out.PB <- balanced$PB; names(out.PB) <- gnames
273-
out.QB <- balanced$QB; names(out.QB) <- gnames
274-
out.EE <- balanced$EE; names(out.EE) <- gnames
275-
out.BA <- model[, BioAcc]; names(out.BA) <- gnames
276-
out.Unassim <- model[, Unassim]; names(out.Unassim) <- gnames
277-
out.GE <- balanced$GE; names(out.GE) <- gnames
278-
279+
out.Group <- gnames; names(out.Group) <- gnames
280+
out.type <- model[, Type]; names(out.type) <- gnames
281+
out.TL <- TL; names(out.TL) <- gnames
282+
out.Biomass <- balanced$Biomass; names(out.Biomass) <- gnames
283+
out.PB <- balanced$PB; names(out.PB) <- gnames
284+
out.QB <- balanced$QB; names(out.QB) <- gnames
285+
out.EE <- balanced$EE; names(out.EE) <- gnames
286+
out.BA <- model[, BioAcc]; names(out.BA) <- gnames
287+
out.Unassim <- model[, Unassim]; names(out.Unassim) <- gnames
288+
out.GE <- balanced$GE; names(out.GE) <- gnames
289+
279290
# list structure for sim inputs
280291
path.model <- list(NUM_GROUPS = ngroups,
281292
NUM_LIVING = nliving,
@@ -295,13 +306,13 @@ rpath <- function(Rpath.params, eco.name = NA, eco.area = 1) {
295306
DetFate = detfatem,
296307
Landings = landmatm,
297308
Discards = discardmatm)
298-
299-
#Define class of output
300-
class(path.model) <- 'Rpath'
301-
attr(path.model, 'eco.name') <- eco.name
302-
attr(path.model, 'eco.area') <- eco.area
303-
304-
return(path.model)
309+
310+
#Define class of output
311+
class(path.model) <- 'Rpath'
312+
attr(path.model, 'eco.name') <- eco.name
313+
attr(path.model, 'eco.area') <- eco.area
314+
315+
return(path.model)
305316
}
306317

307318

R/param.R

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -393,15 +393,20 @@ check.rpath.params <- function(Rpath.params) {
393393

394394
#Check detritus fate is numeric and sum to 1
395395
det.matrix <- Rpath.params$model[, 11:(10 + n.dead), with = F]
396-
test.rows <- rowSums(det.matrix)
397-
if (length(setdiff(which(Rpath.params$model[, Type] == 2), which(test.rows != 1))) > 0) {
398-
warning(paste(
399-
Rpath.params$model[, Group][setdiff(which(Rpath.params$model[, Type] == 2), which(test.rows != 1))],
400-
'detrital fate does not sum to 1 \n',
401-
sep = ' '
402-
))
403-
w <- w + 1
404-
}
396+
397+
# KYA August '25 - I'm not sure why this part of this test should be done - having
398+
# detrital groups' detrital fate not sum to 1 is appropriate if detritus
399+
# is being exported. I think silence here is more appropriate than a warning.
400+
#test.rows <- rowSums(det.matrix)
401+
#if (length(setdiff(which(Rpath.params$model[, Type] == 2), which(test.rows != 1))) > 0) {
402+
# warning(paste(
403+
# Rpath.params$model[, Group][setdiff(which(Rpath.params$model[, Type] == 2), which(test.rows != 1))],
404+
# 'detrital fate does not sum to 1 \n',
405+
# sep = ' '
406+
# ))
407+
# w <- w + 1
408+
#}
409+
405410
if (length(which(is.na(det.matrix))) > 0) {
406411
na.group <- which(is.na(det.matrix))
407412
for (i in 1:length(na.group))

0 commit comments

Comments
 (0)