from util.io import read_setting_json, read_0h_data, read_24h_data, draw_single_curve
from util.convert import split_array_into_samples, calculate_avg_of_sample, convert_to_percentage
from util.calculus import calculate_summary_of_sample, fit_sigmoid_curve

import matplotlib.pyplot as plt
import numpy as np
import csv

setting = read_setting_json()
setting = setting["rule"]

# load experiment parameter
# experiment parameter is stored in file of ./data/setting.json
initial_filename = setting["0h_datafile"]
final_filename = setting["24h_datafile"]

# sample width and height are the size of each sample area
sample_width = setting["sample_width"]
sample_height = setting["sample_height"]
dilution_protocol = setting["dilution_protocol"]

# width of each dilution
basic_width = setting["basic_width"]

# number of each control group
control_number_list = setting["control_number"]

# output directory
output_directory = setting["output_directory"]

# import initial concentration and calculate x_data
initial_concentration = setting["initial_concentration"]

repeat_times = int(sample_width / basic_width)

x_data = []

current_concentration = initial_concentration
for i in range(repeat_times):
    x_data.append(current_concentration)
    current_concentration /= dilution_protocol


# load raw data
initial_sd_data = read_0h_data()
final_sd_data = read_24h_data()

# reshape data into the size of board
rebuild_0h_data = initial_sd_data.reshape((32, -1))
rebuild_24h_data = final_sd_data.reshape((32, -1))

# reshape data into a 2-dimensional array contains each group data
sample_divided_list_0h = split_array_into_samples(rebuild_0h_data, sample_width, sample_height)
sample_divided_list_24h = split_array_into_samples(rebuild_24h_data, sample_width, sample_height)

# handle data of control groups
control_0h_summary = 0
for number in control_number_list:
    number = number - 1
    sample = sample_divided_list_0h[number]
    control_0h_summary = control_0h_summary + calculate_summary_of_sample(sample)

control_0h_average = control_0h_summary / (sample_width * sample_height * len(control_number_list))

control_24h_summary = 0
for number in control_number_list:
    number = number - 1
    sample = sample_divided_list_24h[number]
    control_24h_summary = control_24h_summary + calculate_summary_of_sample(sample)

control_24h_average = control_24h_summary / (sample_width * sample_height * len(control_number_list))

# calculate standard deviation of each grid
sd_matrix = []
for line in rebuild_24h_data:
    new_line = []
    for element in line:
        sd_data = (float(element) - control_0h_average.item()) \
                  / (control_24h_average.item() - control_0h_average.item())
        new_line.append(sd_data)
    sd_matrix.append(new_line)

sd_matrix = np.array(sd_matrix)

# split array into different samples
sd_groups = split_array_into_samples(sd_matrix, sample_width, sample_height)
sd_groups = np.array(sd_groups, dtype=float)

RESULT_LIST = []
for sample in sd_groups:
    result = calculate_avg_of_sample(sample, sample_width, basic_width)
    RESULT_LIST.append(result)

RESULT_LIST = np.array(RESULT_LIST)

FULL_RESULT_LIST = []

for group in sd_groups:
    x_index = 0
    y_index = 0
    sample_buffer = []
    data_buffer = []
    while y_index < sample_height:
        while x_index < basic_width:
            x = x_index
            while x < sample_width:
                data_buffer.append(group[y_index][x])
                x += basic_width
            sample_buffer.append(data_buffer)
            data_buffer = []
            x_index += 1
        y_index += 1
        x_index = 0
    FULL_RESULT_LIST.append(sample_buffer)

FULL_RESULT_LIST = np.array(FULL_RESULT_LIST, dtype=float)


optional_color = ['red', 'orange', 'yellow', 'green', 'cyan', 'blue', 'purple']

EC50_LIST = []
EC50_AVG_LIST = []

sample_num = 0
for SAMPLE in FULL_RESULT_LIST:
    sample_num += 1
    fig, ax = plt.subplots()
    index = 0
    ax.set_title('Sample '+str(sample_num))

    x_buffer = []
    x_sampling_buffer = []
    y_sampling_buffer = []

    for repeat in SAMPLE:
        x, y, x_sampling, y_sampling = fit_sigmoid_curve(x_data, repeat)
        x_buffer.append(x)
        x_sampling_buffer.append(x_sampling)
        y_sampling_buffer.append(y_sampling)
        draw_single_curve(ax, x, y, x_sampling, y_sampling, optional_color[index])
        index += 1

    EC50_LIST.append(x_buffer)

    # draw the average result
    avg = np.mean(x_buffer)

    EC50_AVG_LIST.append(avg)

    # draw the average curve
    x_sampling_buffer = np.array(x_sampling_buffer).T
    y_sampling_buffer = np.array(y_sampling_buffer).T

    x_sampling_avg = []
    y_sampling_avg = []

    for line in x_sampling_buffer:
        x_sampling_avg.append(np.mean(line))

    for line in y_sampling_buffer:
        y_sampling_avg.append(np.mean(line))

    ax.plot(avg, 0.5, 'o', color='black')
    ax.plot(x_sampling_avg, y_sampling_avg, color='black')
    plt.savefig("./output/" + output_directory + "/figs" + "/Sample " + str(sample_num))
    plt.cla()
    plt.close(fig)


# output grouped result
output_f_grouped = open("./output/" + output_directory + "/result_grouped.csv", "w")
csv_writer_grouped = csv.writer(output_f_grouped)
csv_writer_grouped.writerow(["initial concentration: " + str(initial_concentration), "dilution protocol: " + str(dilution_protocol)])
csv_writer_grouped.writerow("")
sample_num = 0
for SAMPLE in FULL_RESULT_LIST:
    SAMPLE = SAMPLE.T
    sample_num += 1
    csv_writer_grouped.writerow(["Sample " + str(sample_num)])
    for repeat in SAMPLE:
        csv_writer_grouped.writerow(repeat)
    csv_writer_grouped.writerow("")
    ec50_result_list = []
    for ec50_index in EC50_LIST[sample_num-1]:
        ec50_result_list.append(10**ec50_index)
    csv_writer_grouped.writerow(ec50_result_list)
    average_ec50 = np.power(10, EC50_AVG_LIST[sample_num-1])
    csv_writer_grouped.writerow([])
    csv_writer_grouped.writerow(["Average EC50", "Std"])
    csv_writer_grouped.writerow([average_ec50, np.std(ec50_result_list)])
    csv_writer_grouped.writerow("")
output_f_grouped.close()

output_f_full = open("./output/" + output_directory + "/result_full.csv", "w")
csv_writer_full = csv.writer(output_f_full)
for line in sd_matrix:
    csv_writer_full.writerow(line)
output_f_full.close()

print("Finished")

[((9, 10, 9, 29), 'util.io.read_setting_json', 'read_setting_json', ({}, {}), '()', False, 'from util.io import read_setting_json, read_0h_data, read_24h_data, draw_single_curve\n'), ((45, 18, 45, 32), 'util.io.read_0h_data', 'read_0h_data', ({}, {}), '()', False, 'from util.io import read_setting_json, read_0h_data, read_24h_data, draw_single_curve\n'), ((46, 16, 46, 31), 'util.io.read_24h_data', 'read_24h_data', ({}, {}), '()', False, 'from util.io import read_setting_json, read_0h_data, read_24h_data, draw_single_curve\n'), ((53, 25, 53, 95), 'util.convert.split_array_into_samples', 'split_array_into_samples', ({(53, 50, 53, 65): 'rebuild_0h_data', (53, 67, 53, 79): 'sample_width', (53, 81, 53, 94): 'sample_height'}, {}), '(rebuild_0h_data, sample_width, sample_height)', False, 'from util.convert import split_array_into_samples, calculate_avg_of_sample, convert_to_percentage\n'), ((54, 26, 54, 97), 'util.convert.split_array_into_samples', 'split_array_into_samples', ({(54, 51, 54, 67): 'rebuild_24h_data', (54, 69, 54, 81): 'sample_width', (54, 83, 54, 96): 'sample_height'}, {}), '(rebuild_24h_data, sample_width, sample_height)', False, 'from util.convert import split_array_into_samples, calculate_avg_of_sample, convert_to_percentage\n'), ((83, 12, 83, 31), 'numpy.array', 'np.array', ({(83, 21, 83, 30): 'sd_matrix'}, {}), '(sd_matrix)', True, 'import numpy as np\n'), ((86, 12, 86, 76), 'util.convert.split_array_into_samples', 'split_array_into_samples', ({(86, 37, 86, 46): 'sd_matrix', (86, 48, 86, 60): 'sample_width', (86, 62, 86, 75): 'sample_height'}, {}), '(sd_matrix, sample_width, sample_height)', False, 'from util.convert import split_array_into_samples, calculate_avg_of_sample, convert_to_percentage\n'), ((87, 12, 87, 44), 'numpy.array', 'np.array', (), '', True, 'import numpy as np\n'), ((94, 14, 94, 35), 'numpy.array', 'np.array', ({(94, 23, 94, 34): 'RESULT_LIST'}, {}), '(RESULT_LIST)', True, 'import numpy as np\n'), ((116, 19, 116, 58), 'numpy.array', 'np.array', (), '', True, 'import numpy as np\n'), ((172, 21, 172, 49), 'csv.writer', 'csv.writer', ({(172, 32, 172, 48): 'output_f_grouped'}, {}), '(output_f_grouped)', False, 'import csv\n'), ((195, 18, 195, 43), 'csv.writer', 'csv.writer', ({(195, 29, 195, 42): 'output_f_full'}, {}), '(output_f_full)', False, 'import csv\n'), ((91, 13, 91, 71), 'util.convert.calculate_avg_of_sample', 'calculate_avg_of_sample', ({(91, 37, 91, 43): 'sample', (91, 45, 91, 57): 'sample_width', (91, 59, 91, 70): 'basic_width'}, {}), '(sample, sample_width, basic_width)', False, 'from util.convert import split_array_into_samples, calculate_avg_of_sample, convert_to_percentage\n'), ((127, 14, 127, 28), 'matplotlib.pyplot.subplots', 'plt.subplots', ({}, {}), '()', True, 'import matplotlib.pyplot as plt\n'), ((146, 10, 146, 27), 'numpy.mean', 'np.mean', ({(146, 18, 146, 26): 'x_buffer'}, {}), '(x_buffer)', True, 'import numpy as np\n'), ((166, 4, 166, 13), 'matplotlib.pyplot.cla', 'plt.cla', ({}, {}), '()', True, 'import matplotlib.pyplot as plt\n'), ((167, 4, 167, 18), 'matplotlib.pyplot.close', 'plt.close', ({(167, 14, 167, 17): 'fig'}, {}), '(fig)', True, 'import matplotlib.pyplot as plt\n'), ((187, 19, 187, 60), 'numpy.power', 'np.power', ({(187, 28, 187, 30): '10', (187, 32, 187, 59): 'EC50_AVG_LIST[sample_num - 1]'}, {}), '(10, EC50_AVG_LIST[sample_num - 1])', True, 'import numpy as np\n'), ((61, 46, 61, 81), 'util.calculus.calculate_summary_of_sample', 'calculate_summary_of_sample', ({(61, 74, 61, 80): 'sample'}, {}), '(sample)', False, 'from util.calculus import calculate_summary_of_sample, fit_sigmoid_curve\n'), ((69, 48, 69, 83), 'util.calculus.calculate_summary_of_sample', 'calculate_summary_of_sample', ({(69, 76, 69, 82): 'sample'}, {}), '(sample)', False, 'from util.calculus import calculate_summary_of_sample, fit_sigmoid_curve\n'), ((136, 39, 136, 72), 'util.calculus.fit_sigmoid_curve', 'fit_sigmoid_curve', ({(136, 57, 136, 63): 'x_data', (136, 65, 136, 71): 'repeat'}, {}), '(x_data, repeat)', False, 'from util.calculus import calculate_summary_of_sample, fit_sigmoid_curve\n'), ((140, 8, 140, 82), 'util.io.draw_single_curve', 'draw_single_curve', ({(140, 26, 140, 28): 'ax', (140, 30, 140, 31): 'x', (140, 33, 140, 34): 'y', (140, 36, 140, 46): 'x_sampling', (140, 48, 140, 58): 'y_sampling', (140, 60, 140, 81): 'optional_color[index]'}, {}), '(ax, x, y, x_sampling, y_sampling, optional_color[index])', False, 'from util.io import read_setting_json, read_0h_data, read_24h_data, draw_single_curve\n'), ((151, 24, 151, 51), 'numpy.array', 'np.array', ({(151, 33, 151, 50): 'x_sampling_buffer'}, {}), '(x_sampling_buffer)', True, 'import numpy as np\n'), ((152, 24, 152, 51), 'numpy.array', 'np.array', ({(152, 33, 152, 50): 'y_sampling_buffer'}, {}), '(y_sampling_buffer)', True, 'import numpy as np\n'), ((158, 30, 158, 43), 'numpy.mean', 'np.mean', ({(158, 38, 158, 42): 'line'}, {}), '(line)', True, 'import numpy as np\n'), ((161, 30, 161, 43), 'numpy.mean', 'np.mean', ({(161, 38, 161, 42): 'line'}, {}), '(line)', True, 'import numpy as np\n'), ((190, 47, 190, 71), 'numpy.std', 'np.std', ({(190, 54, 190, 70): 'ec50_result_list'}, {}), '(ec50_result_list)', True, 'import numpy as np\n')]