Replies: 4 comments 5 replies
-
|
Let's do some high level planning here
# In EasyReflectometryLib
class ReflectometryCalculatorFactory(CalculatorFactoryBase):
_calculators = {'refl1d': Refl1dCalculator, 'refnx': RefnxCalculator}
def create(self, name: str, model, instrumental_parameters, **kwargs) -> CalculatorBase:
return self._calculators[name](model, instrumental_parameters, **kwargs)
# User code
sample = MultilayerSample(...)
instrument = InstrumentalParameters(resolution=0.05, ...)
factory = ReflectometryCalculatorFactory()
calculator = factory.create('refl1d', sample, instrument)
# Single point calculation (uses both sample and instrument internally)
reflectivity = calculator.calculate(q_values)
sld = calculator.get_sld_profile()
# Update instrument parameters (e.g., for different measurement conditions)
new_instrument = InstrumentalParameters(resolution=0.02, ...)
calculator.update_instrumental_parameters(new_instrument)
# Fitting
fitter = Fitter(sample, calculator.calculate)
result = fitter.fit(x_data, y_data)
# Switch calculator engine (keeps same model and instrument)
calculator_new = factory.create('refnx', sample, instrument)
fitter.fit_function = calculator_new.calculate |
Beta Was this translation helpful? Give feedback.
-
|
Adding comment from PR here for documentation purposes: |
Beta Was this translation helpful? Give feedback.
-
|
Another question, should the Factory class be a singleton? If the factory has attributes which can be changed, I think it makes sense to make it a singleton. |
Beta Was this translation helpful? Give feedback.
-
|
It's a bit unclear what the intended role of the abstract calculate() method in CalculatorBase is, especially when compared to technique-specific methods. In reflectometry, calculate() is implemented in ReflectivityCalculator, but there is also a separate get_sld_profile() method defined only there. Could you clarify the conceptual difference between a reflectivity curve and an SLD profile? Are these two fundamentally different results that are both always relevant in reflectometry, or is one more of an auxiliary output? If both outputs are essential, why is only one exposed through the generic calculate() interface, while the other is accessed via a technique-specific method? More generally, how should we handle calculators that naturally produce multiple types of results? For example, in diffraction we may want both a calculated diffraction pattern and calculated Bragg peak positions. In such cases:
|
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
In version 1.1.2 of the
EasySciencewe rely on the classObjects.Inferface.InterfaceFactoryTemplateto obtain functionality to determine the result/response from a sample. In reflectometry these results/responses are thereflectivitycurve and theSLDcurve. The current solution allows the user to change between different physics calculators by switching the state of the "Factory".There are several issues with the current setup:
Interfaceway to generic and even misleading. Instead it should beCalculatorfit_functhat is complete non-explanatoryFactorysince it doesn't produce any objects as expected from a factory patterncreateactually seems to produce an interface (calculator)generate_bindings)FitterIn an attempt to simplify the calculator functionality the following changes are suggested:
fitting.minimizerswhere the factory is only responsible for producing the requested calculator objectEasySciencelevel it will probably only be a matter of defining the calculator base class and defining an abstract base factory to ensure that such calculator objects are returnedEasyXXXLibrepo similar to where the interfaces (calculators) are implementedBeta Was this translation helpful? Give feedback.
All reactions