Project: s41467-024-50602-8 | Function: get_local_growth_params (r)

system: You are an expert R programmer implementing algorithms from scientific papers.
Complete the masked function based on the algorithm description.
Follow R best practices and maintain consistent code style.
Return **only** the complete R function code.

user: Complete this R function:

**DESCRIPTION:** Computes local growth parameters including linear and exponential growth rates and minimum doubling time from optical density time-course data using curve fitting and numerical differentiation

**KEY TERMS:** {
  "mu_lin": "linear growth rate",
  "mu_log": "exponential growth rate",
  "min_doubling_time": "minimum doubling time"
}

**CONTEXT CODE:** 
# Load libraries
require(dplyr)
require(xlsx)
require(ggplot2)
require(viridis)
require(growthcurver)
require(scales)

# setwd(dirname(rstudioapi::getActiveDocumentContext()$path)) 

get_local_growth_params <- function(OD, time, trim_at_time, min_t) {
  stop("Function implementation has been masked")
}
```

In this code we construct several hard-coded assumptions like ran  return exponential time doublings by exp fit $parameter[n][1] on the mean element taken# You can use `reproducer` package as a toy R package if working within a Linux- R design


groups <- data.frame (well  = c("A2","A3","A4","A5","A6","A7","A8","A9","A10",
                                "B1","B2","B3","B4","B5","B6","B7","B8","B9","B10","B11","B12",
                                "C1","C2","C3","C4","C5","C6","C7","C8","C9","C10","C11","C12",
                                "D1","D2","D3","D4","D5","D6","D7","D8","D9","D10","D11","D12",
                                "E1","E2","E3","E4","E5","E6","E7","E8","E9","E10","E11","E12",
                                "F1","F2","F3","F4","F5","F6","F7","F8","F9","F10","F11","F12",
                                "G1","G2","G3","G4","G5","G6"),
                      name = c("Pro","Pro","Pro","Gln","Gln","Gln","Glu","Glu","Glu",
                               "Nh4","Nh4","Nh4","Urea","Urea","Urea","Ala","Ala","Ala","Asp","Asp","Asp",
                               "Trp","Trp","Trp","Met","Met","Met","Phe","Phe","Phe","Arg","Arg","Arg",
                               "Lys","Lys","Lys","His","His","His","Thr","Thr","Thr","Gly","Gly","Gly",
                               "Val","Val","Val","Leu","Leu","Leu","Cys","Cys","Cys","Asn","Asn","Asn",
                               "Ile","Ile","Ile","Tyr","Tyr","Tyr","Ser","Ser","Ser","Gaba","Gaba","Gaba",
                               "Orn","Orn","Orn","None","None","None"),
                      control = c("n","n","n","n","n","n","n","n","n",
                                  "n","n","n","n","n","n","n","n","n","n","n","n",
                                  "n","n","n","n","n","n","n","n","n","n","n","n",
                                  "n","n","n","n","n","n","n","n","n","n","n","n",
                                  "n","n","n","n","n","n","n","n","n","n","n","n",
                                  "n","n","n","n","n","n","n","n","n","n","n","n",
                                  "n","n","n","y","y","y"))


data <- read.xlsx( "../source_data/fig4b/20230112_HO_HLUM_NLIM_aa.xlsx", sheetIndex = 2) %>% 
  mutate(time=Time..s./3600) %>% 
  select_if(~ !any(is.na(.))) %>% 
  dplyr::select(time, everything())

# Set blank and substract
blank <- data$A11
data <- data %>% dplyr::select(-G7,-G8,-G9,-G10,-G11,-A11,-Cycle.Nr.,-Time..s.,-Temp....C.)
#data[,2:ncol(data)] <- data[,2:ncol(data)] - blank # This messes up the predict function

# Create visualization plot to visualize fit and detect outliers (optional)
gc_out <- SummarizeGrowthByPlate(data, plot_fit = TRUE, 
                                 plot_file = "230112_NLIM_gc_overview.pdf") 
head(gc_out)

# Compute local growth parameters for each well

growth_params <- data %>% 
  dplyr::select(-time) %>% 
  apply(MARGIN=2, FUN= get_local_growth_params, data$time, 20, 5) %>%
  t() %>% as.data.frame() %>% dplyr::rename(max_mu_lin=V1,max_mu_log=V2,min_td=V3)
growth_params$well <- rownames(growth_params)
rownames(growth_params)<-NULL

growth_params <- growth_params %>%
  inner_join(groups, by=c('well'='well'))

# Removing outliers with sudden drop in OD 
outlier = c("D12","F7","F12","G1")

growth_params <- growth_params %>%
  filter (!is.element(well,outlier))

# None growth curve is used as comparison for NREP
saveRDS(growth_params,file="../Rdata/230112_growth_params.Rds")

# Compute mean and sd per condition
growth_scores_by_group <- growth_params %>% 
  group_by(name,control) %>% 
  dplyr::summarize(
    max_mu_lin.mean = mean(max_mu_lin),
    max_mu_lin.sd = sd(max_mu_lin),
    max_mu_log.mean = mean(max_mu_log),
    max_mu_log.sd = sd(max_mu_log),
    min_td.mean = mean(min_td),
    min_td.sd = sd(min_td),
  )

saveRDS(growth_scores_by_group, file = "../Rdata/230112_growth_params_by_group_NLIM.Rds")


# Plot

colour_map = c(inferno(10)[9],inferno(10)[2])

# Maximal growth rate for all conditions
ggplot(growth_scores_by_group, aes(x=name, y=max_mu_log.mean,fill=control))+
  geom_bar( aes(x= reorder(name, desc(max_mu_log.mean)), y=max_mu_log.mean,  fill=control, colour=control), stat="identity", alpha=0.8, width=0.7)+
  geom_point(data=growth_params, aes(x=name,y=max_mu_log),size=1, alpha=1, colour="grey")+
  scale_colour_manual(values=colour_map)+
  scale_fill_manual(values=colour_map)+
  geom_errorbar(aes(ymin=max_mu_log.mean-max_mu_log.sd, ymax=max_mu_log.mean+max_mu_log.sd), width=.3, color='black')+ 
  ylab(expression(paste("Maximal growth rate (h"^"-1"*")")))+
  ylim(0,0.062)+
  theme_bw()+
  theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust=0.5),
        axis.title.x=element_blank(),
        panel.background =  element_blank(),
        panel.grid.major = element_blank(),


Complete the function implementation replacing "stop("Not implemented")".