## ------------------------------------------------------------------------------ ##
## Shire HAE model for Lanadelumab
## Use this R file to run simulation
## ------------------------------------------------------------------------------ ##

if (require(deSolve) == FALSE) {
	install.packages('deSolve')
}
library(deSolve)
source('Init_HAE.r')
source('SimInput_HAE.r')
source('Param_HAE.r')

rTol  <- 1e-4									### Relative tolarence
aTol  <- 1e-8									### Absolute tolarence
outputFileName <- 'Sim_output'					### Output file name prefix

times <- seq(time_start, time_end, by = time_interval)
readout_vars <- c(
	'PK_Conc_Central_in_nM',
	'AA_Fold_profile',
	'CS_FXII_in_plasma_ngml',
	'CS_FXIIa_in_plasma_ngml',
	'CS_Total_preKAL_in_plasma',
	'CS_Total_HMWK_in_plasma',
	'CS_preKAL_prct_free',
	'CS_prct_HK2Chain',
	'CS_RO_BDKRB2',
	'CS_prct_HK2Chain_normalized'
)
time <- times - basal_equilibrium_duration - run_in_period
lineWidth <- 1

cat(paste('Reading input file:', inputFileName, '...\n'))
AA_data <- read.csv(file=inputFileName, header=TRUE, sep=',')
data_set <- data.frame(row.names=1:length(time))
max_num_pts <- nrow(AA_data)
if (num_of_patients_to_run > max_num_pts) {
	cat('Number of virtual patients in this simulation cannot be more than the total number of patients in the input file.\n')
	num_of_patients_to_run <- max_num_pts
}
if (num_of_patients_to_run < 1) {
	cat('Number of virtual patients cannot be less than 1.\n')
	num_of_patients_to_run <- 1
}
if (random_patients_selection == TRUE) {
	ptID_list <- sample(1:max_num_pts, num_of_patients_to_run, replace=FALSE)
} else {
	ptID_list <- seq(1, num_of_patients_to_run)
}
cat(paste('Setting output directory:', outputDir, '\n'))
if (dir.exists(outputDir)) {
	cat('Output directory already exists. All the files in there will be deleted.\n')
	unlink(outputDir, recursive = TRUE)
}
dir.create(outputDir, showWarnings = FALSE)

freq_table <- c()
for (ptID in ptID_list) {
	cat(paste('Collecting data for virtual patient #', ptID, '...\n', sep=''))
	fc <- file('Param_AA.h')
	param_lines <- ''
	param_lines <- paste(param_lines, 'double AA_AA_Fold_Max = ', AA_AA_Fold_Max, ';\n', sep='')
	param_lines <- paste(param_lines, 'double AA_Steepness = ', AA_Steepness, ';\n', sep='')
	param_lines <- paste(param_lines, 'double AA_AA_t_duration = ', AA_AA_t_duration, ';\n', sep='')
	param_lines <- paste(param_lines, 'double PK_V_F = ', AA_data[ptID,2], ';\n', sep='')
	param_lines <- paste(param_lines, 'double PK_CL_F = ', AA_data[ptID,3], ';\n', sep='')
	param_lines <- paste(param_lines, 'double PK_ka = ', AA_data[ptID,4], ';\n', sep='')
	param_lines <- paste(param_lines, 'double Num_of_AA = ', AA_data[ptID,5], ';\n', sep='')
	param_lines <- paste(param_lines, '#define Max_Num_of_AA ', Max_Num_of_AA, '\n', sep='')
	param_lines <- paste(param_lines, 'double AA_AA_t_onset[Max_Num_of_AA] = {', paste(AA_data[ptID,6:(6+Max_Num_of_AA-1)]+basal_equilibrium_duration, collapse=','), '};\n', sep='')
	param_lines <- paste(param_lines, 'double AA_AA_Fold_Normalized[Max_Num_of_AA] = {', paste(AA_data[ptID,(6+Max_Num_of_AA):(6+2*Max_Num_of_AA-1)], collapse=','), '};\n', sep='')
	writeLines(param_lines, fc)
	close(fc)
	
	doses_fold <- as.numeric(AA_data[ptID,(length(AA_data[ptID,])-N_dose*Dose_interval/24+1):length(AA_data[ptID,])])
	doses_time_days <- c()
	for (i in seq(length(doses_fold))) {
		if (doses_fold[i] == 1) doses_time_days <- c(doses_time_days, i-1)
	}
	events_time <- basal_equilibrium_duration+run_in_period+doses_time_days*24
	events_method <- c('add')
	events_value <- rep(Dose_amount, sum(doses_fold))
	dosing <- data.frame(var = c('PK_Amount_SC'), time = events_time, value = events_value, method = events_method)
	
	output_pt <- paste(outputDir, '/Pt_', ptID, '/', sep = '')
	dir.create(output_pt)
	dllName <- 'HAE_Contact_System_Model'
	cat('Compiling to dll...\n')
	system(paste('R CMD SHLIB ', dllName, '.c', sep = ''))
	dyn.load(paste(dllName, .Platform$dynlib.ext, sep = ''))
	
	cat('Simulation is running...\n')
	print(system.time(
		outC <- daspk(init, times, "hae_model", parms, rtol = rTol, atol = aTol, events = list(data = dosing),
				  dllname = dllName, verbose = FALSE, ynames = FALSE, nout = 10, outnames = readout_vars)
	))
	cat(paste('Simulation is done for virtual patient #', ptID, '.\n', sep=''))
	
	dyn.unload(paste(dllName, .Platform$dynlib.ext, sep = ''))
	if (file.exists(paste(dllName, '.o', sep = ''))) {
		file.remove(paste(dllName, '.o', sep = ''))
	}
	dfout <- data.frame(outC)
	write.csv(cbind(time, dfout[,c(3:19,63:72)]), file=paste(output_pt, outputFileName, '_pt_', ptID, '.csv', sep=''), row.names=FALSE)
	
	rout <- read.csv(paste(output_pt, outputFileName, '_pt_', ptID, '.csv', sep=''), header = TRUE)
	for (i in seq(1, length(target_vars))) {
		col_stat <- match(target_vars[i], colnames(rout))
		data_set <- cbind(data_set, var = rout[,col_stat])
	}
	## Make plots for single patient by using the following lines
	varName <- rout$'PK_Conc_Central_in_ugml'
	png(paste(output_pt, 'Plot_', 'PK_Conc_Central_in_ugml', '_pt_', ptID, '.png', sep = ''))
	plot(data.frame(time, varName), type = 'l', lwd = lineWidth, col = 'black', xlab = 'Time (h)', ylab = '', main = 'PK_Conc_Central_in_ugml (ug/ml)')
	dev.off()
	varName <- rout$'CS_BK_in_plasma'
	png(paste(output_pt, 'Plot_', 'CS_BK_in_plasma', '_pt_', ptID, '.png', sep = ''))
	plot(data.frame(time, varName), type = 'l', lwd = lineWidth, col = 'black', xlab = 'Time (h)', ylab = '', main = 'CS_BK_in_plasma (nM)')
	dev.off()
	varName <- rout$'CS_FXIIa_in_plasma_ngml'
	png(paste(output_pt, 'Plot_', 'CS_FXIIa_in_plasma_ngml', '_pt_', ptID, '.png', sep = ''))
	plot(data.frame(time, varName), type = 'l', lwd = lineWidth, col = 'black', xlab = 'Time (h)', ylab = '', main = 'CS_FXIIa_in_plasma_ngml (ng/ml)')
	dev.off()
	varName <- rout$'CS_prct_HK2Chain'
	png(paste(output_pt, 'Plot_', 'CS_prct_HK2Chain', '_pt_', ptID, '.png', sep = ''))
	plot(data.frame(time, varName), type = 'l', lwd = lineWidth, col = 'black', xlab = 'Time (h)', ylab = '', main = 'CS_prct_HK2Chain (%)')
	dev.off()
	varName <- rout$'CS_RO_BDKRB2'
	png(paste(output_pt, 'Plot_', 'CS_RO_BDKRB2', '_pt_', ptID, '.png', sep = ''))
	plot(data.frame(time, varName), type = 'l', lwd = lineWidth, col = 'black', xlab = 'Time (h)', ylab = '', main = 'CS_RO_BDKRB2 (%)')
	dev.off()
	
	time_start <- -run_in_period
	month_span <- 24*7*4
	BK <- rout$'CS_BK_in_plasma'
	Num_of_events <- 0
	max_value <- -1
	counted <- FALSE
	event_t_start <- c()
	event_t_end <- c()
	event_max <- c()
	for (i in seq(length(time))) {
		if ((BK[i] >= BK_threshold) & (time[i] >= time_start)) {
			if (counted == FALSE) {
				Num_of_events <- Num_of_events + 1
				event_t_start <- append(event_t_start, time[i])
				counted <- TRUE
			}
			if (BK[i] > max_value) {
				max_value <- BK[i]
			}
		} else {
			if (counted) {
				event_t_end <- append(event_t_end, time[i])
				event_max <- append(event_max, max_value)
				counted <- FALSE
				max_value <- -1
			}
		}
	}
	if ((counted) & (tail(BK, 1) >= BK_threshold)) {
		event_t_end <- append(event_t_end, tail(time, 1))
		event_max <- append(event_max, max_value)
	}
	events <- data.frame(t_start = event_t_start, t_end = event_t_end, max = event_max)
	num_events <- nrow(events)

	month_min <- floor(time_start/month_span)+1
	month_max <- floor(time[length(time)]/month_span)+1
	months <- seq(month_min, month_max)
	freq <- rep(0, length(months))
	for (i in seq(num_events)) {
		midx <- match(floor(event_t_start[i]/month_span)+1, months)
		freq[midx] <- freq[midx] + 1
	}
	freq_table <- rbind(freq_table, freq)
}

cat('Analyzing attack events for all virtual patients...\n')
monthly_rate_avg <- c()
monthly_rate_std <- c()
for (i in seq(length(months))) {
	monthly_rate_avg <- append(monthly_rate_avg, mean(freq_table[,i]))
	monthly_rate_std <- append(monthly_rate_std, sd(freq_table[,i]))
}
monthly_rate <- cbind(months, monthly_rate_avg, monthly_rate_std)
colnames(monthly_rate) <- c('Month', 'Mean', 'SD')
write.csv(monthly_rate, file=paste(outputDir, '/', 'Monthly_Attack_Rate.csv', sep=''), row.names=FALSE)

color_bag <- c('blue', 'black', 'red', 'purple', 'cyan')
cat('Generating statistics...\n')
for (i in seq(1, length(target_vars))) {
	if (num_of_patients_to_run > 1) {
		stat <- cbind(time, t(apply(data_set[,seq(i, num_of_patients_to_run*length(target_vars), length(target_vars))], 1, quantile, probs = percentiles/100.0, na.rm=TRUE)))
	} else {
		stat <- cbind(time, replicate(length(percentiles), data_set[,seq(i, num_of_patients_to_run*length(target_vars), length(target_vars))]))
	}
	colnames(stat) <- c('time', paste(percentiles, 'pct', sep=''))
	write.csv(stat, file=paste(outputDir, '/', 'Stats_', target_vars[i], '.csv', sep=''), row.names=FALSE)
	sout <- read.csv(paste(outputDir, '/', 'Stats_', target_vars[i], '.csv', sep=''), header = TRUE)
	## Make plots for statistics by using the following lines
	png(paste(outputDir, '/', 'Plot_Stats_', target_vars[i], '.png', sep = ''))
	for (j in rev(1:length(percentiles)+1)) {
		value <- sout[,j]
		if (j == length(percentiles)+1) {
			plot(data.frame(time, value), type = 'l', lwd = lineWidth, col = color_bag[(j-2)%%length(color_bag)+1], xlab = 'Time (h)', ylab = '', main = paste('Percentiles_', target_vars[i], sep=''))
		} else {
			lines(data.frame(time, value), type = 'l', lwd = lineWidth, col = color_bag[(j-2)%%length(color_bag)+1])
		}
	}
	dev.off()
}
cat(paste('All results have been saved in:', outputDir, '\n'))
