def test_copy(activity): assert ExchangeDataset.select().count() == 1 assert ActivityDataset.select().count() == 1 cp = activity.copy("baz") assert cp['code'] != activity['code'] assert cp['name'] == 'baz' assert cp['location'] == 'bar' assert ExchangeDataset.select().count() == 2 assert ActivityDataset.select().count() == 2 assert ActivityDataset.select().where( ActivityDataset.code == cp['code'], ActivityDataset.database == cp['database'], ).count() == 1 assert ActivityDataset.select().where( ActivityDataset.code == activity['code'], ActivityDataset.database == activity['database'], ).count() == 1 assert ExchangeDataset.select().where( ExchangeDataset.input_code == cp['code'], ExchangeDataset.input_database == cp['database'], ).count() == 1 assert ExchangeDataset.select().where( ExchangeDataset.input_database == activity['database'], ExchangeDataset.input_code == activity['code'], ).count() == 1
def test_copy_with_kwargs(activity): assert ExchangeDataset.select().count() == 1 assert ActivityDataset.select().count() == 1 cp = activity.copy("baz", location="here", widget="squirt gun") assert cp['code'] != activity['code'] assert cp['name'] == 'baz' assert cp['location'] == 'here' assert cp['widget'] == 'squirt gun' assert ExchangeDataset.select().count() == 2 assert ActivityDataset.select().count() == 2
def select_exchanges_by_database_codes(db_name: str, codes: set): inputs = set(x[0] for x in codes) outputs = set(x[1] for x in codes) query = (ED.select().where((ED.output_database == db_name) & (ED.input_code.in_(inputs)) & (ED.output_code.in_(outputs))).namedtuples()) return query
def select_exchange_data(db_name: str): query = (ED.select(ED.data) .where((ED.output_database == db_name) & (ED.type.in_(["biosphere", "technosphere", "production"]))) .tuples()) data = (x[0] for x in query.iterator()) return data
def find_missing_exchanges(superstruct: set, delta: str) -> Tuple[set, list]: query = (ED.select(ED.input_code, ED.output_code) .where(ED.output_database == delta) .distinct() .tuples()) diff = set(x for x in query.iterator()).difference(superstruct) # Now query again, and create a list of exchanges of the diff. inputs = set(x[0] for x in diff) outputs = set(x[1] for x in diff) query = (ED.select(ED.data) .where((ED.output_database == delta) & (ED.input_code.in_(inputs)) & (ED.output_code.in_(outputs))) .tuples()) diff_list = [x[0] for x in query.iterator()] return diff, diff_list
def exchange_type(self) -> int: exc_type = ExchangeDataset.get( ExchangeDataset.input_code == self.input.code, ExchangeDataset.input_database == self.input.database, ExchangeDataset.output_code == self.output.code, ExchangeDataset.output_database == self.output.database).type return TYPE_DICTIONARY.get(exc_type, -1)
def select_exchanges_from_database(db_name: str, as_namedtuples: bool = True) -> BaseQuery: query = (ExchangeDataset.select().where( ExchangeDataset.output_database == db_name)) if as_namedtuples: query = query.namedtuples() return query
def extract_brightway2_databases(database_names): """Extract a Brightway2 SQLiteBackend database to the Wurst internal format. ``database_names`` is a list of database names. You should already be in the correct project. Returns a list of dataset documents.""" ERROR = "Must pass list of database names" assert isinstance(database_names, (list, tuple)), ERROR databases = [DatabaseChooser(name) for name in database_names] ERROR = "Wrong type of database object (must be SQLiteBackend)" assert all(isinstance(obj, SQLiteBackend) for obj in databases), ERROR # Construct generators for both activities and exchanges # Need to be clever to minimize copying and memory use activity_qs = ActivityDataset.select().where( ActivityDataset.database << database_names) exchange_qs = ExchangeDataset.select().where( ExchangeDataset.output_database << database_names) # Retrieve all activity data print("Getting activity data") activities = [extract_activity(o) for o in tqdm(activity_qs)] # Add each exchange to the activity list of exchanges print("Adding exchange data to activities") add_exchanges_to_consumers(activities, exchange_qs) # Add details on exchanges which come from our databases print("Filling out exchange data") add_input_info_for_indigenous_exchanges(activities, database_names) add_input_info_for_external_exchanges(activities, database_names) return activities
def recalculate_scenario( self, scenario_values: Iterable[float]) -> (np.ndarray, np.ndarray): """ Convenience function that takes new parameter values and returns a fully-formed set of exchange amounts and indices. All parameter types are recalculated in turn before interpreting the ParameterizedExchange formulas into amounts. """ self.param_values = replace_amounts(self.param_values, scenario_values) global_project = self.recalculate_project_parameters() all_db = {} for p in DatabaseParameter.select( DatabaseParameter.database).distinct(): db = self.recalculate_database_parameters(p.database, global_project) all_db[p.database] = {x: y for x, y in db.items()} if db else {} complete_data = [] complete_indices = [] for p in ActivityParameter.select( ActivityParameter.group, ActivityParameter.database).distinct(): combination = {x: y for x, y in global_project.items() } if global_project else {} combination.update(all_db.get(p.database, {})) act = self.recalculate_activity_parameters(p.group, combination) combination.update(act) recalculated = self.recalculate_exchanges( p.group, global_params=combination) # If the parameter group contains no ParameterizedExchanges, skip. if not recalculated: continue # `data` contains the recalculated amounts for the exchanges. ids, data = zip(*recalculated) indices = [] for pk in ids: exc = ExchangeDataset.get_by_id(pk) input_key = (exc.input_database, exc.input_code) output_key = (exc.output_database, exc.output_code) if exc.input_database == bw.config.biosphere: indices.append((input_key, output_key, "biosphere")) else: indices.append((input_key, output_key, "technosphere")) complete_data.extend(data) complete_indices.extend(indices) # After recalculating all the exchanges and adding all samples and indices # to lists, format them according to presamples requirements: # eg: samples as a column of floats and indices as a row of tuples. samples = np.array(complete_data) samples = samples.reshape(1, -1).T indices = np.array(complete_indices) return samples, indices
def find_missing_exchanges(superstruct: set, delta: str) -> (set, list): query = (ED.select( ED.input_code, ED.output_code).where(ED.output_database == delta).distinct().tuples()) diff = set(x for x in query.iterator()).difference(superstruct) # Now query again, and create a list of exchanges of the diff. query = select_exchanges_by_database_codes(delta, diff) diff_list = [x for x in query.iterator()] return diff, diff_list
def build_from_tuple(cls, data: tuple) -> 'Index': obj = cls( input=Key(data[0][0], data[0][1]), output=Key(data[1][0], data[1][1]), ) exc_type = ExchangeDataset.get( ExchangeDataset.input_code == obj.input.code, ExchangeDataset.input_database == obj.input.database, ExchangeDataset.output_code == obj.output.code, ExchangeDataset.output_database == obj.output.database).type return obj._replace(flow_type=exc_type)
def construct_indices(self) -> Indices: """Given that ParameterizedExchanges will always have the same order of indices, construct them once and reuse when needed. """ indices = Indices() for p in self.initial.act_by_group_db: params = self.initial.exc_by_group(p.group) indices.extend( Index.build_from_exchange(ExchangeDataset.get_by_id(pk)) for pk in params) return indices
def parameter_exchange_dependencies(self) -> dict: """ Schema: {param1: List[tuple], param2: List[tuple]} """ parameters = defaultdict(list) for act in self.initial.act_by_group_db: exchanges = self.initial.exc_by_group(act.group) for exc, formula in exchanges.items(): params = get_new_symbols([formula]) # Convert exchange from int to Index exc = Index.build_from_exchange(ExchangeDataset.get_by_id(exc)) for param in params: parameters[param].append(exc) return parameters
def build_presamples_array_from_df( df: pd.DataFrame) -> (np.ndarray, np.ndarray): """Construct a presamples package from a superstructure DataFrame.""" keys = df.loc[pd.IndexSlice[:, EXCHANGE_KEYS]] scenario_columns = df.columns.difference(SUPERSTRUCTURE, sort=False) values = df.loc[pd.IndexSlice[:, scenario_columns]] assert keys.notna().all().all(), "Need all the keys for this." exchanges = (ExchangeDataset.get( input_database=x[0][0], input_code=x[0][1], output_database=x[1][0], output_code=x[1][1], ) for x in keys.itertuples(index=False)) indices = [Index.build_from_exchange(exc) for exc in exchanges] result = np.zeros(len(indices), dtype=object) for i, idx in enumerate(indices): result[i] = (idx.input, idx.output, idx.input.database_type) return result, values.to_numpy()
def construct_exchanges_search(df: pd.DataFrame) -> (pd.Series, set): keys = df.loc[:, EXCHANGE_KEYS] if keys.isna().all().all(): return pd.Series([]), set() # Separate into component sets. in_dbs = set(x[0] for x in keys["from key"]) in_codes = set(x[1] for x in keys["from key"]) out_dbs = set(x[0] for x in keys["to key"]) out_codes = set(x[1] for x in keys["to key"]) query = (ExchangeDataset.select( ExchangeDataset.input_code, ExchangeDataset.input_database, ExchangeDataset.output_code, ExchangeDataset.output_database).where( (ExchangeDataset.input_code.in_(in_codes)) & (ExchangeDataset.input_database.in_(in_dbs)) & (ExchangeDataset.output_code.in_(out_codes)) & (ExchangeDataset.output_database.in_(out_dbs))).namedtuples()) found_exc = set(process_ed_namedtuple(x) for x in query.iterator()) exchanges = keys.apply(tuple, axis=1) return exchanges, found_exc
def select_superstructure_indexes(struct: str) -> set: query = (ED.select(ED.input_code, ED.output_code) .where(ED.output_database == struct) .tuples()) indexes = set(x for x in query.iterator()) return indexes
def test_delete(activity): assert ExchangeDataset.select().count() == 1 assert ActivityDataset.select().count() == 1 activity.delete() assert ExchangeDataset.select().count() == 0 assert ActivityDataset.select().count() == 0