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

Accept array-like instead of just lists #11

Closed
ianhi opened this issue Jul 6, 2021 · 5 comments · Fixed by #101
Closed

Accept array-like instead of just lists #11

ianhi opened this issue Jul 6, 2021 · 5 comments · Fixed by #101

Comments

@ianhi
Copy link
Contributor

ianhi commented Jul 6, 2021

It would be nice to in general accept numpy arrays instead of specifying lists. For example specifying a z_plan with a numpy array breaks:

import numpy as np
from useq import ZRelativePositions

# works
ZRelativePositions(relative=np.arange(-1.5, 1.5, 0.5).tolist())

# breaks
ZRelativePositions(relative=np.arange(-1.5, 1.5, 0.5))

ref: https://numpy.org/devdocs/reference/typing.html

@tlambert03
Copy link
Member

sure, seems reasonable to me:

you could do that by modifying ZPlan as follows:

from pydantic import validator

class ZPlan(BaseModel):
    go_up: bool

    _normrel = validator("relative", pre=True, allow_reuse=True, check_fields=False)(list)
    _normabs = validator("absolute", pre=True, allow_reuse=True, check_fields=False)(list)
    ...

wanna add that in a PR? maybe look for some other List fields that might make sense to convert?

@tlambert03
Copy link
Member

side note: there is a builtin plan for ZRelativePositions(relative=np.arange...) called ZTopBottom (but it's range inclusive which seems to be what people generally want when setting up an experiment)... but I'm realizing now that it's not exported in the top level useq namespace and it should be:

In [20]: from useq._z import ZRelativePositions, ZTopBottom

In [21]: a = ZRelativePositions(relative=np.arange(-1.5, 1.6, 0.5).tolist())

In [22]: b = ZTopBottom(bottom=-1.5, top=1.5, step=0.5)

In [23]: list(a) == list(b)
Out[23]: True

@ianhi
Copy link
Contributor Author

ianhi commented Jul 6, 2021

I think there is a key difference there in that ZTopBottom is absolute units per the readme:

ZTopBottom - specify absolute top, bottom, and step

So it's less helpful than ZRelativePositions if you have multiple positions

@tlambert03
Copy link
Member

ah yes! :) indeed it is, sorry my bad. ZAboveBelow is the relative variant:

In [26]: c = ZAboveBelow(above=1.5, below=-1.5, step=0.5)

In [27]: list(c)
Out[27]: [-1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5]

@tlambert03
Copy link
Member

tlambert03 commented Jul 6, 2021

btw, if the different constructors and argument names feel weird, the primary benefit here is that you could define an experiment declaratively using yaml

# this one can only be `ZRangeAround`
z_plan:
   range: 1.0
   step: 0.5

# this one can only be `ZAboveBelow`
z_plan:
   above: 1.5
   below: -1.5
   step: 0.5

... and the amazing pydantic is smart enough to know that Sequence(z_plan={'range': 1, 'step': 0.5}) should convert z_plan into a ZRangeAround

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 a pull request may close this issue.

2 participants