function run_life_view!(results::Array{Float64,3},environment::Array{Float64,3},
    grn::NamedTuple,diff_adhesion::Array{Float64,2},diffusion_constants::Array{Float64,1},
    Ax::Array{Float64,2},Ay::Array{Float64,2},
    dc::Array{Float64,1},cell_config::CellularConfig,exp_config::ExperimentalConfig,grn_config::FGRNConfig)

    target_cell_areas = Dict{Float64,Float64}()
    n_div = Dict{Float64,Integer}()

    all_cells::Array{Float64,1} = [1.]
    n_div[1.] = 0
    target_cell_areas[1.] = 2*0.25*cell_config.cell_size_upper_limit

    if exp_config.est_strength == "evolve"
        affinity_1 = calculate_affinity(grn.rec_prom[:,:,1],grn_config.substrate_protein)
        affinity_2 = calculate_affinity(grn.rec_prom[:,:,2],grn_config.substrate_protein)
        affinity_3 = calculate_affinity(grn.rec_prom[:,:,3],grn_config.substrate_protein)
        affinity_4 = calculate_affinity(grn.rec_prom[:,:,4],grn_config.substrate_protein)
    else
        affinity_1 = 1 - exp_config.est_strength
        affinity_2 = 1 - exp_config.est_strength
        affinity_3 = 1 - exp_config.est_strength
        affinity_4 = 1 - exp_config.est_strength
    end

    left_segment = Int.(floor(cell_config.grid_size/3))
    middle_segment = Int.(floor(2*cell_config.grid_size/3))

    est_setup = ESTSetup(affinity_1,affinity_2,affinity_3,affinity_4,left_segment,middle_segment)

    for step in 1:size(results,3) # development 

        results[:,:,step] = environment[:,:,2]
        
        environment_update2!(grn,environment,all_cells,diff_adhesion,target_cell_areas,cell_config,exp_config)
    
        if size(all_cells,1) == 0
            break
        end
        
        cell_mitosis_and_apoptosis!(environment,all_cells,n_div,cell_config)
        
        protein_dynamics!(environment,est_setup,grn,all_cells,target_cell_areas,diffusion_constants,Ax,Ay,dc,
            exp_config,cell_config,grn_config)
        
        for cell in all_cells
            if n_div[cell] > cell_config.max_split     
                target_cell_areas[cell] = 0
            end
        end

    end
end  

function run_life_view!(results::Array{Float64,4},environment::Array{Float64,3},
    grn::NamedTuple,diff_adhesion::Array{Float64,2}, diffusion_constants::Array{Float64,1},
    Ax::Array{Float64,2},Ay::Array{Float64,2},dc::Array{Float64,1},cell_config::CellularConfig,exp_config::ExperimentalConfig,grn_config::FGRNConfig)

    target_cell_areas = Dict{Float64,Float64}()
    n_div = Dict{Float64,Integer}()

    all_cells::Array{Float64,1} = [1.]
    n_div[1.] = 0
    target_cell_areas[1.] = 2*0.25*cell_config.cell_size_upper_limit

    if exp_config.est_strength == "evolve"
        affinity_1 = calculate_affinity(grn.rec_prom[:,:,1],grn_config.substrate_protein)
        affinity_2 = calculate_affinity(grn.rec_prom[:,:,2],grn_config.substrate_protein)
        affinity_3 = calculate_affinity(grn.rec_prom[:,:,3],grn_config.substrate_protein)
        affinity_4 = calculate_affinity(grn.rec_prom[:,:,4],grn_config.substrate_protein)
    else
        affinity_1 = 1 - exp_config.est_strength
        affinity_2 = 1 - exp_config.est_strength
        affinity_3 = 1 - exp_config.est_strength
        affinity_4 = 1 - exp_config.est_strength
    end

    left_segment = Int.(floor(cell_config.grid_size/3))
    middle_segment = Int.(floor(2*cell_config.grid_size/3))

    est_setup = ESTSetup(affinity_1,affinity_2,affinity_3,affinity_4,left_segment,middle_segment)

    for step in 1:size(results,4)

        results[:,:,:,step] = environment[:,:,:]
        
        environment_update2!(grn,environment,all_cells,diff_adhesion,target_cell_areas,cell_config,exp_config)
        
        if size(all_cells,1) == 0
            break
        end
        
        cell_mitosis_and_apoptosis!(environment,all_cells,n_div,cell_config)
        
        protein_dynamics!(environment,est_setup,grn,all_cells,target_cell_areas,diffusion_constants,Ax,Ay,dc,
            exp_config,cell_config,grn_config)
        
        for cell in all_cells
            if n_div[cell] > cell_config.max_split     
                target_cell_areas[cell] = 0
            end
        end

    end
end

function run_life_view!(damage_times::Vector{Int64},damage_percentage::Float64,results::Array{Float64,3},environment::Array{Float64,3},
    grn::NamedTuple,diff_adhesion::Array{Float64,2}, diffusion_constants::Array{Float64,1},
    Ax::Array{Float64,2},Ay::Array{Float64,2},dc::Array{Float64,1},
    cell_config::CellularConfig,exp_config::ExperimentalConfig,grn_config::FGRNConfig)

    target_cell_areas = Dict{Float64,Float64}()
    n_div = Dict{Float64,Integer}()

    all_cells::Array{Float64,1} = [1.]
    n_div[1.] = 0
    target_cell_areas[1.] = 2*0.25*cell_config.cell_size_upper_limit

    if exp_config.est_strength == "evolve"
        affinity_1 = calculate_affinity(grn.rec_prom[:,:,1],grn_config.substrate_protein)
        affinity_2 = calculate_affinity(grn.rec_prom[:,:,2],grn_config.substrate_protein)
        affinity_3 = calculate_affinity(grn.rec_prom[:,:,3],grn_config.substrate_protein)
        affinity_4 = calculate_affinity(grn.rec_prom[:,:,4],grn_config.substrate_protein)
    else
        affinity_1 = 1 - exp_config.est_strength
        affinity_2 = 1 - exp_config.est_strength
        affinity_3 = 1 - exp_config.est_strength
        affinity_4 = 1 - exp_config.est_strength
    end

    left_segment = Int.(floor(cell_config.grid_size/3))
    middle_segment = Int.(floor(2*cell_config.grid_size/3))

    est_setup = ESTSetup(affinity_1,affinity_2,affinity_3,affinity_4,left_segment,middle_segment)

    for step in 1:size(results,3)
        
        if step in damage_times
            d_int = Int64.(floor(damage_percentage*size(all_cells,1)))
            damage_pixels = sample(all_cells,d_int,replace = false)
            for dp in damage_pixels
                environment[environment[:,:,1] .== dp,:] .= 0
            end

        end

        results[:,:,step] = environment[:,:,2]
        
        environment_update2!(grn,environment,all_cells,diff_adhesion,target_cell_areas,cell_config,exp_config)
        
        if size(all_cells,1) == 0
            break
        end
        
        cell_mitosis_and_apoptosis!(environment,all_cells,n_div,cell_config)
        
        protein_dynamics!(environment,est_setup,grn,all_cells,target_cell_areas,diffusion_constants,Ax,Ay,dc,
            exp_config,cell_config,grn_config)
        
        for cell in all_cells
            if n_div[cell] > cell_config.max_split     
                target_cell_areas[cell] = 0
            end
        end

    end
end

function run_life_view!(damage_times::Vector{Int64},damage_percentage::Float64,energies::Array{Float64,1},
    results::Array{Float64,3},environment::Array{Float64,3},
    grn::NamedTuple,diff_adhesion::Array{Float64,2}, diffusion_constants::Array{Float64,1},
    Ax::Array{Float64,2},Ay::Array{Float64,2},dc::Array{Float64,1},
    cell_config::CellularConfig,exp_config::ExperimentalConfig,grn_config::FGRNConfig)

    target_cell_areas = Dict{Float64,Float64}()
    n_div = Dict{Float64,Integer}()

    all_cells::Array{Float64,1} = [1.]
    n_div[1.] = 0
    target_cell_areas[1.] = 2*0.25*cell_config.cell_size_upper_limit

    if exp_config.est_strength == "evolve"
        affinity_1 = calculate_affinity(grn.rec_prom[:,:,1],grn_config.substrate_protein)
        affinity_2 = calculate_affinity(grn.rec_prom[:,:,2],grn_config.substrate_protein)
        affinity_3 = calculate_affinity(grn.rec_prom[:,:,3],grn_config.substrate_protein)
        affinity_4 = calculate_affinity(grn.rec_prom[:,:,4],grn_config.substrate_protein)
    else
        affinity_1 = 1 - exp_config.est_strength
        affinity_2 = 1 - exp_config.est_strength
        affinity_3 = 1 - exp_config.est_strength
        affinity_4 = 1 - exp_config.est_strength
    end

    left_segment = Int.(floor(cell_config.grid_size/3))
    middle_segment = Int.(floor(2*cell_config.grid_size/3))

    est_setup = ESTSetup(affinity_1,affinity_2,affinity_3,affinity_4,left_segment,middle_segment)

    for step in 1:size(results,3)
        
        if step in damage_times
            d_int = Int64.(floor(damage_percentage*size(all_cells,1)))
            damage_pixels = sample(all_cells,d_int,replace = false)
            for dp in damage_pixels
                environment[environment[:,:,1] .== dp,:] .= 0
            end

        end

        results[:,:,step] = environment[:,:,2]

        energies[step] = measure_energy(grn,environment,all_cells,diff_adhesion,target_cell_areas,cell_config,exp_config)
        
        environment_update2!(grn,environment,all_cells,diff_adhesion,target_cell_areas,cell_config,exp_config)
        
        if size(all_cells,1) == 0
            break
        end
        
        cell_mitosis_and_apoptosis!(environment,all_cells,n_div,cell_config)
        
        protein_dynamics!(environment,est_setup,grn,all_cells,target_cell_areas,diffusion_constants,Ax,Ay,dc,
            exp_config,cell_config,grn_config)
        
        for cell in all_cells
            if n_div[cell] > cell_config.max_split     
                target_cell_areas[cell] = 0
            end
        end

    end
end

function run_life_fitness!(time_steps::Int64,environment::Array{Float64,3},
    all_cells::Array{Float64,1},target_cell_areas::Dict{Float64,Float64},n_div::Dict{Float64,Integer},
    grn::NamedTuple,diff_adhesion::Array{Float64,2}, diffusion_constants::Array{Float64,1},
    Ax::Array{Float64,2},Ay::Array{Float64,2},dc::Array{Float64,1},cell_config::CellularConfig,
    exp_config::ExperimentalConfig,grn_config::FGRNConfig)

    if exp_config.est_strength == "evolve"
        affinity_1 = calculate_affinity(grn.rec_prom[:,:,1],grn_config.substrate_protein)
        affinity_2 = calculate_affinity(grn.rec_prom[:,:,2],grn_config.substrate_protein)
        affinity_3 = calculate_affinity(grn.rec_prom[:,:,3],grn_config.substrate_protein)
        affinity_4 = calculate_affinity(grn.rec_prom[:,:,4],grn_config.substrate_protein)
    else
        affinity_1 = 1 - exp_config.est_strength
        affinity_2 = 1 - exp_config.est_strength
        affinity_3 = 1 - exp_config.est_strength
        affinity_4 = 1 - exp_config.est_strength
    end

    left_segment = Int.(floor(cell_config.grid_size/3))
    middle_segment = Int.(floor(2*cell_config.grid_size/3))

    est_setup = ESTSetup(affinity_1,affinity_2,affinity_3,affinity_4,left_segment,middle_segment)

    for step in 1:time_steps
        
        environment_update2!(grn,environment,all_cells,diff_adhesion,target_cell_areas,cell_config,exp_config)
        
        if size(all_cells,1) == 0
            break
        end
        
        cell_mitosis_and_apoptosis!(environment,all_cells,n_div,cell_config)
        
        protein_dynamics!(environment,est_setup,grn,all_cells,target_cell_areas,diffusion_constants,Ax,Ay,dc,
            exp_config,cell_config,grn_config)
        
        for cell in all_cells
            if n_div[cell] > cell_config.max_split      
                target_cell_areas[cell] = 0
            end
        end

    end
end  