Ejemplo n.º 1
0
def test_connect(trans_costs, capacity, gid, trans_table):
    """
    Test connection to transmission lines and load centers
    """
    tf = TF(trans_table, **trans_costs)
    avail_cap = tf[gid].get('avail_cap', None)
    if avail_cap is not None:
        if avail_cap > capacity:
            assert tf.connect(gid, capacity, apply=False)
Ejemplo n.º 2
0
def test_cost_calculation(i, trans_costs, distance, gid, trans_table):
    """
    Test tranmission capital cost calculation
    """
    tf = TF(trans_table, **trans_costs)
    true_cost = COSTS['{}-{}-{}'.format(i, distance, gid)]
    trans_cost = tf.cost(gid, distance)

    assert true_cost == trans_cost
Ejemplo n.º 3
0
def test_substation_connect(trans_table):
    """
    Test connection to substation
    """
    capacity = 350
    gid = 68867
    tf = TF(trans_table, **TRANS_COSTS_1, line_limited=False)
    assert tf.connect(gid, capacity, apply=False)

    tf = TF(trans_table, **TRANS_COSTS_1, line_limited=True)
    assert not tf.connect(gid, capacity, apply=False)
Ejemplo n.º 4
0
    def _create_handler(trans_table, trans_costs=None):
        """
        Create TransmissionFeatures handler from supply curve transmission
        mapping table.  Update connection costs if given.

        Parameters
        ----------
        trans_table : str | pandas.DataFrame
            Path to .csv or .json or DataFrame containing supply curve
            transmission mapping
        trans_costs : str | dict
            Transmission feature costs to use with TransmissionFeatures
            handler: line_tie_in_cost, line_cost, station_tie_in_cost,
            center_tie_in_cost, sink_tie_in_cost

        Returns
        -------
        trans_features : TransmissionFeatures
            TransmissionFeatures or TransmissionCosts instance initilized
            with specified transmission costs
        """
        if trans_costs is not None:
            kwargs = TF._parse_dictionary(trans_costs)
        else:
            kwargs = {}

        trans_features = TF(trans_table, **kwargs)

        return trans_features
Ejemplo n.º 5
0
    def _feature_capacity(trans_table, trans_costs=None):
        """
        Add the transmission connection feature capacity to the trans table.

        Parameters
        ----------
        trans_table : pd.DataFrame
            Table mapping supply curve points to transmission features
        trans_costs : str | dict
            Transmission feature costs to use with TransmissionFeatures
            handler: line_tie_in_cost, line_cost, station_tie_in_cost,
            center_tie_in_cost, sink_tie_in_cost

        Returns
        -------
        trans_table : pd.DataFrame
            Table mapping supply curve points to transmission features with
            'avail_cap' column.
        """
        avc = 0.1
        if trans_costs is not None:
            if 'available_capacity' in trans_costs:
                avc = trans_costs['available_capacity']

        feature_cap = TF.feature_capacity(trans_table, available_capacity=avc)
        dtype = trans_table['trans_line_gid'].dtype
        feature_cap['trans_line_gid'] = \
            feature_cap['trans_line_gid'].astype(dtype)
        trans_table = trans_table.merge(feature_cap, on='trans_line_gid')

        return trans_table
Ejemplo n.º 6
0
def test_substation_load_spreading(i, trans_costs, trans_table):
    """
    Test load spreading on connection to substation
    """
    capacity = 350
    gid = 68867
    tf = TF(trans_table, **trans_costs)
    connect = tf.connect(gid, capacity, apply=True)
    assert connect

    line_gids = tf[gid]['lines']
    missing = [gid for gid in line_gids if gid not in LINE_CAPS[i]]

    assert not any(missing), 'New gids not in baseline: {}'.format(missing)
    for line_id in line_gids:
        msg = 'Bad line cap: {}'.format(line_id)
        assert LINE_CAPS[i][line_id] == tf[line_id]['avail_cap'], msg
Ejemplo n.º 7
0
    def fix_missing_dependencies(self, condf, linedf, scdf, simple=False):
        """Check for and find fix missing feature line dependencies.

        Parameters
        ----------
        condf: pd.core.frame.DataFrame
            Data frame of supply curve point to transmission line connections.
        linedf:  pd.core.frame.DataFrame
            Data frame of transmission line features.

        Returns
        -------
        pd.core.frame.DataFrame
            The same data frame with added entries if missing line
            dependencies were found.
        """

        # This requires an extra function
        def find_point(row, scdf):
            """Find the closest supply curve point to a line."""
            # Find all distances to this line
            line = row["geometry"]
            scdists = [point.distance(line) for point in scdf["geometry"]]

            # Find the closest point from the distances
            dist_m = np.min(scdists)
            point_idx = np.where(scdists == dist_m)[0][0]
            point_row = scdf.iloc[point_idx]

            # These have different field names
            fields = {
                "sc_point_gid": "sc_point_gid",
                "sc_row_ind": "sc_point_row_id",
                "sc_col_ind": "sc_point_col_id"
            }

            # We need that points identifiers
            for key, field in fields.items():
                row[field] = point_row[key]

            # Finally add in distance in miles
            row["dist_mi"] = dist_m / 1609.34

            # We only need these fields
            keepers = [
                'ac_cap', 'cap_left', 'category', 'trans_gids',
                'trans_line_gid', 'dist_mi', 'sc_point_gid', 'sc_point_row_id',
                'sc_point_col_id'
            ]
            row = row[keepers]

            return row

        # Get missings dependencies - catching error
        from reV.handlers.transmission import TransmissionFeatures

        missing_dependencies = []
        try:
            TransmissionFeatures(condf)._check_feature_dependencies()
        except RuntimeError as e:
            error = str(e)
            missing_str = error[error.index("dependencies:") + 14:]
            missing_dict = ast.literal_eval(missing_str)
            for gids in missing_dict.values():
                for gid in gids:
                    missing_dependencies.append(gid)

        # Find those features and reformat
        mdf = linedf[linedf["gid"].isin(missing_dependencies)]
        mdf = mdf.replace("null", np.nan)
        mdf = mdf.apply(find_point, scdf=scdf, axis=1)

        # Append these to the table
        condf = pd.concat([condf, mdf])

        return condf
Ejemplo n.º 8
0
    def _compute_lcot(trans_table, fcr, trans_costs=None, max_workers=None,
                      connectable=True, line_limited=False):
        """
        Compute levelized cost of transmission for all combinations of
        supply curve points and tranmission features in trans_table

        Parameters
        ----------
        trans_table : pd.DataFrame
            Table mapping supply curve points to transmission features
            MUST contain supply curve point capacity
        fcr : float
            Fixed charge rate needed to compute LCOT
        trans_costs : str | dict
            Transmission feature costs to use with TransmissionFeatures
            handler: line_tie_in_cost, line_cost, station_tie_in_cost,
            center_tie_in_cost, sink_tie_in_cost
        max_workers : int | NoneType
            Number of workers to use to compute lcot, if > 1 run in parallel.
            None uses all available cpu's.
        connectable : bool
            Determine if connection is possible
        line_limited : bool
            Substation connection is limited by maximum capacity of the
            attached lines, legacy method

        Returns
        -------
        lcot : list
            Levelized cost of transmission for all supply curve -
            tranmission feature connections
        cost : list
            Capital cost of tramsmission for all supply curve - transmission
            feature connections
        """
        if 'capacity' not in trans_table:
            raise SupplyCurveInputError('Supply curve table must have '
                                        'supply curve point capacity '
                                        'to compute lcot')

        if trans_costs is not None:
            trans_costs = TF._parse_dictionary(trans_costs)
        else:
            trans_costs = {}

        if max_workers is None:
            max_workers = os.cpu_count()

        gid_mask = ~pd.isna(trans_table['sc_gid'])

        logger.info('Computing LCOT costs for all possible connections...')
        if max_workers > 1:
            groups = trans_table[gid_mask].groupby('sc_gid')
            loggers = [__name__, 'reV.handlers.transmission']
            with SpawnProcessPool(max_workers=max_workers,
                                  loggers=loggers) as exe:
                futures = []
                for sc_gid, sc_table in groups:
                    if connectable:
                        capacity = sc_table['capacity'].unique()
                        if len(capacity) == 1:
                            capacity = capacity[0]
                        else:
                            msg = ('Each supply curve point should only have '
                                   'a single capacity, but {} has {}'
                                   .format(sc_gid, capacity))
                            logger.error(msg)
                            raise RuntimeError(msg)
                    else:
                        capacity = None

                    futures.append(exe.submit(TC.feature_costs, sc_table,
                                              capacity=capacity,
                                              line_limited=line_limited,
                                              **trans_costs))

                cost = [future.result() for future in futures]
                cost = np.hstack(cost)
        else:
            feature = TC(trans_table, line_limited=line_limited,
                         **trans_costs)
            cost = []
            for _, row in trans_table[gid_mask].iterrows():
                if connectable:
                    capacity = row['capacity']
                else:
                    capacity = None

                tm = row.get('transmission_multiplier', 1)
                cost.append(feature.cost(row['trans_line_gid'], row['dist_mi'],
                                         capacity=capacity,
                                         transmission_multiplier=tm))

            cost = np.array(cost, dtype='float32')

        cf_mean_arr = trans_table.loc[gid_mask, 'mean_cf'].values
        lcot = (cost * fcr) / (cf_mean_arr * 8760)

        logger.info('LCOT cost calculation is complete.')

        return lcot, cost