Skip to content

Commit 41206c8

Browse files
Merge pull request #301 from USEPA/v1.3-release
V1.3 release
2 parents be6ac00 + 32ed6a7 commit 41206c8

File tree

100 files changed

+12313
-894
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

100 files changed

+12313
-894
lines changed

.github/workflows/compare_single_FBS.yml

+9-8
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,22 @@ on:
1212

1313
jobs:
1414
build:
15-
runs-on: ubuntu-latest
15+
runs-on: macos-latest
1616
strategy:
1717
fail-fast: false
1818

1919
steps:
20-
- uses: actions/checkout@v2
20+
- uses: actions/checkout@v3
2121
- name: Set up Python
22-
uses: actions/setup-python@v2
22+
uses: actions/setup-python@v3
2323
with:
2424
python-version: "3.10"
2525

2626
- name: Update pip
2727
run: |
2828
python -VV
2929
python -m pip install --upgrade pip setuptools wheel
30+
pip install pytest
3031
3132
# install package & dependencies
3233
- name: Install package and dependencies
@@ -42,14 +43,14 @@ jobs:
4243
4344
- name: Upload files
4445
if: always()
45-
uses: actions/upload-artifact@v3
46+
uses: actions/upload-artifact@v3.1.1
4647
with:
4748
# Artifact name
4849
name: FBS diff files
4950
# A file, directory or wildcard patter that describes what to upload
50-
path: | # uses local user data dir for ubuntu
51-
~/.local/share/flowsa/FBSComparisons/*
52-
~/.local/share/flowsa/FlowBySector/*
53-
~/.local/share/stewi/Log/*
51+
path: | # uses local user data dir for macos
52+
~/Library/Application Support/flowsa/FBSComparisons/*
53+
~/Library/Application Support/flowsa/FlowBySector/*
54+
~/Library/Application Support/flowsa/Log/*
5455
if-no-files-found: warn # 'warn' or 'ignore' are also available, defaults to `warn`
5556
# retention-days: 5 # cannot exceed the retention limit set by the repository, organization, or enterprise.

.github/workflows/generate_FBS.yml

+6-6
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@ on:
1010

1111
jobs:
1212
build:
13-
runs-on: ubuntu-latest
13+
runs-on: macos-latest
1414
strategy:
1515
fail-fast: false
1616

1717
steps:
18-
- uses: actions/checkout@v2
18+
- uses: actions/checkout@v3
1919
- name: Set up Python
20-
uses: actions/setup-python@v2
20+
uses: actions/setup-python@v3
2121
with:
2222
python-version: "3.10"
2323

@@ -38,13 +38,13 @@ jobs:
3838
3939
- name: Upload files
4040
if: always()
41-
uses: actions/upload-artifact@v3
41+
uses: actions/upload-artifact@v3.1.1
4242
with:
4343
# Artifact name
4444
name: FlowBySector
4545
# A file, directory or wildcard patter that describes what to upload
4646
path: | # uses local user data dir for ubuntu
47-
~/.local/share/flowsa/FlowBySector/*
48-
~/.local/share/stewi/Log/*
47+
~/Library/Application Support/flowsa/FlowBySector/*
48+
~/Library/Application Support/flowsa/Log/*
4949
if-no-files-found: warn # 'warn' or 'ignore' are also available, defaults to `warn`
5050
# retention-days: 5 # cannot exceed the retention limit set by the repository, organization, or enterprise.

.github/workflows/python-app.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@ jobs:
3434
py-version: ['3.8', '3.9', '3.10']
3535

3636
steps:
37-
- uses: actions/checkout@v2
37+
- uses: actions/checkout@v3
3838

3939
# general Python setup
4040
- name: Set up Python ${{ matrix.py-version }}
41-
uses: actions/setup-python@v2
41+
uses: actions/setup-python@v3
4242
with:
4343
python-version: ${{ matrix.py-version }}
4444

.github/workflows/test_methods.yml

+14-11
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ on:
1212

1313
jobs:
1414
FBA_testing:
15-
runs-on: ubuntu-latest
15+
runs-on: macos-latest
1616

1717
steps:
18-
- uses: actions/checkout@v2
18+
- uses: actions/checkout@v3
1919
- name: Set up Python
20-
uses: actions/setup-python@v2
20+
uses: actions/setup-python@v3
2121
with:
2222
python-version: "3.10"
2323

@@ -37,12 +37,12 @@ jobs:
3737
python flowsa/test_methods.py
3838
3939
FBS_testing:
40-
runs-on: ubuntu-latest
40+
runs-on: macos-latest
4141

4242
steps:
43-
- uses: actions/checkout@v2
43+
- uses: actions/checkout@v3
4444
- name: Set up Python
45-
uses: actions/setup-python@v2
45+
uses: actions/setup-python@v3
4646
with:
4747
python-version: "3.10"
4848

@@ -61,19 +61,22 @@ jobs:
6161
id: FBS
6262
if: always() # Proceed even if Test FBA fails
6363
run: |
64-
python flowsa/test_FBS_against_remote.py
64+
for m in $(python flowsa/test_FBS_against_remote.py list)
65+
do
66+
python flowsa/test_FBS_against_remote.py "$m"
67+
done
6568
6669
- name: Upload csv files
6770
# if: steps.FBS.outcome == 'success' # Upload csv only if step succeeds
6871
if: always()
69-
uses: actions/upload-artifact@v2.3.0
72+
uses: actions/upload-artifact@v3.1.1
7073
with:
7174
# Artifact name
7275
name: FBS diff files
7376
# A file, directory or wildcard patter that describes what to upload
7477
path: |
75-
~/.local/share/flowsa/FBSComparisons/*
76-
~/.local/share/flowsa/FlowBySector/*
77-
~/.local/share/flowsa/Log/*
78+
~/Library/Application Support/flowsa/FBSComparisons/*
79+
~/Library/Application Support/flowsa/FlowBySector/*
80+
~/Library/Application Support/flowsa/Log/*
7881
if-no-files-found: warn # 'warn' or 'ignore' are also available, defaults to `warn`
7982
# retention-days: 5 # cannot exceed the retention limit set by the repository, organization, or enterprise.

examples/external_paths.env.example

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
"""
2+
To access a file stored externally from FLOWSA, users can add a filepath to
3+
"external_paths.env" and store the .env in the MODULEPATH defined in
4+
flowsa/settings.py.
5+
6+
"""
7+
WARM-USEEIO_MaterialCrosswalk = "user-path/WARM-USEEIOdocs/data/MaterialCrosswalk.csv"
8+
9+
WARM-USEEIO_Materials = "user-path/git_projects/WARM-USEEIOdocs/data/Materials.csv"

examples/generate_data_visualization.py

+57-7
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,12 @@
77
"""
88

99
import flowsa
10+
import flowsa.datavisualization as dv
1011
from flowsa.settings import plotoutputpath
1112
import matplotlib.pyplot as plt
1213

1314

14-
# Produce facet graph of resources associated with cropland sectors
15+
########## Produce facet graph of resources associated with cropland sectors ##########
1516
sectors = ['112']
1617
sector_length_display = 6
1718
plottype = 'facet_graph'
@@ -20,16 +21,16 @@
2021
'Employment 2017': 'Employment_national_2017'}
2122

2223

23-
flowsa.generateFBSplot(method_dict, plottype,
24-
sector_length_display=sector_length_display,
25-
sectors_to_include=sectors,
26-
plot_title='Direct Resource Use for Livestock'
27-
)
24+
dv.FBSscatterplot(method_dict, plottype,
25+
sector_length_display=sector_length_display,
26+
sectors_to_include=sectors,
27+
plot_title='Direct Resource Use for Livestock'
28+
)
2829
# Can manually adjust the figure pop up before saving
2930
plt.savefig(f"{plotoutputpath}livestock_resource_use.png", dpi=300)
3031

3132

32-
# Compare the results between water method 1 and method 2
33+
########## Compare the results between water method 1 and method 2 ##########
3334
sectors = ['21']
3435
sector_length_display = 6
3536
plottype = 'method_comparison'
@@ -45,3 +46,52 @@
4546
)
4647
# Can manually adjust the figure pop up before saving
4748
plt.savefig(f"{plotoutputpath}mining_water_comp.png", dpi=300)
49+
50+
51+
########## Compare food waste flows via Sankey ##########
52+
methodnames = ['Food_Waste_national_2018_m1', 'Food_Waste_national_2018_m2']
53+
target_sector_level = 'NAICS_2'
54+
target_subset_sector_level = {
55+
'Food_Waste_national_2018_m1': {'NAICS_4': ['2212'],
56+
'NAICS_6': ['62421', '31111', '32411',
57+
'56221', '62421', '115112',
58+
'22132'],
59+
'NAICS_7': ['562212', '562219']
60+
},
61+
'Food_Waste_national_2018_m2': {
62+
'SectorConsumedBy': {'NAICS_6': ['115112', '22132','311119',
63+
'32411', '562213','62421'],
64+
'NAICS_7': ['562212', '562219']
65+
}}
66+
}
67+
# set domain to scale sankey diagrams
68+
domain_dict = {0: {'x': [0.01, 0.49], 'y': [0, 1]},
69+
1: {'x': [.51, 0.99], 'y': [.12, .88]}
70+
}
71+
72+
dv.generateSankeyDiagram(
73+
methodnames,
74+
target_sector_level=target_sector_level,
75+
target_subset_sector_level=target_subset_sector_level,
76+
use_sectordefinition=True,
77+
sectors_to_include=None,
78+
fbsconfigpath=None,
79+
orientation='horizontal',
80+
domain_dict=domain_dict,
81+
value_label_format='brackets',
82+
subplot_titles=['m1', 'm2'],
83+
filename='FoodWasteSankey'
84+
)
85+
86+
87+
####### GHG Bar Chart ############
88+
# Option 1 - GHG emissions by GHG
89+
dv.stackedBarChart('GHG_national_2018_m1',
90+
sectors_to_include=['111110', '112120', '325312'],
91+
filename='GHGEmissions')
92+
93+
# Option 2 - specify indicator, much have LCIAformatter installed
94+
# https://github.com/USEPA/LCIAformatter
95+
dv.stackedBarChart('GHG_national_2018_m1', impact_cat='Global warming',
96+
sectors_to_include=['111110', '112120', '325312'],
97+
filename='GHGEmissionsGlobalWarming')

flowsa/__init__.py

+9-4
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
import flowsa.flowbyactivity
3131
import flowsa.flowbysector
3232
from flowsa.bibliography import generate_fbs_bibliography
33-
from flowsa.datavisualization import plotFBSresults
33+
from flowsa.datavisualization import FBSscatterplot
3434

3535

3636
def getFlowByActivity(datasource, year, flowclass=None, geographic_level=None,
@@ -39,7 +39,8 @@ def getFlowByActivity(datasource, year, flowclass=None, geographic_level=None,
3939
Retrieves stored data in the FlowByActivity format
4040
:param datasource: str, the code of the datasource.
4141
:param year: int, a year, e.g. 2012
42-
:param flowclass: str, a 'Class' of the flow. Optional. E.g. 'Water'
42+
:param flowclass: str or list, a 'Class' of the flow. Optional. E.g.
43+
'Water' or ['Employment', 'Chemicals']
4344
:param geographic_level: str, a geographic level of the data.
4445
Optional. E.g. 'national', 'state', 'county'.
4546
:param download_FBA_if_missing: bool, if True will attempt to load from
@@ -81,7 +82,11 @@ def getFlowByActivity(datasource, year, flowclass=None, geographic_level=None,
8182

8283
# Address optional parameters
8384
if flowclass is not None:
84-
fba = fba[fba['Class'] == flowclass]
85+
# subset df by single class or list of classes
86+
if isinstance(flowclass, str):
87+
fba = fba[fba['Class'] == flowclass]
88+
else:
89+
fba = fba[fba['Class'].isin(flowclass)]
8590
# if geographic level specified, only load rows in geo level
8691
if geographic_level is not None:
8792
fba = filter_by_geoscale(fba, geographic_level)
@@ -234,5 +239,5 @@ def generateFBSplot(method_dict, plottype, sector_length_display=None,
234239
:return: graphic displaying results of FBS models
235240
"""
236241

237-
plotFBSresults(method_dict, plottype, sector_length_display,
242+
FBSscatterplot(method_dict, plottype, sector_length_display,
238243
sectors_to_include, plot_title)

flowsa/allocation.py

+14-7
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from flowsa.settings import log, vLogDetailed
1212
from flowsa.dataclean import replace_NoneType_with_empty_cells, \
1313
replace_strings_with_NoneType
14-
from flowsa.flowbyfunctions import sector_aggregation, \
14+
from flowsa.flowbyfunctions import sector_aggregation, aggregator, \
1515
sector_disaggregation, subset_and_merge_df_by_sector_lengths
1616

1717

@@ -343,20 +343,26 @@ def equal_allocation(fba_load):
343343
"""
344344
from flowsa.flowbyfunctions import assign_columns_of_sector_levels
345345

346+
# aggregate df
347+
aggcols = list(fba_load.select_dtypes(include=['object', 'int']).columns)
348+
fba = aggregator(fba_load, aggcols)
349+
346350
# first check that all sector lengths are the same
347-
dfc = assign_columns_of_sector_levels(fba_load)
351+
dfc = assign_columns_of_sector_levels(fba)
348352
# if duplicated rows, keep assignment to most specific sectors because
349353
# data should already be at final assignment lengths if equally
350354
# allocating and because not manipulating the loaded dataset, but rather
351355
# just checking that all sector lengths match for an activity
352356
duplicate_cols = [e for e in dfc.columns if e not in [
353357
'SectorProducedByLength', 'SectorConsumedByLength']]
354-
duplicate_df = dfc[dfc.duplicated(duplicate_cols)]
358+
duplicate_df = dfc[dfc.duplicated(duplicate_cols, keep=False)]
355359
if len(duplicate_df) > 0:
356360
log.info('Dropping rows duplicated due to assigning sector lengths '
357361
'for ambiguous sectors. Keeping sector length assignments '
358362
'to most specific sectors.')
359-
dfc = dfc[dfc.duplicated(duplicate_cols, keep='first')]
363+
dfc = dfc.sort_values(['SectorProducedByLength',
364+
'SectorConsumedByLength'])
365+
dfc = dfc[~dfc.duplicated(duplicate_cols, keep='last')]
360366

361367
# Before equally allocating, check that each activity is being allocated
362368
# to sectors of the same length
@@ -367,19 +373,20 @@ def equal_allocation(fba_load):
367373
if len(df_dup) > 1:
368374
log.error('Cannot equally allocate because sector lengths vary. All '
369375
'sectors must be the same sector level.')
376+
return fba
370377

371378
# create groupby cols by which to determine allocation
372-
fba_cols = fba_load.select_dtypes([object]).columns.to_list()
379+
fba_cols = fba.select_dtypes([object]).columns.to_list()
373380
groupcols = [e for e in fba_cols if e not in
374381
['SectorProducedBy', 'SectorConsumedBy', 'Description']]
375382
# create counts of rows
376-
df_count = fba_load.groupby(
383+
df_count = fba.groupby(
377384
groupcols, as_index=False, dropna=False).size()
378385
df_count = replace_NoneType_with_empty_cells(df_count)
379386

380387
# merge dfs, replace cells with empty strings to ensure merge occurs
381388
# correctly
382-
fba = replace_NoneType_with_empty_cells(fba_load)
389+
fba = replace_NoneType_with_empty_cells(fba)
383390
dfm = fba.merge(df_count, how='outer', on=groupcols)
384391
# calc new flowamounts
385392
dfm['FlowAmount'] = dfm['FlowAmount'] / dfm['size']

0 commit comments

Comments
 (0)