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")

[((331, 350), 'util.io.read_setting_json', 'read_setting_json', ([], {}), '()\n', (348, 350), False, 'from util.io import read_setting_json, read_0h_data, read_24h_data, draw_single_curve\n'), ((1324, 1338), 'util.io.read_0h_data', 'read_0h_data', ([], {}), '()\n', (1336, 1338), False, 'from util.io import read_setting_json, read_0h_data, read_24h_data, draw_single_curve\n'), ((1355, 1370), 'util.io.read_24h_data', 'read_24h_data', ([], {}), '()\n', (1368, 1370), False, 'from util.io import read_setting_json, read_0h_data, read_24h_data, draw_single_curve\n'), ((1606, 1676), 'util.convert.split_array_into_samples', 'split_array_into_samples', (['rebuild_0h_data', 'sample_width', 'sample_height'], {}), '(rebuild_0h_data, sample_width, sample_height)\n', (1630, 1676), False, 'from util.convert import split_array_into_samples, calculate_avg_of_sample, convert_to_percentage\n'), ((1703, 1774), 'util.convert.split_array_into_samples', 'split_array_into_samples', (['rebuild_24h_data', 'sample_width', 'sample_height'], {}), '(rebuild_24h_data, sample_width, sample_height)\n', (1727, 1774), False, 'from util.convert import split_array_into_samples, calculate_avg_of_sample, convert_to_percentage\n'), ((2785, 2804), 'numpy.array', 'np.array', (['sd_matrix'], {}), '(sd_matrix)\n', (2793, 2804), True, 'import numpy as np\n'), ((2855, 2919), 'util.convert.split_array_into_samples', 'split_array_into_samples', (['sd_matrix', 'sample_width', 'sample_height'], {}), '(sd_matrix, sample_width, sample_height)\n', (2879, 2919), False, 'from util.convert import split_array_into_samples, calculate_avg_of_sample, convert_to_percentage\n'), ((2932, 2964), 'numpy.array', 'np.array', (['sd_groups'], {'dtype': 'float'}), '(sd_groups, dtype=float)\n', (2940, 2964), True, 'import numpy as np\n'), ((3126, 3147), 'numpy.array', 'np.array', (['RESULT_LIST'], {}), '(RESULT_LIST)\n', (3134, 3147), True, 'import numpy as np\n'), ((3695, 3734), 'numpy.array', 'np.array', (['FULL_RESULT_LIST'], {'dtype': 'float'}), '(FULL_RESULT_LIST, dtype=float)\n', (3703, 3734), True, 'import numpy as np\n'), ((5226, 5254), 'csv.writer', 'csv.writer', (['output_f_grouped'], {}), '(output_f_grouped)\n', (5236, 5254), False, 'import csv\n'), ((6237, 6262), 'csv.writer', 'csv.writer', (['output_f_full'], {}), '(output_f_full)\n', (6247, 6262), False, 'import csv\n'), ((3021, 3079), 'util.convert.calculate_avg_of_sample', 'calculate_avg_of_sample', (['sample', 'sample_width', 'basic_width'], {}), '(sample, sample_width, basic_width)\n', (3044, 3079), False, 'from util.convert import split_array_into_samples, calculate_avg_of_sample, convert_to_percentage\n'), ((3934, 3948), 'matplotlib.pyplot.subplots', 'plt.subplots', ([], {}), '()\n', (3946, 3948), True, 'import matplotlib.pyplot as plt\n'), ((4472, 4489), 'numpy.mean', 'np.mean', (['x_buffer'], {}), '(x_buffer)\n', (4479, 4489), True, 'import numpy as np\n'), ((5065, 5074), 'matplotlib.pyplot.cla', 'plt.cla', ([], {}), '()\n', (5072, 5074), True, 'import matplotlib.pyplot as plt\n'), ((5079, 5093), 'matplotlib.pyplot.close', 'plt.close', (['fig'], {}), '(fig)\n', (5088, 5093), True, 'import matplotlib.pyplot as plt\n'), ((5869, 5912), 'numpy.power', 'np.power', (['(10)', 'EC50_AVG_LIST[sample_num - 1]'], {}), '(10, EC50_AVG_LIST[sample_num - 1])\n', (5877, 5912), True, 'import numpy as np\n'), ((1980, 2015), 'util.calculus.calculate_summary_of_sample', 'calculate_summary_of_sample', (['sample'], {}), '(sample)\n', (2007, 2015), False, 'from util.calculus import calculate_summary_of_sample, fit_sigmoid_curve\n'), ((2294, 2329), 'util.calculus.calculate_summary_of_sample', 'calculate_summary_of_sample', (['sample'], {}), '(sample)\n', (2321, 2329), False, 'from util.calculus import calculate_summary_of_sample, fit_sigmoid_curve\n'), ((4146, 4179), 'util.calculus.fit_sigmoid_curve', 'fit_sigmoid_curve', (['x_data', 'repeat'], {}), '(x_data, repeat)\n', (4163, 4179), False, 'from util.calculus import calculate_summary_of_sample, fit_sigmoid_curve\n'), ((4305, 4379), 'util.io.draw_single_curve', 'draw_single_curve', (['ax', 'x', 'y', 'x_sampling', 'y_sampling', 'optional_color[index]'], {}), '(ax, x, y, x_sampling, y_sampling, optional_color[index])\n', (4322, 4379), False, 'from util.io import read_setting_json, read_0h_data, read_24h_data, draw_single_curve\n'), ((4575, 4602), 'numpy.array', 'np.array', (['x_sampling_buffer'], {}), '(x_sampling_buffer)\n', (4583, 4602), True, 'import numpy as np\n'), ((4629, 4656), 'numpy.array', 'np.array', (['y_sampling_buffer'], {}), '(y_sampling_buffer)\n', (4637, 4656), True, 'import numpy as np\n'), ((4774, 4787), 'numpy.mean', 'np.mean', (['line'], {}), '(line)\n', (4781, 4787), True, 'import numpy as np\n'), ((4855, 4868), 'numpy.mean', 'np.mean', (['line'], {}), '(line)\n', (4862, 4868), True, 'import numpy as np\n'), ((6051, 6075), 'numpy.std', 'np.std', (['ec50_result_list'], {}), '(ec50_result_list)\n', (6057, 6075), True, 'import numpy as np\n')]