3
3
Using diffpy.morph in Python
4
4
############################
5
5
6
- On top of the command-line usage described in the `quickstart tutorial <quickstart.html >`__,
6
+ On top of the command-line (CLI) usage described in the `quickstart tutorial <quickstart.html >`__,
7
7
``diffpy.morph `` also supports Python integration.
8
- This functionality is intended for those acquainted with the basic morphs
8
+ All functionality supported on the CLI is also available for Python.
9
+ This page is intended for those acquainted with the basic morphs
9
10
described in the aforementioned quickstart tutorial who want to use ``diffpy.morph `` in their
10
11
Python scripts.
11
12
@@ -150,15 +151,6 @@ ipradius: float
150
151
equatorial radius iradius and polar radius ipradius.
151
152
If only ipradius is specified, instead apply inverse
152
153
characteristic function of sphere with radius ipradius.
153
- funcy: tuple (function, dict)
154
- See Python-Specific Morphs below.
155
-
156
- Python-Specific Morphs
157
- ======================
158
-
159
- Some morphs in ``diffpy.morph `` are supported only in Python. Here, we detail
160
- how they are used and how to call them.
161
-
162
154
funcy: tuple (function, dict)
163
155
This morph applies the function funcy[0] with parameters given in funcy[1].
164
156
The function funcy[0] must be a function of both the abscissa and ordinate
@@ -172,3 +164,90 @@ funcy: tuple (function, dict)
172
164
This function takes in both the abscissa and ordinate on top of three additional
173
165
parameters a, b, and c. To use the funcy parameter with initial guesses
174
166
a=1.0, b=2.0, c=3.0, we would pass ``funcy=(linear, {a: 1.0, b: 2.0, c: 3.0}) ``.
167
+ For an example use-case, see the Python-Specific Morphs section below.
168
+
169
+
170
+ Python-Specific Morphs
171
+ ======================
172
+
173
+ Some morphs in ``diffpy.morph `` are supported only in Python. Here, we detail
174
+ how they are used and how to call them.
175
+
176
+ MorphFuncy: Applying custom functions
177
+ -------------------------------------
178
+
179
+ The ``MorphFuncy `` morph allows users to apply a custom Python function
180
+ to the y-axis values of a dataset, enabling flexible and user-defined
181
+ transformations.
182
+
183
+ In this tutorial, we walk through how to use ``MorphFuncy `` with an example
184
+ transformation. Unlike other morphs that can be run from the command line,
185
+ ``MorphFuncy `` requires a Python function and is therefore intended to be used
186
+ through Python scripting.
187
+
188
+ 1. Import the necessary modules into your Python script:
189
+
190
+ .. code-block :: python
191
+
192
+ from diffpy.morph.morph_api import morph, morph_default_config
193
+ import numpy as np
194
+
195
+ 2. Define a custom Python function to apply a transformation to the data.
196
+ The function must take ``x `` and ``y `` (1D arrays of the same length)
197
+ along with named parameters, and return a transformed ``y `` array of the
198
+ same length.
199
+ For this example, we will use a simple linear transformation that
200
+ scales the input and applies an offset:
201
+
202
+ .. code-block :: python
203
+
204
+ def linear_function (x , y , scale , offset ):
205
+ return (scale * x) * y + offset
206
+
207
+ 3. In this example, we use a sine function for the morph data and generate
208
+ the target data by applying the linear transformation with known scale
209
+ and offset to it:
210
+
211
+ .. code-block :: python
212
+
213
+ x_morph = np.linspace(0 , 10 , 101 )
214
+ y_morph = np.sin(x_morph)
215
+ x_target = x_morph.copy()
216
+ y_target = np.sin(x_target) * 20 * x_target + 0.8
217
+
218
+ 4. Set up the morph configuration dictionary. This includes both the
219
+ transformation parameters (our initial guess) and the transformation
220
+ function itself:
221
+
222
+ .. code-block :: python
223
+
224
+ morph_config = morph_default_config(funcy = {" scale" : 1.2 , " offset" : 0.1 })
225
+ morph_config[" function" ] = linear_function
226
+
227
+ # morph_config now contains:
228
+ # {'funcy': {'scale': 1.2, 'offset': 0.1}, 'function': linear_function}
229
+
230
+ 5. Run the morph using the ``morph(...) ``. This will apply the user-defined
231
+ function and refine the parameters to best align the morph data
232
+ with the target data:
233
+
234
+ .. code-block :: python
235
+
236
+ morph_result = morph(x_morph, y_morph, x_target, y_target, ** morph_config)
237
+
238
+ 6. Extract the morphed output and the fitted parameters from the result:
239
+
240
+ .. code-block :: python
241
+
242
+ fitted_config = morph_result[" morphed_config" ]
243
+ x_morph_out, y_morph_out, x_target_out, y_target_out = morph_result[" morph_chain" ].xyallout
244
+
245
+ fitted_params = fitted_config[" funcy" ]
246
+ print (f " Fitted scale: { fitted_params[' scale' ]} " )
247
+ print (f " Fitted offset: { fitted_params[' offset' ]} " )
248
+
249
+ As you can see, the fitted scale and offset values match the ones used
250
+ to generate the target (scale=20 & offset=0.8). This example shows how
251
+ ``MorphFuncy `` can be used to fit and apply custom transformations. Now
252
+ it's your turn to experiment with other custom functions that may be useful
253
+ for analyzing your data.
0 commit comments