r-plumer-example / function.R
hadimaster65555's picture
fix one cycle feeding generator
f182108
Raw
History Blame Contribute Delete
12.2 kB
# plumber.R
#* Echo back the input
#* @get /
function() {
message("---- hello world triggered ----")
list(msg = paste0("Hello, World!"))
}
#* Echo back the input
#* @get /iris
function() {
message("---- call iris data ----")
list(data = janitor::clean_names(head(iris)))
}
#* Echo back the input
#* @param msg The message to echo
#* @get /echo
function(msg="") {
message("---- echo ----")
list(msg = paste0("The message is: '", msg, "'"))
}
#* Return the sum of two numbers
#* @param a The first number to add
#* @param b The second number to add
#* @post /sum
function(a, b) {
message("---- sum two number ----")
as.numeric(a) + as.numeric(b)
}
#* Growth Calculation
#* #* @serializer unboxedJSON
#* @post /growth-calculation
function(req) {
# data,
# init_size = 0.01,
# max_doc = 120,
# method = "gm"
message("---- call growth function ----")
data_from_user <- req$body
data <- data_from_user$data
init_size <- data_from_user$init_size
max_doc <- data_from_user$max_doc
method <- data_from_user$model_method
# set maximum doc
doc_vec <- 1:max_doc
if (method == "gm") {
print("use gm")
model_res <-nls(
mbw ~ asymptotic_growth*(1-(1-(init_size/asymptotic_growth)^(1/allometric_scale))*exp(-growth_rate*doc))^allometric_scale,
data = data,
start = list(
asymptotic_growth = 40,
allometric_scale = 3,
growth_rate = 0.015
)
)
pred_res <- predict(
model_res,
list(
doc = doc_vec
)
)
tibble(
doc = doc_vec,
mbw = round(pred_res,3)
) -> growth_res
} else if(method == "interp_abw") {
min_doc <- min(data$doc)
max_doc <- max(data$doc)
growth_res <- data.frame(
with(data,
approx(doc, mbw, xout = seq(min_doc, max_doc, by = 1), method = "linear")
)
) %>%
rename(doc = x, mbw = y)
} else {
initial_weight <- init_size
final_doc <- max_doc
adg_data <- data
abw_container <- list()
for (indeks in 1:nrow(adg_data)) {
if (indeks == 1) {
abw_container[[indeks]] <- c(initial_weight, initial_weight + cumsum(rep(adg_data$adg[indeks], adg_data$doc[indeks + 1] - adg_data$doc[indeks] - 1)))
} else if(indeks == nrow(adg_data)) {
initial_weight <- max(abw_container[[indeks-1]])
abw_container[[indeks]] <- c(initial_weight + cumsum(rep(adg_data$adg[indeks], final_doc - adg_data$doc[indeks] + 1)))
} else {
initial_weight <- max(abw_container[[indeks-1]])
abw_container[[indeks]] <- c(initial_weight + cumsum(rep(adg_data$adg[indeks], adg_data$doc[indeks + 1] - adg_data$doc[indeks])))
}
}
mbw_ <- unlist(abw_container)
tibble(
doc = 1:final_doc,
mbw = mbw_
) -> growth_res
}
return(growth_res)
}
#* One Cycle Feeding Generator
#* @serializer unboxedJSON
#* @post /one-cycle-generator
function(req) {
data_from_user <- req$body
start_date <- data_from_user$start_date
maximum_doc <- data_from_user$maximum_doc
pond_setting <- data_from_user$pond_setting %>%
janitor::clean_names()
partial_harvest_setting <- data_from_user$partial_harvest_setting %>%
janitor::clean_names()
survival_calculation_method <- data_from_user$survival_calculation_method
target_survival <- data_from_user$target_survival
survival_model <- data_from_user$survival_model
fi_multiplier_setting <- data_from_user$fi_multiplier_setting
fr_type_setting <- data_from_user$fr_type_setting
fr_coef_x <- data_from_user$fr_coef_x
fr_coef_y <- data_from_user$fr_coef_y
blind_feeding_start_feeding_setting <- data_from_user$blind_feeding_start_feeding_setting
blind_feeding_increment_setting <- data_from_user$blind_feeding_increment_setting %>%
janitor::clean_names()
growth_calculation_method <- data_from_user$growth_calculation_method
initial_abw <- data_from_user$initial_abw
initial_growth_data <- data_from_user$initial_growth_data %>%
janitor::clean_names()
message("---- generate growth scenario table ----")
growth_scenario_table <- growth_function_training(
data = initial_growth_data,
init_size = initial_abw,
max_doc = maximum_doc,
method = growth_calculation_method
)
message("---- generate feeding for one cycle ----")
result <- all_feeding_generator_function_v2(
date_data = as.Date(start_date),
max_doc = maximum_doc,
shrimp_stock_data = pond_setting,
harvest_setting = partial_harvest_setting,
survival_calculation_method = survival_calculation_method,
target_survival = target_survival,
survival_model = survival_model,
blind_feeding_day_1_setting = blind_feeding_start_feeding_setting,
blind_feeding_day_2_setting = blind_feeding_increment_setting,
fi_multiplier = fi_multiplier_setting,
fr_calculation_method = fr_type_setting,
fr_coef_x = fr_coef_x,
fr_coef_y = fr_coef_y,
growth_scenario_table = growth_scenario_table
)
message("---- check result ----")
### blind feed table
result$blind_feed_table -> blind_feed_table
### demand feeding table
result$demand_feeding_table -> demand_feeding_table
### survival table
result$survival_table -> survival_table
### stocking data
pond_setting -> stocking_data
### partial harvest setting
partial_harvest_setting
### feeding plan generation
message("---- blind feeding generation ----")
blind_feed_table %>%
pivot_wider(names_from = type, values_from = total_feed) %>%
mutate(
feed_per_day_fr = blind_feeding,
feed_per_day_indeks = blind_feeding
) %>%
select(-blind_feeding) -> blind_feed_table
message("---- demand feeding generation ----")
blind_feed_table %>%
bind_rows(
demand_feeding_table %>%
select(doc, pond_code, feed_per_day_indeks, feed_per_day_fr)
) %>%
mutate(feed_type = ifelse(doc <= 30, "blind_feeding", "demand_feeding")) %>%
left_join(growth_scenario_table) %>%
left_join(survival_table) %>%
left_join(stocking_data) %>%
arrange(pond_code, doc) %>%
group_by(pond_code) %>%
mutate(cumulative_harvested = cumsum(harvested)) %>%
ungroup() %>%
mutate(biomass = mbw * population_left/1000) %>%
mutate(biomass_total = biomass + (cumulative_harvested*mbw)/1000) %>%
group_by(pond_code) %>%
mutate(
cumulative_feed_indeks = cumsum(feed_per_day_indeks),
cumulative_feed_fr = cumsum(feed_per_day_fr),
) %>%
ungroup() %>%
mutate(
fcr_indeks = cumulative_feed_indeks/biomass_total,
fcr_fr = cumulative_feed_fr/biomass_total
) %>%
mutate(
data_type = "planning"
) -> result
# variable setting
## datetime information
datetime_info <- lubridate::now(tzone = "UTC")
tibble(
pond_code = as.character(),
doc = as.numeric(),
feed_index = as.numeric()
) -> feed_indeks_table
for (pond_code in pond_setting$pond_code) {
feed_indeks_table <- feed_indeks_table %>%
bind_rows(
fi_generator(
total_feed_day_1 = blind_feeding_start_feeding_setting,
blind_feeding_rules_table = blind_feeding_increment_setting
) %>%
mutate(
pond_code = pond_code
)
)
}
feed_indeks_table <- feed_indeks_table %>%
bind_rows(
demand_feeding_table %>%
select(pond_code, doc, indeks_plan) %>%
rename(feed_index = indeks_plan)
) %>%
arrange(pond_code, doc)
## feeding_strategy_planning_datatable
message("---- Save Feeding Plan for One Cycle ----")
result %>%
mutate(
created_date = datetime_info
) %>%
group_by(pond_code) %>%
mutate(adg = mbw-lag(mbw)) %>%
ungroup() -> result
if (fr_type_setting == "FR Type 1") {
result <- result %>%
mutate(
fr_plan = 10^(fr_coef_x-(fr_coef_y*log10(mbw)))
)
} else if(fr_calculation_method == "FR Type 2") {
result <- result %>%
mutate(
fr_plan = 10^(fr_coef_x-(fr_coef_y*log10(mbw))) * 100
)
} else {
result <- result %>%
mutate(
fr_plan = 10^(fr_coef_x-(fr_coef_y*log10(mbw)))
)
}
result <- result %>%
group_by(pond_code) %>%
mutate(adg = round(mbw-lag(mbw), 2)) %>%
ungroup() %>%
mutate(
carrying_capacity = biomass/pond_area,
partial_biomass = population_left * harvest_percentage * mbw
) %>%
left_join(
feed_indeks_table
) %>%
select(
pond_code, doc, date, mbw, adg, fr_plan, sr_est,
harvest_percentage, biomass, carrying_capacity, partial_biomass,
biomass_total, population_left, feed_index, feed_per_day_fr, feed_per_day_indeks,
cumulative_feed_fr, cumulative_feed_indeks, fcr_fr, fcr_indeks
)
return(result)
}
#* One Cycle Feeding Generator
#* @serializer unboxedJSON
#* @post /one-week-generator
function(req) {
data_from_user <- req$body
# Weekly pond setting ----
result_data <- data_from_user$data %>%
janitor::clean_names()
# date input ----
weekly_feeding_date_input <- as.Date(data_from_user$date_input)
# sr setting ----
sr_method <- data_from_user$sr_method
sr_model <- data_from_user$sr_model
# fr setting ----
fr_method <- data_from_user$fr_method
fr_x_coef <- data_from_user$fr_x_coef
fr_y_coef <- data_from_user$fr_y_coef
# growth method ----
growth_method <- data_from_user$growth_method
feed_data_container <- tibble(
pond_code = as.character(),
doc_data = as.numeric(),
mbw_data = as.numeric(),
sr_data = as.numeric(),
fi_data = as.numeric(),
fr_data = as.numeric(),
feed_fi = as.numeric(),
feed_fr = as.numeric(),
biomass_data = as.numeric(),
population_data = as.numeric(),
date_data = as.Date(character())
)
result_data %>%
select(pond_code, stocking_actual, fi_multiplier) -> ponds_setting
for (i in 1:nrow(result_data)) {
pond_data <- result_data[i,]
stock_data <- ponds_setting %>%
filter(pond_code == pond_data$pond) %>%
pull(stocking_actual)
fi_mult <- ponds_setting %>%
filter(pond_code == pond_data$pond) %>%
pull(fi_multiplier)
doc_data <- cumsum(c(pond_data$doc, rep(1, 7)))[2:8]
mbw_data <- cumsum(c(pond_data$mbw_sampling, rep(pond_data$adg_target, 7)))[2:8]
fi_data <- rep(pond_data$adg_target* fi_mult, 7)
if (fr_method == "FR Tipe 1") {
fr_data <- 10^(fr_x_coef-(fr_y_coef*log10(mbw_data))) * 100
} else if(fr_method == "FR Tipe 2") {
fr_data <- 10^(fr_x_coef-(fr_y_coef*log10(mbw_data)))
} else {
fr_data <- 10^(fr_x_coef-(fr_y_coef*log10(mbw_data))) * 100
}
if (sr_method == "Nilai SR Konstan") {
message("---- Use Constant SR Model ----")
sr_est <- pond_data$sr_input
} else if(sr_method == "Berdasarkan Target") {
message("---- Use Target Based SR ----")
survival_input <- pond_data$sr_input
survival_target <- pond_data$sr_target
sr_est <- seq(from = survival_input, to = survival_target, length.out = 7)
} else {
if(model == "Model Survival Logistik") {
message("---- Use Survival Logistic Model ----")
sr_est <- (100 - 2.86*log2(doc_data))/100
}
}
feed_fi <- (stock_data * (sr_est) * doc_data * fi_data)/100000
feed_fr <- (stock_data * (sr_est) * mbw_data * fr_data)/1000
population_data <- stock_data * (sr_est)
biomass <- population_data * mbw_data
date_data <- seq(weekly_feeding_date_input, by = "day", length.out = 7)
tibble(
pond_code = pond_data$pond,
doc_data = doc_data,
mbw_data = mbw_data,
sr_data = sr_est,
fi_data = fi_data,
fr_data = fr_data,
feed_fi = feed_fi,
feed_fr = feed_fr,
fi_fr_ratio = feed_fi/feed_fr,
biomass_data = biomass,
population_data = population_data,
date_data = date_data
) %>%
bind_rows(feed_data_container) -> feed_data_container
}
feed_data_container <- feed_data_container %>%
arrange(date_data, pond_code)
return(feed_data_container)
}