-
Notifications
You must be signed in to change notification settings - Fork 8
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
Implement geomopt Constraints #313
base: main
Are you sure you want to change the base?
Conversation
- Separate parameter from filter_func - kwargs come from minimize_args, same as filter args - Check if the constraint needs "atoms" and insert if so
38d149c
to
71969dd
Compare
At this point the info is passed into the GeomOpt class. @ElliottKasoar suggests we can simplify things with something like struct.set_constraint(constraint)
GeomOpt(struct) in cli.geomopt, instead. I suppose the main reason not to do this would be that it moves more logic into the (more awkward to test) command-line wrapper, and reduces feature parity between If as a project, Janus intends that the Python API is quite similar to the CLI then it might make sense to keep the model here. But if it is expected that the Python API is a bit more streamlined and aimed at expert users, then it would be good to pull the constraint options out of GeomOpt and delegate the information to the incoming structure. |
That was partly intended as a temporarily solution that I think should work for now, before we merge something like this PR. For API goals, as long as any features added to the CLI are still possible through the Python, I wouldn't rule things out, and I think this could work either way. But, in general I'd prefer to keep how we interact with each interface similar (this wasn't quite the driving force, but was a nice benefit of adding reading structure files natively to each calculation class), even at the expense of slightly more code/complexity, so it probably still makes most sense to set the constraint within each Python calculation class, as you have now. In terms of implementation, I'd imagine eventually we'll want to have a helper function to set the constraint(s?), since we may want to use this elsewhere (e.g. @alinelena used it in MD in the past). Having the less general implementation just for geom_opt is fine for now though. |
I had wondered about the multiple constraints case, too! Choosing more than one constraint name is not so bad, but the command line syntax could get rather unwieldy if multiple sets of parameter kwargs are also needed. |
If using the Python API and then selecting a constraint in I don't really like mutating inputs except when a function only mutates input. |
The command line could actually be nicer than you might think, since the way lists are passed is by repeating the option e.g.
I'm definitely open to opinions on what makes most sense and feels consistent with ASE usage generally. Currently the inputs are mutated, but not in a way that should effect future calculations, so I think detaching the constraint would be most consistent with that? |
The question is if a constraint takes multiple parameters how are these grouped? Can you build a list of arbitrary tuples? e.g
|
I think Janus already requires that other kwargs are provided as string-quoted Python dictionaries. It's a bit ugly but for consistency we should stick with that rather then running into Typer's inability to deal with arbitrary-length options again. So we end up with which isn't so bad. It's nice to see a good case of the "forcing you to repeat the kwarg" behaviour for a change 😆 |
Nothing too specific. I tend to add CLI tests since it effectively tests both the CLI and the Python, but otherwise as long as being able to set the constraint is tested, and ideally error handling is tested etc. too for good coverage, it should be fine.
I'm not against changing both to
The summary is built from the From your docstring in geom_opt.py, it looks like this should work the same way for In general it is also fine to append things to be saved in the summary that aren't directly passed to the calculation class, but in this case I don't think it should be necessary. |
we will need an example, check stfc/janus-tutorials |
Closes #311
TODO:
constraint_func
is used here for consistency withfilter_func
, but it's a bad name because constraints are actually a class. So are Filter instances; the difference is that Filter is typically called on the Atoms (wrapping them) whereas constraints are attached. From the CLI it would really be nicer if these were "--filter" and "--constraint", and inside the Python API it would be clearer if they werex_class
.filter_kwargs
appear in the summary YAML but notconstraint_kwargs
.