Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 19
add new features in scale_to() so user can run without an x-value#289
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
e91661d4a87d002c8335c630011a66c67c60a155aa13f227dcdf4b4927da4de8d7b5400691e54File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| **Added:** | ||
| * new feature in `scale_to()`: default scaling is based on the max q-value in each diffraction object. | ||
sbillinge marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| **Changed:** | ||
| * <news item> | ||
| **Deprecated:** | ||
| * <news item> | ||
| **Removed:** | ||
| * <news item> | ||
| **Fixed:** | ||
| * <news item> | ||
| **Security:** | ||
| * <news item> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -396,37 +396,48 @@ def on_tth(self): | ||
| def on_d(self): | ||
| return [self.all_arrays[:, 3], self.all_arrays[:, 0]] | ||
| def scale_to(self, target_diff_object, q=None, tth=None, d=None, offset=0): | ||
| def scale_to(self, target_diff_object, q=None, tth=None, d=None, offset=None): | ||
sbillinge marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| """Returns a new diffraction object which is the current object but | ||
| rescaled in y to the target. | ||
| The y-value in the target at the closest specified x-value will be used as the factor to scale to. | ||
| By default, if `q`, `tth`, or `d` are not provided, scaling is based on the max intensity from each object. | ||
sbillinge marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| Otherwise, y-value in the target at the closest specified x-value will be used as the factor to scale to. | ||
sbillinge marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| The entire array is scaled by this factor so that one object places on top of the other at that point. | ||
| If multiple values of `q`, `tth`, or `d` are provided, or none are provided, an error will be raised. | ||
| If multiple values of `q`, `tth`, or `d` are provided, an error will be raised. | ||
| Parameters | ||
| ---------- | ||
| target_diff_object: DiffractionObject | ||
| the diffraction object you want to scale the current one onto | ||
| The diffraction object you want to scale the current one onto. | ||
| q, tth, d : float, optional, must specify exactly one of them | ||
| q, tth, d : float, optional, default is None | ||
| The value of the x-array where you want the curves to line up vertically. | ||
| Specify a value on one of the allowed grids, q, tth, or d), e.g., q=10. | ||
| offset : float, optional, default is 0 | ||
| an offset to add to the scaled y-values | ||
| offset : float, optional, default is None | ||
| The offset to add to the scaled y-values. | ||
| Returns | ||
| ------- | ||
| the rescaled DiffractionObject as a new object | ||
| scaled : DiffractionObject | ||
| The rescaled DiffractionObject as a new object. | ||
| """ | ||
| if offset is None: | ||
| offset = 0 | ||
| scaled = self.copy() | ||
| count = sum([q is not None, tth is not None, d is not None]) | ||
| if count != 1: | ||
| if count > 1: | ||
| raise ValueError( | ||
| "You must specify exactly one of 'q', 'tth', or 'd'. Please rerun specifying only one." | ||
| "You must specify none or exactly one of 'q', 'tth', or 'd'. " | ||
sbillinge marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| "Please provide either none or one value." | ||
| ) | ||
| if count == 0: | ||
| q_target_max = max(target_diff_object.on_q()[1]) | ||
| q_self_max = max(self.on_q()[1]) | ||
| scaled._all_arrays[:, 0] = scaled._all_arrays[:, 0] * q_target_max / q_self_max + offset | ||
| return scaled | ||
sbillinge marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| xtype = "q" if q is not None else "tth" if tth is not None else "d" | ||
| data = self.on_xtype(xtype) | ||
| target = target_diff_object.on_xtype(xtype) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -191,7 +191,23 @@ def test_init_invalid_xtype(): | ||
| "org_do_args, target_do_args, scale_inputs, expected", | ||
| [ | ||
| # Test whether the original y-array is scaled as expected | ||
| ( # C1: Same x-arrays | ||
| ( # C1: none of q, tth, d, provided, expect to scale on the maximal intensity from each object | ||
| { | ||
| "xarray": np.array([0.1, 0.2, 0.3]), | ||
| "yarray": np.array([1, 2, 3]), | ||
| "xtype": "q", | ||
| "wavelength": 2 * np.pi, | ||
| }, | ||
| { | ||
| "xarray": np.array([0.05, 0.1, 0.2, 0.3]), | ||
| "yarray": np.array([5, 10, 20, 30]), | ||
| "xtype": "q", | ||
| "wavelength": 2 * np.pi, | ||
| }, | ||
| {}, | ||
| {"xtype": "q", "yarray": np.array([10, 20, 30])}, | ||
| ), | ||
| ( # C2: Same x-arrays | ||
| # x-value has exact matches at tth=60 (y=60) and tth=60 (y=6), | ||
| # for original and target diffraction objects, | ||
| # expect original y-array to multiply by 6/60=1/10 | ||
| @@ -207,15 +223,10 @@ def test_init_invalid_xtype(): | ||
| "xtype": "tth", | ||
| "wavelength": 2 * np.pi, | ||
| }, | ||
| { | ||
| "q": None, | ||
| "tth": 60, | ||
| "d": None, | ||
| "offset": 0, | ||
| }, | ||
| {"tth": 60}, | ||
| {"xtype": "tth", "yarray": np.array([1, 2, 2.5, 3, 6, 10])}, | ||
| ), | ||
| ( # C2: Different x-arrays with same length, | ||
| ( # C3: Different x-arrays with same length, | ||
| # x-value has closest match at q=0.12 (y=10) and q=0.14 (y=1) | ||
| # for original and target diffraction objects, | ||
| # expect original y-array to multiply by 1/10 | ||
| @@ -231,15 +242,10 @@ def test_init_invalid_xtype(): | ||
| "xtype": "q", | ||
| "wavelength": 2 * np.pi, | ||
| }, | ||
| { | ||
| "q": 0.1, | ||
| "tth": None, | ||
| "d": None, | ||
| "offset": 0, | ||
| }, | ||
| {"q": 0.1}, | ||
| {"xtype": "q", "yarray": np.array([1, 2, 4, 6])}, | ||
| ), | ||
| ( # C3: Different x-array lengths | ||
| ( # C4: Different x-array lengths | ||
| # x-value has closest matches at tth=61 (y=50) and tth=62 (y=5), | ||
| # for original and target diffraction objects, | ||
| # expect original y-array to multiply by 5/50=1/10 | ||
| @@ -255,43 +261,48 @@ def test_init_invalid_xtype(): | ||
| "xtype": "tth", | ||
| "wavelength": 2 * np.pi, | ||
| }, | ||
| { | ||
| "q": None, | ||
| "tth": 60, | ||
| "d": None, | ||
| "offset": 0, | ||
| }, | ||
| {"tth": 60}, | ||
| {"xtype": "tth", "yarray": np.array([1, 2, 3, 4, 5, 6, 10])}, | ||
| ), | ||
| ( # C4: Same x-array and y-array with 2.1 offset, expect y-array to shift up by 2.1 | ||
| ( # C5.1: Reuse test case from C1, none of q, tth, d, provided, but include an offset, | ||
| # expect scaled y-array in C1 to shift up by 2 | ||
sbillinge marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| { | ||
| "xarray": np.array([10, 15, 25, 30, 60, 140]), | ||
| "yarray": np.array([2, 3, 4, 5, 6, 7]), | ||
| "xtype": "tth", | ||
| "xarray": np.array([0.1, 0.2, 0.3]), | ||
| "yarray": np.array([1, 2, 3]), | ||
| "xtype": "q", | ||
| "wavelength": 2 * np.pi, | ||
| }, | ||
| { | ||
| "xarray": np.array([10, 15, 25, 30, 60, 140]), | ||
| "yarray": np.array([2, 3, 4, 5, 6, 7]), | ||
| "xarray": np.array([0.05, 0.1, 0.2, 0.3]), | ||
| "yarray": np.array([5, 10, 20, 30]), | ||
| "xtype": "q", | ||
| "wavelength": 2 * np.pi, | ||
| }, | ||
| {"offset": 2}, | ||
| {"xtype": "q", "yarray": np.array([12, 22, 32])}, | ||
| ), | ||
| ( # C5.2: Reuse test case from C4, but include an offset, expect scaled y-array in C4 to shift up by 2 | ||
| { | ||
| "xarray": np.array([10, 25, 30.1, 40.2, 61, 120, 140]), | ||
| "yarray": np.array([10, 20, 30, 40, 50, 60, 100]), | ||
| "xtype": "tth", | ||
| "wavelength": 2 * np.pi, | ||
| }, | ||
| { | ||
| "q": None, | ||
| "tth": 60, | ||
| "d": None, | ||
| "offset": 2.1, | ||
| "xarray": np.array([20, 25.5, 32, 45, 50, 62, 100, 125, 140]), | ||
| "yarray": np.array([1.1, 2, 3, 3.5, 4, 5, 10, 12, 13]), | ||
| "xtype": "tth", | ||
| "wavelength": 2 * np.pi, | ||
| }, | ||
| {"xtype": "tth", "yarray": np.array([4.1, 5.1, 6.1, 7.1, 8.1, 9.1])}, | ||
| {"tth": 60, "offset": 2}, | ||
| {"xtype": "tth", "yarray": np.array([3, 4, 5, 6, 7, 8, 12])}, | ||
| ), | ||
| ], | ||
| ) | ||
| def test_scale_to(org_do_args, target_do_args, scale_inputs, expected): | ||
| original_do = DiffractionObject(**org_do_args) | ||
| target_do = DiffractionObject(**target_do_args) | ||
| scaled_do = original_do.scale_to( | ||
| target_do, q=scale_inputs["q"], tth=scale_inputs["tth"], d=scale_inputs["d"], offset=scale_inputs["offset"] | ||
| ) | ||
| scaled_do = original_do.scale_to(target_do, **scale_inputs) | ||
sbillinge marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| # Check the intensity data is the same as expected | ||
| assert np.allclose(scaled_do.on_xtype(expected["xtype"])[1], expected["yarray"]) | ||
| @@ -300,27 +311,7 @@ def test_scale_to(org_do_args, target_do_args, scale_inputs, expected): | ||
| "org_do_args, target_do_args, scale_inputs", | ||
| [ | ||
| # Test expected errors produced from scale_to() with invalid inputs | ||
| ( # C1: none of q, tth, d, provided, expect ValueError | ||
| { | ||
| "xarray": np.array([0.1, 0.2, 0.3]), | ||
| "yarray": np.array([1, 2, 3]), | ||
| "xtype": "q", | ||
| "wavelength": 2 * np.pi, | ||
| }, | ||
| { | ||
| "xarray": np.array([0.05, 0.1, 0.2, 0.3]), | ||
| "yarray": np.array([5, 10, 20, 30]), | ||
| "xtype": "q", | ||
| "wavelength": 2 * np.pi, | ||
| }, | ||
| { | ||
| "q": None, | ||
| "tth": None, | ||
| "d": None, | ||
| "offset": 0, | ||
| }, | ||
| ), | ||
| ( # C2: tth and d both provided, expect ValueErrort | ||
| ( # C2: tth and d both provided, expect ValueError | ||
| { | ||
| "xarray": np.array([10, 25, 30.1, 40.2, 61, 120, 140]), | ||
| "yarray": np.array([10, 20, 30, 40, 50, 60, 100]), | ||
| @@ -334,10 +325,8 @@ def test_scale_to(org_do_args, target_do_args, scale_inputs, expected): | ||
| "wavelength": 2 * np.pi, | ||
| }, | ||
| { | ||
| "q": None, | ||
| "tth": 60, | ||
| "d": 10, | ||
| "offset": 0, | ||
| }, | ||
| ), | ||
| ], | ||
| @@ -346,15 +335,11 @@ def test_scale_to_bad(org_do_args, target_do_args, scale_inputs): | ||
| original_do = DiffractionObject(**org_do_args) | ||
| target_do = DiffractionObject(**target_do_args) | ||
| with pytest.raises( | ||
| ValueError, match="You must specify exactly one of 'q', 'tth', or 'd'. Please rerun specifying only one." | ||
| ValueError, | ||
| match="You must specify none or exactly one of 'q', 'tth', or 'd'. " | ||
| "Please provide either none or one value.", | ||
| ): | ||
| original_do.scale_to( | ||
| target_do, | ||
| q=scale_inputs["q"], | ||
| tth=scale_inputs["tth"], | ||
| d=scale_inputs["d"], | ||
| offset=scale_inputs["offset"], | ||
| ) | ||
| original_do.scale_to(target_do, **scale_inputs) | ||
| @pytest.mark.parametrize( | ||
Uh oh!
There was an error while loading. Please reload this page.