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

Allow relative z in multi_d_acquisition_events #158

Merged
merged 4 commits into from
Oct 18, 2020

Conversation

ianhi
Copy link
Contributor

@ianhi ianhi commented Oct 13, 2020

Closes: #153

This should maintain all the previous behaviors but also allow for specifying z positions in these new ways:

  • z_positions as 2D array
  • z_positions as 1D array
  • z_positions as 1D array + relative positions

which is hopefully made clear in the new docs page I added for this.

Stuff like this is a great candidate for pytest, I thought about adding that but didn't becuase you already have a large user automated testing DIR that I wasn't sure would work with pytest on CI. Let me know what would be best

@henrypinkard
Copy link
Member

A couple things:

  • The contents and the description of the notebook are not in the same order on the applications page
  • In the notebook I think you can delete the part with np.c_ and just show hstack, since this is showing a feature of numpy, not pycromanager
  • I was a bit confused about the docstring for multi_d_acquisition_events, specifically the "for each xy point, or 2D (shape: (N, n_z) ) to fully specify the xyz points". After reading the notebook I get what n_z is supposed to be. But I think it might be a simpler interface for this to have xyz_positions and xy_positions, where the former automatically puts you into relative z mode and any z stacks are relative to it, while the latter defaults to absolute z mode if a z stack is provided. This wway i think would fit in more with the existing API, and it would leave less work for the user in the case of different z stacks at different positions (i.e. just supply xyz_positions and z_start, z_end, z_step without having to construct the 2d array yourself). What do you think?
  • The additional descriptions of channels/time in the notebook is really nice. It could be good to link to this notebook from the features page on MDAs

@henrypinkard
Copy link
Member

Also, yes, it would be great to some more stuff built into automatic testing. That test directory is not automated at the moment, I just copy and paste them to quickly debug when I think things are broken. @bryantChhun has also been thinking about adding automated testing. Maybe better to continue this conversation on the issue for it

@ianhi
Copy link
Contributor Author

ianhi commented Oct 14, 2020

The contents and the description of the notebook are not in the same order on the applications page

The additional descriptions of channels/time in the notebook is really nice. It could be good to link to this notebook from the features page on MDAs

I'm not sure I understand what the order is meant to be. Is it chronological? Also, if anything this notebook is more of a tutorial than an application, would it make sense to fold it into the page on MDAs?

I was a bit confused about the docstring for multi_d_acquisition_events, specifically the "for each xy point, or 2D (shape: (N, n_z) ) to fully specify the xyz points". After reading the notebook I get what n_z is supposed to be. But I think it might be a simpler interface for this to have xyz_positions and xy_positions, where the former automatically puts you into relative z mode and any z stacks are relative to it, while the latter defaults to absolute z mode if a z stack is provided. This wway i think would fit in more with the existing API, and it would leave less work for the user in the case of different z stacks at different positions (i.e. just supply xyz_positions and z_start, z_end, z_step without having to construct the 2d array yourself). What do you think?

I was probably doing some premature optimization here, the current setup allows for different non-uniform stepped z stacks for each positions. So you could have
pos1: z = [-3,-1,0]
pos2: z= [-10, -1, 0]

but that's probably not necessary to include.

To be explicit you're proposing the following call signatures:

# Gives relative z
multi_d_acquisition_events(xyz_positions = xyz)
multi_d_acquisition_events(xyz_positions = xyz, z_start=-1, z_stop = 1, z_step=1)

# absolute z
multi_d_acquisition_events(z_start=0, z_stop=10,z_step=1)
multi_d_acquisition_events(xy_positions = xy, z_start=0, z_stop=10,z_step=1)

I'd suggest adding the option of an array of relative z values:
(this should give the same result as xyz_positions passed with z_start et al)

multi_d_acquisition_events(xyz_positions = xyz, z_rel = np.linspace(-1,1,3))

The only downsides I see are:

  1. you need to know current xy point in order to make a single position z stack
  2. not totally clear to me how best to handle an order string like zp
    • This PR already probably won't work in that case though :/

@henrypinkard
Copy link
Member

The additional descriptions of channels/time in the notebook is really nice. It could be good to link to this notebook from the features page on MDAs

I'm not sure I understand what the order is meant to be. Is it chronological? Also, if anything this notebook is more of a tutorial than an application, would it make sense to fold it into the page on MDAs?

Vaguely scales with complexity. Either position in the ordering is fine, you've just got it first in the TOC but second on the actual list right now (or vice versa). I think given the density of it, it makes more sense to have it with applications.

I was a bit confused about the docstring for multi_d_acquisition_events, specifically the "for each xy point, or 2D (shape: (N, n_z) ) to fully specify the xyz points". After reading the notebook I get what n_z is supposed to be. But I think it might be a simpler interface for this to have xyz_positions and xy_positions, where the former automatically puts you into relative z mode and any z stacks are relative to it, while the latter defaults to absolute z mode if a z stack is provided. This wway i think would fit in more with the existing API, and it would leave less work for the user in the case of different z stacks at different positions (i.e. just supply xyz_positions and z_start, z_end, z_step without having to construct the 2d array yourself). What do you think?

I was probably doing some premature optimization here, the current setup allows for different non-uniform stepped z stacks for each positions. So you could have
pos1: z = [-3,-1,0]
pos2: z= [-10, -1, 0]

but that's probably not necessary to include.

Makes sense. Generally speaking I don't think its worth the effort to try to get every edge case into this function, since for customized stuff you should probably just be going a level deeper and creating events manually anyway. In my mind z-stacks with custom nonuniform step spacing would fall under this

To be explicit you're proposing the following call signatures:

# Gives relative z
multi_d_acquisition_events(xyz_positions = xyz)
multi_d_acquisition_events(xyz_positions = xyz, z_start=-1, z_stop = 1, z_step=1)

# absolute z
multi_d_acquisition_events(z_start=0, z_stop=10,z_step=1)
multi_d_acquisition_events(xy_positions = xy, z_start=0, z_stop=10,z_step=1)

Yeah exactly. Or maybe a relative_z=True argument could be added to make this explicit. What do you prefer?

I'd suggest adding the option of an array of relative z values:
(this should give the same result as xyz_positions passed with z_start et al)

multi_d_acquisition_events(xyz_positions = xyz, z_rel = np.linspace(-1,1,3))

I think its better to make an example of doing this manually than to have an explicit option. The purpose of this function is a a convenience for people who dont want to dig any deeper into the API, so I think the fewer ways of doing things, the better

The only downsides I see are:

1. you need to know current xy point in order to make a single position z stack

Maybe this is an argument for relative_z=True argument

2. not totally clear to me how best to handle an order string like `zp`

Fine to just throw in an exception in the cases that it doesnt make sense

@ianhi ianhi closed this Oct 15, 2020
@ianhi ianhi reopened this Oct 15, 2020
@ianhi ianhi force-pushed the relative-z branch 2 times, most recently from 58766a6 to 8f3d320 Compare October 15, 2020 02:38
@ianhi
Copy link
Contributor Author

ianhi commented Oct 15, 2020

@henrypinkard I think this is good now. I ended up adding github actions to run the pytest tests I added for MDA, but I think you need to change a setting to get them to run on PRs. I opened a PR against my fork and the tests all ran there: ianhi#1 I think you need to modify these settings:
image

@ianhi
Copy link
Contributor Author

ianhi commented Oct 15, 2020

Yeah exactly. Or maybe a relative_z=True argument could be added to make this explicit. What do you prefer?

I went for raising errors rather than adding yet more kwargs.

Makes sense. Generally speaking I don't think its worth the effort to try to get every edge case into this function,

sounds good! It indeed simplified it greatly.

@bryantChhun has also been thinking about adding automated testing. Maybe better to continue this conversation on the issue for it

In a moment of forgiveness is better than permission I went ahead and greated github actions + pytest tests for the content of this PR. Testing the actual functionality of the integration with μmanager would be much more complex though so I'll leave that to the other issue.

pytest supports multiple test directories and I think its pretty standard to have one inside the pycromanager folder so I added one there for testing things that are contained to python, should be easy enough to add in the other test directory or combine them in future. But I wanted to keep the automated and non-automated stuff separate for now.

z_positions = xyz_positions[:,2][:, None]

if has_zsteps:
z_rel = np.arange(z_start, z_end + z_step, z_step)
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This includes one more point than the old version. To me this way make more sense but it is clearly backwards incompatible.. let me know if you'd prefer this to be

Suggested change
z_rel = np.arange(z_start, z_end + z_step, z_step)
z_rel = np.arange(z_start, z_end, z_step)

Copy link
Member

Choose a reason for hiding this comment

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

Yeah I think that's fine and probably an upgrade

@bryantChhun
Copy link

In a moment of forgiveness is better than permission I went ahead and greated github actions + pytest tests for the content of this PR. Testing the actual functionality of the integration with μmanager would be much more complex though so I'll leave that to the other issue.

no worries! I didn't do much other than add some mocks and a couple tests. Will create a PR soon. And in general, I never discourage anyone from writing tests for their code :-)

There was a discussion by email about the more complex testing with umanager (apologies, we agreed we'll move those discussions to github issues). The general conclusion was that other umanager work (release of 2.0) is taking priority. Continuous Integration with micromanager will require solving some issues in the 2.1 release..

@henrypinkard henrypinkard merged commit 9450c3f into micro-manager:master Oct 18, 2020
@henrypinkard
Copy link
Member

I think this is good now. I ended up adding github actions to run the pytest tests I added for MDA, but I think you need to change a setting to get them to run on PRs. I opened a PR against my fork and the tests all ran there: ianhi#1 I think you need to modify these settings:

I looked on the settings but it was the same as the picture you posted -- allow all actions was already selected.

@henrypinkard
Copy link
Member

Any other ideas on how to set it up like you had in that link?

@ianhi
Copy link
Contributor Author

ianhi commented Oct 19, 2020

Any other ideas on how to set it up like you had in that link?

🤔 hmm. I would have thought that was all that was necessary. I suppose there isn't an error in the yaml file as they ran on my fork. It looks as though they did run once you merged it:
image

I'm going to try opening a dummy PR to see if they will trigger on that now that they're properly in master, maybe its different than my repo bc I don't own it.

@ianhi
Copy link
Contributor Author

ianhi commented Oct 19, 2020

See #162. looks as though the tests work on newly created PR

@ianhi ianhi deleted the relative-z branch October 19, 2020 18:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Variable z positions in multi_d_acquisition_events
3 participants