diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2ee9f0e2..817b2831 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -193,6 +193,30 @@ git add . git commit -m "Improve performance of time integrator for large systems" ``` +### Imports in Tutorials and Examples + +Anything user-facing — the tutorial notebooks and the `python` examples +in docstrings — reaches EasyDynamics through a single namespace: + +```python +import easydynamics as edyn + +experiment = edyn.Experiment('Vanadium') +model = edyn.SampleModel(components=edyn.Gaussian(width=0.1)) +``` + +Every public name is re-exported from `easydynamics`, so this always +works. Please do not mix in `import easydynamics.sample_model as sm`, or +reach into a module with +`from easydynamics.analysis.analysis1d import Analysis1d`: a reader then +has to scroll back to the imports to find out where a name came from. + +If something you need is missing from `edyn.`, add it to `__all__` in +`src/easydynamics/__init__.py` rather than importing around it. + +Inside the library itself, keep importing from the specific module that +defines a name. Only the public front door is flat. + --- ## 6. Code Quality Checks diff --git a/docs/docs/tutorials/analysis.ipynb b/docs/docs/tutorials/analysis.ipynb index 7ba7858b..671e38a7 100644 --- a/docs/docs/tutorials/analysis.ipynb +++ b/docs/docs/tutorials/analysis.ipynb @@ -24,7 +24,6 @@ "import pooch\n", "\n", "import easydynamics as edyn\n", - "import easydynamics.sample_model as sm\n", "\n", "%matplotlib widget" ] @@ -56,28 +55,28 @@ "# Example of Analysis with a simple sample model and instrument model\n", "# The scattering from vanadium is purely elastic, so we model it with a\n", "# delta function\n", - "delta_function = sm.DeltaFunction(display_name='DeltaFunction', area=1)\n", - "sample_model = sm.SampleModel(\n", + "delta_function = edyn.DeltaFunction(display_name='DeltaFunction', area=1)\n", + "sample_model = edyn.SampleModel(\n", " components=delta_function,\n", ")\n", "\n", "# The resolution is in this case modeled as a Gaussian. However, we can\n", "# add as many components as we like to the resolution model\n", - "res_gauss = sm.Gaussian(width=0.1)\n", + "res_gauss = edyn.Gaussian(width=0.1)\n", "res_gauss.area.fixed = True\n", - "resolution_components = sm.ComponentCollection()\n", + "resolution_components = edyn.ComponentCollection()\n", "resolution_components.append_component(res_gauss)\n", - "resolution_model = sm.ResolutionModel(components=resolution_components)\n", + "resolution_model = edyn.ResolutionModel(components=resolution_components)\n", "\n", "# The background model is created in the same way. In this case, we use\n", "# a flat background\n", - "background_model = sm.BackgroundModel(components=sm.Polynomial(coefficients=[0.001]))\n", + "background_model = edyn.BackgroundModel(components=edyn.Polynomial(coefficients=[0.001]))\n", "\n", "# We combine the resolution abd background model into an instrument\n", "# model. This model also contains a small energy offset to account for\n", "# instrument misalignment.\n", "\n", - "instrument_model = sm.InstrumentModel(\n", + "instrument_model = edyn.InstrumentModel(\n", " resolution_model=resolution_model,\n", " background_model=background_model,\n", ")\n", @@ -190,19 +189,19 @@ "# Now we set up the model, similarly to how we set up the model for the\n", "# vanadium data.\n", "\n", - "delta_function = sm.DeltaFunction(display_name='DeltaFunction', area=0.2)\n", - "lorentzian = sm.Lorentzian(display_name='Lorentzian', area=0.5, width=0.3)\n", - "component_collection = sm.ComponentCollection(\n", + "delta_function = edyn.DeltaFunction(display_name='DeltaFunction', area=0.2)\n", + "lorentzian = edyn.Lorentzian(display_name='Lorentzian', area=0.5, width=0.3)\n", + "component_collection = edyn.ComponentCollection(\n", " components=[delta_function, lorentzian],\n", ")\n", "\n", - "sample_model = sm.SampleModel(\n", + "sample_model = edyn.SampleModel(\n", " components=component_collection,\n", ")\n", "\n", - "background_model = sm.BackgroundModel(components=sm.Polynomial(coefficients=[0.001]))\n", + "background_model = edyn.BackgroundModel(components=edyn.Polynomial(coefficients=[0.001]))\n", "\n", - "instrument_model = sm.InstrumentModel(\n", + "instrument_model = edyn.InstrumentModel(\n", " background_model=background_model,\n", ")\n", "\n", @@ -265,22 +264,22 @@ "# Let us now fit directly to a diffusion model. We replace the\n", "# Lorentzian with a Brownian translational diffusion model and keep the\n", "# other parameters the same.\n", - "delta_function = sm.DeltaFunction(display_name='DeltaFunction', area=0.2)\n", - "component_collection = sm.ComponentCollection(\n", + "delta_function = edyn.DeltaFunction(display_name='DeltaFunction', area=0.2)\n", + "component_collection = edyn.ComponentCollection(\n", " components=[delta_function],\n", ")\n", - "diffusion_model = sm.BrownianTranslationalDiffusion(\n", + "diffusion_model = edyn.BrownianTranslationalDiffusion(\n", " display_name='Brownian Translational Diffusion', diffusion_coefficient=2.4e-9, scale=0.5\n", ")\n", "\n", - "sample_model = sm.SampleModel(\n", + "sample_model = edyn.SampleModel(\n", " components=component_collection,\n", " diffusion_models=diffusion_model,\n", ")\n", "\n", - "background_model = sm.BackgroundModel(components=sm.Polynomial(coefficients=[0.001]))\n", + "background_model = edyn.BackgroundModel(components=edyn.Polynomial(coefficients=[0.001]))\n", "\n", - "instrument_model = sm.InstrumentModel(\n", + "instrument_model = edyn.InstrumentModel(\n", " background_model=background_model,\n", ")\n", "\n", diff --git a/docs/docs/tutorials/analysis1d.ipynb b/docs/docs/tutorials/analysis1d.ipynb index 5ee06676..77b19bab 100644 --- a/docs/docs/tutorials/analysis1d.ipynb +++ b/docs/docs/tutorials/analysis1d.ipynb @@ -19,8 +19,6 @@ "import pooch\n", "\n", "import easydynamics as edyn\n", - "import easydynamics.sample_model as sm\n", - "from easydynamics.analysis.analysis1d import Analysis1d\n", "\n", "%matplotlib widget" ] @@ -49,24 +47,24 @@ "metadata": {}, "outputs": [], "source": [ - "# Example of Analysis1d with a simple sample model and instrument model\n", - "delta_function = sm.DeltaFunction(display_name='DeltaFunction', area=1)\n", - "sample_model = sm.SampleModel(\n", + "# Example of edyn.Analysis1d with a simple sample model and instrument model\n", + "delta_function = edyn.DeltaFunction(display_name='DeltaFunction', area=1)\n", + "sample_model = edyn.SampleModel(\n", " components=delta_function,\n", ")\n", "\n", - "res_gauss = sm.Gaussian(width=0.1)\n", - "resolution_model = sm.ResolutionModel(components=res_gauss)\n", + "res_gauss = edyn.Gaussian(width=0.1)\n", + "resolution_model = edyn.ResolutionModel(components=res_gauss)\n", "\n", "\n", - "background_model = sm.BackgroundModel(components=sm.Polynomial(coefficients=[0.001]))\n", + "background_model = edyn.BackgroundModel(components=edyn.Polynomial(coefficients=[0.001]))\n", "\n", - "instrument_model = sm.InstrumentModel(\n", + "instrument_model = edyn.InstrumentModel(\n", " resolution_model=resolution_model,\n", " background_model=background_model,\n", ")\n", "\n", - "my_analysis = Analysis1d(\n", + "my_analysis = edyn.Analysis1d(\n", " display_name='Vanadium Analysis',\n", " experiment=vanadium_experiment,\n", " sample_model=sample_model,\n", diff --git a/docs/docs/tutorials/bayesian.ipynb b/docs/docs/tutorials/bayesian.ipynb index bc92e21f..d76a2c3b 100644 --- a/docs/docs/tutorials/bayesian.ipynb +++ b/docs/docs/tutorials/bayesian.ipynb @@ -24,8 +24,6 @@ "import pooch\n", "\n", "import easydynamics as edyn\n", - "import easydynamics.sample_model as sm\n", - "from easydynamics.analysis.analysis1d import Analysis1d\n", "\n", "# Make the plots interactive; the Q sliders need the widget backend\n", "%matplotlib widget" @@ -77,17 +75,17 @@ "metadata": {}, "outputs": [], "source": [ - "vanadium_components = sm.ComponentCollection()\n", - "vanadium_components.append_component(sm.Gaussian(width=0.1, area=1, name='Res. Gauss'))\n", + "vanadium_components = edyn.ComponentCollection()\n", + "vanadium_components.append_component(edyn.Gaussian(width=0.1, area=1, name='Res. Gauss'))\n", "\n", - "instrument_model = sm.InstrumentModel(\n", - " background_model=sm.BackgroundModel(components=sm.Polynomial(coefficients=[0.001])),\n", + "instrument_model = edyn.InstrumentModel(\n", + " background_model=edyn.BackgroundModel(components=edyn.Polynomial(coefficients=[0.001])),\n", ")\n", "\n", - "analysis = Analysis1d(\n", + "analysis = edyn.Analysis1d(\n", " display_name='Vanadium Analysis',\n", " experiment=vanadium_experiment,\n", - " sample_model=sm.SampleModel(components=vanadium_components),\n", + " sample_model=edyn.SampleModel(components=vanadium_components),\n", " instrument_model=instrument_model,\n", " Q_index=5,\n", ")\n", @@ -345,15 +343,15 @@ "source": [ "# Fresh models, so this analysis is independent of the single-Q one above rather than\n", "# sharing its already-sampled components.\n", - "all_q_components = sm.ComponentCollection()\n", - "all_q_components.append_component(sm.Gaussian(width=0.1, area=1, name='Res. Gauss'))\n", + "all_q_components = edyn.ComponentCollection()\n", + "all_q_components.append_component(edyn.Gaussian(width=0.1, area=1, name='Res. Gauss'))\n", "\n", "full_analysis = edyn.Analysis(\n", " display_name='Vanadium, all Q',\n", " experiment=vanadium_experiment,\n", - " sample_model=sm.SampleModel(components=all_q_components),\n", - " instrument_model=sm.InstrumentModel(\n", - " background_model=sm.BackgroundModel(components=sm.Polynomial(coefficients=[0.001])),\n", + " sample_model=edyn.SampleModel(components=all_q_components),\n", + " instrument_model=edyn.InstrumentModel(\n", + " background_model=edyn.BackgroundModel(components=edyn.Polynomial(coefficients=[0.001])),\n", " ),\n", ")\n", "full_analysis.fit(fit_method='independent')\n", diff --git a/docs/docs/tutorials/component_collection.ipynb b/docs/docs/tutorials/component_collection.ipynb index 656fcf59..b286d0f1 100644 --- a/docs/docs/tutorials/component_collection.ipynb +++ b/docs/docs/tutorials/component_collection.ipynb @@ -20,7 +20,7 @@ "import matplotlib.pyplot as plt\n", "import numpy as np\n", "\n", - "import easydynamics.sample_model as sm\n", + "import easydynamics as edyn\n", "\n", "%matplotlib widget" ] @@ -32,13 +32,15 @@ "metadata": {}, "outputs": [], "source": [ - "component_collection = sm.ComponentCollection()\n", + "component_collection = edyn.ComponentCollection()\n", "\n", "# Creating components\n", - "gaussian = sm.Gaussian(display_name='Gaussian', width=0.5, area=1)\n", - "dho = sm.DampedHarmonicOscillator(display_name='DHO', center=1.0, width=0.3, area=2.0)\n", - "lorentzian = sm.Lorentzian(display_name='Lorentzian', center=-1.0, width=0.2, area=1.0)\n", - "polynomial = sm.Polynomial(display_name='Polynomial', coefficients=[0.1, 0, 0.5]) # y=0.1+0.5*x^2\n", + "gaussian = edyn.Gaussian(display_name='Gaussian', width=0.5, area=1)\n", + "dho = edyn.DampedHarmonicOscillator(display_name='DHO', center=1.0, width=0.3, area=2.0)\n", + "lorentzian = edyn.Lorentzian(display_name='Lorentzian', center=-1.0, width=0.2, area=1.0)\n", + "polynomial = edyn.Polynomial(\n", + " display_name='Polynomial', coefficients=[0.1, 0, 0.5]\n", + ") # y=0.1+0.5*x^2\n", "\n", "# Adding components to the component collection\n", "component_collection.append_component(gaussian)\n", diff --git a/docs/docs/tutorials/components.ipynb b/docs/docs/tutorials/components.ipynb index eafa8897..0fa5a888 100644 --- a/docs/docs/tutorials/components.ipynb +++ b/docs/docs/tutorials/components.ipynb @@ -23,7 +23,7 @@ "import numpy as np\n", "import scipp as sc\n", "\n", - "import easydynamics.sample_model as sm\n", + "import easydynamics as edyn\n", "\n", "%matplotlib widget" ] @@ -36,13 +36,13 @@ "outputs": [], "source": [ "# Creating a component\n", - "gaussian = sm.Gaussian(display_name='Gaussian', width=0.5, area=1)\n", - "dho = sm.DampedHarmonicOscillator(display_name='DHO', center=1.0, width=0.3, area=2.0)\n", - "lorentzian = sm.Lorentzian(display_name='Lorentzian', center=-1.0, width=0.2, area=1.0)\n", - "polynomial = sm.Polynomial(\n", + "gaussian = edyn.Gaussian(display_name='Gaussian', width=0.5, area=1)\n", + "dho = edyn.DampedHarmonicOscillator(display_name='DHO', center=1.0, width=0.3, area=2.0)\n", + "lorentzian = edyn.Lorentzian(display_name='Lorentzian', center=-1.0, width=0.2, area=1.0)\n", + "polynomial = edyn.Polynomial(\n", " display_name='Polynomial', coefficients=[-0.2, 0, 0.5]\n", ") # y=-0.2+0.5*x^2\n", - "exponential = sm.Exponential(display_name='Exponential', amplitude=1.0, rate=-0.5)\n", + "exponential = edyn.Exponential(display_name='Exponential', amplitude=1.0, rate=-0.5)\n", "\n", "x = np.linspace(-2, 2, 100)\n", "\n", @@ -94,7 +94,7 @@ "metadata": {}, "outputs": [], "source": [ - "delta = sm.DeltaFunction(display_name='Delta', center=0.0, area=1.0)\n", + "delta = edyn.DeltaFunction(display_name='Delta', center=0.0, area=1.0)\n", "x1 = np.linspace(-2, 2, 100)\n", "y = delta.evaluate(x1)\n", "x2 = np.linspace(-2, 2, 51)\n", @@ -122,7 +122,9 @@ "x1 = sc.linspace(dim='x', start=-2.0, stop=2.0, num=100, unit='meV')\n", "x2 = sc.linspace(dim='x', start=-2.0 * 1e3, stop=2.0 * 1e3, num=101, unit='microeV')\n", "\n", - "polynomial = sm.Polynomial(display_name='Polynomial', coefficients=[0.1, 0, 0.5]) # y=0.1+0.5*x^2\n", + "polynomial = edyn.Polynomial(\n", + " display_name='Polynomial', coefficients=[0.1, 0, 0.5]\n", + ") # y=0.1+0.5*x^2\n", "y1 = polynomial.evaluate(x1)\n", "y2 = polynomial.evaluate(x2)\n", "\n", @@ -148,7 +150,7 @@ "metadata": {}, "outputs": [], "source": [ - "expr = sm.ExpressionComponent(\n", + "expr = edyn.ExpressionComponent(\n", " 'A * exp(-(x - x0)**2 / (2*sigma**2)) +B*sin(2*pi*x/period)',\n", " parameters={'A': 10, 'x0': 0, 'sigma': 1},\n", " parameter_units={\n", @@ -185,7 +187,7 @@ "metadata": {}, "outputs": [], "source": [ - "expr = sm.ExpressionComponent(\n", + "expr = edyn.ExpressionComponent(\n", " 'A*erf(B*x)',\n", ")\n", "\n", diff --git a/docs/docs/tutorials/convolution.ipynb b/docs/docs/tutorials/convolution.ipynb index 2e962555..c366478c 100644 --- a/docs/docs/tutorials/convolution.ipynb +++ b/docs/docs/tutorials/convolution.ipynb @@ -24,9 +24,7 @@ "import matplotlib.pyplot as plt\n", "import numpy as np\n", "\n", - "import easydynamics.sample_model as sm\n", - "from easydynamics.convolution import Convolution\n", - "from easydynamics.utils import detailed_balance_factor\n", + "import easydynamics as edyn\n", "\n", "%matplotlib widget" ] @@ -40,25 +38,25 @@ "source": [ "# Standard example of convolution of a sample model with a\n", "# resolution model\n", - "sample_components = sm.ComponentCollection()\n", - "gaussian = sm.Gaussian(display_name='Gaussian', width=0.5, area=1)\n", - "dho = sm.DampedHarmonicOscillator(display_name='DHO', center=1.0, width=0.3, area=2.0)\n", - "lorentzian = sm.Lorentzian(display_name='Lorentzian', center=-1.0, width=0.2, area=1.0)\n", - "delta = sm.DeltaFunction(display_name='Delta', center=0.4, area=0.5)\n", + "sample_components = edyn.ComponentCollection()\n", + "gaussian = edyn.Gaussian(display_name='Gaussian', width=0.5, area=1)\n", + "dho = edyn.DampedHarmonicOscillator(display_name='DHO', center=1.0, width=0.3, area=2.0)\n", + "lorentzian = edyn.Lorentzian(display_name='Lorentzian', center=-1.0, width=0.2, area=1.0)\n", + "delta = edyn.DeltaFunction(display_name='Delta', center=0.4, area=0.5)\n", "sample_components.append_component(gaussian)\n", "# sample_components.append_component(dho)\n", "sample_components.append_component(lorentzian)\n", "sample_components.append_component(delta)\n", "\n", - "resolution_components = sm.ComponentCollection()\n", - "resolution_gaussian = sm.Gaussian(display_name='Resolution Gaussian', width=0.05, area=0.8)\n", - "resolution_lorentzian = sm.Lorentzian(display_name='Resolution Lorentzian', width=0.05, area=0.2)\n", + "resolution_components = edyn.ComponentCollection()\n", + "resolution_gaussian = edyn.Gaussian(display_name='Resolution Gaussian', width=0.05, area=0.8)\n", + "resolution_lorentzian = edyn.Lorentzian(display_name='Resolution Lorentzian', width=0.05, area=0.2)\n", "resolution_components.append_component(resolution_gaussian)\n", "resolution_components.append_component(resolution_lorentzian)\n", "\n", "energy = np.linspace(-2, 2, 100)\n", "\n", - "convolver = Convolution(\n", + "convolver = edyn.Convolution(\n", " sample_components=sample_components, resolution_components=resolution_components, energy=energy\n", ")\n", "y = convolver.convolution()\n", @@ -66,7 +64,7 @@ "plt.plot(energy, y, label='Convoluted Model')\n", "plt.xlabel('Energy (meV)')\n", "plt.ylabel('Intensity (arb. units)')\n", - "plt.title('Convolution of Sample Model with Resolution Model')\n", + "plt.title('edyn.Convolution of Sample Model with Resolution Model')\n", "\n", "plt.plot(energy, sample_components.evaluate(energy), label='Sample Model', linestyle='--')\n", "plt.plot(energy, resolution_components.evaluate(energy), label='Resolution Model', linestyle=':')\n", @@ -85,19 +83,19 @@ "outputs": [], "source": [ "# Use some of the extra settings for the numerical convolution\n", - "sample_components = sm.ComponentCollection()\n", - "gaussian = sm.Gaussian(display_name='Gaussian', width=0.3, area=1)\n", - "dho = sm.DampedHarmonicOscillator(display_name='DHO', center=1.0, width=0.3, area=2.0)\n", - "lorentzian = sm.Lorentzian(display_name='Lorentzian', center=-1.0, width=0.2, area=1.0)\n", - "delta = sm.DeltaFunction(display_name='Delta', center=0.4, area=0.5)\n", + "sample_components = edyn.ComponentCollection()\n", + "gaussian = edyn.Gaussian(display_name='Gaussian', width=0.3, area=1)\n", + "dho = edyn.DampedHarmonicOscillator(display_name='DHO', center=1.0, width=0.3, area=2.0)\n", + "lorentzian = edyn.Lorentzian(display_name='Lorentzian', center=-1.0, width=0.2, area=1.0)\n", + "delta = edyn.DeltaFunction(display_name='Delta', center=0.4, area=0.5)\n", "sample_components.append_component(gaussian)\n", "sample_components.append_component(dho)\n", "sample_components.append_component(lorentzian)\n", "sample_components.append_component(delta)\n", "\n", - "resolution_components = sm.ComponentCollection()\n", - "resolution_gaussian = sm.Gaussian(display_name='Resolution Gaussian', width=0.15, area=0.8)\n", - "resolution_lorentzian = sm.Lorentzian(display_name='Resolution Lorentzian', width=0.25, area=0.2)\n", + "resolution_components = edyn.ComponentCollection()\n", + "resolution_gaussian = edyn.Gaussian(display_name='Resolution Gaussian', width=0.15, area=0.8)\n", + "resolution_lorentzian = edyn.Lorentzian(display_name='Resolution Lorentzian', width=0.25, area=0.2)\n", "resolution_components.append_component(resolution_gaussian)\n", "resolution_components.append_component(resolution_lorentzian)\n", "\n", @@ -112,7 +110,7 @@ "plt.xlabel('Energy (meV)')\n", "plt.ylabel('Intensity (arb. units)')\n", "\n", - "convolver = Convolution(\n", + "convolver = edyn.Convolution(\n", " sample_components=sample_components,\n", " resolution_components=resolution_components,\n", " energy=energy - energy_offset,\n", @@ -130,13 +128,13 @@ "plt.plot(\n", " energy,\n", " sample_components.evaluate(energy - energy_offset)\n", - " * detailed_balance_factor(energy - energy_offset, temperature),\n", + " * edyn.detailed_balance_factor(energy - energy_offset, temperature),\n", " label='Sample Model with DB',\n", " linestyle='--',\n", ")\n", "\n", "plt.plot(energy, resolution_components.evaluate(energy), label='Resolution Model', linestyle=':')\n", - "plt.title('Convolution of Sample Model with Resolution Model with detailed balancing')\n", + "plt.title('edyn.Convolution of Sample Model with Resolution Model with detailed balancing')\n", "\n", "plt.legend()\n", "plt.ylim(0, 2.5)\n", @@ -151,19 +149,19 @@ "outputs": [], "source": [ "# Use some of the extra settings for the numerical convolution\n", - "sample_components = sm.ComponentCollection()\n", - "gaussian = sm.Gaussian(display_name='Gaussian', width=0.3, area=1)\n", - "dho = sm.DampedHarmonicOscillator(display_name='DHO', center=1.0, width=0.3, area=2.0)\n", - "lorentzian = sm.Lorentzian(display_name='Lorentzian', center=-1.0, width=0.2, area=1.0)\n", - "delta = sm.DeltaFunction(display_name='Delta', center=0.4, area=0.5)\n", + "sample_components = edyn.ComponentCollection()\n", + "gaussian = edyn.Gaussian(display_name='Gaussian', width=0.3, area=1)\n", + "dho = edyn.DampedHarmonicOscillator(display_name='DHO', center=1.0, width=0.3, area=2.0)\n", + "lorentzian = edyn.Lorentzian(display_name='Lorentzian', center=-1.0, width=0.2, area=1.0)\n", + "delta = edyn.DeltaFunction(display_name='Delta', center=0.4, area=0.5)\n", "sample_components.append_component(gaussian)\n", "# sample_components.append_component(dho)\n", "sample_components.append_component(lorentzian)\n", "# sample_components.append_component(delta)\n", "\n", - "resolution_components = sm.ComponentCollection()\n", - "resolution_gaussian = sm.Gaussian(display_name='Resolution Gaussian', width=0.15, area=0.8)\n", - "resolution_lorentzian = sm.Lorentzian(display_name='Resolution Lorentzian', width=0.25, area=0.2)\n", + "resolution_components = edyn.ComponentCollection()\n", + "resolution_gaussian = edyn.Gaussian(display_name='Resolution Gaussian', width=0.15, area=0.8)\n", + "resolution_lorentzian = edyn.Lorentzian(display_name='Resolution Lorentzian', width=0.25, area=0.2)\n", "resolution_components.append_component(resolution_gaussian)\n", "# resolution_components.append_component(resolution_lorentzian)\n", "\n", @@ -178,7 +176,7 @@ "plt.xlabel('Energy (meV)')\n", "plt.ylabel('Intensity (arb. units)')\n", "\n", - "convolver = Convolution(\n", + "convolver = edyn.Convolution(\n", " sample_components=sample_components,\n", " resolution_components=resolution_components,\n", " energy=energy,\n", @@ -200,7 +198,7 @@ ")\n", "\n", "plt.plot(energy, resolution_components.evaluate(energy), label='Resolution Model', linestyle=':')\n", - "plt.title('Convolution of Sample Model with Resolution Model')\n", + "plt.title('edyn.Convolution of Sample Model with Resolution Model')\n", "\n", "plt.legend()\n", "plt.ylim(0, 2.5)\n", diff --git a/docs/docs/tutorials/delta_lorentz.ipynb b/docs/docs/tutorials/delta_lorentz.ipynb index d676ddf8..47cf6bd9 100644 --- a/docs/docs/tutorials/delta_lorentz.ipynb +++ b/docs/docs/tutorials/delta_lorentz.ipynb @@ -29,7 +29,7 @@ "import matplotlib.pyplot as plt\n", "import numpy as np\n", "\n", - "import easydynamics.sample_model as sm\n", + "import easydynamics as edyn\n", "\n", "%matplotlib widget" ] @@ -48,7 +48,7 @@ "A_0 = 0.01\n", "lorentzian_width = 0.2\n", "\n", - "diffusion_model = sm.DeltaLorentz(\n", + "diffusion_model = edyn.DeltaLorentz(\n", " scale=scale,\n", " mean_u_squared=mean_u_squared,\n", " A_0=A_0,\n", diff --git a/docs/docs/tutorials/detailed_balance.ipynb b/docs/docs/tutorials/detailed_balance.ipynb index bd6fccce..0b57b18c 100644 --- a/docs/docs/tutorials/detailed_balance.ipynb +++ b/docs/docs/tutorials/detailed_balance.ipynb @@ -25,7 +25,7 @@ "import matplotlib.pyplot as plt\n", "import numpy as np\n", "\n", - "from easydynamics.utils import detailed_balance_factor\n", + "import easydynamics as edyn\n", "\n", "%matplotlib widget" ] @@ -45,7 +45,7 @@ "\n", "plt.figure()\n", "for temperature in temperatures:\n", - " DBF = detailed_balance_factor(energy, temperature, energy_unit, temperature_unit)\n", + " DBF = edyn.detailed_balance_factor(energy, temperature, energy_unit, temperature_unit)\n", " plt.plot(energy, DBF, label=f'T={temperature} K')\n", "plt.legend()\n", "plt.xlabel('Energy transfer (meV)')\n", @@ -72,7 +72,7 @@ "\n", "plt.figure()\n", "for temperature in temperatures:\n", - " DBF = detailed_balance_factor(\n", + " DBF = edyn.detailed_balance_factor(\n", " energy, temperature, energy_unit, temperature_unit, divide_by_temperature=False\n", " )\n", " plt.plot(energy, DBF, label=f'T={temperature} K')\n", diff --git a/docs/docs/tutorials/diffusion_model.ipynb b/docs/docs/tutorials/diffusion_model.ipynb index ffc26cc0..e3d61328 100644 --- a/docs/docs/tutorials/diffusion_model.ipynb +++ b/docs/docs/tutorials/diffusion_model.ipynb @@ -19,7 +19,7 @@ "import matplotlib.pyplot as plt\n", "import numpy as np\n", "\n", - "import easydynamics.sample_model as sm\n", + "import easydynamics as edyn\n", "\n", "%matplotlib widget" ] @@ -40,7 +40,7 @@ "scale = 1.0\n", "diffusion_coefficient = 2.4e-9 # m^2/s\n", "\n", - "diffusion_model = sm.BrownianTranslationalDiffusion(\n", + "diffusion_model = edyn.BrownianTranslationalDiffusion(\n", " display_name='DiffusionModel', scale=scale, diffusion_coefficient=diffusion_coefficient, Q=Q\n", ")\n", "\n", diff --git a/docs/docs/tutorials/instrument_model.ipynb b/docs/docs/tutorials/instrument_model.ipynb index 99e05545..4f30fad4 100644 --- a/docs/docs/tutorials/instrument_model.ipynb +++ b/docs/docs/tutorials/instrument_model.ipynb @@ -21,7 +21,7 @@ "source": [ "import numpy as np\n", "\n", - "import easydynamics.sample_model as sm\n", + "import easydynamics as edyn\n", "\n", "%matplotlib widget" ] @@ -38,13 +38,13 @@ "\n", "Q = np.linspace(0.1, 2.0, 5)\n", "\n", - "background_model = sm.BackgroundModel()\n", - "background_model.components = sm.Polynomial(coefficients=[1, 0.1, 0.01])\n", + "background_model = edyn.BackgroundModel()\n", + "background_model.components = edyn.Polynomial(coefficients=[1, 0.1, 0.01])\n", "\n", - "resolution_model = sm.ResolutionModel()\n", - "resolution_model.append_component(sm.Gaussian(width=0.05))\n", + "resolution_model = edyn.ResolutionModel()\n", + "resolution_model.append_component(edyn.Gaussian(width=0.05))\n", "\n", - "instrument_model = sm.InstrumentModel(\n", + "instrument_model = edyn.InstrumentModel(\n", " Q=Q,\n", " resolution_model=resolution_model,\n", " background_model=background_model,\n", diff --git a/docs/docs/tutorials/sample_model.ipynb b/docs/docs/tutorials/sample_model.ipynb index 0edad8e3..ca42289f 100644 --- a/docs/docs/tutorials/sample_model.ipynb +++ b/docs/docs/tutorials/sample_model.ipynb @@ -23,7 +23,7 @@ "import matplotlib.pyplot as plt\n", "import numpy as np\n", "\n", - "import easydynamics.sample_model as sm\n", + "import easydynamics as edyn\n", "\n", "%matplotlib widget" ] @@ -41,7 +41,7 @@ "\n", "scale = 1.0\n", "diffusion_coefficient = 2.4e-9 # m^2/s\n", - "diffusion_model = sm.BrownianTranslationalDiffusion(\n", + "diffusion_model = edyn.BrownianTranslationalDiffusion(\n", " display_name='DiffusionModel',\n", " scale=scale,\n", " diffusion_coefficient=diffusion_coefficient,\n", @@ -49,15 +49,15 @@ "\n", "\n", "# Creating components\n", - "component_collection = sm.ComponentCollection()\n", - "gaussian = sm.Gaussian(display_name='Gaussian', width=0.2, area=1, center=1.5)\n", - "dho = sm.DampedHarmonicOscillator(display_name='DHO', center=1.0, width=0.3, area=2.0)\n", + "component_collection = edyn.ComponentCollection()\n", + "gaussian = edyn.Gaussian(display_name='Gaussian', width=0.2, area=1, center=1.5)\n", + "dho = edyn.DampedHarmonicOscillator(display_name='DHO', center=1.0, width=0.3, area=2.0)\n", "\n", "# Adding components to the component collection\n", "component_collection.append_component(gaussian)\n", "component_collection.append_component(dho)\n", "\n", - "sample_model = sm.SampleModel(\n", + "sample_model = edyn.SampleModel(\n", " diffusion_models=diffusion_model,\n", " components=component_collection,\n", " Q=Q,\n", @@ -89,17 +89,17 @@ "source": [ "# Create a BackgroundModel and show other ways to set Q and components\n", "\n", - "background_model = sm.BackgroundModel()\n", + "background_model = edyn.BackgroundModel()\n", "background_model.Q = Q\n", "\n", - "background_model.components = sm.Polynomial(coefficients=[1, 0.1, 0.01])\n", + "background_model.components = edyn.Polynomial(coefficients=[1, 0.1, 0.01])\n", "background = background_model.evaluate(energy)\n", "\n", "# Also create a ResolutionModel.\n", "# It doesn't do anything here, but shows how to set it up.\n", - "resolution_model = sm.ResolutionModel()\n", + "resolution_model = edyn.ResolutionModel()\n", "resolution_model.Q = Q\n", - "resolution_model.append_component(sm.Gaussian(width=0.05))\n", + "resolution_model.append_component(edyn.Gaussian(width=0.05))\n", "resolution = resolution_model.evaluate(energy)" ] }, diff --git a/docs/docs/tutorials/tutorial0_basics.ipynb b/docs/docs/tutorials/tutorial0_basics.ipynb index 335e2ac0..45f83061 100644 --- a/docs/docs/tutorials/tutorial0_basics.ipynb +++ b/docs/docs/tutorials/tutorial0_basics.ipynb @@ -23,7 +23,6 @@ "import scipp as sc\n", "\n", "import easydynamics as edyn\n", - "import easydynamics.sample_model as sm\n", "\n", "# Make the plots interactive\n", "%matplotlib widget" @@ -132,7 +131,7 @@ "metadata": {}, "outputs": [], "source": [ - "gaussian = sm.Gaussian(name='Gaussian', area=1, width=0.05)" + "gaussian = edyn.Gaussian(name='Gaussian', area=1, width=0.05)" ] }, { @@ -171,7 +170,7 @@ "metadata": {}, "outputs": [], "source": [ - "model = sm.SampleModel(components=gaussian)" + "model = edyn.SampleModel(components=gaussian)" ] }, { @@ -409,7 +408,7 @@ "metadata": {}, "outputs": [], "source": [ - "fit_func = sm.Polynomial(\n", + "fit_func = edyn.Polynomial(\n", " coefficients=[3.7, -0.5],\n", " x_unit='1/angstrom',\n", " y_unit='meV',\n", diff --git a/docs/docs/tutorials/tutorial0_more_advanced.ipynb b/docs/docs/tutorials/tutorial0_more_advanced.ipynb index 4bbcdf22..f8fe2250 100644 --- a/docs/docs/tutorials/tutorial0_more_advanced.ipynb +++ b/docs/docs/tutorials/tutorial0_more_advanced.ipynb @@ -22,7 +22,6 @@ "import pooch\n", "\n", "import easydynamics as edyn\n", - "import easydynamics.sample_model as sm\n", "\n", "# Make the plots interactive\n", "%matplotlib widget" @@ -73,11 +72,11 @@ "metadata": {}, "outputs": [], "source": [ - "gaussian = sm.Gaussian(name='Gaussian', area=3, width=0.05)\n", - "lorentzian = sm.Lorentzian(name='Lorentzian', area=2, width=0.3)\n", - "dho = sm.DampedHarmonicOscillator(name='DHO', area=1.5, width=0.2, center=1.5)\n", + "gaussian = edyn.Gaussian(name='Gaussian', area=3, width=0.05)\n", + "lorentzian = edyn.Lorentzian(name='Lorentzian', area=2, width=0.3)\n", + "dho = edyn.DampedHarmonicOscillator(name='DHO', area=1.5, width=0.2, center=1.5)\n", "\n", - "collection = sm.ComponentCollection()\n", + "collection = edyn.ComponentCollection()\n", "collection.append_component(gaussian)\n", "collection.append_component(lorentzian)\n", "collection.append_component(dho)" @@ -104,7 +103,7 @@ "metadata": {}, "outputs": [], "source": [ - "model = sm.SampleModel(components=collection)" + "model = edyn.SampleModel(components=collection)" ] }, { @@ -130,7 +129,7 @@ "metadata": {}, "outputs": [], "source": [ - "instrument = sm.InstrumentModel(energy_offset=0.05)" + "instrument = edyn.InstrumentModel(energy_offset=0.05)" ] }, { @@ -161,7 +160,7 @@ "metadata": {}, "outputs": [], "source": [ - "background = sm.BackgroundModel(components=sm.Polynomial(coefficients=[1.2, 0.05]))" + "background = edyn.BackgroundModel(components=edyn.Polynomial(coefficients=[1.2, 0.05]))" ] }, { @@ -329,13 +328,13 @@ "metadata": {}, "outputs": [], "source": [ - "gauss_fit_func = sm.Polynomial(\n", + "gauss_fit_func = edyn.Polynomial(\n", " coefficients=[3.7, -0.5], x_unit='1/angstrom', y_unit='meV', name='Gauss area fit'\n", ")\n", - "dho_area_fit_func = sm.Polynomial(\n", + "dho_area_fit_func = edyn.Polynomial(\n", " coefficients=[2.0, 0.12], x_unit='1/angstrom', y_unit='meV', name='DHO area fit'\n", ")\n", - "dho_center_fit_func = sm.Polynomial(\n", + "dho_center_fit_func = edyn.Polynomial(\n", " coefficients=[1.1, 0.2], x_unit='1/angstrom', y_unit='meV', name='DHO center fit'\n", ")\n", "\n", diff --git a/docs/docs/tutorials/tutorial1_brownian.ipynb b/docs/docs/tutorials/tutorial1_brownian.ipynb index 3c902ea1..c5cf5e9b 100644 --- a/docs/docs/tutorials/tutorial1_brownian.ipynb +++ b/docs/docs/tutorials/tutorial1_brownian.ipynb @@ -22,7 +22,6 @@ "import pooch\n", "\n", "import easydynamics as edyn\n", - "import easydynamics.sample_model as sm\n", "\n", "# Make the plots interactive\n", "%matplotlib widget" @@ -112,10 +111,10 @@ "metadata": {}, "outputs": [], "source": [ - "vanadium_components = sm.ComponentCollection()\n", - "res_gauss = sm.Gaussian(width=0.1, area=1, name='Res. Gauss')\n", + "vanadium_components = edyn.ComponentCollection()\n", + "res_gauss = edyn.Gaussian(width=0.1, area=1, name='Res. Gauss')\n", "vanadium_components.append_component(res_gauss)\n", - "vanadium_model = sm.SampleModel(components=vanadium_components)" + "vanadium_model = edyn.SampleModel(components=vanadium_components)" ] }, { @@ -133,7 +132,7 @@ "metadata": {}, "outputs": [], "source": [ - "background_model = sm.BackgroundModel(components=sm.Polynomial(coefficients=[0.001]))" + "background_model = edyn.BackgroundModel(components=edyn.Polynomial(coefficients=[0.001]))" ] }, { @@ -151,7 +150,7 @@ "metadata": {}, "outputs": [], "source": [ - "instrument_model = sm.InstrumentModel(\n", + "instrument_model = edyn.InstrumentModel(\n", " background_model=background_model,\n", ")" ] @@ -319,17 +318,17 @@ "metadata": {}, "outputs": [], "source": [ - "delta_function = sm.DeltaFunction(name='DeltaFunction', area=0.2)\n", - "lorentzian = sm.Lorentzian(name='Lorentzian', area=0.5, width=0.3)\n", - "component_collection = sm.ComponentCollection(\n", + "delta_function = edyn.DeltaFunction(name='DeltaFunction', area=0.2)\n", + "lorentzian = edyn.Lorentzian(name='Lorentzian', area=0.5, width=0.3)\n", + "component_collection = edyn.ComponentCollection(\n", " components=[delta_function, lorentzian],\n", ")\n", "\n", - "sample_model = sm.SampleModel(\n", + "sample_model = edyn.SampleModel(\n", " components=component_collection,\n", ")\n", "\n", - "background_model = sm.BackgroundModel(components=sm.Polynomial(coefficients=[0.001]))" + "background_model = edyn.BackgroundModel(components=edyn.Polynomial(coefficients=[0.001]))" ] }, { @@ -347,7 +346,7 @@ "metadata": {}, "outputs": [], "source": [ - "instrument_model = sm.InstrumentModel(\n", + "instrument_model = edyn.InstrumentModel(\n", " background_model=background_model,\n", " resolution_model=vanadium_analysis.sample_model,\n", ")\n", @@ -461,7 +460,7 @@ "metadata": {}, "outputs": [], "source": [ - "brownian_diffusion_model = sm.BrownianTranslationalDiffusion(\n", + "brownian_diffusion_model = edyn.BrownianTranslationalDiffusion(\n", " name='Brownian Translational Diffusion',\n", " lorentzian_name='Lorentzian',\n", " diffusion_coefficient=2.4e-9,\n", @@ -615,20 +614,20 @@ "metadata": {}, "outputs": [], "source": [ - "delta_function = sm.DeltaFunction(name='DeltaFunction', area=0.2)\n", - "component_collection = sm.ComponentCollection(\n", + "delta_function = edyn.DeltaFunction(name='DeltaFunction', area=0.2)\n", + "component_collection = edyn.ComponentCollection(\n", " components=[delta_function],\n", ")\n", - "diffusion_model = sm.BrownianTranslationalDiffusion(\n", + "diffusion_model = edyn.BrownianTranslationalDiffusion(\n", " name='Brownian Translational Diffusion', diffusion_coefficient=2.4e-9, scale=0.5\n", ")\n", "\n", - "sample_model = sm.SampleModel(\n", + "sample_model = edyn.SampleModel(\n", " components=component_collection,\n", " diffusion_models=diffusion_model,\n", ")\n", "\n", - "background_model = sm.BackgroundModel(components=sm.Polynomial(coefficients=[0.001]))" + "background_model = edyn.BackgroundModel(components=edyn.Polynomial(coefficients=[0.001]))" ] }, { @@ -638,7 +637,7 @@ "metadata": {}, "outputs": [], "source": [ - "instrument_model = sm.InstrumentModel(\n", + "instrument_model = edyn.InstrumentModel(\n", " background_model=background_model,\n", " resolution_model=vanadium_analysis.sample_model,\n", ")" diff --git a/docs/docs/tutorials/tutorial2_nanoparticles.ipynb b/docs/docs/tutorials/tutorial2_nanoparticles.ipynb index cca884bb..c74f1f13 100644 --- a/docs/docs/tutorials/tutorial2_nanoparticles.ipynb +++ b/docs/docs/tutorials/tutorial2_nanoparticles.ipynb @@ -43,8 +43,6 @@ "import scipp as sc\n", "\n", "import easydynamics as edyn\n", - "import easydynamics.sample_model as sm\n", - "from easydynamics.utils.utils import hbar\n", "\n", "# Make the plots interactive\n", "%matplotlib widget" @@ -135,20 +133,20 @@ "metadata": {}, "outputs": [], "source": [ - "res_sample_model = sm.SampleModel()\n", - "res_components = sm.ComponentCollection()\n", - "res_gauss = sm.Gaussian(area=40, width=0.02)\n", + "res_sample_model = edyn.SampleModel()\n", + "res_components = edyn.ComponentCollection()\n", + "res_gauss = edyn.Gaussian(area=40, width=0.02)\n", "\n", "res_components.append_component(res_gauss)\n", "res_sample_model.components = res_components\n", "\n", - "background_model = sm.BackgroundModel()\n", - "polynomial = sm.Polynomial(coefficients=[1.5])\n", + "background_model = edyn.BackgroundModel()\n", + "polynomial = edyn.Polynomial(coefficients=[1.5])\n", "polynomial.coefficients[0].min = 0.0\n", "background_model.components = polynomial\n", "\n", "\n", - "res_instrument_model = sm.InstrumentModel(\n", + "res_instrument_model = edyn.InstrumentModel(\n", " background_model=background_model,\n", ")\n", "\n", @@ -246,21 +244,21 @@ "metadata": {}, "outputs": [], "source": [ - "sample_model = sm.SampleModel()\n", - "water_delta_function = sm.DeltaFunction(name='Water delta function', area=100)\n", - "water_lorentzian = sm.Lorentzian(name='Water Lorentzian', area=10, width=0.2)\n", + "sample_model = edyn.SampleModel()\n", + "water_delta_function = edyn.DeltaFunction(name='Water delta function', area=100)\n", + "water_lorentzian = edyn.Lorentzian(name='Water Lorentzian', area=10, width=0.2)\n", "sample_model.append_component(water_delta_function)\n", "sample_model.append_component(water_lorentzian)\n", "sample_model.temperature = 150\n", "\n", "\n", - "background_model = sm.BackgroundModel()\n", - "polynomial = sm.Polynomial(name='Polynomial', coefficients=[0.15])\n", + "background_model = edyn.BackgroundModel()\n", + "polynomial = edyn.Polynomial(name='Polynomial', coefficients=[0.15])\n", "polynomial.coefficients[0].min = 0.0\n", "background_model.components = polynomial\n", "\n", "\n", - "instrument_model = sm.InstrumentModel(\n", + "instrument_model = edyn.InstrumentModel(\n", " background_model=background_model,\n", " resolution_model=res_analysis.sample_model,\n", ")\n", @@ -380,25 +378,25 @@ "outputs": [], "source": [ "# Now make a new analysis with this sample model\n", - "mag_sample_model = sm.SampleModel()\n", - "water_delta_function = sm.DeltaFunction(name='Water delta function', area=100)\n", - "water_lorentzian = sm.Lorentzian(name='Water Lorentzian', area=100, width=0.2)\n", + "mag_sample_model = edyn.SampleModel()\n", + "water_delta_function = edyn.DeltaFunction(name='Water delta function', area=100)\n", + "water_lorentzian = edyn.Lorentzian(name='Water Lorentzian', area=100, width=0.2)\n", "mag_sample_model.append_component(water_delta_function)\n", "mag_sample_model.append_component(water_lorentzian)\n", "\n", "# Add all the magnetic components\n", - "DHO1 = sm.DampedHarmonicOscillator(name='DHO1', area=5, center=0.35, width=0.2)\n", - "DHO2 = sm.DampedHarmonicOscillator(name='DHO2', area=1, center=1.1, width=0.1)\n", - "mag_lorz = sm.Lorentzian(name='Magnetic Lorentzian', area=30, width=0.01)\n", + "DHO1 = edyn.DampedHarmonicOscillator(name='DHO1', area=5, center=0.35, width=0.2)\n", + "DHO2 = edyn.DampedHarmonicOscillator(name='DHO2', area=1, center=1.1, width=0.1)\n", + "mag_lorz = edyn.Lorentzian(name='Magnetic Lorentzian', area=30, width=0.01)\n", "mag_sample_model.append_component(DHO1)\n", "mag_sample_model.append_component(DHO2)\n", "mag_sample_model.append_component(mag_lorz)\n", "\n", - "background_model = sm.BackgroundModel()\n", - "polynomial = sm.Polynomial(name='Polynomial', coefficients=[0.15])\n", + "background_model = edyn.BackgroundModel()\n", + "polynomial = edyn.Polynomial(name='Polynomial', coefficients=[0.15])\n", "background_model.components = polynomial\n", "\n", - "instrument_model = sm.InstrumentModel(\n", + "instrument_model = edyn.InstrumentModel(\n", " background_model=background_model,\n", " resolution_model=res_analysis.sample_model,\n", ")\n", @@ -544,7 +542,7 @@ "print(width1)\n", "print(width2)\n", "print(width)\n", - "tau = hbar / width\n", + "tau = edyn.hbar / width\n", "tau.convert_unit('ns')\n", "print(tau)" ] diff --git a/src/easydynamics/__init__.py b/src/easydynamics/__init__.py index f4c956e5..0b8e27cb 100644 --- a/src/easydynamics/__init__.py +++ b/src/easydynamics/__init__.py @@ -1,19 +1,91 @@ # SPDX-FileCopyrightText: 2025 EasyScience contributors # SPDX-License-Identifier: BSD-3-Clause -"""EasyDynamics library.""" +""" +EasyDynamics library. + +Everything public is re-exported here, so ``import easydynamics as edyn`` reaches all of it and a +reader never has to look up which sub-package a name came from. The sub-packages remain importable +for anyone who prefers them; this is only the front door. +""" from easydynamics.analysis import Analysis +from easydynamics.analysis import BoundsSuggestion +from easydynamics.analysis import BoundsSuggestions +from easydynamics.analysis import MultiQPosteriorSampler +from easydynamics.analysis import ParameterAnalysis +from easydynamics.analysis import ParameterLabels +from easydynamics.analysis import ParameterPosterior +from easydynamics.analysis import PosteriorSampler +from easydynamics.analysis import PosteriorSummary +from easydynamics.analysis.analysis1d import Analysis1d from easydynamics.analysis.fit_binding import FitBinding -from easydynamics.analysis.parameter_analysis import ParameterAnalysis +from easydynamics.base_classes import EasyDynamicsBase +from easydynamics.base_classes import EasyDynamicsModelBase +from easydynamics.convolution import Convolution from easydynamics.experiment import Experiment -from easydynamics.settings.convolution_settings import ConvolutionSettings -from easydynamics.settings.detailed_balance_settings import DetailedBalanceSettings +from easydynamics.sample_model import BackgroundModel +from easydynamics.sample_model import BrownianTranslationalDiffusion +from easydynamics.sample_model import ComponentCollection +from easydynamics.sample_model import DampedHarmonicOscillator +from easydynamics.sample_model import DeltaFunction +from easydynamics.sample_model import DeltaLorentz +from easydynamics.sample_model import Exponential +from easydynamics.sample_model import ExpressionComponent +from easydynamics.sample_model import Gaussian +from easydynamics.sample_model import InstrumentModel +from easydynamics.sample_model import JumpTranslationalDiffusion +from easydynamics.sample_model import Lorentzian +from easydynamics.sample_model import Polynomial +from easydynamics.sample_model import ResolutionModel +from easydynamics.sample_model import SampleModel +from easydynamics.sample_model import Voigt +from easydynamics.settings import ConvolutionSettings +from easydynamics.settings import DetailedBalanceSettings +from easydynamics.utils import detailed_balance_factor +from easydynamics.utils import plot_corner +from easydynamics.utils import plot_posterior_predictive +from easydynamics.utils import plot_trace +from easydynamics.utils import slicerplot_with_residuals +from easydynamics.utils.utils import hbar __all__ = [ 'Analysis', + 'Analysis1d', + 'BackgroundModel', + 'BoundsSuggestion', + 'BoundsSuggestions', + 'BrownianTranslationalDiffusion', + 'ComponentCollection', + 'Convolution', 'ConvolutionSettings', + 'DampedHarmonicOscillator', + 'DeltaFunction', + 'DeltaLorentz', 'DetailedBalanceSettings', + 'EasyDynamicsBase', + 'EasyDynamicsModelBase', 'Experiment', + 'Exponential', + 'ExpressionComponent', 'FitBinding', + 'Gaussian', + 'InstrumentModel', + 'JumpTranslationalDiffusion', + 'Lorentzian', + 'MultiQPosteriorSampler', 'ParameterAnalysis', + 'ParameterLabels', + 'ParameterPosterior', + 'Polynomial', + 'PosteriorSampler', + 'PosteriorSummary', + 'ResolutionModel', + 'SampleModel', + 'Voigt', + 'detailed_balance_factor', + 'hbar', + 'plot_corner', + 'plot_posterior_predictive', + 'plot_trace', + 'slicerplot_with_residuals', ] diff --git a/src/easydynamics/analysis/analysis.py b/src/easydynamics/analysis/analysis.py index 46645afa..89af3fc8 100644 --- a/src/easydynamics/analysis/analysis.py +++ b/src/easydynamics/analysis/analysis.py @@ -45,7 +45,6 @@ class Analysis(AnalysisBase): ```python import pooch import easydynamics as edyn - import easydynamics.sample_model as sm file_path = pooch.retrieve( url='https://github.com/easyscience/dynamics-lib/raw/refs/heads/master/docs/docs/tutorials/data/vanadium_data_example.h5', @@ -54,10 +53,10 @@ class Analysis(AnalysisBase): experiment = edyn.Experiment('Vanadium') experiment.load_hdf5(filename=file_path) - sample_model = sm.SampleModel(components=sm.DeltaFunction(area=1)) - resolution_model = sm.ResolutionModel(components=sm.Gaussian(width=0.1)) - background_model = sm.BackgroundModel(components=sm.Polynomial(coefficients=[0.001])) - instrument_model = sm.InstrumentModel( + sample_model = edyn.SampleModel(components=edyn.DeltaFunction(area=1)) + resolution_model = edyn.ResolutionModel(components=edyn.Gaussian(width=0.1)) + background_model = edyn.BackgroundModel(components=edyn.Polynomial(coefficients=[0.001])) + instrument_model = edyn.InstrumentModel( resolution_model=resolution_model, background_model=background_model, ) diff --git a/src/easydynamics/analysis/analysis1d.py b/src/easydynamics/analysis/analysis1d.py index 5c8a68be..2814e269 100644 --- a/src/easydynamics/analysis/analysis1d.py +++ b/src/easydynamics/analysis/analysis1d.py @@ -45,8 +45,6 @@ class Analysis1d(AnalysisBase): ```python import pooch import easydynamics as edyn - import easydynamics.sample_model as sm - from easydynamics.analysis.analysis1d import Analysis1d file_path = pooch.retrieve( url='https://github.com/easyscience/dynamics-lib/raw/refs/heads/master/docs/docs/tutorials/data/vanadium_data_example.h5', @@ -55,15 +53,15 @@ class Analysis1d(AnalysisBase): experiment = edyn.Experiment('Vanadium') experiment.load_hdf5(filename=file_path) - sample_model = sm.SampleModel(components=sm.DeltaFunction(area=1)) - resolution_model = sm.ResolutionModel(components=sm.Gaussian(width=0.1)) - background_model = sm.BackgroundModel(components=sm.Polynomial(coefficients=[0.001])) - instrument_model = sm.InstrumentModel( + sample_model = edyn.SampleModel(components=edyn.DeltaFunction(area=1)) + resolution_model = edyn.ResolutionModel(components=edyn.Gaussian(width=0.1)) + background_model = edyn.BackgroundModel(components=edyn.Polynomial(coefficients=[0.001])) + instrument_model = edyn.InstrumentModel( resolution_model=resolution_model, background_model=background_model, ) - analysis = Analysis1d( + analysis = edyn.Analysis1d( display_name='Vanadium 1D Analysis', experiment=experiment, sample_model=sample_model, diff --git a/src/easydynamics/analysis/fit_binding.py b/src/easydynamics/analysis/fit_binding.py index 2b3cf7d3..58a190f9 100644 --- a/src/easydynamics/analysis/fit_binding.py +++ b/src/easydynamics/analysis/fit_binding.py @@ -32,9 +32,8 @@ class FitBinding(EasyDynamicsBase): values): ```python import easydynamics as edyn - import easydynamics.sample_model as sm - fit_func = sm.Polynomial( + fit_func = edyn.Polynomial( coefficients=[3.7, -0.5], x_unit='1/angstrom', y_unit='meV', @@ -49,7 +48,7 @@ class FitBinding(EasyDynamicsBase): ``'delta_area'``). With ``targets=None`` all predictions are fitted against default dataset keys derived from the model's component names: ```python - brownian = sm.BrownianTranslationalDiffusion( + brownian = edyn.BrownianTranslationalDiffusion( diffusion_coefficient=2.4e-9, scale=0.5, lorentzian_name='Lorentzian', @@ -63,7 +62,7 @@ class FitBinding(EasyDynamicsBase): ```python binding = edyn.FitBinding(model=brownian, targets=['width']) - delta_lorentz = sm.DeltaLorentz(A_0=0.5, lorentzian_width=0.1) + delta_lorentz = edyn.DeltaLorentz(A_0=0.5, lorentzian_width=0.1) binding = edyn.FitBinding( model=delta_lorentz, targets={ diff --git a/src/easydynamics/analysis/parameter_analysis.py b/src/easydynamics/analysis/parameter_analysis.py index 1ac49684..ffe5fd2c 100644 --- a/src/easydynamics/analysis/parameter_analysis.py +++ b/src/easydynamics/analysis/parameter_analysis.py @@ -41,10 +41,9 @@ class ParameterAnalysis(EasyDynamicsModelBase): dataset keys using a ``FitBinding``: ```python import easydynamics as edyn - import easydynamics.sample_model as sm # analysis is an edyn.Analysis object with previously fitted parameters - diffusion_model = sm.BrownianTranslationalDiffusion(diffusion_coefficient=2.4e-9, scale=0.5) + diffusion_model = edyn.BrownianTranslationalDiffusion(diffusion_coefficient=2.4e-9, scale=0.5) binding = edyn.FitBinding( model=diffusion_model, targets={'width': 'Lorentzian width'}, @@ -65,7 +64,7 @@ class ParameterAnalysis(EasyDynamicsModelBase): (or pass ``x_unit=None`` / ``y_unit=None`` to fit raw values): ```python area_binding = edyn.FitBinding( - model=sm.Polynomial(coefficients=[0.5, 0.0], x_unit='1/angstrom', y_unit='meV'), + model=edyn.Polynomial(coefficients=[0.5, 0.0], x_unit='1/angstrom', y_unit='meV'), targets='Lorentzian area', ) param_analysis = edyn.ParameterAnalysis( diff --git a/src/easydynamics/convolution/convolution.py b/src/easydynamics/convolution/convolution.py index a2da80a2..578df564 100644 --- a/src/easydynamics/convolution/convolution.py +++ b/src/easydynamics/convolution/convolution.py @@ -42,16 +42,15 @@ class Convolution(NumericalConvolutionBase): ``Gaussian``, ``Lorentzian``, or ``Voigt``: ```python import numpy as np - import easydynamics.sample_model as sm - from easydynamics.convolution import Convolution + import easydynamics as edyn - sample_components = sm.ComponentCollection( - components=[sm.DeltaFunction(area=0.5), sm.Lorentzian(area=1.0, width=0.3)] + sample_components = edyn.ComponentCollection( + components=[edyn.DeltaFunction(area=0.5), edyn.Lorentzian(area=1.0, width=0.3)] ) - resolution_components = sm.ComponentCollection(components=[sm.Gaussian(width=0.05)]) + resolution_components = edyn.ComponentCollection(components=[edyn.Gaussian(width=0.05)]) energy = np.linspace(-2, 2, 100) - convolver = Convolution( + convolver = edyn.Convolution( sample_components=sample_components, resolution_components=resolution_components, energy=energy, diff --git a/src/easydynamics/sample_model/background_model.py b/src/easydynamics/sample_model/background_model.py index 031d9493..0699c34c 100644 --- a/src/easydynamics/sample_model/background_model.py +++ b/src/easydynamics/sample_model/background_model.py @@ -20,11 +20,11 @@ class BackgroundModel(ModelBase): A constant background independent of Q: ```python import numpy as np - import easydynamics.sample_model as sm + import easydynamics as edyn Q = np.linspace(0.5, 2, 7) - background_model = sm.BackgroundModel( - components=sm.Polynomial(coefficients=[0.001]), + background_model = edyn.BackgroundModel( + components=edyn.Polynomial(coefficients=[0.001]), Q=Q, ) energy = np.linspace(-2, 2, 100) @@ -35,10 +35,10 @@ class BackgroundModel(ModelBase): Higher-order polynomials can model a sloping or curved baseline: ```python - import easydynamics.sample_model as sm + import easydynamics as edyn - background_model = sm.BackgroundModel( - components=sm.Polynomial(coefficients=[1.0, 0.1, 0.01]), + background_model = edyn.BackgroundModel( + components=edyn.Polynomial(coefficients=[1.0, 0.1, 0.01]), ) ``` """ diff --git a/src/easydynamics/sample_model/component_collection.py b/src/easydynamics/sample_model/component_collection.py index b63135fb..adf3bc14 100644 --- a/src/easydynamics/sample_model/component_collection.py +++ b/src/easydynamics/sample_model/component_collection.py @@ -33,11 +33,11 @@ class ComponentCollection(EasyDynamicsList, EasyDynamicsModelBase): ```python import numpy as np - import easydynamics.sample_model as sm + import easydynamics as edyn - component1 = sm.Gaussian(name='Gaussian1', area=1.0, width=1.0) - component2 = sm.Lorentzian(name='Lorentzian1', area=2.0, width=0.5) - collection = sm.ComponentCollection(components=[component1, component2]) + component1 = edyn.Gaussian(name='Gaussian1', area=1.0, width=1.0) + component2 = edyn.Lorentzian(name='Lorentzian1', area=2.0, width=0.5) + collection = edyn.ComponentCollection(components=[component1, component2]) ``` **Evaluating, appending, and removing components** @@ -46,7 +46,7 @@ class ComponentCollection(EasyDynamicsList, EasyDynamicsModelBase): x = np.linspace(-5, 5, 100) values = collection.evaluate(x) - component3 = sm.Gaussian(name='Gaussian2', area=0.5, width=0.8) + component3 = edyn.Gaussian(name='Gaussian2', area=0.5, width=0.8) collection.append(component3) collection.remove('Gaussian1') diff --git a/src/easydynamics/sample_model/components/damped_harmonic_oscillator.py b/src/easydynamics/sample_model/components/damped_harmonic_oscillator.py index 90a63562..707823f5 100644 --- a/src/easydynamics/sample_model/components/damped_harmonic_oscillator.py +++ b/src/easydynamics/sample_model/components/damped_harmonic_oscillator.py @@ -34,9 +34,9 @@ class DampedHarmonicOscillator(CreateParametersMixin, ModelComponent): (at ±center) are captured by the model: ```python import numpy as np - import easydynamics.sample_model as sm + import easydynamics as edyn - dho = sm.DampedHarmonicOscillator(area=1.0, center=10.0, width=1.0) + dho = edyn.DampedHarmonicOscillator(area=1.0, center=10.0, width=1.0) x = np.linspace(-20, 20, 200) values = dho.evaluate(x) ``` @@ -44,9 +44,9 @@ class DampedHarmonicOscillator(CreateParametersMixin, ModelComponent): **Modifying parameters after construction** ```python - import easydynamics.sample_model as sm + import easydynamics as edyn - dho = sm.DampedHarmonicOscillator(area=2.0, center=5.0, width=0.5, name='Phonon') + dho = edyn.DampedHarmonicOscillator(area=2.0, center=5.0, width=0.5, name='Phonon') dho.area = 3.0 dho.center = 8.0 dho.width = 0.3 diff --git a/src/easydynamics/sample_model/components/delta_function.py b/src/easydynamics/sample_model/components/delta_function.py index 60c343a3..539f2970 100644 --- a/src/easydynamics/sample_model/components/delta_function.py +++ b/src/easydynamics/sample_model/components/delta_function.py @@ -37,9 +37,9 @@ class DeltaFunction(CreateParametersMixin, ModelComponent): convolutions, making it useful for modelling the elastic line in QENS: ```python import numpy as np - import easydynamics.sample_model as sm + import easydynamics as edyn - delta = sm.DeltaFunction(area=1.0) + delta = edyn.DeltaFunction(area=1.0) x = np.linspace(-2, 2, 100) values = delta.evaluate(x) # all zeros except at the bin nearest to center ``` @@ -48,9 +48,9 @@ class DeltaFunction(CreateParametersMixin, ModelComponent): Pass a numeric value for ``center`` to place the elastic line at a specific energy transfer: ```python - import easydynamics.sample_model as sm + import easydynamics as edyn - delta = sm.DeltaFunction(area=0.7, center=0.5) + delta = edyn.DeltaFunction(area=0.7, center=0.5) delta.area = 0.5 ``` """ diff --git a/src/easydynamics/sample_model/components/exponential.py b/src/easydynamics/sample_model/components/exponential.py index 08dd3b43..941394b2 100644 --- a/src/easydynamics/sample_model/components/exponential.py +++ b/src/easydynamics/sample_model/components/exponential.py @@ -28,9 +28,9 @@ class Exponential(CreateParametersMixin, ModelComponent): By default the center is fixed at 0. A negative ``rate`` gives a decaying exponential: ```python import numpy as np - import easydynamics.sample_model as sm + import easydynamics as edyn - exp = sm.Exponential(amplitude=1.0, rate=-0.5) + exp = edyn.Exponential(amplitude=1.0, rate=-0.5) x = np.linspace(0, 5, 100) values = exp.evaluate(x) ``` @@ -39,9 +39,9 @@ class Exponential(CreateParametersMixin, ModelComponent): Pass a numeric value for ``center`` to leave it free during fitting: ```python - import easydynamics.sample_model as sm + import easydynamics as edyn - exp = sm.Exponential(amplitude=2.0, center=1.0, rate=-1.0, name='Background') + exp = edyn.Exponential(amplitude=2.0, center=1.0, rate=-1.0, name='Background') exp.amplitude = 3.0 exp.rate = -0.5 ``` diff --git a/src/easydynamics/sample_model/components/expression_component.py b/src/easydynamics/sample_model/components/expression_component.py index 5fff46b3..25e26104 100644 --- a/src/easydynamics/sample_model/components/expression_component.py +++ b/src/easydynamics/sample_model/components/expression_component.py @@ -41,9 +41,9 @@ class ExpressionComponent(ModelComponent): construction: ```python import numpy as np - import easydynamics.sample_model as sm + import easydynamics as edyn - expr = sm.ExpressionComponent( + expr = edyn.ExpressionComponent( 'A * exp(-(x - x0)**2 / (2*sigma**2))', parameters={'A': 10, 'x0': 0, 'sigma': 1}, x_unit='meV', @@ -68,7 +68,7 @@ class ExpressionComponent(ModelComponent): the unit of the evaluated expression is derived from the parameter units and x_unit (see ``output_unit``), and a warning is issued if it does not match y_unit: ```python - expr = sm.ExpressionComponent( + expr = edyn.ExpressionComponent( 'A * exp(-(x - x0)**2 / (2*sigma**2))', parameters={'A': 10, 'x0': 0, 'sigma': 1}, parameter_units={'A': '1/meV', 'x0': 'meV', 'sigma': 'meV'}, @@ -82,7 +82,7 @@ class ExpressionComponent(ModelComponent): The symbols ``hbar`` (in meV*s) and ``kb`` (in meV/K) are provided automatically as read-only constants (DescriptorNumbers) when they appear in the expression: ```python - boltzmann = sm.ExpressionComponent( + boltzmann = edyn.ExpressionComponent( 'exp(-x / (kb * T))', parameters={'T': 300.0}, parameter_units={'T': 'K'}, diff --git a/src/easydynamics/sample_model/components/gaussian.py b/src/easydynamics/sample_model/components/gaussian.py index 364e89ab..db9ad082 100644 --- a/src/easydynamics/sample_model/components/gaussian.py +++ b/src/easydynamics/sample_model/components/gaussian.py @@ -36,9 +36,9 @@ class Gaussian(CreateParametersMixin, ModelComponent): By default the center is fixed at 0, which is the typical setup for a QENS elastic line: ```python import numpy as np - import easydynamics.sample_model as sm + import easydynamics as edyn - g = sm.Gaussian(area=1.0, width=0.5) + g = edyn.Gaussian(area=1.0, width=0.5) x = np.linspace(-2, 2, 100) values = g.evaluate(x) ``` @@ -48,9 +48,9 @@ class Gaussian(CreateParametersMixin, ModelComponent): Pass a numeric value for ``center`` to leave it free during fitting, and use the property setters to update parameter values after construction: ```python - import easydynamics.sample_model as sm + import easydynamics as edyn - g = sm.Gaussian(area=2.0, center=0.5, width=0.3, name='Peak') + g = edyn.Gaussian(area=2.0, center=0.5, width=0.3, name='Peak') g.area = 3.0 g.width = 0.2 ``` diff --git a/src/easydynamics/sample_model/components/lorentzian.py b/src/easydynamics/sample_model/components/lorentzian.py index fe36340f..6aade54f 100644 --- a/src/easydynamics/sample_model/components/lorentzian.py +++ b/src/easydynamics/sample_model/components/lorentzian.py @@ -35,9 +35,9 @@ class Lorentzian(CreateParametersMixin, ModelComponent): By default the center is fixed at 0, which is the typical setup for a QENS quasi-elastic line: ```python import numpy as np - import easydynamics.sample_model as sm + import easydynamics as edyn - l = sm.Lorentzian(area=1.0, width=0.3) + l = edyn.Lorentzian(area=1.0, width=0.3) x = np.linspace(-2, 2, 100) values = l.evaluate(x) ``` @@ -46,9 +46,9 @@ class Lorentzian(CreateParametersMixin, ModelComponent): Pass a numeric value for ``center`` to leave it free during fitting: ```python - import easydynamics.sample_model as sm + import easydynamics as edyn - l = sm.Lorentzian(area=2.0, center=0.5, width=0.3, name='QE peak') + l = edyn.Lorentzian(area=2.0, center=0.5, width=0.3, name='QE peak') l.area = 3.0 l.width = 0.2 ``` diff --git a/src/easydynamics/sample_model/components/polynomial.py b/src/easydynamics/sample_model/components/polynomial.py index e30ff96b..4e592cf6 100644 --- a/src/easydynamics/sample_model/components/polynomial.py +++ b/src/easydynamics/sample_model/components/polynomial.py @@ -33,9 +33,9 @@ class Polynomial(ModelComponent): ```python import numpy as np - import easydynamics.sample_model as sm + import easydynamics as edyn - poly = sm.Polynomial(coefficients=[1.5]) + poly = edyn.Polynomial(coefficients=[1.5]) x = np.linspace(-5, 5, 100) values = poly.evaluate(x) ``` @@ -44,9 +44,9 @@ class Polynomial(ModelComponent): Coefficients are ordered as ``[c0, c1, ...]``, where ``c0`` is the constant term: ```python - import easydynamics.sample_model as sm + import easydynamics as edyn - poly = sm.Polynomial(coefficients=[2.0, 0.1], name='Background') + poly = edyn.Polynomial(coefficients=[2.0, 0.1], name='Background') poly.coefficients = [1.5, 0.05] ``` @@ -54,17 +54,17 @@ class Polynomial(ModelComponent): Powers that are not listed are filled with coefficients fixed to zero: ```python - import easydynamics.sample_model as sm + import easydynamics as edyn - poly = sm.Polynomial(coefficients={2: 1.5}) # 1.5*x^2, with c0 and c1 fixed at 0 + poly = edyn.Polynomial(coefficients={2: 1.5}) # 1.5*x^2, with c0 and c1 fixed at 0 ``` **Changing the degree after construction** ```python - import easydynamics.sample_model as sm + import easydynamics as edyn - poly = sm.Polynomial(coefficients=[2.0, 0.1]) + poly = edyn.Polynomial(coefficients=[2.0, 0.1]) poly.add_coefficient(0.05) # now 2.0 + 0.1*x + 0.05*x^2 removed = poly.remove_coefficient() # returns 0.05, back to 2.0 + 0.1*x ``` diff --git a/src/easydynamics/sample_model/components/voigt.py b/src/easydynamics/sample_model/components/voigt.py index ee8c2904..d0bd070d 100644 --- a/src/easydynamics/sample_model/components/voigt.py +++ b/src/easydynamics/sample_model/components/voigt.py @@ -35,9 +35,9 @@ class Voigt(CreateParametersMixin, ModelComponent): fixed at 0: ```python import numpy as np - import easydynamics.sample_model as sm + import easydynamics as edyn - v = sm.Voigt(area=1.0, gaussian_width=0.1, lorentzian_width=0.3) + v = edyn.Voigt(area=1.0, gaussian_width=0.1, lorentzian_width=0.3) x = np.linspace(-2, 2, 100) values = v.evaluate(x) ``` @@ -47,9 +47,9 @@ class Voigt(CreateParametersMixin, ModelComponent): Pass a numeric value for ``center`` to leave it free during fitting, and use the property setters to adjust the two width components after construction: ```python - import easydynamics.sample_model as sm + import easydynamics as edyn - v = sm.Voigt(area=2.0, center=0.5, gaussian_width=0.2, lorentzian_width=0.4, name='Peak') + v = edyn.Voigt(area=2.0, center=0.5, gaussian_width=0.2, lorentzian_width=0.4, name='Peak') v.gaussian_width = 0.1 v.lorentzian_width = 0.2 ``` diff --git a/src/easydynamics/sample_model/diffusion_model/brownian_translational_diffusion.py b/src/easydynamics/sample_model/diffusion_model/brownian_translational_diffusion.py index b15d0012..cfcefae9 100644 --- a/src/easydynamics/sample_model/diffusion_model/brownian_translational_diffusion.py +++ b/src/easydynamics/sample_model/diffusion_model/brownian_translational_diffusion.py @@ -33,10 +33,10 @@ class BrownianTranslationalDiffusion(DiffusionModelBase): construction or later via ``create_component_collections``: ```python import numpy as np - import easydynamics.sample_model as sm + import easydynamics as edyn Q = np.linspace(0.5, 2, 7) - diffusion_model = sm.BrownianTranslationalDiffusion( + diffusion_model = edyn.BrownianTranslationalDiffusion( scale=1.0, diffusion_coefficient=2.4e-9, Q=Q, diff --git a/src/easydynamics/sample_model/diffusion_model/delta_lorentz.py b/src/easydynamics/sample_model/diffusion_model/delta_lorentz.py index 1e855243..2e255d42 100644 --- a/src/easydynamics/sample_model/diffusion_model/delta_lorentz.py +++ b/src/easydynamics/sample_model/diffusion_model/delta_lorentz.py @@ -42,10 +42,10 @@ class DeltaLorentz(DiffusionModelBase): Set ``allow_Q_variation`` to allow individual parameters to vary with Q: ```python import numpy as np - import easydynamics.sample_model as sm + import easydynamics as edyn Q = np.linspace(0.5, 2, 7) - model = sm.DeltaLorentz( + model = edyn.DeltaLorentz( display_name='DiffusionModel', scale=1.0, mean_u_squared=0.02, diff --git a/src/easydynamics/sample_model/diffusion_model/jump_translational_diffusion.py b/src/easydynamics/sample_model/diffusion_model/jump_translational_diffusion.py index 67a69320..ad615e3b 100644 --- a/src/easydynamics/sample_model/diffusion_model/jump_translational_diffusion.py +++ b/src/easydynamics/sample_model/diffusion_model/jump_translational_diffusion.py @@ -35,10 +35,10 @@ class JumpTranslationalDiffusion(DiffusionModelBase): Pass the diffusion coefficient (in m²/s) and relaxation time (in ps) along with Q values: ```python import numpy as np - import easydynamics.sample_model as sm + import easydynamics as edyn Q = np.linspace(0.5, 2, 7) - diffusion_model = sm.JumpTranslationalDiffusion( + diffusion_model = edyn.JumpTranslationalDiffusion( scale=1.0, diffusion_coefficient=2.4e-9, relaxation_time=1.0, diff --git a/src/easydynamics/sample_model/instrument_model.py b/src/easydynamics/sample_model/instrument_model.py index e6d45447..f8a9fa6e 100644 --- a/src/easydynamics/sample_model/instrument_model.py +++ b/src/easydynamics/sample_model/instrument_model.py @@ -33,13 +33,13 @@ class InstrumentModel(NewBase): ```python import numpy as np - import easydynamics.sample_model as sm + import easydynamics as edyn Q = np.linspace(0.5, 2, 7) - resolution_model = sm.ResolutionModel(components=sm.Gaussian(width=0.05)) - background_model = sm.BackgroundModel(components=sm.Polynomial(coefficients=[0.001])) + resolution_model = edyn.ResolutionModel(components=edyn.Gaussian(width=0.05)) + background_model = edyn.BackgroundModel(components=edyn.Polynomial(coefficients=[0.001])) - instrument_model = sm.InstrumentModel( + instrument_model = edyn.InstrumentModel( Q=Q, resolution_model=resolution_model, background_model=background_model, diff --git a/src/easydynamics/sample_model/resolution_model.py b/src/easydynamics/sample_model/resolution_model.py index a9fc9e1e..3949f843 100644 --- a/src/easydynamics/sample_model/resolution_model.py +++ b/src/easydynamics/sample_model/resolution_model.py @@ -27,11 +27,11 @@ class ResolutionModel(ModelBase): ``Polynomial``, and ``Exponential`` components are not allowed in a ResolutionModel: ```python import numpy as np - import easydynamics.sample_model as sm + import easydynamics as edyn Q = np.linspace(0.5, 2, 7) - resolution_model = sm.ResolutionModel( - components=sm.Gaussian(width=0.05, area=1.0), + resolution_model = edyn.ResolutionModel( + components=edyn.Gaussian(width=0.05, area=1.0), Q=Q, ) energy = np.linspace(-2, 2, 100) @@ -43,7 +43,7 @@ class ResolutionModel(ModelBase): After fitting vanadium data with a SampleModel, use ``from_sample_model`` to convert it directly into a ResolutionModel: ```python - resolution_model = sm.ResolutionModel.from_sample_model(fitted_sample_model) + resolution_model = edyn.ResolutionModel.from_sample_model(fitted_sample_model) ``` """ diff --git a/src/easydynamics/sample_model/sample_model.py b/src/easydynamics/sample_model/sample_model.py index 6d699688..fc6b7762 100644 --- a/src/easydynamics/sample_model/sample_model.py +++ b/src/easydynamics/sample_model/sample_model.py @@ -34,15 +34,15 @@ class SampleModel(ModelBase): A single component is copied to each Q value automatically: ```python import numpy as np - import easydynamics.sample_model as sm + import easydynamics as edyn Q = np.linspace(0.5, 2, 7) energy = np.linspace(-2, 2, 100) - sample_model = sm.SampleModel( + sample_model = edyn.SampleModel( components=[ - sm.DeltaFunction(display_name='Elastic', area=0.5), - sm.Lorentzian(display_name='QE', area=0.5, width=0.3), + edyn.DeltaFunction(display_name='Elastic', area=0.5), + edyn.Lorentzian(display_name='QE', area=0.5, width=0.3), ], Q=Q, ) @@ -54,11 +54,11 @@ class SampleModel(ModelBase): Pass ``temperature`` to apply the detailed balance factor automatically: ```python import numpy as np - import easydynamics.sample_model as sm + import easydynamics as edyn Q = np.linspace(0.5, 2, 7) - btd = sm.BrownianTranslationalDiffusion(diffusion_coefficient=2.4e-9, scale=0.5) - sample_model = sm.SampleModel(diffusion_models=btd, Q=Q, temperature=10) + btd = edyn.BrownianTranslationalDiffusion(diffusion_coefficient=2.4e-9, scale=0.5) + sample_model = edyn.SampleModel(diffusion_models=btd, Q=Q, temperature=10) intensity = sample_model.evaluate(np.linspace(-2, 2, 100)) ``` """ diff --git a/src/easydynamics/utils/detailed_balance.py b/src/easydynamics/utils/detailed_balance.py index 90fdf650..a3b540cd 100644 --- a/src/easydynamics/utils/detailed_balance.py +++ b/src/easydynamics/utils/detailed_balance.py @@ -75,9 +75,9 @@ def detailed_balance_factor( **Basic usage** ```python - from easydynamics.utils.detailed_balance import detailed_balance_factor + import easydynamics as edyn - dbf = detailed_balance_factor(1.0, 300) # 1 meV at 300 K + dbf = edyn.detailed_balance_factor(1.0, 300) # 1 meV at 300 K ``` **Specifying units and disabling temperature normalisation** diff --git a/src/easydynamics/utils/plotting.py b/src/easydynamics/utils/plotting.py index 35d604c5..cb8ee0a9 100644 --- a/src/easydynamics/utils/plotting.py +++ b/src/easydynamics/utils/plotting.py @@ -31,14 +31,14 @@ def slicerplot_with_residuals( ```python import scipp as sc - from easydynamics.utils.plotting import slicerplot_with_residuals + import easydynamics as edyn dg = sc.DataGroup({ 'Data': my_data, 'Model': my_model, 'Residuals': my_residuals, }) - fig = slicerplot_with_residuals(dg, residuals_key='Residuals', keep='energy') + fig = edyn.slicerplot_with_residuals(dg, residuals_key='Residuals', keep='energy') ``` Parameters diff --git a/tests/unit/easydynamics/test_public_api.py b/tests/unit/easydynamics/test_public_api.py new file mode 100644 index 00000000..fb81e81e --- /dev/null +++ b/tests/unit/easydynamics/test_public_api.py @@ -0,0 +1,78 @@ +# SPDX-FileCopyrightText: 2026 EasyScience contributors +# SPDX-License-Identifier: BSD-3-Clause + +""" +Tests for the flat public namespace. + +Tutorials and docstring examples reach everything through ``import easydynamics as edyn``, which +only works while the front door keeps up with the sub-packages. These check that it does. +""" + +import importlib +import json +import pathlib +import re + +import pytest + +import easydynamics as edyn + +SUB_PACKAGES = [ + 'easydynamics.analysis', + 'easydynamics.base_classes', + 'easydynamics.convolution', + 'easydynamics.experiment', + 'easydynamics.sample_model', + 'easydynamics.settings', + 'easydynamics.utils', +] + +TUTORIALS = pathlib.Path(__file__).resolve().parents[3] / 'docs' / 'docs' / 'tutorials' + + +class TestFrontDoor: + def test_everything_declared_is_importable(self): + # THEN EXPECT no name in __all__ that cannot actually be reached + missing = [name for name in edyn.__all__ if not hasattr(edyn, name)] + assert missing == [] + + @pytest.mark.parametrize('module_name', SUB_PACKAGES) + def test_sub_package_exports_are_re_exported(self, module_name): + # THEN + module = importlib.import_module(module_name) + + # EXPECT anything public in a sub-package is on the front door too, so a tutorial never + # has to import from the sub-package to reach it + missing = [name for name in getattr(module, '__all__', []) if name not in edyn.__all__] + assert missing == [], f'{module_name} exports not re-exported: {missing}' + + def test_re_exports_are_the_same_objects(self): + # WHEN + from easydynamics.sample_model import Gaussian + + # THEN EXPECT the front door is an alias, not a copy + assert edyn.Gaussian is Gaussian + + def test_all_is_sorted_and_unique(self): + # THEN EXPECT a list that stays easy to scan and cannot hide a duplicate + assert edyn.__all__ == sorted(edyn.__all__) + assert len(edyn.__all__) == len(set(edyn.__all__)) + + +class TestTutorialImportStyle: + @pytest.mark.parametrize('notebook', sorted(TUTORIALS.glob('*.ipynb')), ids=lambda p: p.name) + def test_notebooks_use_only_the_flat_namespace(self, notebook): + # THEN + cells = json.loads(notebook.read_text(encoding='utf-8'))['cells'] + imports = [ + line.strip() + for cell in cells + if cell['cell_type'] == 'code' + for line in ''.join(cell['source']).splitlines() + if re.match(r'^\s*(import|from)\s+easydynamics', line) + ] + + # EXPECT one way in, so a reader never has to scroll back to find where a name came from + assert set(imports) <= {'import easydynamics as edyn'}, ( + f'{notebook.name} imports EasyDynamics some other way: {imports}' + )