This notebook runs sanity checks on the Boiler Fuel data that are reported in EIA Form 923. These are the same tests which are run by the bf_eia923 validation tests by PyTest. The notebook and visualizations are meant to be used as a diagnostic tool, to help understand what's wrong when the PyTest based data validations fail for some reason.
In [ ]:
%load_ext autoreload
%autoreload 2
In [ ]:
import sys
import pandas as pd
import sqlalchemy as sa
import pudl
In [ ]:
import warnings
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
handler = logging.StreamHandler(stream=sys.stdout)
formatter = logging.Formatter('%(message)s')
handler.setFormatter(formatter)
logger.handlers = [handler]
In [ ]:
import matplotlib.pyplot as plt
import matplotlib as mpl
%matplotlib inline
In [ ]:
plt.style.use('ggplot')
mpl.rcParams['figure.figsize'] = (10,4)
mpl.rcParams['figure.dpi'] = 150
pd.options.display.max_columns = 56
In [ ]:
pudl_settings = pudl.workspace.setup.get_defaults()
ferc1_engine = sa.create_engine(pudl_settings['ferc1_db'])
pudl_engine = sa.create_engine(pudl_settings['pudl_db'])
pudl_settings
First we pull the original (post-ETL) EIA 923 data out of the database. We will use the values in this dataset as a baseline for checking that latter aggregated data and derived values remain valid. We will also eyeball these values here to make sure they are within the expected range. This may take a minute or two depending on the speed of your machine.
In [ ]:
pudl_out_orig = pudl.output.pudltabl.PudlTabl(pudl_engine, freq=None)
bf_eia923_orig = pudl_out_orig.bf_eia923()
Some of the variables reported in this table have a fixed range of reasonable values, like the heat content per unit of a given fuel type. These varaibles can be tested for validity against external standards directly. In general we have two kinds of tests in this section:
These are all contained in the frc_eia923
table data validations, and those should just be re-used if possible. Ugh, names not all the same though. Annoying.
ash_content_pct
(BIT, SUB, LIG, coal)fuel_mmbtu_per_unit
(BIT, SUB, LIG, coal, DFO, oil, gas)sulfur_content_pct
(BIT, SUB, LIG, coal)
In [ ]:
bf_eia923_orig.sample(10)
In [ ]:
pudl.validate.plot_vs_bounds(bf_eia923_orig, pudl.validate.bf_eia923_coal_heat_content)
In [ ]:
pudl.validate.plot_vs_bounds(bf_eia923_orig, pudl.validate.bf_eia923_oil_heat_content)
In [ ]:
pudl.validate.plot_vs_bounds(bf_eia923_orig, pudl.validate.bf_eia923_gas_heat_content)
In [ ]:
pudl.validate.plot_vs_bounds(bf_eia923_orig, pudl.validate.bf_eia923_coal_ash_content)
In [ ]:
pudl.validate.plot_vs_bounds(bf_eia923_orig, pudl.validate.bf_eia923_coal_sulfur_content)
As a sanity check of the testing process itself, we can check to see whether the entire historical distribution has attributes that place it within the extremes of a historical subsampling of the distribution. In this case, we sample each historical year, and look at the range of values taken on by some quantile, and see whether the same quantile for the whole of the dataset fits within that range
In [ ]:
pudl.validate.plot_vs_self(bf_eia923_orig, pudl.validate.bf_eia923_self)
In [ ]:
pudl_out_month = pudl.output.pudltabl.PudlTabl(pudl_engine, freq="MS")
bf_eia923_month = pudl_out_month.bf_eia923()
In [ ]:
pudl.validate.plot_vs_agg(bf_eia923_orig, bf_eia923_month, pudl.validate.bf_eia923_agg)
In [ ]:
pudl_out_year = pudl.output.pudltabl.PudlTabl(pudl_engine, freq="AS")
bf_eia923_year = pudl_out_year.bf_eia923()
In [ ]:
pudl.validate.plot_vs_agg(bf_eia923_orig, bf_eia923_year, pudl.validate.bf_eia923_agg)