// File for reading population parameters of the 3D RGC 
// Before running this file, make sure to remove the strings in the file and convert to .txt
// Written by Keith Ly GSBME UNSW 2022

load_file("nrngui.hoc")
load_file("Parameters.hoc")

// Parameters of the population.csv file
RGC_size = 135 // Size of full RGC 3D population
csv_size = 10 // Number of columns in "population.csv"
max_num_dendrites = 100 // Maximum number of dendtrites in each RGC
//RGC_patch_size = 0.012 // Parameter for isolating RGCs

// objects for matrix and file respectively
objref RGC_param, readRGC_param

// objects for position of soma, type of RGC, dendritic radius, number of dendrites
objref RGC_position, pop_ONOFF_type, pop_RGC_dend_radius, num_dends, pop_Dend_x, pop_Dend_y, pop_Dend_z
objref Cell_index, Dend_x, Dend_y, Dend_z, ONOFF_type, RGC_dend_radius

// objects for cells
objref Ganglion[RGC_size]

// objects for storing template name
objref template_names

// object for storing dendrite centres
objref Dend_centres_x[RGC_size], Dend_centres_y[RGC_size], Dend_centres_z[RGC_size]

// Function for reading files
proc read_write_RGC_population() {

    readRGC_param = new File("mod_RGC_population.txt")
    readRGC_param.ropen()
    RGC_param = new Matrix(RGC_size, csv_size)
    RGC_param.scanf(readRGC_param, RGC_size, csv_size)

}

// Function for splitting imported full matrix to 
proc split_RGC_parameters() {

    RGC_position = new Matrix(RGC_size, 3)
    pop_ONOFF_type = new Matrix(RGC_size, 1)
    pop_RGC_dend_radius = new Matrix(RGC_size, 1)
    pop_Dend_x = new Matrix(RGC_size, 1)
    pop_Dend_y = new Matrix(RGC_size, 1)
    pop_Dend_z = new Matrix(RGC_size, 1)

    for i = 0, RGC_size - 1 {
        for j = 0, 2 {
            RGC_position.x[i][j] = RGC_param.x[i][j + 2]
        }

        pop_ONOFF_type.x[i][0] = RGC_param.x[i][1]
        pop_RGC_dend_radius.x[i][0] = (RGC_param.x[i][5])/2
        pop_Dend_x.x[i][0] = RGC_param.x[i][7]
        pop_Dend_y.x[i][0] = RGC_param.x[i][8]
        pop_Dend_z.x[i][0] = RGC_param.x[i][9]
    }

}

// Function for looping through the template files for all the RGCs
proc load_RGC_templates() {

    strdef RGC_name_init, fullRGC_name
    template_names = new Matrix(RGC_size, 1)

    for i = 0, RGC_size - 1 {
        if(i < 10) {
            RGC_name_init = "cell_000"
            sprint(fullRGC_name, "%s%s%d.%s", "cellHoc/", RGC_name_init, i, "hoc")
            load_file(fullRGC_name)
        } 
        if(i >= 10 && i < 100) {
            RGC_name_init = "cell_00"
            sprint(fullRGC_name, "%s%s%d.%s", "cellHoc/", RGC_name_init, i, "hoc")
            load_file(fullRGC_name)
        }
        if(i >= 100 && i < 1000) {
            RGC_name_init = "cell_0"
            sprint(fullRGC_name, "%s%s%d.%s", "cellHoc/", RGC_name_init, i, "hoc")
            load_file(fullRGC_name)
        }
    }

}

proc generate_RGC_cells() {

    strdef template_name, generate_template
    Dend_x = new Matrix(RGC_size, 1)
    Dend_y = new Matrix(RGC_size, 1)
    Dend_z = new Matrix(RGC_size, 1)
    Cell_index = new Matrix(RGC_size, 1)
    ONOFF_type = new Matrix(RGC_size, 1)
    RGC_dend_radius = new Matrix(RGC_size, 1)
    num_gang = 0

    for i = 0, RGC_size - 1 {
        if(i < 10) {
            //if((abs(pop_Dend_x.x[i][0]-Eccentricity_x*1000) < (RGC_patch_size*1000)) && (abs(pop_Dend_y.x[i][0]-Eccentricity_y*1000) < (RGC_patch_size*1000))) {
                RGC_name_init = "cell_000"
                sprint(template_name, "%s%d", RGC_name_init, i)
                sprint(generate_template, "Ganglion[%d] = new %s(0, 0, 0)", num_gang, template_name)
                execute(generate_template)
                Cell_index.x[num_gang][0] = i
                Dend_x.x[num_gang][0] = pop_Dend_x.x[i][0]
                Dend_y.x[num_gang][0] = pop_Dend_y.x[i][0]
                Dend_z.x[num_gang][0] = pop_Dend_z.x[i][0]
                ONOFF_type.x[num_gang][0] = pop_ONOFF_type.x[i][0]
                RGC_dend_radius.x[num_gang][0] = pop_RGC_dend_radius.x[i][0]
                num_gang = num_gang + 1
                print template_name
            //}
        } 
        if(i >= 10 && i < 100) {
            //if((abs(pop_Dend_x.x[i][0]-Eccentricity_x*1000) < (RGC_patch_size*1000)) && (abs(pop_Dend_y.x[i][0]-Eccentricity_y*1000) < (RGC_patch_size*1000))) {
                RGC_name_init = "cell_00"
                sprint(template_name, "%s%d", RGC_name_init, i)
                sprint(generate_template, "Ganglion[%d] = new %s(0, 0, 0)", num_gang, template_name)
                execute(generate_template)
                Cell_index.x[num_gang][0] = i
                Dend_x.x[num_gang][0] = pop_Dend_x.x[i][0]
                Dend_y.x[num_gang][0] = pop_Dend_y.x[i][0]
                Dend_z.x[num_gang][0] = pop_Dend_z.x[i][0]
                ONOFF_type.x[num_gang][0] = pop_ONOFF_type.x[i][0]
                RGC_dend_radius.x[num_gang][0] = pop_RGC_dend_radius.x[i][0]
                num_gang = num_gang + 1
                print template_name
            //}
        }
        if(i >= 100 && i < 1000) {
            //if((abs(pop_Dend_x.x[i][0]-Eccentricity_x*1000) < (RGC_patch_size*1000)) && (abs(pop_Dend_y.x[i][0]-Eccentricity_y*1000) < (RGC_patch_size*1000))) {
                RGC_name_init = "cell_0"
                sprint(template_name, "%s%d", RGC_name_init, i)
                sprint(generate_template, "Ganglion[%d] = new %s(0, 0, 0)", num_gang, template_name)
                execute(generate_template)
                Cell_index.x[num_gang][0] = i
                Dend_x.x[num_gang][0] = pop_Dend_x.x[i][0]
                Dend_y.x[num_gang][0] = pop_Dend_y.x[i][0]
                Dend_z.x[num_gang][0] = pop_Dend_z.x[i][0]
                ONOFF_type.x[num_gang][0] = pop_ONOFF_type.x[i][0]
                RGC_dend_radius.x[num_gang][0] = pop_RGC_dend_radius.x[i][0]
                num_gang = num_gang + 1
                print template_name
            //}
        }
    }

}

// Function for calculating the centre points of each dendrite for synapse use
proc calc_dendrite_centre() {
    
    num_dends = new Vector(num_gang)
    for i = 0, num_gang - 1 {
        Dend_centres_x[i] = new Vector(max_num_dendrites)
        Dend_centres_y[i] = new Vector(max_num_dendrites)
        Dend_centres_z[i] = new Vector(max_num_dendrites)
        k = 0
        forsec Ganglion[i].dendrites {
            Dend_centres_x[i].x[k] = x3d(1) //- (x3d(1) - x3d(0))/2
            Dend_centres_y[i].x[k] = y3d(1) //- (y3d(1) - y3d(0))/2
            Dend_centres_z[i].x[k] = z3d(1) //- (z3d(1) - z3d(0))/2
            k = k + 1
        }
        num_dends.x[i] = k
        Dend_centres_x[i].resize(k)
        Dend_centres_y[i].resize(k)
        Dend_centres_z[i].resize(k)
    }

}

// Function for changing RGC ionic channel properties
proc change_RGC_ionic_properties() {

    for i = 0, num_gang - 1 {
        forsec Ganglion[i].aises {
            gnabar_spike = 0.350
        }
    }

}