Replies: 4 comments 1 reply
-
Here is a basic example of how I imagine the decorator: import zospy as zp
import zospy.constants as constants
import zospy.api._ZOSAPI as _ZOSAPI
from zospy.analyses.base import new_analysis, AnalysisResult, OnComplete
def opticstudio_analysis(analysis_type: constants.Analysis.AnalysisIDM | str, txtoutfile: bool = False, cfgoutfile: bool = False):
def analysis_decorator(f):
def wrapper(oss: zp.zpcore.OpticStudioSystem, *args, **kwargs):
analysis_type = constants.process_constant(constants.Analysis.AnalysisIDM, analysis_type)
analysis = new_analysis(oss, analysis_type)
txtoutfile_path = kwargs.pop("txtoutfile", None)
cfgoutfile_path = kwargs.pop("txtoutfile", None)
oncomplete = kwargs.pop("oncomplete", OnComplete.Close)
if txtoutfile:
# Handle txtoutfile
if cfgoutfile:
# Handle cfgoutfile
result = f(analysis, *args, **kwargs)
result.headerdata = analysis.get_headerdata()
result.metadata = analysis.get_metadata()
result.messages = analysis.get_messages()
return analysis.complete(result, oncomplete)
return wrapper |
Beta Was this translation helpful? Give feedback.
-
I think this could be a good change and I like the implementation by @crnh. Originally, my thinking was that there would be decorators e.g. for handling creation and cleanup of txtoutfile or cfgoutfile only. They could be added whenever these files are needed to the analysis function and thus keep the code of the analysis itself clean. I imagine using it something like this: @textoutputfile
@cfgoutputfile
def polarization_pupil_map(
oss: OpticStudioSystem,
jx: float = 1,
jy: float = 0,
x_phase: float = 0,
y_phase: float = 0,
wavelength: int = 1,
field: int = 1,
surface: str | int = "Image",
sampling: str | int = "11x11",
add_configs: str = "",
sub_configs: str = "",
oncomplete: OnComplete | str = OnComplete.Close,
cfgoutfile: str | None = None,
txtoutfile: str | None = None,
) -> AnalysisResult:
# Run analysis and retrieve result
...
return analysis.complete(oncomplete, result) I was not quite sure how to get the arguments from the analysis function correctly, even if they are 'None' but I think @crnh solved that :) |
Beta Was this translation helpful? Give feedback.
-
This feature is planned for the next major release, which will streamline the development of new analysis wrappers. |
Beta Was this translation helpful? Give feedback.
-
It's been a while, but we are currently working on something related to this; see PR #78 . |
Beta Was this translation helpful? Give feedback.
-
Currently, a lot of code is duplicated between all analyses. This has been improved by the
Analysis.complete
method, but still many analyses contain the same code for handling input and output files and retrieving header data, metadata and error messages.I briefly considered using analysis classes instead of analysis functions, but this would change the API, which I would like to avoid. Furthermore, I prefer a procedural interface over an object-oriented interface for analyses.
Based on a suggestion by @andibarg, I propose to write a decorator for analyses. This decorator creates the analysis, handles
txtoutfile
andcfgoutfile
, runs the decorated analysis function, adds the header data, metadata and error messages to theAnalysisResult
, and then handlesoncomplete
.It should be noted that this decorator will change the signature of the analysis function, i.e. it will add the
oss
,txtoutfile
,cfgoutfile
andoncomplete
parameters, and remove theanalysis
parameter, since this is injected by the decorator. I think this will break autocomplete. I knowfunctools.wraps
is often used to propagate docstrings and annotations to the decorated function, but this won't help in our case, due to the changed signature.However, it will still be possible to provide correct autocompletions by adding
.pyi
files with the signatures and docstrings for the decorated functions.I would like to hear your opinion on this! Is there anything that can be improved in this design, or do you know about different methods to preserve autocomplete without having to add
.pyi
files?Beta Was this translation helpful? Give feedback.
All reactions