EU-kalat: Difference between revisions

From Opasnet
Jump to navigation Jump to search
Line 460: Line 460:
<rcode name="pollutant_bayes" label="Initiate conc_pcddf with PFAS, OT (for developers only)" embed=0>
<rcode name="pollutant_bayes" label="Initiate conc_pcddf with PFAS, OT (for developers only)" embed=0>
# This is code Op_en3104/pollutant_bayes on page [[EU-kalat]]
# This is code Op_en3104/pollutant_bayes on page [[EU-kalat]]
# The code is also available at https://github.com/jtuomist/pfas/blob/main/conc_pcddf_preprocess.R


library(OpasnetUtils)
library(OpasnetUtils)
Line 467: Line 468:
library(MASS) # mvrnorm
library(MASS) # mvrnorm
library(car) # scatterplotMatrix
library(car) # scatterplotMatrix
#' Find the level of quantification for dinterval function
#' @param df data.frame
#' @return data.matrix
add_loq <- function(df) {
  LOQ <- unlist(lapply(df, FUN = function(x) min(x[x!=0], na.rm=TRUE)))
  out <- sapply(
    1:length(LOQ),
    FUN = function(x) ifelse(df[,x]==0, 0.5*LOQ[x], df[,x])
  )
  out <- data.matrix(out)
  return(out)
}


#size <- Ovariable("size", ddata="Op_en7748", subset="Size distribution of fish species")
#size <- Ovariable("size", ddata="Op_en7748", subset="Size distribution of fish species")
Line 487: Line 501:
# Catchment year affects all species similarly.  
# Catchment year affects all species similarly.  


conl <- as.character(unique(eu2$Compound)) # indices$Compound.TEQ2
eu2 <- eu2[!eu2$Compound %in% c("MPhT","DOT","BDE138"),] # No values > 0
fisl <- as.character(unique(eu2$Fish)) # c("Baltic herring","Salmon")


eu3 <- eu2[eu2$Compound %in% conl & eu2$Fish %in% fisl & eu2$Matrix == "Muscle" , ]@output
eu3 <- eu2[eu2$Matrix == "Muscle" , ]@output
eu3 <- reshape(  
eu3 <- reshape(  
   eu3,  
   eu3,  
Line 501: Line 514:
colnames(eu3) <- gsub("eu2Result\\.","",colnames(eu3))
colnames(eu3) <- gsub("eu2Result\\.","",colnames(eu3))


oprint(head(eu3))
conl_nd <- c("PFOA","PFOS","DBT","MBT","TBT","DPhT","TPhT")
eu4 <- eu3[rowSums(is.na(eu3[conl_nd]))<7 , c(1:5,match(conl_nd,colnames(eu3)))]
fisl_nd <- as.character(unique(eu4$Fish))
conc_nd <- add_loq(eu4[6:ncol(eu4)])


#> colnames(eu3)
eu3 <- eu3[!is.na(eu3$PCDDF) , !colnames(eu3) %in% conl_nd]
#[1] "THLcode"        "Fish"          "N"              "Length"        "Year"         
conl <- colnames(eu3)[-(1:5)]
#[6] "euResult.PCDDF" "euResult.PCB" 
fisl <- as.character(unique(eu3$Fish))


eu3$MPhT <- NULL # No values > 0
oprint(head(eu3))
eu3$DOT <- NULL # No values > 0
eu3$BDE138 <- NULL # No values > 0


C <- length(conl)
C <- length(conl)
Fi <- length(fisl)
Fi <- length(fisl)
N <- 1000
N <- 100
conl
conl
fisl
fisl


conc <- eu3[6:ncol(eu3)]
conc <- add_loq(eu3[rowSums(is.na(eu3))==0 , 6:ncol(eu3)]) # Remove rows with missing data.
 
# Find the level of quantification for dinterval function
LOQ <- unlist(lapply(eu3[6:ncol(eu3)], FUN = function(x) min(x[x!=0], na.rm=TRUE)))
# With TEQ, there are no zeros. So this is useful only if there are congener-specific results.
#names(LOQ) <- conl
 


conc <- sapply(
# The model assumes that all fish groups have the same Omega but mu varies.
  1:length(LOQ),
  FUN = function(x) ifelse(is.na(conc[,x]) | conc[,x]==0, 0.5*LOQ[x], conc[,x])
)
conc <- data.matrix(conc)
 
# It assumes that all fish groups have the same Omega but mu varies.


mod <- textConnection(
mod <- textConnection(
   "
   "
   model{
   model{
  for(i in 1:S) { # S = fish sample
    for(i in 1:S) { # S = fish sample
  #        below.LOQ[i,j] ~ dinterval(-conc[i,j], -LOQ[j])
      #        below.LOQ[i,j] ~ dinterval(-conc[i,j], -LOQ[j])
  conc[i,1:C] ~ dmnorm(muind[i,], Omega[fis[i],,])
      conc[i,1:C] ~ dmnorm(muind[i,], Omega[fis[i],,])
  muind[i,1:C] <- mu[fis[i],1:C] #+ lenp[fis[i]]*length[i] + timep*year[i]
      muind[i,1:C] <- mu[fis[i],1:C] #+ lenp[fis[i]]*length[i] + timep*year[i]
  }
    }
 
    for(i in 1:S_nd) {
  # Priors for parameters
      for(j in 1:C_nd) {
  # Time trend. Assumed a known constant because at the moment there is little time variation in data.
        conc_nd[i,j] ~ dnorm(muind_nd[i,j], tau_nd[j])
  # https://www.evira.fi/elintarvikkeet/ajankohtaista/2018/itameren-silakoissa-yha-vahemman-ymparistomyrkkyja---paastojen-rajoitukset-vaikuttavat/
        muind_nd[i,j] <- mu_nd[fis_nd[i],j] #+ lenp[fis[i]]*length[i] + timep*year[i]
  # PCDDF/PCB-concentations 2001: 9 pg/g fw, 2016: 3.5 pg/g fw. (3.5/9)^(1/15)-1=-0.06102282
      }
#  timep ~ dnorm(-0.0610, 10000)  
    }
#  lenp[1] ~ dnorm(0.01,0.01) # length parameter for herring
   
#  lenp[2] ~ dnorm(0,10000) # length parameter for salmon: assumed zero
    # Priors for parameters
 
    # Time trend. Assumed a known constant because at the moment there is little time variation in data.
  for(i in 1:Fi) { # Fi = fish species
    # https://www.evira.fi/elintarvikkeet/ajankohtaista/2018/itameren-silakoissa-yha-vahemman-ymparistomyrkkyja---paastojen-rajoitukset-vaikuttavat/
  Omega[i,1:C,1:C] ~ dwish(Omega0[1:C,1:C],S)
    # PCDDF/PCB-concentations 2001: 9 pg/g fw, 2016: 3.5 pg/g fw. (3.5/9)^(1/15)-1=-0.06102282
  pred[i,1:C] ~ dmnorm(mu[i,1:C], Omega[i,,]) #+lenp[i]*lenpred+timep*timepred, Omega[i,,]) # Model prediction.
  #  timep ~ dnorm(-0.0610, 10000)  
  for(j in 1:C) {  
  #  lenp[1] ~ dnorm(0.01,0.01) # length parameter for herring
  mu[i,j] ~ dnorm(0, 0.0001) # mu1[j], tau1[j]) # Congener-specific mean for fishes
  #  lenp[2] ~ dnorm(0,10000) # length parameter for salmon: assumed zero
   
    for(i in 1:Fi) { # Fi = fish species
      Omega[i,1:C,1:C] ~ dwish(Omega0[1:C,1:C],S)
      pred[i,1:C] ~ dmnorm(mu[i,1:C], Omega[i,,]) #+lenp[i]*lenpred+timep*timepred, Omega[i,,]) # Model prediction.
      for(j in 1:C) {  
        mu[i,j] ~ dnorm(0, 0.0001) # mu1[j], tau1[j]) # Congener-specific mean for fishes
      }
    }
    # Non-dioxins
    for(i in 1:Fi_nd) { # Fi = fish species
      for(j in 1:C_nd) {
        pred_nd[i,j] ~ dnorm(mu[i,j], tau_nd[j])
        mu_nd[i,j] ~ dnorm(0, 0.0001)
      }
    }
    for(j in 1:C_nd) {
      tau_nd[j] ~ dgamma(0.001,0.001)
    }
   }
   }
  }
")
  }
  ")


jags <- jags.model(
jags <- jags.model(
   mod,
   mod,
   data = list(
   data = list(
     S = nrow(eu3),
     S = nrow(conc),
    S_nd = nrow(conc_nd),
     C = C,
     C = C,
    C_nd = ncol(conc_nd),
     Fi = Fi,
     Fi = Fi,
    Fi_nd = length(fisl_nd),
     conc = log(conc),
     conc = log(conc),
#    length = eu3$Length-170, # Subtract average herring size
    conc_nd = conc_nd,
#    year = eu3$Year-2009, # Substract baseline year
    #    length = eu3$Length-170, # Subtract average herring size
    #    year = eu3$Year-2009, # Substract baseline year
     fis = match(eu3$Fish, fisl),
     fis = match(eu3$Fish, fisl),
#    lenpred = 233-170,
    fis_nd = match(eu4$Fish, fisl_nd),
#    timepred = 2009-2009,
    #    lenpred = 233-170,
    #    timepred = 2009-2009,
     Omega0 = diag(C)/100000
     Omega0 = diag(C)/100000
   ),
   ),
Line 578: Line 601:
)
)


update(jags, 1000)
update(jags, 100)


samps.j <- jags.samples(
samps.j <- jags.samples(
Line 585: Line 608:
     'mu', # mean by fish and compound
     'mu', # mean by fish and compound
     'Omega', # precision matrix by compound
     'Omega', # precision matrix by compound
#    'lenp',# parameters for length
    #    'lenp',# parameters for length
#    'timep', # parameter for Year
    #    'timep', # parameter for Year
     'pred' # predicted concentration for year 2009 and length 17 cm
     'pred', # predicted concentration for year 2009 and length 17 cm
    'pred_nd',
    'mu_nd',
    'tau_nd'
   ),  
   ),  
   #  thin=1000,
   #  thin=1000,
Line 596: Line 622:
#dimnames(samps.j$lenp) <- list(Fish = fisl, Iter = 1:N, Chain = 1:4)
#dimnames(samps.j$lenp) <- list(Fish = fisl, Iter = 1:N, Chain = 1:4)
dimnames(samps.j$pred) <- list(Fish = fisl, Compound = conl, Iter = 1:N, Chain = 1:4)
dimnames(samps.j$pred) <- list(Fish = fisl, Compound = conl, Iter = 1:N, Chain = 1:4)
dimnames(samps.j$pred_nd) <- list(Fish = fisl_nd, Compound = conl_nd, Iter = 1:N, Chain = 1:4)
dimnames(samps.j$mu_nd) <- list(Fish = fisl_nd, Compound = conl_nd, Iter = 1:N, Chain = 1:4)
dimnames(samps.j$tau_nd) <- list(Compound = conl_nd, Iter = 1:N, Chain = 1:4)
#dimnames(samps.j$timep) <- list(Dummy = "time", Iter = 1:N, Chain = 1:4)
#dimnames(samps.j$timep) <- list(Dummy = "time", Iter = 1:N, Chain = 1:4)


##### conc.param contains expected values of the distribution parameters from the model
##### conc.param contains expected values of the distribution parameters from the model


conc.param <- Ovariable(
conc.param <- list(
  "conc.param",
     Omega = apply(samps.j$Omega, MARGIN = 1:3, FUN = mean),
  dependencies = data.frame(Name = "samps.j", Ident=NA),
    #      lenp = cbind(
  formula = function(...) {
    #        mean = apply(samps.j$lenp, MARGIN = 1, FUN = mean),
     conc.param <- list(
    #        sd = apply(samps.j$lenp, MARGIN = 1, FUN = sd)
      Omega = apply(samps.j$Omega, MARGIN = 1:3, FUN = mean),
    #      ),
#      lenp = cbind(
    mu = apply(samps.j$mu, MARGIN = 1:2, FUN = mean),
#        mean = apply(samps.j$lenp, MARGIN = 1, FUN = mean),
    #      timep = cbind(
#        sd = apply(samps.j$lenp, MARGIN = 1, FUN = sd)
    #        mean = apply(samps.j$timep, MARGIN = 1, FUN = mean),
#      ),
    #        sd = apply(samps.j$timep, MARGIN = 1, FUN = sd)
      mu = apply(samps.j$mu, MARGIN = 1:2, FUN = mean)#,
    #      )
#      timep = cbind(
     mu_nd =  apply(samps.j$mu_nd, MARGIN = 1:2, FUN = mean),
#        mean = apply(samps.j$timep, MARGIN = 1, FUN = mean),
    tau_nd =  apply(samps.j$tau_nd, MARGIN = 1, FUN = mean)
#        sd = apply(samps.j$timep, MARGIN = 1, FUN = sd)
  )
#      )
  #    names(dimnames(conc.param$lenp)) <- c("Fish","Metaparam")
     )
  #    names(dimnames(conc.param$timep)) <- c("Dummy","Metaparam")
#    names(dimnames(conc.param$lenp)) <- c("Fish","Metaparam")
 
#    names(dimnames(conc.param$timep)) <- c("Dummy","Metaparam")
conc.param <- melt(conc.param)
    conc.param <- melt(conc.param)
colnames(conc.param)[colnames(conc.param)=="value"] <- "Result"
    colnames(conc.param)[colnames(conc.param)=="value"] <- "Result"
colnames(conc.param)[colnames(conc.param)=="L1"] <- "Parameter"
    colnames(conc.param)[colnames(conc.param)=="L1"] <- "Parameter"
    conc.param$Dummy <- NULL
#    conc.param$Metaparam <- ifelse(is.na(conc.param$Metaparam), conc.param$Parameter, as.character(conc.param$Metaparam))
    return(Ovariable(output=conc.param, marginal=colnames(conc.param)!="Result"))
  }
)


objects.store(conc.param, samps.j)
objects.store(conc.param)
cat("Lists conc.params and samps.j stored.\n")
cat("Data frame conc.params stored.\n")


######################3
######################3
Line 645: Line 668:
ggplot(tmp, aes(x = eu2Result, colour=Fish))+stat_ecdf()+
ggplot(tmp, aes(x = eu2Result, colour=Fish))+stat_ecdf()+
   facet_wrap( ~ Compound, scales="free_x")+scale_x_log10()
   facet_wrap( ~ Compound, scales="free_x")+scale_x_log10()
conc.param <- EvalOutput(conc.param)


if(FALSE) {
if(FALSE) {
scatterplotMatrix(t(exp(samps.j$pred[1,,,1])), main = "Predictions for all compounds for Baltic herring")
  scatterplotMatrix(t(exp(samps.j$pred[1,,,1])), main = "Predictions for all compounds for Baltic herring")
scatterplotMatrix(t(exp(samps.j$pred[,1,,1])), main = "Predictions for all fish species for PCDDF")
  scatterplotMatrix(t(exp(samps.j$pred[,1,,1])), main = "Predictions for all fish species for PCDDF")
scatterplotMatrix(t(samps.j$Omega[,1,1,,1]))
  scatterplotMatrix(t(samps.j$Omega[,1,1,,1]))
#scatterplotMatrix(t(cbind(samps.j$Omega[1,1,1,,1],samps.j$mu[1,1,,1])))
  #scatterplotMatrix(t(cbind(samps.j$Omega[1,1,1,,1],samps.j$mu[1,1,,1])))
 
 
plot(coda.samples(jags, 'Omega', N))
  plot(coda.samples(jags, 'Omega', N))
plot(coda.samples(jags, 'mu', N))
  plot(coda.samples(jags, 'mu', N))
plot(coda.samples(jags, 'lenp', N))
  plot(coda.samples(jags, 'lenp', N))
plot(coda.samples(jags, 'timep', N))
  plot(coda.samples(jags, 'timep', N))
plot(coda.samples(jags, 'pred', N))
  plot(coda.samples(jags, 'pred', N))
}
}</rcode>
</rcode>





Revision as of 12:10, 8 March 2021


EU-kalat is a study, where concentrations of PCDD/Fs, PCBs, PBDEs and heavy metals have been measured from fish

Question

The scope of EU-kalat study was to measure concentrations of persistent organic pollutants (POPs) including dioxin (PCDD/F), PCB and BDE in fish from Baltic sea and Finnish inland lakes and rivers. [1] [2] [3].

Answer

Dioxin concentrations in Baltic herring.

The original sample results can be acquired from Opasnet base. The study showed that levels of PCDD/Fs and PCBs depends especially on the fish species. Highest levels were on salmon and large sized herring. Levels of PCDD/Fs exceeded maximum level of 4 pg TEQ/g fw multiple times. Levels of PCDD/Fs were correlated positively with age of the fish.

Mean congener concentrations as WHO2005-TEQ in Baltic herring can be printed out with this link or by running the codel below.

+ Show code

Rationale

Data

Data was collected between 2009-2010. The study contains years, tissue type, fish species, and fat content for each concentration measurement. Number of observations is 285.

There is a new study EU-kalat 3, which will produce results in 2016.

Calculations

Preprocess

  • Preprocess model 22.2.2017 [4]
  • Model run 25.1.2017 [5]
  • Model run 22.5.2017 with new ovariables euRaw, euAll, euMain, and euRatio [6]
  • Model run 23.5.2017 with adjusted ovariables euRaw, eu, euRatio [7]
  • Model run 11.10.2017: Small herring and Large herring added as new species [8]
  • Model rerun 15.11.2017 because the previous stored run was lost in update [9]
  • Model run 21.3.2018: Small and large herring replaced by actual fish length [10]
  • Model run 26.3.2018 eu2 moved here [11]

See an updated version of preprocess code for eu on Health effects of Baltic herring and salmon: a benefit-risk assessment#Code for estimating TEQ from chinese PCB7

+ Show code

Bayes model for dioxin concentrations

  • Model run 28.2.2017 [12]
  • Model run 28.2.2017 with corrected survey model [13]
  • Model run 28.2.2017 with Mu estimates [14]
  • Model run 1.3.2017 [15]
  • Model run 23.4.2017 [16] produces list conc.param and ovariable concentration
  • Model run 24.4.2017 [17]
  • Model run 19.5.2017 without ovariable concentration [18] ⇤--#: . The model does not mix well, so the results should not be used for final results. --Jouni (talk) 19:37, 19 May 2017 (UTC) (type: truth; paradigms: science: attack)
----#: . Maybe we should just estimate TEQs until the problem is fixed. --Jouni (talk) 19:37, 19 May 2017 (UTC) (type: truth; paradigms: science: comment)
  • Model run 22.5.2017 with TEQdx and TEQpcb as the only Compounds [19]
  • Model run 23.5.2017 debugged [20] [21] [22]
  • Model run 24.5.2017 TEQdx, TECpcb -> PCDDF, PCB [23]
  • Model run 11.10.2017 with small and large herring [24] (removed in update)
  • Model run 12.3.2018: bugs fixed with data used in Bayes. In addition, redundant fish species removed and Omega assumed to be the same for herring and salmon. [25]
  • Model run 22.3.2018 [26] Model does not mix well. Thinning gives little help?
  • Model run 25.3.2018 with conc.param as ovariable [27]

+ Show code

Initiate conc_pcddf for PFAS disease burden study

Bayesian approach for PCDDF, PCB, OT, PFAS.

  • Model run 2021-02-07 [28]

+ Show code


NOTE! This is not a probabilistic approach. Species and area-specific distributions should be created.

+ Show code

Initiate conc_pcddf for Goherr

  • Model run 19.5.2017 [29]
  • Model run 23.5.2017 with bugs fixed [30]
  • Model run 12.10.2017: TEQ calculation added [31]
  • Model rerun 15.11.2017 because the previous stored run was lost in update [32]
  • 12.3.2018 adjusted to match the same Omega for all fish species [33]
  • 26.3.2018 includes length and time as parameters, lengt ovariable initiated here [34]

+ Show code

⇤--#: . These codes should be coherent with POPs in Baltic herring. --Jouni (talk) 12:14, 7 June 2017 (UTC) (type: truth; paradigms: science: attack)

See also

References

  1. A. Hallikainen, H. Kiviranta, P. Isosaari, T. Vartiainen, R. Parmanne, P.J. Vuorinen: Kotimaisen järvi- ja merikalan dioksiinien, furaanien, dioksiinien kaltaisten PCB-yhdisteiden ja polybromattujen difenyylieettereiden pitoisuudet. Elintarvikeviraston julkaisuja 1/2004. [1]
  2. E-R.Venäläinen, A. Hallikainen, R. Parmanne, P.J. Vuorinen: Kotimaisen järvi- ja merikalan raskasmetallipitoisuudet. Elintarvikeviraston julkaisuja 3/2004. [2]
  3. Anja Hallikainen, Riikka Airaksinen, Panu Rantakokko, Jani Koponen, Jaakko Mannio, Pekka J. Vuorinen, Timo Jääskeläinen, Hannu Kiviranta. Itämeren kalan ja muun kotimaisen kalan ympäristömyrkyt: PCDD/F-, PCB-, PBDE-, PFC- ja OT-yhdisteet. Eviran tutkimuksia 2/2011. ISSN 1797-2981 ISBN 978-952-225-083-4 [3]