Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get last non-null value instead of latest XBRL filing. #3545

Merged
merged 5 commits into from
Apr 16, 2024

Conversation

jdangerx
Copy link
Member

@jdangerx jdangerx commented Apr 5, 2024

Overview

Closes #3309.

What problem does this address?

A bunch of utilities sent diff-only reports to update their 2021 data, which led to some important XBRL tables being mostly-null.

What did you change?

After much debate and investigation, we decided to change the XBRL deduplication to take the latest non-null value (across multiple filings) instead of taking the value from the latest single filing.

Testing

How did you make sure this worked? How can a reviewer verify this?

@cmgosnell I'd love if you could take a look and see if this affects rate base table in the expected way.

To-do list

Preview Give feedback

@jdangerx jdangerx requested a review from cmgosnell April 5, 2024 19:45
@jdangerx jdangerx marked this pull request as ready for review April 9, 2024 14:21
@jdangerx jdangerx force-pushed the 3309-change-xbrl-dedup branch from fe95010 to d4807c4 Compare April 9, 2024 14:28
@cmgosnell
Copy link
Member

cmgosnell commented Apr 10, 2024

@jdangerx the few logs and/or metrics make this change seem pretty beneficial!

before your change

Log from corrections from core_ferc1__yearly_depreciation_by_function_sched219:

Correcting 95.02% of all non-null reported values (439/462) out of a total of 143284 original records.
out_ferc1__yearly_rate_base.row_type_xbrl.value_counts()
row_type_xbrl
reported_value             442993
calculated_value            10204
subdimension_correction       205
correction                     75
calculation_metrics = defs.load_asset_value("_core_ferc1__calculation_metric_checks")
errors = calculation_metrics[
    calculation_metrics.filter(like="is_error").any(axis=1)
]
len(errors)
> 36

post change

Log from corrections from core_ferc1__yearly_depreciation_by_function_sched219:

Correcting 32.94% of all non-null reported values (28/85) out of a total of 143284 original records.
out_ferc1__yearly_rate_base.row_type_xbrl.value_counts()
row_type_xbrl
reported_value             442993
calculated_value            10204
correction                    178
subdimension_correction        15
calculation_metrics = defs.load_asset_value("_core_ferc1__calculation_metric_checks")
errors = calculation_metrics[
    calculation_metrics.filter(like="is_error").any(axis=1)
]
len(errors)
> 24

some comparison

it looks like it fully cleaned up a bunch of utilities calced values in the core_ferc1__yearly_utility_plant_summary_sched200 table

newly_good_idx = (
    calculation_metrics[calculation_metrics.error_frequency != 0]
    .index.difference(calculation_metrics_new[calculation_metrics_new.error_frequency != 0].index)
)
calculation_metrics.loc[newly_good_idx].reset_index(level="group_value").index.value_counts()

> group             table_name                                       
> utility_id_ferc1  core_ferc1__yearly_utility_plant_summary_sched200    157

@zaneselvans zaneselvans added ferc1 Anything having to do with FERC Form 1 xbrl Related to the FERC XBRL transition labels Apr 10, 2024
Copy link
Member

@cmgosnell cmgosnell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i love how simple this change is. i have two very minor suggestions.

Comment on lines 709 to 714
dupe_mask = original.duplicated(subset=xbrl_context_cols, keep=False)
duped_groups = original.loc[dupe_mask].groupby(
xbrl_context_cols, as_index=False
)
never_duped = original.loc[~dupe_mask]
return pd.concat([never_duped, duped_groups.last()], ignore_index=True)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

omigosh this is so nice and simple!

Can you add dropna=True into the groupby (even though it is set that was as a default) just to make is more clear how that last is getting the non-null values?

Comment on lines +701 to +705
This means that if a utility reports a non-null value, then later
either reports a null value for it or simply omits it from the report,
we keep the old non-null value, which may be erroneous. This appears to
be fairly rare, affecting < 0.005% of reported values.
Copy link
Member

@cmgosnell cmgosnell Apr 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we add a little defensive check in the here to make sure that expected % of values stays semi-constant? I assume this rate is ~ table dependent but i assume the worst offenders % would be a good high bar mark to test against

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, this is a little tricky - we'd have to calculate both the best snapshot and the apply diffs methodologies, stack them all up, then compare the two - which we can do, but seems like a lot of complexity to add for this check.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea i didn't realize how complicated this request was going to be. I don't think what you have here is too too complicated but it is a lot more than was here before. I'd be inclined to keep it in but if you feel otherwise I think it would be fine to revert to not checking this.

@jdangerx jdangerx force-pushed the 3309-change-xbrl-dedup branch from d4807c4 to 7f32384 Compare April 10, 2024 22:13
):
"""Compare deduplication methodologies.

By cross-referencing these we can make sure that the apply-diff
Copy link
Member Author

@jdangerx jdangerx Apr 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😓 this turned out to be surprisingly annoying

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm yeah it is surprisingly annoying!! I'm now semi regretting suggesting it but i think this looks okay. i like that it makes it clear that there are a few options and

This suggestion is probably oos for this pr but i wonder if this type of check that assesses methodological choices we've made in validation tests when it gets a lil too complicated. I've personally struggled with this distinction and the tension around testing with a lot of extra code that is not necessary for the actually thing you want to consistently produce. but i don't think this is tooo much!

@jdangerx jdangerx requested a review from cmgosnell April 10, 2024 22:14
@jdangerx
Copy link
Member Author

cc @e-belfer

@jdangerx jdangerx force-pushed the 3309-change-xbrl-dedup branch from 7f32384 to 0f9e95b Compare April 15, 2024 20:58
@jdangerx jdangerx added this pull request to the merge queue Apr 15, 2024
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Apr 15, 2024
@jdangerx
Copy link
Member Author

jdangerx commented Apr 15, 2024

Oy, the integration tests failed with a bunch of error thresholds being broken:


ERROR test/integration/console_scripts_test.py::test_pudl_service_territories[inprocess-pudl_service_territories --entity-type balancing_authority -y 2022 --limit-by-state --no-dissolve -o -balancing_authority_geometry_limited.parquet-expected_cols0] - AssertionError: Found errors while running tests on the calculations:
                                  error_frequency  tolerance_error_frequency  is_error_error_frequency  relative_error_magnitude  tolerance_relative_error_magnitude  is_error_relative_error_magnitude  null_calculated_value_frequency  tolerance_null_calculated_value_frequency is_error_null_calculated_value_frequency  null_reported_value_frequency  tolerance_null_reported_value_frequency  is_error_null_reported_value_frequency
group     table_name group_value                                                                                                                                                                                                                                                                                                                                                                                                            
ungrouped ungrouped  ungrouped           0.059571                      0.058                      True                       NaN                               0.045                              False                         0.014635                                        0.7                                    False                       0.539281                                      1.0                                   False
ERROR test/integration/console_scripts_test.py::test_pudl_service_territories[inprocess-pudl_service_territories --entity-type balancing_authority -y 2021 -y 2022 --no-dissolve -o -balancing_authority_geometry.parquet-expected_cols1] - AssertionError: Found errors while running tests on the calculations:
                                  error_frequency  tolerance_error_frequency  is_error_error_frequency  relative_error_magnitude  tolerance_relative_error_magnitude  is_error_relative_error_magnitude  null_calculated_value_frequency  tolerance_null_calculated_value_frequency is_error_null_calculated_value_frequency  null_reported_value_frequency  tolerance_null_reported_value_frequency  is_error_null_reported_value_frequency
group     table_name group_value                                                                                                                                                                                                                                                                                                                                                                                                            
ungrouped ungrouped  ungrouped           0.059571                      0.058                      True                       NaN                               0.045                              False                         0.014635                                        0.7                                    False                       0.539281                                      1.0                                   False
ERROR test/integration/console_scripts_test.py::test_pudl_service_territories[inprocess-pudl_service_territories --entity-type utility -y 2022 --dissolve -o -utility_geometry_dissolved.parquet-expected_cols2] - AssertionError: Found errors while running tests on the calculations:
                                  error_frequency  tolerance_error_frequency  is_error_error_frequency  relative_error_magnitude  tolerance_relative_error_magnitude  is_error_relative_error_magnitude  null_calculated_value_frequency  tolerance_null_calculated_value_frequency is_error_null_calculated_value_frequency  null_reported_value_frequency  tolerance_null_reported_value_frequency  is_error_null_reported_value_frequency
group     table_name group_value                                                                                                                                                                                                                                                                                                                                                                                                            
ungrouped ungrouped  ungrouped           0.059571                      0.058                      True                       NaN                               0.045                              False                         0.014635                                        0.7                                    False                       0.539281                                      1.0                                   False
ERROR test/integration/datasette_metadata_test.py::test_database_metadata - AssertionError: Found errors while running tests on the calculations:
                                  error_frequency  tolerance_error_frequency  is_error_error_frequency  relative_error_magnitude  tolerance_relative_error_magnitude  is_error_relative_error_magnitude  null_calculated_value_frequency  tolerance_null_calculated_value_frequency is_error_null_calculated_value_frequency  null_reported_value_frequency  tolerance_null_reported_value_frequency  is_error_null_reported_value_frequency
group     table_name group_value                                                                                                                                                                                                                                                                                                                                                                                                            
ungrouped ungrouped  ungrouped           0.059571                      0.058                      True                       NaN                               0.045                              False                         0.014635                                        0.7                                    False                       0.539281                                      1.0                                   False
ERROR test/integration/output_test.py::test_annual_eia_outputs[gen_fuel_by_generator_energy_source_owner_eia923] - AssertionError: Found errors while running tests on the calculations:
                                  error_frequency  tolerance_error_frequency  is_error_error_frequency  relative_error_magnitude  tolerance_relative_error_magnitude  is_error_relative_error_magnitude  null_calculated_value_frequency  tolerance_null_calculated_value_frequency is_error_null_calculated_value_frequency  null_reported_value_frequency  tolerance_null_reported_value_frequency  is_error_null_reported_value_frequency
group     table_name group_value                                                                                                                                                                                                                                                                                                                                                                                                            
ungrouped ungrouped  ungrouped           0.059571                      0.058                      True                       NaN                               0.045                              False                         0.014635                                        0.7                                    False                       0.539281                                      1.0                                   False
ERROR test/integration/output_test.py::test_null_rows[mcoe_generators-0.9] - AssertionError: Found errors while running tests on the calculations:
                                  error_frequency  tolerance_error_frequency  is_error_error_frequency  relative_error_magnitude  tolerance_relative_error_magnitude  is_error_relative_error_magnitude  null_calculated_value_frequency  tolerance_null_calculated_value_frequency is_error_null_calculated_value_frequency  null_reported_value_frequency  tolerance_null_reported_value_frequency  is_error_null_reported_value_frequency
group     table_name group_value                                                                                                                                                                                                                                                                                                                                                                                                            
ungrouped ungrouped  ungrouped           0.059571                      0.058                      True                       NaN                               0.045                              False                         0.014635                                        0.7                                    False                       0.539281                                      1.0                                   False
ERROR test/integration/output_test.py::test_outputs_by_table_suffix[eia861] - AssertionError: Found errors while running tests on the calculations:
                                  error_frequency  tolerance_error_frequency  is_error_error_frequency  relative_error_magnitude  tolerance_relative_error_magnitude  is_error_relative_error_magnitude  null_calculated_value_frequency  tolerance_null_calculated_value_frequency is_error_null_calculated_value_frequency  null_reported_value_frequency  tolerance_null_reported_value_frequency  is_error_null_reported_value_frequency
group     table_name group_value                                                                                                                                                                                                                                                                                                                                                                                                            
ungrouped ungrouped  ungrouped           0.059571                      0.058                      True                       NaN                               0.045                              False                         0.014635                                        0.7                                    False                       0.539281                                      1.0                                   False
ERROR test/integration/output_test.py::test_outputs_by_table_suffix[ferc714] - AssertionError: Found errors while running tests on the calculations:
                                  error_frequency  tolerance_error_frequency  is_error_error_frequency  relative_error_magnitude  tolerance_relative_error_magnitude  is_error_relative_error_magnitude  null_calculated_value_frequency  tolerance_null_calculated_value_frequency is_error_null_calculated_value_frequency  null_reported_value_frequency  tolerance_null_reported_value_frequency  is_error_null_reported_value_frequency
group     table_name group_value                                                                                                                                                                                                                                                                                                                                                                                                            
ungrouped ungrouped  ungrouped           0.059571                      0.058                      True                       NaN                               0.045                              False                         0.014635                                        0.7                                    False                       0.539281                                      1.0                                   False
ERROR test/integration/output_test.py::test_ferc714_outputs[out_ferc714__summarized_demand] - AssertionError: Found errors while running tests on the calculations:
                                  error_frequency  tolerance_error_frequency  is_error_error_frequency  relative_error_magnitude  tolerance_relative_error_magnitude  is_error_relative_error_magnitude  null_calculated_value_frequency  tolerance_null_calculated_value_frequency is_error_null_calculated_value_frequency  null_reported_value_frequency  tolerance_null_reported_value_frequency  is_error_null_reported_value_frequency
group     table_name group_value                                                                                                                                                                                                                                                                                                                                                                                                            
ungrouped ungrouped  ungrouped           0.059571                      0.058                      True                       NaN                               0.045                              False                         0.014635                                        0.7                                    False                       0.539281                                      1.0                                   False
ERROR test/integration/output_test.py::test_ferc714_outputs[out_ferc714__respondents_with_fips] - AssertionError: Found errors while running tests on the calculations:
                                  error_frequency  tolerance_error_frequency  is_error_error_frequency  relative_error_magnitude  tolerance_relative_error_magnitude  is_error_relative_error_magnitude  null_calculated_value_frequency  tolerance_null_calculated_value_frequency is_error_null_calculated_value_frequency  null_reported_value_frequency  tolerance_null_reported_value_frequency  is_error_null_reported_value_frequency
group     table_name group_value                                                                                                                                                                                                                                                                                                                                                                                                            
ungrouped ungrouped  ungrouped           0.059571                      0.058                      True                       NaN                               0.045                              False                         0.014635                                        0.7                                    False                       0.539281                                      1.0                                   False
ERROR test/integration/output_test.py::test_service_territory_outputs[out_eia861__yearly_balancing_authority_service_territory] - AssertionError: Found errors while running tests on the calculations:
                                  error_frequency  tolerance_error_frequency  is_error_error_frequency  relative_error_magnitude  tolerance_relative_error_magnitude  is_error_relative_error_magnitude  null_calculated_value_frequency  tolerance_null_calculated_value_frequency is_error_null_calculated_value_frequency  null_reported_value_frequency  tolerance_null_reported_value_frequency  is_error_null_reported_value_frequency
group     table_name group_value                                                                                                                                                                                                                                                                                                                                                                                                            
ungrouped ungrouped  ungrouped           0.059571                      0.058                      True                       NaN                               0.045                              False                         0.014635                                        0.7                                    False                       0.539281                                      1.0                                   False
ERROR test/integration/output_test.py::test_service_territory_outputs[out_eia861__yearly_utility_service_territory] - AssertionError: Found errors while running tests on the calculations:
                                  error_frequency  tolerance_error_frequency  is_error_error_frequency  relative_error_magnitude  tolerance_relative_error_magnitude  is_error_relative_error_magnitude  null_calculated_value_frequency  tolerance_null_calculated_value_frequency is_error_null_calculated_value_frequency  null_reported_value_frequency  tolerance_null_reported_value_frequency  is_error_null_reported_value_frequency
group     table_name group_value                                                                                                                                                                                                                                                                                                                                                                                                            
ungrouped ungrouped  ungrouped           0.059571                      0.058                      True                       NaN                               0.045                              False                         0.014635                                        0.7                                    False                       0.539281                                      1.0                                   False
ERROR test/integration/output_test.py::test_state_demand_outputs[out_ferc714__hourly_estimated_state_demand] - AssertionError: Found errors while running tests on the calculations:
                                  error_frequency  tolerance_error_frequency  is_error_error_frequency  relative_error_magnitude  tolerance_relative_error_magnitude  is_error_relative_error_magnitude  null_calculated_value_frequency  tolerance_null_calculated_value_frequency is_error_null_calculated_value_frequency  null_reported_value_frequency  tolerance_null_reported_value_frequency  is_error_null_reported_value_frequency
group     table_name group_value                                                                                                                                                                                                                                                                                                                                                                                                            
ungrouped ungrouped  ungrouped           0.059571                      0.058                      True                       NaN                               0.045                              False                         0.014635                                        0.7                                    False                       0.539281                                      1.0                                   False

What seems a little strange is that the same dang dataframe is getting reported in every failing test - that seems surprising to me. I don't know quite what to make of it but I'll see if I can get this breaking locally for now. @zaneselvans this seems like something you might have some insight into?

@zaneselvans
Copy link
Member

I think the reason the same dataframe is coming up repeatedly is that it's not a test failure, it's a defensive check which is erroring out in the ETL phase, and so you're getting identical "errors" raised in every test which depends on the fixture that's generating the errors.

@jdangerx
Copy link
Member Author

Ahhh that makes sense. OK! I'll go look at where those checks are (presumably) hard coded and see if I can make heads or tails of it.

@zaneselvans
Copy link
Member

I'd probably try to materialize the exploded tables locally, which I think would exercise this check, and then you could fiddle with the parameters that set the acceptable error levels. However, this could reveal real issues. @cmgosnell will be the most familiar with what the error levels are supposed to look like and why the new data might be setting off these alarm bells.

@jdangerx
Copy link
Member Author

jdangerx commented Apr 15, 2024

OK, so core_ferc1__yearly_depreciation_changes_sched219 is newly failing in the fast ETL, but not the full.

I compared the calculation reconciliation metrics across this branch & the main branch for the fast ETL:

metric new value (apply-diffs) old value (main) threshold
error frequency 0.059571 0.05792 0.058
relative error magnitude NaN NaN 0.045
null calc value freq 0.014635 0.015244 0.7
null reported value freq 0.539281 0.560459 1.0

So the error frequency is newly a little higher, and the null calcs/reported values are both less frequent.

I'm not sure how to convince myself that this is OK vs. continuing to dig deeper - @cmgosnell maybe let's grab some time in the morning tomorrow to chat about this?

@jdangerx jdangerx force-pushed the 3309-change-xbrl-dedup branch from 0f9e95b to dccd775 Compare April 15, 2024 23:14
@zaneselvans
Copy link
Member

zaneselvans commented Apr 15, 2024

If that's the only thing tripping it up, and it's only happening in the fast and not the full ETL, then upping the allowed error frequency to 0.06 seems fine. Those thresholds are arbitrary, and really intended to detect changes so they can be evaluated for significance / tracked down if they're wacked.

But I'm worried there might be a long series of little error tolerance tweaks that need to be made after this one is fixed.

@zaneselvans
Copy link
Member

zaneselvans commented Apr 16, 2024

I ran the fast ETL through the Dagster UI locally and thankfully core_ferc1__yearly_depreciation_changes_sched219 was the only asset that failed. I bumped the error frequency to 0.06 and re-ran it, and it passed. So I think we should just make that tiny adjustment to get this merged in.

@cmgosnell do you think we should check the other error metrics for the other FERC 1 assets, and ratchet them down if we have significantly lower error rates with the new diff-based extractions? Do we expect this to have broad impacts across the board? I can't remember if we had an easy way of generating all the error tolerance outputs.

@jdangerx I also noticed 2 failing asset checks in the fast ETL, which was a little surprising:

  • _core_eia860__fgd_equipment_fgd_equipment_null_check
  • _core_eia860__cooling_equipment_cooling_equipment_null_cols

If they're failing, should they be causing the fast ETL to fail as well?

@zaneselvans zaneselvans force-pushed the 3309-change-xbrl-dedup branch from dccd775 to f8f2d2b Compare April 16, 2024 03:22
@zaneselvans zaneselvans enabled auto-merge April 16, 2024 03:23
@zaneselvans zaneselvans added this pull request to the merge queue Apr 16, 2024
Merged via the queue into main with commit b082be6 Apr 16, 2024
12 checks passed
@zaneselvans zaneselvans deleted the 3309-change-xbrl-dedup branch April 16, 2024 04:43
@cmgosnell
Copy link
Member

I'm glad y'all figured out how to tweak the error tolerances! ( i don't super love how it ended up, structurally/ergonomically )

It makes sense to me that more non-null values in data would result in at least slightly worse error metircs. It is very standard for the fast ETL to require higher error tolerances and that is not a big change. Believe it or not the XBRL data is less calculable with its own calculations as the old data. So it makes sense that adding more XBRL values -> more errors.

I was hoping to spend a lil time after this gets merged in to see if null frequency tolerance can be turned down a bit on any of the tables.

We do have a way to check all of the metrics all at once. that's this asset: _core_ferc1__calculation_metric_checks. That runs all of the calc checks on all of the tables that have non-null params in reconcile_table_calculations (i.e. are we checking their calcs). It outputs a table of all of the error metrics with standard tolerances in the table (it was a lil too complicated/deemed not worth it to use table-specific tolerances in this asset).

@jdangerx
Copy link
Member Author

If they're failing, should they be causing the fast ETL to fail as well?

Yes... we have them set as "blocking" and also had a bunch of extra logic in there to stop the fast ETL from failing. Strange...

zaneselvans added a commit that referenced this pull request Apr 16, 2024
The change in how we select XBRL records to extract in PR #3545 also
changed how many records appear in a few tables, but only by 1 or 2
records. If anything it's surprising how few records were added/lost, so
I've just adopted the new row counts in these tables:

* plant in service
* small plants
* all FERC 1 plants
github-merge-queue bot pushed a commit that referenced this pull request Apr 16, 2024
The change in how we select XBRL records to extract in PR #3545 also
changed how many records appear in a few tables, but only by 1 or 2
records. If anything it's surprising how few records were added/lost, so
I've just adopted the new row counts in these tables:

* plant in service
* small plants
* all FERC 1 plants
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ferc1 Anything having to do with FERC Form 1 xbrl Related to the FERC XBRL transition
Projects
Archived in project
3 participants