<gh_stars>1-10
import numpy as np
import pvlib.pvsystem as pvsyst
import interconnection as connect
import matplotlib.pyplot as plt


def calculate_reverse_scaling_factor(voltages, breakdown_voltage, miller_exponent):
    """
    :param voltages: numpy array of voltages
    :param breakdown_voltage: the minimum voltage before the avelanche breakdown happens
    :param miller_exponent: --> google
    :return: numpy array of according factors
    """
    reverse_scaling_factor = np.reciprocal(1. - np.power((np.absolute(voltages) / -breakdown_voltage), miller_exponent))
    return reverse_scaling_factor


def calculate_sub_cell_characteristics(irrad_on_subcells, evaluated_cell_voltages, num_subcells,
                                       reverse_scaling_factor, irrad_temp_lookup_np, t_ambient, irrad_noct, t_noct,
                                       t_a_noct, alpha_short_current, module_params, egap_ev, round_irrad_to_ten):
    """

    :param irrad_on_subcells: 
    :param evaluated_voltages: 
    :param numcells: 
    :param irrad_temp_lookup_df: 
    :param irrad_noct: 
    :param t_noct: 
    :param t_a_noct: 
    :param alpha_short_current: 
    :param module_params: 
    :param egap_ev: 
    :return:    subcell_v_values: List of np arrays where a list of v-values is stored for every cell
                subcell_i_values,:List of np arrays where a list of v-values is stored for every cell
    """

    subcell_i_values = np.empty((len(irrad_on_subcells), len(
        evaluated_cell_voltages)))  # List of lists where a list of i-values is stored for every subcell
    subcell_v_values = np.empty((len(irrad_on_subcells), len(
        evaluated_cell_voltages)))  # List of lists where a list of v-values is stored for every cell, basically the same as for cells

    irrad_on_subcells_np = np.array(irrad_on_subcells)  # Take this out of the function
    sub_cell_irrad_np = np.rint(irrad_on_subcells_np).astype(int)  # Take this out of the function
    t_ambient = int(t_ambient)  # Take this out of the function

    temperature_row = irrad_temp_lookup_np[t_ambient + 25]  # +25 because row on is at -25Celsius

    for position, irradiance_value in np.ndenumerate(sub_cell_irrad_np):

        if round_irrad_to_ten == True:
            irradiance_value_lookup=irradiance_value/10
        else:
            irradiance_value_lookup = irradiance_value

        if not (temperature_row[irradiance_value_lookup,0,0] != temperature_row[irradiance_value_lookup,0,0]):  # Checks for NaNs
            subcell_i_values[position] = temperature_row[irradiance_value_lookup][0]  # should collect a numpy array
            subcell_v_values[position] = temperature_row[irradiance_value_lookup][1]  # should collect a numpy array

        else:
            if irradiance_value == 0:
                irradiance_value = 1

            t_cell = float(t_ambient) + float(irradiance_value) / irrad_noct * (t_noct - t_a_noct)  # t_cell in deg C
            desoto_values = pvsyst.calcparams_desoto(irradiance_value, t_cell, alpha_short_current, module_params,
                                                     egap_ev, 0.0001, 1, 1000, 25)
            # calcparams_desoto takes the temperature in degrees Celsius!
            photocurrent = desoto_values[0]  # [A]
            sat_current = desoto_values[1]  # [A]
            series_resistance = desoto_values[2]  # [Ohm]
            shunt_resistance = desoto_values[3]  # [Ohm]
            nnsvth = desoto_values[4]
            evaluated_module_voltages = evaluated_cell_voltages*56

            # Basic assumption here: Module IV-curve can be converted to a cell IV-curve by dividing the module voltage
            # by the number of cells further the subcell current is calculated by dividing currents by the number of
            # subcells.
            evaluated_currents = pvsyst.i_from_v(shunt_resistance, series_resistance, nnsvth,
                                                         evaluated_module_voltages, sat_current, photocurrent)


            subcell_v_values[position] = evaluated_cell_voltages  # Save for later use

            # calculate the subcell forward and reverse characteristc
            subcell_current = np.multiply(evaluated_currents, reverse_scaling_factor) / num_subcells  # Numpy array

            subcell_i_values[position] = subcell_current  # Save for later use
            irrad_temp_lookup_np[t_ambient + 25][irradiance_value_lookup] = [subcell_current, evaluated_cell_voltages]

        # plt.plot(subcell_v_values[position],subcell_i_values[position])
        # plt.show()

    return subcell_i_values, subcell_v_values


def sub_cells_2_cells(subcell_i_values, num_subcells):
    """
    :param subcell_i_values:  numpy array
    :param num_subcells: 
    :return: cell_i_values, numpy array
    simple reshaping can be used, because the subcell v values all have the same basis
    """
    cell_i_values = subcell_i_values.reshape((-1, num_subcells, len(subcell_i_values[0]))).sum(axis=1)
    return cell_i_values


def cells2substrings(cell_v_values_np, cell_i_values_np, cells_per_substring, number_of_substrings, max_i_module,
                     min_i_module, interpolation_resolution_submodules):
    """
    :param cell_v_values_np: numpy array of cell voltage values [[cell1values][cell2values] etc]
    :param cell_i_values_np: numpy array of cell current values [[cell1values][cell2values] etc]
    :param cells_per_substring: int, this value represents how many cells are in a substring = number of cells per 
            bypass diode
    :param number_of_substrings: int, here equal to number of bypass diodes 
    :param max_i_module: this is the maximum expected current in the module. Setting a value close above Isc prevents
            having huge unnecessary interpolations when connecting the cells.
    :param min_i_module: zero can be used as long as cells are not connected in parallel to other cells
    :return: returns numpy dtype object array with i and v values for each substring/submodule
    """
    i_connected_np = np.empty(number_of_substrings, dtype=object)
    v_connected_np = np.empty(number_of_substrings, dtype=object)

    for substring in range(number_of_substrings):  # iterate through all the substrings by number

        substring_v_values_np = cell_v_values_np[substring * cells_per_substring:(substring + 1) * cells_per_substring]
        substring_i_values_np = cell_i_values_np[substring * cells_per_substring:(substring + 1) * cells_per_substring]
        i_connected_np[substring], v_connected_np[substring] = connect.series_connect_multiple(substring_i_values_np,
                                                                                       substring_v_values_np,
                                                                                       max_i_module, min_i_module,
                                                                                    interpolation_resolution_submodules)
    return i_connected_np, v_connected_np


def bypass_diodes_on_substrings(substring_i_values_np, substring_v_values_np, number_of_substrings,
                                diode_saturation_current=1.0e-7, n_x_Vt=1.7e-2, numerical_diode_threshold=-1):
    """
    :param substring_i_values: numpy array dtype object
    :param substring_v_values: numpy array dtype object
    :param number_of_substrings: int, here equal to number of bypass diodes 
    :param diode_saturation_current: float, the saturation current of the modelled diode
    :param n_x_Vt: float, thermal voltage multiplied by the diode ideality factor
    :param numerical_diode_threshold: this is a value to speed up the calculation by not taking any values into account
            below this voltage and thereby not causing any overflow errors.
    :return: returns the parallel addition of the bypass diodes and the substring currents
    """

    diode_current = np.empty(number_of_substrings, dtype=object)  # List of np ndarrays for the current of each diode

    for substring in range(number_of_substrings):
        # Do diode calculations diode_current = 1.e-7*np.exp(-voltage_selected/1.7e-2) Where from??
        # diode_steps = np.empty(len(substring_v_values[substring]))

        substring_v_values_np[substring][substring_v_values_np[substring] < numerical_diode_threshold] = numerical_diode_threshold
        diode_steps = diode_saturation_current * np.exp(-substring_v_values_np[substring] / n_x_Vt)
        diode_current[substring]=diode_steps

    for substring in range(number_of_substrings):
        substring_i_values_np[substring] = np.add(substring_i_values_np[substring], diode_current[substring])

    return substring_i_values_np


def partial_shading(irrad_on_subcells, temperature=25, irrad_temp_lookup_np=None,
                    breakdown_voltage=-6.10, evaluated_module_voltages=None, simulation_parameters=None,
                    module_params=None):
    """
    This function returns the module IV curve of a module under any partial shading conditions or unequal irradiance.
    :param irrad_on_subcells: list, list of all irradiance values on the specific module (for one specific hour) make
                                sure that the dimensions of this list equals the number of cells or subcells that are
                                used for the module. E.G number of cells = 56, num_subcells=4 --> list length = 274
    :param temperature: float, Ambient temperature value for the given hour
    :param irrad_temp_lookup_df: 
    :param module_df: 
    :param module_name: 
    :param numcells: 
    :param n_bypass_diodes: 
    :param num_subcells: 
    :param vmax: 
    :param v_threshold: 
    :param breakdown_voltage: 
    :return: 
    """

    # Definition of constants, these are defined in hardcode because they are fixed:
    t_a_noct = 20  # [a,NOCT]
    irrad_noct = 800  # [W/m2]
    egap_ev = 1.12  # Band gap energy [eV]
    miller_exponent = 3  # This is set


    #For now here, change to parameters:
    max_i_module = module_params["max_module_current"]  # [A]
    min_i_module = module_params["min_module_current"] # [A], min value of interpolation in series connect
    n_bypass_diodes = module_params["number_of_bypass_diodes"]
    numcells = module_params["number_of_cells"]
    num_subcells = module_params["number_of_subcells"]
    alpha_short_current = module_params['alpha_short_current']
    t_noct = module_params['t_noct']

    interpolation_resolution_submodules = simulation_parameters["interpolation_resolution_submodules"]  # [A]
    interpolation_resolution_module = simulation_parameters["interpolation_resolution_module"]  # [A]
    final_module_iv_resolution = simulation_parameters["final_module_iv_resolution"]  # [A] or [V] counts for both dimensions
    round_irrad_to_ten = simulation_parameters["round_irradiance_to_ten"]



    if n_bypass_diodes > 0:
        cells_per_substring = numcells / n_bypass_diodes
    else:
        cells_per_substring = numcells

    if cells_per_substring % 1 != 0:
        print "WARNING: Number of bypass diodes or number of cells is wrong."
    else:
        pass

    # Rearrange irrad_on_subcells
    irrad_on_subcells = connect.rearrange_shading_pattern_miasole(irrad_on_subcells, num_subcells)

    evaluated_cell_voltages = evaluated_module_voltages / numcells  # Only divide by the number of cells

    reverse_scaling_factor = calculate_reverse_scaling_factor(evaluated_cell_voltages, breakdown_voltage, miller_exponent)

    t_ambient = temperature  # degC, if measured, use data here

    # Calculate sub_cell characteristic
    subcell_i_values, subcell_v_values = calculate_sub_cell_characteristics(irrad_on_subcells=irrad_on_subcells,
                                                                            evaluated_cell_voltages=evaluated_cell_voltages,
                                                                            num_subcells=num_subcells,
                                                                            reverse_scaling_factor=reverse_scaling_factor,
                                                                            irrad_temp_lookup_np=irrad_temp_lookup_np,
                                                                            t_ambient=t_ambient,
                                                                            irrad_noct=irrad_noct,
                                                                            t_noct=t_noct, t_a_noct=t_a_noct,
                                                                            alpha_short_current=alpha_short_current,
                                                                            module_params=module_params,
                                                                            egap_ev=egap_ev,
                                                                            round_irrad_to_ten=round_irrad_to_ten)


    # Calculate cell characteristics
    cell_i_values_np = sub_cells_2_cells(subcell_i_values, num_subcells)
    cell_v_values_np = np.tile(evaluated_cell_voltages, (numcells, 1))


    # Calculate basic substring characteristics
    i_connected_np, v_connected_np = cells2substrings(cell_v_values_np, cell_i_values_np, cells_per_substring,
                                                      n_bypass_diodes, max_i_module, min_i_module,
                                                      interpolation_resolution_submodules)

    # add bypass diode to sub_strings

    i_connected_np = bypass_diodes_on_substrings(substring_i_values_np=i_connected_np,
                                                 substring_v_values_np=v_connected_np,
                                                 number_of_substrings=n_bypass_diodes)

    # add sub_module voltages:

    i_module, v_module = connect.series_connect_multiple(i_connected_np, v_connected_np, max_i_module, min_i_module,
                                                         interpolation_resolution_module)

    i_module, v_module = connect.clean_curve([i_module, v_module], final_module_iv_resolution)


    # print len(v_module)
    # plt.plot(v_module, i_module)
    # plt.show()

    return i_module, v_module, irrad_temp_lookup_np




import numpy as np
import pvlib.pvsystem as pvsyst
import interconnection as connect
import matplotlib.pyplot as plt


def calculate_reverse_scaling_factor(voltages, breakdown_voltage, miller_exponent):
    """
    :param voltages: numpy array of voltages
    :param breakdown_voltage: the minimum voltage before the avelanche breakdown happens
    :param miller_exponent: --> google
    :return: numpy array of according factors
    """
    reverse_scaling_factor = np.reciprocal(1. - np.power((np.absolute(voltages) / -breakdown_voltage), miller_exponent))
    return reverse_scaling_factor


def calculate_sub_cell_characteristics(irrad_on_subcells, evaluated_cell_voltages, num_subcells,
                                       reverse_scaling_factor, irrad_temp_lookup_np, t_ambient, irrad_noct, t_noct,
                                       t_a_noct, alpha_short_current, module_params, egap_ev, round_irrad_to_ten):
    """

    :param irrad_on_subcells: 
    :param evaluated_voltages: 
    :param numcells: 
    :param irrad_temp_lookup_df: 
    :param irrad_noct: 
    :param t_noct: 
    :param t_a_noct: 
    :param alpha_short_current: 
    :param module_params: 
    :param egap_ev: 
    :return:    subcell_v_values: List of np arrays where a list of v-values is stored for every cell
                subcell_i_values,:List of np arrays where a list of v-values is stored for every cell
    """

    subcell_i_values = np.empty((len(irrad_on_subcells), len(
        evaluated_cell_voltages)))  # List of lists where a list of i-values is stored for every subcell
    subcell_v_values = np.empty((len(irrad_on_subcells), len(
        evaluated_cell_voltages)))  # List of lists where a list of v-values is stored for every cell, basically the same as for cells

    irrad_on_subcells_np = np.array(irrad_on_subcells)  # Take this out of the function
    sub_cell_irrad_np = np.rint(irrad_on_subcells_np).astype(int)  # Take this out of the function
    t_ambient = int(t_ambient)  # Take this out of the function

    temperature_row = irrad_temp_lookup_np[t_ambient + 25]  # +25 because row on is at -25Celsius

    for position, irradiance_value in np.ndenumerate(sub_cell_irrad_np):

        if round_irrad_to_ten == True:
            irradiance_value_lookup=irradiance_value/10
        else:
            irradiance_value_lookup = irradiance_value

        if not (temperature_row[irradiance_value_lookup,0,0] != temperature_row[irradiance_value_lookup,0,0]):  # Checks for NaNs
            subcell_i_values[position] = temperature_row[irradiance_value_lookup][0]  # should collect a numpy array
            subcell_v_values[position] = temperature_row[irradiance_value_lookup][1]  # should collect a numpy array

        else:
            if irradiance_value == 0:
                irradiance_value = 1

            t_cell = float(t_ambient) + float(irradiance_value) / irrad_noct * (t_noct - t_a_noct)  # t_cell in deg C
            desoto_values = pvsyst.calcparams_desoto(irradiance_value, t_cell, alpha_short_current, module_params,
                                                     egap_ev, 0.0001, 1, 1000, 25)
            # calcparams_desoto takes the temperature in degrees Celsius!
            photocurrent = desoto_values[0]  # [A]
            sat_current = desoto_values[1]  # [A]
            series_resistance = desoto_values[2]  # [Ohm]
            shunt_resistance = desoto_values[3]  # [Ohm]
            nnsvth = desoto_values[4]
            evaluated_module_voltages = evaluated_cell_voltages*56

            # Basic assumption here: Module IV-curve can be converted to a cell IV-curve by dividing the module voltage
            # by the number of cells further the subcell current is calculated by dividing currents by the number of
            # subcells.
            evaluated_currents = pvsyst.i_from_v(shunt_resistance, series_resistance, nnsvth,
                                                         evaluated_module_voltages, sat_current, photocurrent)


            subcell_v_values[position] = evaluated_cell_voltages  # Save for later use

            # calculate the subcell forward and reverse characteristc
            subcell_current = np.multiply(evaluated_currents, reverse_scaling_factor) / num_subcells  # Numpy array

            subcell_i_values[position] = subcell_current  # Save for later use
            irrad_temp_lookup_np[t_ambient + 25][irradiance_value_lookup] = [subcell_current, evaluated_cell_voltages]

        # plt.plot(subcell_v_values[position],subcell_i_values[position])
        # plt.show()

    return subcell_i_values, subcell_v_values


def sub_cells_2_cells(subcell_i_values, num_subcells):
    """
    :param subcell_i_values:  numpy array
    :param num_subcells: 
    :return: cell_i_values, numpy array
    simple reshaping can be used, because the subcell v values all have the same basis
    """
    cell_i_values = subcell_i_values.reshape((-1, num_subcells, len(subcell_i_values[0]))).sum(axis=1)
    return cell_i_values


def cells2substrings(cell_v_values_np, cell_i_values_np, cells_per_substring, number_of_substrings, max_i_module,
                     min_i_module, interpolation_resolution_submodules):
    """
    :param cell_v_values_np: numpy array of cell voltage values [[cell1values][cell2values] etc]
    :param cell_i_values_np: numpy array of cell current values [[cell1values][cell2values] etc]
    :param cells_per_substring: int, this value represents how many cells are in a substring = number of cells per 
            bypass diode
    :param number_of_substrings: int, here equal to number of bypass diodes 
    :param max_i_module: this is the maximum expected current in the module. Setting a value close above Isc prevents
            having huge unnecessary interpolations when connecting the cells.
    :param min_i_module: zero can be used as long as cells are not connected in parallel to other cells
    :return: returns numpy dtype object array with i and v values for each substring/submodule
    """
    i_connected_np = np.empty(number_of_substrings, dtype=object)
    v_connected_np = np.empty(number_of_substrings, dtype=object)

    for substring in range(number_of_substrings):  # iterate through all the substrings by number

        substring_v_values_np = cell_v_values_np[substring * cells_per_substring:(substring + 1) * cells_per_substring]
        substring_i_values_np = cell_i_values_np[substring * cells_per_substring:(substring + 1) * cells_per_substring]
        i_connected_np[substring], v_connected_np[substring] = connect.series_connect_multiple(substring_i_values_np,
                                                                                       substring_v_values_np,
                                                                                       max_i_module, min_i_module,
                                                                                    interpolation_resolution_submodules)
    return i_connected_np, v_connected_np


def bypass_diodes_on_substrings(substring_i_values_np, substring_v_values_np, number_of_substrings,
                                diode_saturation_current=1.0e-7, n_x_Vt=1.7e-2, numerical_diode_threshold=-1):
    """
    :param substring_i_values: numpy array dtype object
    :param substring_v_values: numpy array dtype object
    :param number_of_substrings: int, here equal to number of bypass diodes 
    :param diode_saturation_current: float, the saturation current of the modelled diode
    :param n_x_Vt: float, thermal voltage multiplied by the diode ideality factor
    :param numerical_diode_threshold: this is a value to speed up the calculation by not taking any values into account
            below this voltage and thereby not causing any overflow errors.
    :return: returns the parallel addition of the bypass diodes and the substring currents
    """

    diode_current = np.empty(number_of_substrings, dtype=object)  # List of np ndarrays for the current of each diode

    for substring in range(number_of_substrings):
        # Do diode calculations diode_current = 1.e-7*np.exp(-voltage_selected/1.7e-2) Where from??
        # diode_steps = np.empty(len(substring_v_values[substring]))

        substring_v_values_np[substring][substring_v_values_np[substring] < numerical_diode_threshold] = numerical_diode_threshold
        diode_steps = diode_saturation_current * np.exp(-substring_v_values_np[substring] / n_x_Vt)
        diode_current[substring]=diode_steps

    for substring in range(number_of_substrings):
        substring_i_values_np[substring] = np.add(substring_i_values_np[substring], diode_current[substring])

    return substring_i_values_np


def partial_shading(irrad_on_subcells, temperature=25, irrad_temp_lookup_np=None,
                    breakdown_voltage=-6.10, evaluated_module_voltages=None, simulation_parameters=None,
                    module_params=None):
    """
    This function returns the module IV curve of a module under any partial shading conditions or unequal irradiance.
    :param irrad_on_subcells: list, list of all irradiance values on the specific module (for one specific hour) make
                                sure that the dimensions of this list equals the number of cells or subcells that are
                                used for the module. E.G number of cells = 56, num_subcells=4 --> list length = 274
    :param temperature: float, Ambient temperature value for the given hour
    :param irrad_temp_lookup_df: 
    :param module_df: 
    :param module_name: 
    :param numcells: 
    :param n_bypass_diodes: 
    :param num_subcells: 
    :param vmax: 
    :param v_threshold: 
    :param breakdown_voltage: 
    :return: 
    """

    # Definition of constants, these are defined in hardcode because they are fixed:
    t_a_noct = 20  # [a,NOCT]
    irrad_noct = 800  # [W/m2]
    egap_ev = 1.12  # Band gap energy [eV]
    miller_exponent = 3  # This is set


    #For now here, change to parameters:
    max_i_module = module_params["max_module_current"]  # [A]
    min_i_module = module_params["min_module_current"] # [A], min value of interpolation in series connect
    n_bypass_diodes = module_params["number_of_bypass_diodes"]
    numcells = module_params["number_of_cells"]
    num_subcells = module_params["number_of_subcells"]
    alpha_short_current = module_params['alpha_short_current']
    t_noct = module_params['t_noct']

    interpolation_resolution_submodules = simulation_parameters["interpolation_resolution_submodules"]  # [A]
    interpolation_resolution_module = simulation_parameters["interpolation_resolution_module"]  # [A]
    final_module_iv_resolution = simulation_parameters["final_module_iv_resolution"]  # [A] or [V] counts for both dimensions
    round_irrad_to_ten = simulation_parameters["round_irradiance_to_ten"]



    if n_bypass_diodes > 0:
        cells_per_substring = numcells / n_bypass_diodes
    else:
        cells_per_substring = numcells

    if cells_per_substring % 1 != 0:
        print "WARNING: Number of bypass diodes or number of cells is wrong."
    else:
        pass

    # Rearrange irrad_on_subcells
    irrad_on_subcells = connect.rearrange_shading_pattern_miasole(irrad_on_subcells, num_subcells)

    evaluated_cell_voltages = evaluated_module_voltages / numcells  # Only divide by the number of cells

    reverse_scaling_factor = calculate_reverse_scaling_factor(evaluated_cell_voltages, breakdown_voltage, miller_exponent)

    t_ambient = temperature  # degC, if measured, use data here

    # Calculate sub_cell characteristic
    subcell_i_values, subcell_v_values = calculate_sub_cell_characteristics(irrad_on_subcells=irrad_on_subcells,
                                                                            evaluated_cell_voltages=evaluated_cell_voltages,
                                                                            num_subcells=num_subcells,
                                                                            reverse_scaling_factor=reverse_scaling_factor,
                                                                            irrad_temp_lookup_np=irrad_temp_lookup_np,
                                                                            t_ambient=t_ambient,
                                                                            irrad_noct=irrad_noct,
                                                                            t_noct=t_noct, t_a_noct=t_a_noct,
                                                                            alpha_short_current=alpha_short_current,
                                                                            module_params=module_params,
                                                                            egap_ev=egap_ev,
                                                                            round_irrad_to_ten=round_irrad_to_ten)


    # Calculate cell characteristics
    cell_i_values_np = sub_cells_2_cells(subcell_i_values, num_subcells)
    cell_v_values_np = np.tile(evaluated_cell_voltages, (numcells, 1))


    # Calculate basic substring characteristics
    i_connected_np, v_connected_np = cells2substrings(cell_v_values_np, cell_i_values_np, cells_per_substring,
                                                      n_bypass_diodes, max_i_module, min_i_module,
                                                      interpolation_resolution_submodules)

    # add bypass diode to sub_strings

    i_connected_np = bypass_diodes_on_substrings(substring_i_values_np=i_connected_np,
                                                 substring_v_values_np=v_connected_np,
                                                 number_of_substrings=n_bypass_diodes)

    # add sub_module voltages:

    i_module, v_module = connect.series_connect_multiple(i_connected_np, v_connected_np, max_i_module, min_i_module,
                                                         interpolation_resolution_module)

    i_module, v_module = connect.clean_curve([i_module, v_module], final_module_iv_resolution)


    # print len(v_module)
    # plt.plot(v_module, i_module)
    # plt.show()

    return i_module, v_module, irrad_temp_lookup_np
:param voltages: numpy array of voltages     :param breakdown_voltage: the minimum voltage before the avelanche breakdown happens     :param miller_exponent: --> google     :return: numpy array of according factors :param irrad_on_subcells:      :param evaluated_voltages:      :param numcells:      :param irrad_temp_lookup_df:      :param irrad_noct:      :param t_noct:      :param t_a_noct:      :param alpha_short_current:      :param module_params:      :param egap_ev:      :return:    subcell_v_values: List of np arrays where a list of v-values is stored for every cell                 subcell_i_values,:List of np arrays where a list of v-values is stored for every cell # List of lists where a list of i-values is stored for every subcell # List of lists where a list of v-values is stored for every cell, basically the same as for cells # Take this out of the function # Take this out of the function # Take this out of the function # +25 because row on is at -25Celsius # Checks for NaNs # should collect a numpy array # should collect a numpy array # t_cell in deg C # calcparams_desoto takes the temperature in degrees Celsius! # [A] # [A] # [Ohm] # [Ohm] # Basic assumption here: Module IV-curve can be converted to a cell IV-curve by dividing the module voltage # by the number of cells further the subcell current is calculated by dividing currents by the number of # subcells. # Save for later use # calculate the subcell forward and reverse characteristc # Numpy array # Save for later use # plt.plot(subcell_v_values[position],subcell_i_values[position]) # plt.show() :param subcell_i_values:  numpy array     :param num_subcells:      :return: cell_i_values, numpy array     simple reshaping can be used, because the subcell v values all have the same basis :param cell_v_values_np: numpy array of cell voltage values [[cell1values][cell2values] etc]     :param cell_i_values_np: numpy array of cell current values [[cell1values][cell2values] etc]     :param cells_per_substring: int, this value represents how many cells are in a substring = number of cells per              bypass diode     :param number_of_substrings: int, here equal to number of bypass diodes      :param max_i_module: this is the maximum expected current in the module. Setting a value close above Isc prevents             having huge unnecessary interpolations when connecting the cells.     :param min_i_module: zero can be used as long as cells are not connected in parallel to other cells     :return: returns numpy dtype object array with i and v values for each substring/submodule # iterate through all the substrings by number :param substring_i_values: numpy array dtype object     :param substring_v_values: numpy array dtype object     :param number_of_substrings: int, here equal to number of bypass diodes      :param diode_saturation_current: float, the saturation current of the modelled diode     :param n_x_Vt: float, thermal voltage multiplied by the diode ideality factor     :param numerical_diode_threshold: this is a value to speed up the calculation by not taking any values into account             below this voltage and thereby not causing any overflow errors.     :return: returns the parallel addition of the bypass diodes and the substring currents # List of np ndarrays for the current of each diode # Do diode calculations diode_current = 1.e-7*np.exp(-voltage_selected/1.7e-2) Where from?? # diode_steps = np.empty(len(substring_v_values[substring])) This function returns the module IV curve of a module under any partial shading conditions or unequal irradiance.     :param irrad_on_subcells: list, list of all irradiance values on the specific module (for one specific hour) make                                 sure that the dimensions of this list equals the number of cells or subcells that are                                 used for the module. E.G number of cells = 56, num_subcells=4 --> list length = 274     :param temperature: float, Ambient temperature value for the given hour     :param irrad_temp_lookup_df:      :param module_df:      :param module_name:      :param numcells:      :param n_bypass_diodes:      :param num_subcells:      :param vmax:      :param v_threshold:      :param breakdown_voltage:      :return: # Definition of constants, these are defined in hardcode because they are fixed: # [a,NOCT] # [W/m2] # Band gap energy [eV] # This is set #For now here, change to parameters: # [A] # [A], min value of interpolation in series connect # [A] # [A] # [A] or [V] counts for both dimensions # Rearrange irrad_on_subcells # Only divide by the number of cells # degC, if measured, use data here # Calculate sub_cell characteristic # Calculate cell characteristics # Calculate basic substring characteristics # add bypass diode to sub_strings # add sub_module voltages: # print len(v_module) # plt.plot(v_module, i_module) # plt.show()