Skip to content

Conversation

@chris-langfield
Copy link
Collaborator

@chris-langfield chris-langfield commented Feb 10, 2022

Step 2 of the plan to replace Image.downsample() with the MATLAB ported version.

The current implementation of downsample does not pass all of these.

Step 1 is #565, addition of the crop_2d method required for this algorithm.

#566 #140

@chris-langfield chris-langfield self-assigned this Feb 10, 2022
@chris-langfield chris-langfield added CI Continuous Integration cleanup enhancement New feature or request labels Feb 10, 2022
This was linked to issues Feb 10, 2022
@codecov
Copy link

codecov bot commented Feb 10, 2022

Codecov Report

Merging #567 (25b5914) into develop (b000a87) will not change coverage.
The diff coverage is n/a.

@@           Coverage Diff            @@
##           develop     #567   +/-   ##
========================================
  Coverage    86.49%   86.49%           
========================================
  Files          108      108           
  Lines         8277     8277           
========================================
  Hits          7159     7159           
  Misses        1118     1118           

📣 Codecov can now indicate which changes are the most critical in Pull Requests. Learn more

@chris-langfield
Copy link
Collaborator Author

My reasoning for removing the following test:

def testImageDownsampleAndWhiten(self):
self.src.downsample(16)
self.src.whiten(noise_filter=ScalarFilter(dim=2, value=0.02450909546680349))
first_whitened_image = self.src.images(0, 1)[0]
self.assertTrue(
np.allclose(
first_whitened_image,
np.load(
os.path.join(DATA_DIR, "starfile_image_0_whitened.npy")
).T, # RCOPT
atol=1e-6,
)
)

is that the processes involved are covered by the new downsampling tests added in this PR, and that the whitening seems to be robustly tested here:

def testWhiten(self):
noise_estimator = AnisotropicNoiseEstimator(self.sim)
self.sim.whiten(noise_estimator.filter)
imgs_wt = self.sim.images(start=0, num=self.n).asnumpy()
# calculate correlation between two neighboring pixels from background
corr_coef = np.corrcoef(
imgs_wt[:, self.L - 1, self.L - 1], imgs_wt[:, self.L - 2, self.L - 1]
)
# correlation matrix should be close to identity
self.assertTrue(np.allclose(np.eye(2), corr_coef, atol=1e-1))
def testWhiten2(self):
# Excercises missing cases using odd image resolutions with filter.
# Relates to GitHub issue #401.
# Otherwise this is the same as testWhiten, though the accuracy
# (atol) for odd resolutions seems slightly worse.
L = self.L - 1
assert L % 2 == 1, "Test resolution should be odd"
sim = Simulation(
L=L,
n=self.n,
unique_filters=[
RadialCTFFilter(defocus=d) for d in np.linspace(1.5e4, 2.5e4, 7)
],
noise_filter=self.noise_filter,
dtype=self.dtype,
)
noise_estimator = AnisotropicNoiseEstimator(sim)
sim.whiten(noise_estimator.filter)
imgs_wt = sim.images(start=0, num=self.n).asnumpy()
corr_coef = np.corrcoef(imgs_wt[:, L - 1, L - 1], imgs_wt[:, L - 2, L - 1])
# Correlation matrix should be close to identity
self.assertTrue(np.allclose(np.eye(2), corr_coef, atol=2e-1))

We can probably do the test without hardcoding if it's felt that we should keep it.

@chris-langfield
Copy link
Collaborator Author

chris-langfield commented Feb 17, 2022

Summary of changes @j-c-c :

  1. ➕ Add test_downsample.py for the main logical tests. This tests 4 cases (odd-even, odd-odd, etc.) with two different tests. First the "center" gridpoint of the image should match the center of the downsampled image. Then the overall signal energy normalized to the resolution should be approximately conserved. The current downsampling method does not pass this test for one case, but the new method will.
  2. 🔁 Change testDownsample in test_Volume. Instead of hardcoded test add a test with the same logic as in 1). In principle this could be extended to more cases as in 1), but since Volume.downsample() uses Image.downsample() under the hood anyway, I don't believe it's necessary.
  3. ➖ Remove test02Downsample from test_preprocess.py. This hardcoded test should be covered by the tests in 1).
  4. ➖ Remove testDownsample from test_preprocess_pipeline.py. This logical test was expanded and turned into the tests in 1).
  5. ➖ Remove hardcodedtestImageDownsampleAndWhiten from test_starfile_stack.py. The downsampling logic test should be covered by the tests in 1), while there is a logical test for the whitening logic in testWhiten in test_preprocess_pipeline.py.
  6. Leave testImageDownsample in test_starfile_stack.py where it is (right above the test in 5)). I think this test makes sense because it tests the ImageSource.downsample() method specifically, and its behavior, not the downsample algorithm itself.

np.allclose(
anorm(vols.asnumpy(), axes=(1, 2, 3)) / res,
anorm(result.asnumpy(), axes=(1, 2, 3)) / ds_res,
atol=1e-3,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is atol related to the total energy in some way? Just wondering why 1e-3.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Absolute tolerance level for allclose. The default is 1e-8, but I had to bump up the tolerance for our downsample method to pass the test.

Copy link
Collaborator

Choose a reason for hiding this comment

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

If we use smooth Gaussian instead, we should get better energy conservation since we have much less energy in the high frequencies. It may make sense to do this (i.e., generate volumes using gaussian_blobs instead of loading this ribosome).

Copy link
Collaborator

@j-c-c j-c-c left a comment

Choose a reason for hiding this comment

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

Looks good. Just a couple questions.

@chris-langfield chris-langfield requested a review from j-c-c March 4, 2022 15:17
j-c-c
j-c-c previously approved these changes Mar 4, 2022
Copy link
Collaborator

@j-c-c j-c-c left a comment

Choose a reason for hiding this comment

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

Looks good!

@chris-langfield chris-langfield marked this pull request as ready for review March 4, 2022 21:43
@chris-langfield chris-langfield requested a review from janden as a code owner March 4, 2022 21:43
Copy link
Collaborator

@janden janden left a comment

Choose a reason for hiding this comment

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

As I mentioned in the last comment, it may make sense to take this one step further and replace the ribosome volume with Gaussian blobs (that are sufficiently smooth). That should get rid of the loose tolerances since the energy will be preserved.

np.allclose(
anorm(vols.asnumpy(), axes=(1, 2, 3)) / res,
anorm(result.asnumpy(), axes=(1, 2, 3)) / ds_res,
atol=1e-3,
Copy link
Collaborator

Choose a reason for hiding this comment

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

If we use smooth Gaussian instead, we should get better energy conservation since we have much less energy in the high frequencies. It may make sense to do this (i.e., generate volumes using gaussian_blobs instead of loading this ribosome).

janden
janden previously approved these changes Mar 21, 2022
Copy link
Collaborator

@janden janden left a comment

Choose a reason for hiding this comment

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

LGTM

@chris-langfield
Copy link
Collaborator Author

LGTM

We're still using the ribosome file as the test volume for the 3D downsampling. I was working on trying to use 3D Gaussians (but was having a lot of trouble 😁). Did you want to merge this as-is or should I continue?

@chris-langfield
Copy link
Collaborator Author

Could also break it out into a new issue in the interest of getting this downsampling method fully in

@janden
Copy link
Collaborator

janden commented Mar 21, 2022

Sorry got a bit trigger-happy this morning. I'm fine moving it into a separate issue. As a rule, we should be moving to these Gaussian phantoms (away from fixed maps, such as the ribosome).

@chris-langfield
Copy link
Collaborator Author

Sorry got a bit trigger-happy this morning. I'm fine moving it into a separate issue. As a rule, we should be moving to these Gaussian phantoms (away from fixed maps, such as the ribosome).

Sounds good!

@chris-langfield
Copy link
Collaborator Author

Created #600

Re requesting because there was a conflict

Copy link
Collaborator

@janden janden left a comment

Choose a reason for hiding this comment

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

Sorry for the delay. Merge ahead!

@chris-langfield chris-langfield merged commit 05b561f into develop Mar 31, 2022
garrettwrong pushed a commit that referenced this pull request Apr 15, 2022
* downsample tests

* cleanup and deleting test downsample from preprocess_pipeline

* remove hardcoded ds / whiten test

* flake8

* 3d volume downsample test

* remove redundant test from tests/test_preprocess.py

* remove unused import

* remove numbered tests for uniformity

* typo

* skip one of the ds tests

* use gaussian_3d to generate test volume

* isort

* checkCenterPoint

* max_resolution -> L_ds

* parametrize ds tests
chris-langfield added a commit that referenced this pull request Aug 11, 2022
* Fix `k` bug in BFSReddyChetterji

* restrict corr to a disc

* Change `self.L` and `self.n` to `self.src.L` and `self.src.n` for estimators (#550)

* changed self.L and self.n to self.src.L and self.src.n for estimators

* extraneous comma

* Add `aspire.utils.coor_trans.crop_2d` and move `coor_trans` objects to second-level API access (#565)

* utils.coor_trans methods accessible from second level

* crop_2d method

* crop2d test

* clarify flooring behavior for centering and add apdding

* tests finished

* isort shenanigans

* fix even to odd n->n+1 padding bug

* slightly better comment

* better behavior for dtype

* remove mistaken characters

* fixes after merge

* last ensure removed

* rect tests

* padding tests and fill value test

* better comments

* even better comments

* np.diag

* crop_pad_2d

* clarifying comment when padding

* Logical rather than hardcoded downsample tests (#567)

* downsample tests

* cleanup and deleting test downsample from preprocess_pipeline

* remove hardcoded ds / whiten test

* flake8

* 3d volume downsample test

* remove redundant test from tests/test_preprocess.py

* remove unused import

* remove numbered tests for uniformity

* typo

* skip one of the ds tests

* use gaussian_3d to generate test volume

* isort

* checkCenterPoint

* max_resolution -> L_ds

* parametrize ds tests

* Bessel zero finding cleanup (#596)

* docstring for besselj_zeros

* rest of docstrings

* remove pdb import

* second order differences comment

* comments and docstring for num_besselj_zeros

* formatting

* tiny fixes;

* docstring fixes

* NumPy

* NumPy again

* sanity check

* parentheses inside sentence

* `Basis` size fixes (#598)

* fix size checking bug

* fb2d

* fb3d and pswf2d

* dirac

* fpswf

* polar

* format

* sz -> size

* test init with int

* docstring

* typo

* the same typo

* Authors page grammar fix.

* cmap=gray

* Gallery verb tense. Change cmap to gray.

* Update gallery/experiments/README.rst header language.

* Encode size in 2D FB test

* Add test for 2D FB Gaussian expansion

* Add eval–expand test for 2D FB

* Add adjoint test for 2D FB

* Add test for isotropic and modulated in 2D FB

* Add test for indices

* Add test for specific FB 2D basis element

* Make 2D FB tests FFB friendly

Cast `Images` to arrays when needed.

* Move tests not specific to FB into a mixin

* Add mixin to FFB 2D tests

* Remove hardcoding from complex conversion tests

* First attempt at testElement for FFB2D

* Remove hardcoded (F)FB2D tests

* Parameterize tests

* Pass dtype to gaussian_2d

* Expand on comment regarding factor of 1/2

* Fix rtoc bug

* Add shape checks

To make sure we don't get the same inadvertent broadcasting bug again.

* Loop over different indices in 2D (F)FB tests

* Fix #604 (#607)

* Bump version: 0.9.0 → 0.9.1

* Fourier-Bessel Mixin class (#599)

Fourier Bessel Mixin Class: fb.py

* initial changes to code and tests

* FFB bases

* dirac

* tentative fixes to mean estimator tests

* import

* covar3d mat_evaluate fix

* unnecessary check

* comments

* black

* fb2d check evaluate

* fb3d

* ffb3d

* fb3d comments

* dirac

* fb2d

* ffb2d

* importvolume

* pswf

* fpswf

* class checking logic moved to Basis

* asnumpy in evaluate_t fb 3d bases

* evaluate_t fixes

* f string

* fixes

* fb2d image check consistent with fb3d

* import

* ISinstance

* an Image

* fix Dirac basis evaluate_t

* dirac basis comments

* remove volume check

* Revert "remove volume check"

This reverts commit 86d920e.

* repr for Volume class

* right place to squeeze in estimate()

* no pdb

* adjusted comments

* remove new space clutter

* clarified kernel_convolve squeeze

* some changes

* FB evaluate_t inputs are always Images/Volumes, just take transpose of asnumpy

* remove dtype warnings

* no pdb

* diract evaluate_t take images

* move repetitive function tests up to basis_util

* cleanups

* no self.L pswf

* mat_evaluate_t

* remove dirac

* remove dirac tests

* pswf

* int size test in _basis_util

* polar2d

* remove image assert

* remove type checks

* space

* spaces

* final format

* fix self.size typo

* comment in mat_evaluate_t

* replace DiracBasis with PolarBasis2D in unit test

Co-authored-by: Garrett Wright <[email protected]>
Co-authored-by: Garrett Wright <[email protected]>
Co-authored-by: Joakim Andén <[email protected]>
Co-authored-by: Josh Carmichael <[email protected]>
Co-authored-by: Josh Carmichael <[email protected]>
chris-langfield added a commit that referenced this pull request Sep 1, 2022
* Fix `k` bug in BFSReddyChetterji

* restrict corr to a disc

* Change `self.L` and `self.n` to `self.src.L` and `self.src.n` for estimators (#550)

* changed self.L and self.n to self.src.L and self.src.n for estimators

* extraneous comma

* Add `aspire.utils.coor_trans.crop_2d` and move `coor_trans` objects to second-level API access (#565)

* utils.coor_trans methods accessible from second level

* crop_2d method

* crop2d test

* clarify flooring behavior for centering and add apdding

* tests finished

* isort shenanigans

* fix even to odd n->n+1 padding bug

* slightly better comment

* better behavior for dtype

* remove mistaken characters

* fixes after merge

* last ensure removed

* rect tests

* padding tests and fill value test

* better comments

* even better comments

* np.diag

* crop_pad_2d

* clarifying comment when padding

* Logical rather than hardcoded downsample tests (#567)

* downsample tests

* cleanup and deleting test downsample from preprocess_pipeline

* remove hardcoded ds / whiten test

* flake8

* 3d volume downsample test

* remove redundant test from tests/test_preprocess.py

* remove unused import

* remove numbered tests for uniformity

* typo

* skip one of the ds tests

* use gaussian_3d to generate test volume

* isort

* checkCenterPoint

* max_resolution -> L_ds

* parametrize ds tests

* Bessel zero finding cleanup (#596)

* docstring for besselj_zeros

* rest of docstrings

* remove pdb import

* second order differences comment

* comments and docstring for num_besselj_zeros

* formatting

* tiny fixes;

* docstring fixes

* NumPy

* NumPy again

* sanity check

* parentheses inside sentence

* `Basis` size fixes (#598)

* fix size checking bug

* fb2d

* fb3d and pswf2d

* dirac

* fpswf

* polar

* format

* sz -> size

* test init with int

* docstring

* typo

* the same typo

* Authors page grammar fix.

* cmap=gray

* Gallery verb tense. Change cmap to gray.

* Update gallery/experiments/README.rst header language.

* Encode size in 2D FB test

* Add test for 2D FB Gaussian expansion

* Add eval–expand test for 2D FB

* Add adjoint test for 2D FB

* Add test for isotropic and modulated in 2D FB

* Add test for indices

* Add test for specific FB 2D basis element

* Make 2D FB tests FFB friendly

Cast `Images` to arrays when needed.

* Move tests not specific to FB into a mixin

* Add mixin to FFB 2D tests

* Remove hardcoding from complex conversion tests

* First attempt at testElement for FFB2D

* Remove hardcoded (F)FB2D tests

* Parameterize tests

* Pass dtype to gaussian_2d

* Expand on comment regarding factor of 1/2

* Fix rtoc bug

* Add shape checks

To make sure we don't get the same inadvertent broadcasting bug again.

* Loop over different indices in 2D (F)FB tests

* Fix #604 (#607)

* Bump version: 0.9.0 → 0.9.1

* Fourier-Bessel Mixin class (#599)

Fourier Bessel Mixin Class: fb.py

* New downsample method (#606)

* dropped in new ds method

* adjust tests temporarily

* some imports

* change to centered_fft2 and allow gridpoint checks

* format

* remove debug show()

* comment

* simplify centered_fft2 and centered_ifft2

* dict of dicts

* adjusted tests

* Zenodo file with authors and affiliations (#615)

* add zenodo file with just creators

* name

* add zenodo file to manifest

* json errors

* chris orcid

* updated affiliations

* update tox.ini to include json.tool check

* josh orcid

* author ordering

* review changes

* Remove offending sk import

* Explicitly use svd_solver='full' for repro unit test

* Fix PIL deprecation warning

* sensible defaults

* optional saving mrc

* populate_unique_filters and read_ctf_file

* body of populate_unique_filters

* loop var

* tests

* work around ImageSource.set_metadata

* update test

* final test

* rationalize sample CTF values

* readme space

* correct metadata test

* write_all_star

* remove write_one_star

* method name

* reading from Relion micrograph_ctf.star

* format

* import_ctf() instead of __init__ option

* added tests and clarified import_ctf method

* condense ctf args coordinate source

* .values() instead of items()

* add save image flags to increase test converage

* docstrings

* rest of docstrings

* rename fun to populate_ctf

* first pass refactor

* refactor 2

* docstring

* refactor 3

Co-authored-by: Garrett Wright <[email protected]>
Co-authored-by: Garrett Wright <[email protected]>
Co-authored-by: Joakim Andén <[email protected]>
Co-authored-by: Josh Carmichael <[email protected]>
Co-authored-by: Josh Carmichael <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI Continuous Integration cleanup enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Move from hardcoded to logical downsampling tests Downsample bug

5 participants