Skip to content

Refactor _resampled_scene() and _reduce_data() methods of the Scene class - #3178

Open
pnuu wants to merge 9 commits into
pytroll:mainfrom
pnuu:refactor_resampled_scene
Open

Refactor _resampled_scene() and _reduce_data() methods of the Scene class#3178
pnuu wants to merge 9 commits into
pytroll:mainfrom
pnuu:refactor_resampled_scene

Conversation

@pnuu

@pnuu pnuu commented Jul 28, 2025

Copy link
Copy Markdown
Member

This PR refactors Scene._resampled_scene() that @gerritholl reported to be complicated in #3168 (comment) . As there was a change to _reduce_data(), I did some additional refactoring to it too.

  • Closes #xxxx
  • Tests added
  • Fully documented
  • Add your name to AUTHORS.md if not there already

@pnuu pnuu self-assigned this Jul 28, 2025
@pnuu
pnuu requested review from djhoese and mraspaud as code owners July 28, 2025 08:13
@pnuu pnuu added component:scene cleanup Code cleanup but otherwise no change in functionality labels Jul 28, 2025
@codecov

codecov Bot commented Jul 28, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.85714% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 96.33%. Comparing base (fbfbe21) to head (f70d80f).
⚠️ Report is 6 commits behind head on main.

Files with missing lines Patch % Lines
satpy/scene.py 92.85% 5 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3178      +/-   ##
==========================================
+ Coverage   96.32%   96.33%   +0.01%     
==========================================
  Files         466      467       +1     
  Lines       59096    59143      +47     
==========================================
+ Hits        56922    56977      +55     
+ Misses       2174     2166       -8     
Flag Coverage Δ
behaviourtests 3.61% <24.28%> (+0.02%) ⬆️
unittests 96.42% <92.85%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@pnuu

pnuu commented Jul 28, 2025

Copy link
Copy Markdown
Member Author

I'll do some more refactoring to _reduce_data().

@coveralls

coveralls commented Jul 28, 2025

Copy link
Copy Markdown

Pull Request Test Coverage Report for Build 16566762203

Details

  • 51 of 56 (91.07%) changed or added relevant lines in 1 file are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage remained the same at 96.381%

Changes Missing Coverage Covered Lines Changed/Added Lines %
satpy/scene.py 51 56 91.07%
Totals Coverage Status
Change from base Build 16528353281: 0.0%
Covered Lines: 56082
Relevant Lines: 58188

💛 - Coveralls

@pnuu pnuu changed the title Refactor Scene._resampled_scene() Refactor _resampled_scene() and _reduce_data() methods of the Scene class Jul 28, 2025
@gerritholl

Copy link
Copy Markdown
Member

Thanks! I've merged this into #3168 but there is still an issue with missing test coverage.

Comment thread satpy/scene.py Outdated
Comment thread satpy/scene.py
Comment thread satpy/scene.py Outdated
@pnuu

pnuu commented May 20, 2026

Copy link
Copy Markdown
Member Author

I made the Fine Choice(tm) of asking Copilot (Claude Sonnet 4.6) to refactor the method. After couple of iterations we ended up with this version that uses a data class to hold resampling context and a method that is called for each resampled dataset.

@djhoese

djhoese commented May 20, 2026

Copy link
Copy Markdown
Member

Interesting...I've never personally used data classes beyond toy programs and watching programming videos. What it is doing here makes me wonder if this deserves a full blown helper class where instead of context in these sub-methods it is just self..

@djhoese

djhoese commented May 20, 2026

Copy link
Copy Markdown
Member

And sorry, I don't fully remember all the previous context for this PR and past thoughts I had about it.

@pnuu

pnuu commented Jun 17, 2026

Copy link
Copy Markdown
Member Author

Unrelated test failure:

ERROR satpy/tests/reader_tests/test_mviri_l1b_fiduceo_nc.py::TestFiduceoMviriFileHandlers - satpy/tests/reader_tests/test_mviri_l1b_fiduceo_nc.py::TestFiduceoMviriFileHandlers::test_init: duplicate parametrization of 'projection_longitude'

I can't replicate this locally with package versions I have.

@pnuu

pnuu commented Jun 17, 2026

Copy link
Copy Markdown
Member Author

Seems to be somehow related to pytest-dev/pytest#13974 that have several links from the few last days.

@pnuu

pnuu commented Jun 17, 2026

Copy link
Copy Markdown
Member Author

Possible fix in #3415

@gerritholl

Copy link
Copy Markdown
Member

Needs more test coverage?

@gerritholl

Copy link
Copy Markdown
Member

This PR increases the overhead/runtime of _reduce_data by a factor 5. Test script:

import os
from satpy import Scene
from glob import glob
from satpy.tests.utils import CustomScheduler
from satpy.writers.core.compute import compute_writer_results
import dask.config
import time
reduce = True
with dask.config.set(scheduler=CustomScheduler(max_computes=0)):
    seviri_files = glob("/media/nas/x21308/scratch/SEVIRI/202103300900/H-000*")
    sc = Scene(filenames={"seviri_l1b_hrit": seviri_files})
    nms = {"ash", "natural_color", "dwd_RGB_12_12_9i_N", "convection",
           "dwd_IR_108", "dwd_HRV", "airmass", "dust"}
    sc.load(nms, generate=False)
    tic = time.time()
    ls = sc.resample("nqeuro3km",
                     resampler="gradient_search", reduce_data=reduce)
    print("resample", time.time() - tic, "seconds")
    res_all = []
    for nm in nms:
        res_all.append(ls.save_dataset(
                nm,
                "{platform_name}-{sensor}-{name}-{area.area_id}-{start_time:%Y%m%d%H%M}-geotiff.tif",
                writer="ninjogeotiff",
                ChannelID="IR 10.8",
                DataType="GORN",
                PhysicValue="Temperature",
                PhysicUnit="K",
                SatelliteNameID="METEOSAT Europe-Atlantic",
                fill_value=0,
                #dynamic_fields={"mean_time"},
                compute=False))

Satpy main: 8.2 seconds

This PR: 44.0 seconds

@gerritholl

gerritholl commented Jun 24, 2026

Copy link
Copy Markdown
Member

Profiling reveals:

  • the time per call for _reduce_data increases from 1.02 to 5.97 seconds.
  • The number of calls to spherical.py:492(get_next_intersection) increases from 302 to 1812.
  • The number of calls to geometry.py:2654(get_area_slices) (first entry point into pyresample) increases from 2 to 12.

Here both profiles:

profile-results.zip

@gerritholl gerritholl left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Serious performance regression in _reduce_data. The reductions dictionary appears no longer functional, leading to _reduce_data being called for every dataset. For my test script, that increases the time for calling resample from ca. 8 seconds to ca. 40 seconds. Without computing anything.

Comment thread satpy/scene.py
Comment thread satpy/scene.py
Comment thread satpy/scene.py Outdated
Comment thread satpy/scene.py
Fix a performance regression in _reduce_data, where the reductions
dictionary was no longer used correctly, leading to reduce_data being
called for every dataset instead of every source area.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cleanup Code cleanup but otherwise no change in functionality component:scene

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants