Skip to content

Conversation

@j-c-c
Copy link
Collaborator

@j-c-c j-c-c commented Jul 25, 2024

This resolves the issues found in #1155. See issue for results of the changes in this PR.

The main changes in this PR are:

  1. Use centered_fftn for Volume.downsample:
  2. Option to not zero out nyquist frequency for even resolution in Image.project and Image.backproject. Set to not zero out by default.
  3. Resolve some hardcoded test failures related to the above changes.
  4. Improve tolerance for some tests that were using project with nyquist frequencies zero'd out.

@j-c-c j-c-c added the bug Something isn't working label Jul 25, 2024
@j-c-c j-c-c self-assigned this Jul 25, 2024
@j-c-c j-c-c requested a review from garrettwrong July 29, 2024 19:05
Copy link
Collaborator

@garrettwrong garrettwrong left a comment

Choose a reason for hiding this comment

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

Thanks for tracking this down. Couple cleanup items, but overall very good thanks!

@j-c-c j-c-c force-pushed the ds_bug branch 2 times, most recently from 29e04b1 to 6503a17 Compare August 1, 2024 18:21
@j-c-c j-c-c requested a review from garrettwrong August 1, 2024 18:27
garrettwrong
garrettwrong previously approved these changes Aug 1, 2024
Copy link
Collaborator

@garrettwrong garrettwrong left a comment

Choose a reason for hiding this comment

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

Up to you regarding the method overload vs hiding option from user. Either should work well.

I think this can move forward as it is obviously an improvement that we want.

However, I have a nagging concern about both our 2d and 3d downsamples. They don't seem to agree very well (IMO) with an idealized real space downsample. Consider this function. (It's easily extended to more dimensions).

def ds2(x, bs=2):
    x = x.reshape(L//bs, bs, L//bs, bs)
    x = np.mean(x, (1,3))  # traditionally I think would be a sum here, but... regardless...
    return x

I looked at it as a sanity reference when we were chatting about the shifting/centering yesterday, and then decided not to look anymore 😇 🙈 .


# take 3D Fourier transform of each volume in the stack
fx = fft.fftshift(fft.fftn(xp.asarray(v._data), axes=(1, 2, 3)))
fx = fft.centered_fftn(xp.asarray(v._data), axes=(1, 2, 3))
Copy link
Collaborator

Choose a reason for hiding this comment

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

Don't think you need to specify axes here.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Did you need the axes after all?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Oops. Thought I removed those. They are now removed :)

return self._projections_accessor

def _projections(self, indices):
def _projections(self, indices, legacy=False):
Copy link
Collaborator

Choose a reason for hiding this comment

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

There are ways to avoid this extra argument; mentioned one in other remark.

If you keep the flag, Joakim can let you know if he prefers to continue using the other var name (zero_nyquist).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thought about using zero_nyquist too, but went with legacy so it would be more apparent that it would need to be removed if we eventually do away with _LegacySimulation.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I figured, might not need. No worries.

@j-c-c j-c-c marked this pull request as ready for review August 1, 2024 19:53
@j-c-c j-c-c requested a review from janden as a code owner August 1, 2024 19:53
@j-c-c
Copy link
Collaborator Author

j-c-c commented Aug 12, 2024

@janden, I made the changes that we discussed during our last dev meeting. Namely, that we default to zeroing out the Nyquist frequencies in Volume.project and Image.backproject for even resolutions. And also, adding a zero_nyquist flag to Image.downsample and Volume.downsample, which by default zeroes out the Nyquist frequency when downsampling into even resolution.

These changes maintain our centering convention and also have the property that vol.project().downsample() == vol.downsample().project().

However, there are definitely artifacts introduced by removing the Nyquist frequencies in project. For example, for a random volume we have
np.allclose(vol.project(), manual_proj) == False, but
np.allclose(vol.project(zero_nyquist=False), manual_proj) == True,

where manual_proj is the manual projection of the volume found by taking the mean over the z-axis.

We can see these artifacts in the one_hot example I posted in the related issue, which now looks like this:
Screenshot 2024-08-12 at 3 45 47 PM

Ultimately, I think we just need to decide what we want our defaults to be.

janden
janden previously approved these changes Aug 26, 2024
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.

Looks great! Just one small question.

Regarding the artifacts, I think this is fine for now. Recall that the one-hot volumes and images are actually quite different from the type of images we expect to see (i.e., they are not smooth, but “discontinuous”).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants