Column

map

data table

Column

Rrs

IOPs

---
title: "lighthouse"
output: 
  flexdashboard::flex_dashboard:
    logo: logo_AQUATEL_1.svg
    theme: united
    #social: menu
    css: style2.css
    source_code: embed
    orientation: columns
    vertical_layout: fill

---

```{r setup, include=FALSE}
library(dplyr)
library(tidyr)
library(DT)
library(stringr)
library(lubridate)
library(leaflet)
library(crosstalk)
library(plotly)
library(purrr)
library(leafem)
#library(mapview)
library(leaflet.extras)
library(htmltools)
library(leafpop)


knitr::opts_knit$set(root.dir = "~/R/lighthouse/R/")
knitr::opts_chunk$set(echo = F, cache = F, message = F, warning = F)
```

```{r load data,}
load("/mnt/D/Documents/Maitrise/Paper/Models/Data/models_db.RData")

# models_db <- models_db %>% mutate(ROI= str_extract(PID,"[:alpha:]+[:digit:]{0,1}"))

# Create a DataLog to keep track of comments on data and outlier removal
if (!file.exists("/mnt/D/Documents/Maitrise/Paper/Models/DataLog.csv")) {
	DataLog <- models_db %>% select(ID,PID) %>%
		mutate(QC_SPM=1,
			  QC_Ag=1,
			  QC_Bbp=1,
			  Comment="")
	
	write.csv(DataLog, "/mnt/D/Documents/Maitrise/Paper/Models/DataLog.csv", row.names=F)
	
} else {
	DataLog <- readr::read_csv("/mnt/D/Documents/Maitrise/Paper/Models/DataLog.csv")
}

# Check for bottom effect, linearly based on secchi depth
br_check <- function(Zsecchi,Zstation){
	
	if (is.na(Zsecchi) | is.na(Zstation)) {
		NA
	} else if (Zsecchi > Zstation){
		# Case when error of entry
		NA
	} else if (Zsecchi == 999) {
		# Case when Secchi touch the bottom
		T
	} else if (Zsecchi*2 > Zstation) {
		# assume a linear travel of light in water...
		T
	} else {
		F
	}
	#str_c(Zstation, Zsecchi)
}

models_db <- models_db %>% left_join(DataLog %>% select(ID,QC_SPM,QC_Ag,QC_Bbp,Comment), by="ID") %>%
	mutate(Region = ifelse(str_detect(Project,"CHONe|WISE|PMZA"),"EGSL","JB"),
		  OptShallow = br_check(Zsecchi,Zstation),
		  PIM_frac = ifelse((PIM/SPM)*100 <= 100,(PIM/SPM)*100,NA)) %>%
	relocate(matches("QC|Comment|ROI|Region"), .after = "DateTime") %>%
	relocate("OptShallow", .after = "Zsecchi")
	

# Simulated data for matchup and validation
wide_sensor <- models_db %>% 
	select(!c("data")) %>%
	unnest(cols = c(OLI,S2A), names_sep="_")

wide_sensor <- wide_sensor %>% rename_with(~str_replace(.,"S2A","MSI"), starts_with("S2A")) %>%
	mutate(across(matches("OLI|MSI"), ~na_if(., .<0)))

long_sensor <- wide_sensor %>%
	pivot_longer(cols = all_of(str_subset(names(wide_sensor),"OLI|MSI")),
			   names_to = c("Sensor","Band","Cwl"),
			   values_to = "Rrs",
			   values_drop_na = T,
			   names_sep = "_") %>%
	mutate(Cwl = as.numeric(Cwl))

# In-situ data for algo development
possibleApprox <- purrr::possibly(approx, otherwise=NA)

approx_op <- models_db %>%
	mutate(dataprox = purrr::map(.x = data, ~ data.frame(possibleApprox(.x$Lambda,.x$Rrs,c(380:800), na.rm = T)))) %>%
	mutate(dataprox = purrr::map(dataprox, ~ dplyr::rename(.,Lambda = x, Rrs = y))) %>%
	relocate(dataprox, .after=data)

# long_insitu_raw <- approx_op %>%
# 	#mutate(data = (purrr::map(data, ~ dplyr::filter(., Lambda %in% c(440:450,540:560,650:670,725:750))))) %>%
# 	select(!c("OLI","S2A","S3A","dataprox")) %>%
# 	unnest(cols= c(data))
# 
# wide_insitu_raw <- long_insitu_raw %>%
# 	pivot_wider(names_from = Lambda,
# 			  values_from = Rrs,
# 			  names_prefix = "Rrs_") %>%
# 	relocate(matches("Rrs"), .after = Region)

long_insitu <- approx_op %>%
	mutate(dataprox = (purrr::map(dataprox, ~ dplyr::filter(., Lambda %in% c(380,395,440,560,665,710,740,800))))) %>%
	select(!c("OLI","S2A","data")) %>%
	unnest(cols= c(dataprox))

wide_insitu <- long_insitu %>%
	pivot_wider(names_from = Lambda,
			  values_from = Rrs,
			  names_prefix = "Rrs_") %>%
	relocate(matches("Rrs"), .after = Region) %>%
	ungroup()

# Check that aprox function dont mess up
# plot(wide_insitu_raw$Rrs_650, wide_insitu$Rrs_665)
```

```{r interpolation of iop to common wl 394-700 nm}
iop_long <- wide_insitu %>%
	select(matches("^ID$|A_|Ap_|Aph_|Ag_|Anap_|Bbp_|Bb_")) %>%
	pivot_longer(cols = all_of(str_subset(names(wide_insitu), "A_|Ap_|Aph_|Ag_|Anap_|Bbp_|Bb_")),
			   names_to = c(".value","Lambda"),
	 		   names_pattern = "(.+)_(.+)",
	 		   values_drop_na = T
	 		   ) %>%
	mutate(Lambda = as.numeric(Lambda))
	


iop_nest <- iop_long %>% arrange(ID,Lambda) %>%
	group_by(ID) %>% nest()

possibleApprox <- purrr::possibly(approx, otherwise=NA)

Approxiop <- iop_nest %>%
	mutate(
		Lambda = purrr::map(.x = data, ~ data.frame(Lambda = .x$Lambda)),
		A = purrr::map(.x = data, ~ data.frame(possibleApprox(.x$Lambda,.x$A,.x$Lambda, na.rm = T))),
		Ap = purrr::map(.x = data, ~ data.frame(possibleApprox(.x$Lambda,.x$Ap,.x$Lambda, na.rm = T))),
		Aph = purrr::map(.x = data, ~ data.frame(possibleApprox(.x$Lambda,.x$Aph,.x$Lambda, na.rm = T))),
		Anap = purrr::map(.x = data, ~ data.frame(possibleApprox(.x$Lambda,.x$Anap,.x$Lambda, na.rm = T))),
		Ag = purrr::map(.x = data, ~ data.frame(possibleApprox(.x$Lambda,.x$Ag,.x$Lambda, na.rm = T))),
		Bbp = purrr::map(.x = data, ~ data.frame(possibleApprox(.x$Lambda,.x$Bbp,.x$Lambda, na.rm = T))),
		Bb = purrr::map(.x = data, ~ data.frame(possibleApprox(.x$Lambda,.x$Bb,.x$Lambda, na.rm = T))),
		  ) %>%
	select(ID,Lambda,A,Ap,Aph,Anap,Ag,Bbp,Bb)

Approxiop <- Approxiop %>%
	dplyr::filter(purrr::map_lgl(A, ~ !is_empty(.)) | purrr::map_lgl(Ap, ~ !is_empty(.)) | purrr::map_lgl(Aph, ~ !is_empty(.)) | purrr::map_lgl(Anap, ~ !is_empty(.)) | purrr::map_lgl(Ag, ~ !is_empty(.)) | purrr::map_lgl(Bbp, ~ !is_empty(.)) | purrr::map_lgl(Bb, ~ !is_empty(.)))

Approxiop <- Approxiop %>% unnest(cols = c(Lambda, A, Ap, Aph, Anap, Ag, Bbp, Bb), names_sep="_") # %>% na.omit()

Approxiop <- Approxiop %>% select(A_x,!contains("x")) %>% mutate(
	Lambda = as.numeric(Lambda_Lambda),
	A = A_y,
	Ap = Ap_y,
	Aph = Aph_y,
	Anap = Anap_y,
	Ag = Ag_y,
	Bbp = Bbp_y,
	Bb = Bb_y
	) %>%
	select(!contains(c("y","x","Lambda_Lambda"))) %>%
	filter(Lambda %in%
		  	c(305,320,330,340,380,394,395,412,420,443,465,470,490,510,532,555,560,589,620,625,665,683,694,700,710,740,780,875))

# Rrs at 9 wl give 255 731 row ... rather slow but working
# iopgate <- long_sensorBand %>% filter(Sensor=="MSI") %>%
# 	select(matches("ID|ROI|Sensor|Band|Rrs|SPM|Ag_440")) %>%
# 	right_join(Approxiop, by="ID") %>%
# 	na.omit() %>% ungroup()


iopgate <- wide_insitu %>%
	select(ID,PID,Project,Station,Zstation,DateTime,Comment,SPM,QC_SPM,QC_Ag) %>%
	right_join(Approxiop, by="ID")
```

```{r sharedata objects}
sd_iops <- SharedData$new(iopgate %>% group_by(ID), key = ~str_pad(ID,3,pad = "0"), group = "iops")

submap <- wide_insitu %>% mutate(DateTime = as.POSIXct(DateTime, tz='UTC', format = "%Y-%m-%dT%H:%M:%S")) %>%
	select(ID,PID,Project,Station,DateTime,SPM,Zstation,Zsecchi,Lat,Lon,Ag_440,SID) %>%
	group_by(ID)
sd_map <- SharedData$new(submap, key = ~str_pad(ID,3,pad = "0"), group = "iops")

subrrs <- long_insitu %>% #dplyr::filter(Sensor=="MSI") %>%
	select(ID,PID,Station,Zstation,Zsecchi,DateTime,Comment,Lambda,Rrs,SPM,Ag_440,QC_SPM,QC_Ag) %>%
	group_by(ID)
sd_rrs <- SharedData$new(subrrs, key = ~str_pad(ID,3,pad = "0"), group = "iops")

subtab <- wide_insitu %>%
	mutate(ID = str_pad(ID,3,pad = "0"),
		  DateTime = as.POSIXct(DateTime, tz='UTC', format = "%Y-%m-%dT%H:%M:%S")) %>%
	select(ID,SID,PID,SPID,Station,Zstation,Zsecchi,DateTime,QC_SPM,QC_Ag,Comment) %>% group_by(ID)

sd_tab <- SharedData$new(subtab, key = ~str_pad(ID,3,pad = "0"), group = "iops")
```

	



Row {.sidebar}
-----------------------------------------------------------------------
### filters
```{r}
filter_checkbox(id = "Project",
              label = "Project",
              sharedData = sd_map,
		    group = ~Project,
		    inline = T
		    )

filter_select(id = "ID",
              label = "ID",
              sharedData = sd_map,
		    group = ~ID
		    )

filter_select(id = "PID",
              label = "PID",
              sharedData = sd_map,
		    group = ~PID
		    )

filter_select(id = "Station",
              label = "Station",
              sharedData = sd_map,
		    group = ~Station
		    )
# not working ... some bug in display
# filter_slider(id = "DateTime",
#               label = "",
#               sharedData = sd_map,
# 		    column = ~DateTime, step = NULL, width = '100%', dragRange = TRUE
# 		    )

filter_select(id = "DateTime",
              label = "Date",
              sharedData = sd_map,
		    group = ~lubridate::date(DateTime)
		    )

filter_slider(id = "Depth",
              label = "Station Depth",
              sharedData = sd_map,
		    column = ~Zstation
		    )

filter_slider(id = "SPM",
              label = "SPM concentration",
              sharedData = sd_map,
		    column = ~signif(SPM,2)
		    )

filter_slider(id = "Ag_440",
              label = "CDOM concentration",
              sharedData = sd_map,
		    column = ~signif(Ag_440,2)
		    )
```

Column {data-width=450}
-------------------------------------

###  map

```{r map}

# Temp <- CTD_sd %>% plot_ly(x=~Temp, y=~Depth, showlegend=T, connectgaps = F) %>% add_paths() %>%
# 	layout(yaxis = Noax, xaxis = list(title = "\u00B0C"))
# 
# PSU <- CTD_sd %>% plot_ly(x=~PSU, y=~Depth, showlegend=T, connectgaps = F) %>% add_paths() %>%
# 	layout(yaxis = Noax, xaxis = list(title = "PSU")) 
# 
# CTD <- subplot(Temp, PSU, shareY= T, titleY = T, titleX = T) %>%
# 	highlight(on = "plotly_click", off = "plotly_doubleclick", selectize = F, dynamic = F, persistent = F)
# 
# CTD <- bscols()

#leafpop::popupGraph should be the way to add a plot_ly graph as leaflet popup

link <- "/mnt/D/Data/WISEMan/L2/066/COPS_Kildir/PDF/WISE_CAST_006_190821_143528_URC.csv.pdf"

map <- leaflet(sd_map) %>%
	addScaleBar("bottomright") %>% leafem::addMouseCoordinates() %>%
	addProviderTiles(provider = providers$CartoDB.Positron, group = 'Positron') %>%
	addProviderTiles("Esri.WorldImagery", group = 'Aerial') %>%
	addProviderTiles("OpenTopoMap", group = 'Terrain') %>%
	addAwesomeMarkers(lat = ~Lat, lng = ~Lon, 
				  group = "Stations",
				  label = ~paste0("PID: ", PID),
				  popup = ~paste0('

Station Details


', 'ID: ', ID, '
', 'SID: ', str_c(SID, collapse = ", "), '
', 'PID: ', PID, '
', 'Station: ', Station, '
', 'DateTime: ', DateTime, '
', 'SPM: ', SPM, ' [mg.l-1]
', 'Zstation: ', Zstation, ' [m-1]
', 'Zsecchi: ', Zsecchi, ' [m-1]
', paste0('COPS Report:') ) ) %>% addLayersControl( baseGroups = c("Positron", "Aerial", "Terrain"), overlayGroups = 'Stations', options = layersControlOptions(collapsed = TRUE) ) %>% addEasyButton(easyButton( icon="fa-globe", title="Zoom to Level 1", onClick=JS("function(btn, map){ map.setZoom(1); }"))) %>% addEasyButton(easyButton( icon="fa-crosshairs", title="Locate Me", onClick=JS("function(btn, map){ map.locate({setView: true}); }"))) %>% addSearchFeatures(targetGroups = c("Stations")) map #bscols(widths = c(2, NA) ,Qfilter ,map) # Cannot filter and cluster at the same time for now : https://github.com/rstudio/leaflet/issues/478 # clusterOptions = markerClusterOptions(disableClusteringAtZoom = 10) ``` ### data table ```{r} datatable(sd_tab, extensions = c("Buttons", "Scroller", "Select"), filter = "top", escape = TRUE, rownames = FALSE, style = "bootstrap", class = "compact", height = 100, options = list( dom = "Brtip", select = list(style = 'os', items = 'row'), buttons = list(I("colvis"),"selectNone","csv"), columnDefs = list( list( visible = FALSE, targets = c(1,3,5,6,8,9) )), deferRender = TRUE, scrollY = 10, pageLength = 10, scroller = TRUE ), selection = "none" ) ``` Column {.tabset} ------------------------------------- ### Rrs ```{r Rrs ,echo=FALSE, message=FALSE} prrs <- plot_ly(sd_rrs, x = ~Lambda, y = ~Rrs, text=~paste0( 'ID: ', ID, '
', 'PID: ', PID, '
', 'Station: ', Station, '
', 'DateTime: ', DateTime, '
', 'SPM: ', SPM, ' [mg.L-1]
', 'ag(440): ', Ag_440, ' [m-1]
', 'Zstation: ', Zstation, ' [m-1]
', 'Zsecchi: ', Zsecchi, ' [m-1]
', 'QC: ', QC_SPM, '
', 'Comment: ', Comment, '
' )) %>% add_lines(color = ~as.character(QC_SPM), colors = c("0" = "red", "1" = "steelblue3", "2"="orange"), showlegend= T) %>% layout( shapes = list( type = "rect", fillcolor = "transparent", xref = "paper", yref = "paper", x0 = 0, x1 = 1, y0 = 0.01, y1 = 1), xaxis = list(title = TeX("wavelength\\ [nm]"), type = ""), yaxis = list(title = TeX("R_{rs}\\ [sr^{-1}]"), type = "") ) %>% highlight(on = "plotly_click", off = "plotly_relayout", selectize = F, dynamic = F, persistent = F) %>% config(mathjax = "cdn", displayModeBar = T) prrs ``` ### IOPs ```{r IOPs, echo=FALSE, message=FALSE} piops <- plot_ly(sd_iops, x = ~Lambda, visible = "legendonly", # linetype = ~as.character(QC_SPM), linetypes = c("0" = "dash", "1" = "solid"), showlegend = T, text=~paste0( 'PID: ', PID, '
', 'Station: ', Station, '
', 'DateTime: ', DateTime, '
', 'SPM: ', SPM, ' [mg.l-1]
', 'Zstation: ', Zstation, ' [m-1]
', 'QC: ', QC_Ag, '
', 'Comment: ', Comment, '
' )) %>% add_lines(y = ~A , color="A", showlegend = T) %>% add_lines(y = ~Ap , color="Ap", showlegend = T) %>% add_lines(y = ~Aph , color="Aph", showlegend = T) %>% add_lines(y = ~Anap , color="Anap", showlegend = T) %>% add_lines(y = ~Ag , color="Ag", showlegend = T) %>% add_lines(y = ~Bb , color="Bb", showlegend = T) %>% add_lines(y = ~Bbp , color="Bbp", showlegend = T) %>% layout( shapes = list( type = "rect", fillcolor = "transparent", xref = "paper", yref = "paper", x0 = 0, x1 = 1, y0 = 0.01, y1 = 1), xaxis = list(title = TeX("wavelength\\ [nm]"), type = ""), yaxis = list(title = TeX("IOP\\ coefficient\\ [m^{-1}]"), type = "") ) %>% highlight(on = "plotly_click", off = "plotly_relayout", selectize = F, dynamic = F, persistent = F) %>% config(mathjax = "cdn", displayModeBar = T) piops ```