@@ -193,12 +193,6 @@ funcy: tuple (function, dict)
193
193
funcx: tuple (function, dict)
194
194
Apply a function to the x-axis of the (two-column) data.
195
195
196
- This morph works fundamentally differently from the other grid morphs
197
- (e.g. stretch and squeeze) as it directly modifies the grid of the
198
- morph function.
199
- The other morphs maintain the original grid and apply the morphs by interpolating
200
- the function ***.
201
-
202
196
This morph applies the function funcx[0] with parameters given in funcx[1].
203
197
The function funcx[0] take in as parameters both the abscissa and ordinate
204
198
(i.e. take in at least two inputs with as many additional parameters as needed).
@@ -403,137 +397,4 @@ how much the
403
397
MorphFuncxy:
404
398
^^^^^^^^^^^^
405
399
The ``MorphFuncxy `` morph allows users to apply a custom Python function
406
- to a dataset that modifies both the ``x `` and ``y `` column values.
407
- This is equivalent to applying a ``MorphFuncx `` and ``MorphFuncy ``
408
- simultaneously.
409
-
410
- This morph is useful when you want to apply operations that modify both
411
- the grid and function value. A PDF-specific example includes computing
412
- PDFs from 1D diffraction data (see paragraph at the end of this section).
413
-
414
- For this tutorial, we will go through two examples. One simple one
415
- involving shifting a function in the ``x `` and ``y `` directions, and
416
- another involving a Fourier transform.
417
-
418
- 1. Let's start by taking a simple ``sine `` function.
419
-
420
- .. code-block :: python
421
-
422
- import numpy as np
423
- morph_x = np.linspace(0 , 10 , 101 )
424
- morph_y = np.sin(morph_x)
425
- morph_table = np.array([morph_x, morph_y]).T
426
-
427
- 2. Then, let our target function be that same ``sine `` function shifted
428
- to the right by ``0.3 `` and up by ``0.7 ``.
429
-
430
- .. code-block :: python
431
-
432
- target_x = morph_x + 0.3
433
- target_y = morph_y + 0.7
434
- target_table = np.array([target_x, target_y]).T
435
-
436
- 3. While we could use the ``hshift `` and ``vshift `` morphs,
437
- this would require us to refine over two separate morph
438
- operations. We can instead perform these morphs simultaneously
439
- by defining a function:
440
-
441
- .. code-block :: python
442
-
443
- def shift (x , y , hshift , vshift ):
444
- return x + hshift, y + vshift
445
-
446
- 4. Now, let's try finding the optimal shift parameters using the ``MorphFuncxy `` morph.
447
- We can try an initial guess of ``hshift=0.0 `` and ``vshift=0.0 ``.
448
-
449
- .. code-block :: python
450
-
451
- from diffpy.morph.morphpy import morph_arrays
452
- initial_guesses = {" hshift" : 0.0 , " vshift" : 0.0 }
453
- info, table = morph_arrays(morph_table, target_table, funcxy = (shift, initial_guesses))
454
-
455
- 5. Finally, to see the refined ``hshift `` and ``vshift `` parameters, we extract them from ``info ``.
456
-
457
- .. code-block :: python
458
-
459
- print (f " Refined hshift: { info[" funcxy" ][" hshift" ]} " )
460
- print (f " Refined vshift: { info[" funcxy" ][" vshift" ]} " )
461
-
462
- Now for an example involving a Fourier transform.
463
-
464
- 1. Let's say you measured a signal of the form :math: `f(x)=\exp \{\cos (\pi x)\}`.
465
- Unfortunately, your measurement was taken against a noisy sinusoidal
466
- background of the form :math: `n(x)=A\sin (Bx)`, where ``A ``, ``B `` are unknown.
467
- For our example, let's say (unknown to us) that ``A=2 `` and ``B=1.7 ``.
468
-
469
- .. code-block :: python
470
-
471
- import numpy as np
472
- n = 201
473
- dx = 0.01
474
- measured_x = np.linspace(0 , 2 , n)
475
-
476
- def signal (x ):
477
- return np.exp(np.cos(np.pi * x))
478
-
479
- def noise (x , A , B ):
480
- return A * np.sin(B * x)
481
-
482
- measured_f = signal(measured_x) + noise(measured_x, 2 , 1.7 )
483
- morph_table = np.array([measured_x, measured_f]).T
484
-
485
- 2. Your colleague remembers they previously computed the Fourier transform
486
- of the function and has sent that to you.
487
-
488
- .. code-block :: python
489
-
490
- # We only consider the region where the grid is positive for simplicity
491
- target_x = np.fft.fftfreq(n, dx)[:n// 2 ]
492
- target_f = np.real(np.fft.fft(signal(measured_x))[:n// 2 ])
493
- target_table = np.array([target_x, target_f]).T
494
-
495
- 3. We can now write a noise subtraction function that takes in our measured
496
- signal and guesses for parameters ``A ``, ``B ``, and computes the Fourier
497
- transform post-noise-subtraction.
498
-
499
- .. code-block :: python
500
-
501
- def noise_subtracted_ft (x , y , A , B ):
502
- n = 201
503
- dx = 0.01
504
- background_subtracted_y = y - noise(x, A, B)
505
-
506
- ft_x = np.fft.fftfreq(n, dx)[:n// 2 ]
507
- ft_f = np.real(np.fft.fft(background_subtracted_y)[:n// 2 ])
508
-
509
- return ft_x, ft_f
510
-
511
- 4. Finally, we can provide initial guesses of ``A=0 `` and ``B=1 `` to the
512
- ``MorphFuncxy `` morph and see what refined values we get.
513
-
514
- .. code-block :: python
515
-
516
- from diffpy.morph.morphpy import morph_arrays
517
- initial_guesses = {" A" : 0 , " B" : 1 }
518
- info, table = morph_arrays(morph_table, target_table, funcxy = (background_subtracted_ft, initial_guesses))
519
-
520
- 5. Print these values to see if they match with the true values of
521
- of ``A=2.0 `` and ``B=1.7 ``!
522
-
523
- .. code-block :: python
524
-
525
- print (f " Refined A: { info[" funcxy" ][" A" ]} " )
526
- print (f " Refined B: { info[" funcxy" ][" B" ]} " )
527
-
528
- You can also use this morph to help find optimal parameters
529
- (e.g. ``rpoly ``, ``qmin ``, ``qmax ``, ``bgscale ``) for computing
530
- PDFs of materials with known structures.
531
- One does this by setting the ``MorphFuncxy `` function to a PDF
532
- computing function such as
533
- `PDFgetx3 <https://www.diffpy.org/products/pdfgetx.html >`_.
534
- The input (morphed) 1D function should be the 1D diffraction data
535
- one wishes to compute the PDF of and the target 1D function
536
- can be the PDF of a target material with similar geometry.
537
- More information about this will be released in the ``diffpy.morph ``
538
- manuscript, and we plan to integrate this feature automatically into
539
- ``PDFgetx3 `` soon.
400
+ to a dataset, ***.
0 commit comments