From 90fbc8725861dd2cf12d97bbb39d62fa27ba492b Mon Sep 17 00:00:00 2001 From: deepanshs <21365911+deepanshs@users.noreply.github.com> Date: Thu, 19 Sep 2024 19:06:08 -0400 Subject: [PATCH 1/3] add is_complex to configs --- src/c_lib/base/base_model.pxd | 6 ++-- src/c_lib/base/base_model.pyx | 6 ++-- src/c_lib/include/interpolation.h | 2 +- src/c_lib/include/schemes.h | 5 +-- src/c_lib/lib/frequency_averaging.c | 35 ++++++++++++------- src/c_lib/lib/interpolation.c | 17 ++++++--- src/c_lib/lib/schemes.c | 6 ++-- src/c_lib/lib/simulation.c | 6 ++-- src/c_lib/sandbox/sandbox.pxd | 6 ++-- src/c_lib/sandbox/sandbox.pyx | 3 +- src/mrsimulator/simulator/config.py | 1 + .../simulator/tests/test_config.py | 4 +++ 12 files changed, 65 insertions(+), 32 deletions(-) diff --git a/src/c_lib/base/base_model.pxd b/src/c_lib/base/base_model.pxd index 797921e76..c82b00dd8 100644 --- a/src/c_lib/base/base_model.pxd +++ b/src/c_lib/base/base_model.pxd @@ -36,7 +36,8 @@ cdef extern from "schemes.h": bool_t allow_4th_rank, unsigned int n_gamma, unsigned int integration_volume, - bool_t interpolation) + bool_t interpolation, + bool_t is_complex) MRS_averaging_scheme *MRS_create_averaging_scheme_from_alpha_beta( double *alpha, @@ -47,7 +48,8 @@ cdef extern from "schemes.h": unsigned int n_gamma, unsigned int position_size, int32_t *positions, - bool_t interpolation) + bool_t interpolation, + bool_t is_complex) void MRS_free_averaging_scheme(MRS_averaging_scheme *scheme) MRS_fftw_scheme *create_fftw_scheme(unsigned int total_orientations, diff --git a/src/c_lib/base/base_model.pyx b/src/c_lib/base/base_model.pyx index 3762303ea..1bcc78b99 100644 --- a/src/c_lib/base/base_model.pyx +++ b/src/c_lib/base/base_model.pyx @@ -25,6 +25,7 @@ def core_simulator(method, unsigned int integration_volume=1, unsigned int isotropic_interpolation=0, unsigned int number_of_gamma_angles=1, + bool_t is_complex=True, bool_t interpolation=True, bool_t auto_switch=True, debug=False, @@ -66,13 +67,14 @@ def core_simulator(method, averaging_scheme = clib.MRS_create_averaging_scheme_from_alpha_beta( alpha=&alpha[0], beta=&beta[0], weight=&weight[0], n_angles=alpha.size, allow_4th_rank=allow_4th_rank, n_gamma=number_of_gamma_angles, - position_size=position_size, positions=&positions[0], interpolation=interpolation + position_size=position_size, positions=&positions[0], interpolation=interpolation, + is_complex=is_complex ) else: averaging_scheme = clib.MRS_create_averaging_scheme( integration_density=integration_density, allow_4th_rank=allow_4th_rank, n_gamma=number_of_gamma_angles, integration_volume=integration_volume, - interpolation=interpolation + interpolation=interpolation, is_complex=is_complex ) # create C spectral dimensions ________________________________________________ diff --git a/src/c_lib/include/interpolation.h b/src/c_lib/include/interpolation.h index 1f8d2cc94..bee46c793 100644 --- a/src/c_lib/include/interpolation.h +++ b/src/c_lib/include/interpolation.h @@ -32,7 +32,7 @@ extern void one_d_averaging(double *spec, const unsigned int freq_size, double * double *amp_real, double *amp_imag, int dimension_count, const unsigned int position_size, int32_t *positions, const unsigned int nt, bool user_defined, - bool interpolation); + bool interpolation, bool is_complex); extern void two_d_averaging(double *spec, const unsigned int freq_size, double *freq1, double *freq2, double *amp, int amp_stride, diff --git a/src/c_lib/include/schemes.h b/src/c_lib/include/schemes.h index 87e72ceea..964763fd7 100644 --- a/src/c_lib/include/schemes.h +++ b/src/c_lib/include/schemes.h @@ -60,6 +60,7 @@ typedef struct MRS_averaging_scheme { unsigned int position_size; // number of triangle vertexes (faces) on mesh bool user_defined; // if true, the scheme is user defined bool interpolation; // if true, use frequency triangle interpolation + bool is_complex; // return cmoplex simulation } MRS_averaging_scheme; // typedef struct MRS_averaging_scheme; @@ -86,7 +87,7 @@ MRS_averaging_scheme *MRS_create_averaging_scheme(unsigned int integration_densi bool allow_4th_rank, unsigned int n_gamma, unsigned int integration_volume, - bool interpolation); + bool interpolation, bool is_complex); /** * Create a new orientation averaging scheme from given alpha and beta. @@ -109,7 +110,7 @@ MRS_averaging_scheme *MRS_create_averaging_scheme(unsigned int integration_densi MRS_averaging_scheme *MRS_create_averaging_scheme_from_alpha_beta( double *alpha, double *beta, double *weight, unsigned int n_angles, bool allow_4th_rank, unsigned int n_gamma, const unsigned int position_size, - int32_t *positions, bool interpolation); + int32_t *positions, bool interpolation, bool is_complex); /** * Free the memory allocated for the spatial orientation averaging scheme. diff --git a/src/c_lib/lib/frequency_averaging.c b/src/c_lib/lib/frequency_averaging.c index fc2c5557f..0df687e4f 100644 --- a/src/c_lib/lib/frequency_averaging.c +++ b/src/c_lib/lib/frequency_averaging.c @@ -117,13 +117,17 @@ void one_dimensional_averaging(MRS_dimension *dimensions, MRS_averaging_scheme * // multiply phase to the amplitudes. vm_double_multiply(scheme->total_orientations, phase_ptr, 2, &s[k1], amps_real); - vm_double_multiply(scheme->total_orientations, phase_ptr + 1, 2, &s[k1], - amps_imag); + if (scheme->is_complex) { + vm_double_multiply(scheme->total_orientations, phase_ptr + 1, 2, &s[k1], + amps_imag); + } while (j++ < planA->n_octants) { octahedronDeltaInterpolation(nt, &offset, &s_real[address], 1, dimensions->count, spec, iso_intrp); - octahedronDeltaInterpolation(nt, &offset, &s_imag[address], 1, - dimensions->count, spec + 1, iso_intrp); + if (scheme->is_complex) { + octahedronDeltaInterpolation(nt, &offset, &s_imag[address], 1, + dimensions->count, spec + 1, iso_intrp); + } address += npts; } } @@ -139,8 +143,10 @@ void one_dimensional_averaging(MRS_dimension *dimensions, MRS_averaging_scheme * // multiply phase to the amplitudes. vm_double_multiply(scheme->total_orientations, phase_ptr, 2, &s[k1], amps_real); - vm_double_multiply(scheme->total_orientations, phase_ptr + 1, 2, &s[k1], - amps_imag); + if (scheme->is_complex) { + vm_double_multiply(scheme->total_orientations, phase_ptr + 1, 2, &s[k1], + amps_imag); + } for (j = 0; j < planA->n_octants; j++) { // Add offset(isotropic + sideband_order) to the local frequencies. vm_double_add_offset(npts, &freq[address], offset, dimensions->freq_offset); @@ -148,7 +154,7 @@ void one_dimensional_averaging(MRS_dimension *dimensions, MRS_averaging_scheme * one_d_averaging(spec, npts, dimensions->freq_offset, &s_real[address], &s_imag[address], dimensions->count, scheme->position_size, scheme->positions, nt, user_defined, - interpolation); + interpolation, scheme->is_complex); address += npts; } } @@ -270,12 +276,15 @@ void two_dimensional_averaging(MRS_dimension *dimensions, MRS_averaging_scheme * dimensions[0].count, dimensions[1].count, iso_intrp, scheme->integration_density, user_defined, interpolation); - // imaginary part - two_d_averaging(spec + 1, npts, dimensions[0].freq_offset, - dimensions[1].freq_offset, freq_amp + 1, 2, - scheme->position_size, scheme->positions, - dimensions[0].count, dimensions[1].count, iso_intrp, - scheme->integration_density, user_defined, interpolation); + if (scheme->is_complex) { + // imaginary part + two_d_averaging(spec + 1, npts, dimensions[0].freq_offset, + dimensions[1].freq_offset, freq_amp + 1, 2, + scheme->position_size, scheme->positions, + dimensions[0].count, dimensions[1].count, iso_intrp, + scheme->integration_density, user_defined, + interpolation); + } } } } diff --git a/src/c_lib/lib/interpolation.c b/src/c_lib/lib/interpolation.c index 633fd078a..11be4ba08 100644 --- a/src/c_lib/lib/interpolation.c +++ b/src/c_lib/lib/interpolation.c @@ -912,20 +912,27 @@ void hist1d(double *spec, const unsigned int freq_size, double *freq, double *am void one_d_averaging(double *spec, const unsigned int freq_size, double *freq, double *amp_real, double *amp_imag, int dimension_count, const unsigned int position_size, int32_t *positions, - const unsigned int nt, bool user_defined, bool interpolation) { + const unsigned int nt, bool user_defined, bool interpolation, + bool is_complex) { if (!user_defined) { if (interpolation) { octahedronInterpolation(spec, freq, nt, amp_real, 1, dimension_count); - octahedronInterpolation(spec + 1, freq, nt, amp_imag, 1, dimension_count); + if (is_complex) { + octahedronInterpolation(spec + 1, freq, nt, amp_imag, 1, dimension_count); + } } else { hist1d(spec, freq_size, freq, amp_real, dimension_count, nt); - hist1d(spec + 1, freq_size, freq, amp_imag, dimension_count, nt); + if (is_complex) { + hist1d(spec + 1, freq_size, freq, amp_imag, dimension_count, nt); + } } } else { generic_1d_triangle_average(spec, freq_size, freq, amp_real, dimension_count, position_size, positions, nt); - generic_1d_triangle_average(spec + 1, freq_size, freq, amp_imag, dimension_count, - position_size, positions, nt); + if (is_complex) { + generic_1d_triangle_average(spec + 1, freq_size, freq, amp_imag, dimension_count, + position_size, positions, nt); + } } } diff --git a/src/c_lib/lib/schemes.c b/src/c_lib/lib/schemes.c index 50c343fa3..3744583b8 100644 --- a/src/c_lib/lib/schemes.c +++ b/src/c_lib/lib/schemes.c @@ -139,7 +139,7 @@ MRS_averaging_scheme *MRS_create_averaging_scheme(unsigned int integration_densi bool allow_4th_rank, unsigned int n_gamma, unsigned int integration_volume, - bool interpolation) { + bool interpolation, bool is_complex) { int alpha_size; MRS_averaging_scheme *scheme = malloc(sizeof(MRS_averaging_scheme)); @@ -151,6 +151,7 @@ MRS_averaging_scheme *MRS_create_averaging_scheme(unsigned int integration_densi scheme->integration_density = integration_density; scheme->integration_volume = integration_volume; scheme->allow_4th_rank = allow_4th_rank; + scheme->is_complex = is_complex; scheme->octant_orientations = ((integration_density + 1) * (integration_density + 2)) / 2; @@ -196,7 +197,7 @@ MRS_averaging_scheme *MRS_create_averaging_scheme(unsigned int integration_densi MRS_averaging_scheme *MRS_create_averaging_scheme_from_alpha_beta( double *alpha, double *beta, double *weight, unsigned int n_angles, bool allow_4th_rank, unsigned int n_gamma, const unsigned int position_size, - int32_t *positions, bool interpolation) { + int32_t *positions, bool interpolation, bool is_complex) { double scale; MRS_averaging_scheme *scheme = malloc(sizeof(MRS_averaging_scheme)); @@ -208,6 +209,7 @@ MRS_averaging_scheme *MRS_create_averaging_scheme_from_alpha_beta( scheme->integration_density = 0; scheme->integration_volume = 0; scheme->allow_4th_rank = allow_4th_rank; + scheme->is_complex = is_complex; scheme->octant_orientations = n_angles; diff --git a/src/c_lib/lib/simulation.c b/src/c_lib/lib/simulation.c index cf3a5b699..4a21614aa 100644 --- a/src/c_lib/lib/simulation.c +++ b/src/c_lib/lib/simulation.c @@ -187,6 +187,7 @@ void mrsimulator_core( bool allow_4th_rank = false; bool interpolation = true; + bool is_complex = true; if (sites[0].spin[0] > 0.5 && quad_second_order == 1) { allow_4th_rank = true; @@ -199,8 +200,9 @@ void mrsimulator_core( number_of_sidebands = 1; } - MRS_averaging_scheme *scheme = MRS_create_averaging_scheme( - integration_density, allow_4th_rank, 9, integration_volume, interpolation); + MRS_averaging_scheme *scheme = + MRS_create_averaging_scheme(integration_density, allow_4th_rank, 9, + integration_volume, interpolation, is_complex); MRS_fftw_scheme *fftw_scheme = create_fftw_scheme(scheme->total_orientations, number_of_sidebands); diff --git a/src/c_lib/sandbox/sandbox.pxd b/src/c_lib/sandbox/sandbox.pxd index ff2d672de..7d52e87a7 100644 --- a/src/c_lib/sandbox/sandbox.pxd +++ b/src/c_lib/sandbox/sandbox.pxd @@ -21,7 +21,8 @@ cdef extern from "schemes.h": bool_t allow_4th_rank, unsigned int n_gamma, unsigned int integration_volume, - bool_t interpolation) + bool_t interpolation, + bool_t is_complex) MRS_averaging_scheme *MRS_create_averaging_scheme_from_alpha_beta( double *alpha, double *beta, @@ -29,7 +30,8 @@ cdef extern from "schemes.h": bool_t allow_4th_rank, const unsigned int position_size, int32_t *positions, - bool_t interpolation) + bool_t interpolation, + bool_t is_complex) void MRS_free_averaging_scheme(MRS_averaging_scheme *scheme) diff --git a/src/c_lib/sandbox/sandbox.pyx b/src/c_lib/sandbox/sandbox.pyx index cf0d9efce..6cb64305d 100644 --- a/src/c_lib/sandbox/sandbox.pyx +++ b/src/c_lib/sandbox/sandbox.pyx @@ -78,11 +78,12 @@ cdef class AveragingScheme: allow_4th_rank: Boolean, If True, pre-calculates tables for computing fourth rank tensors. """ self.allow_4th_rank = allow_4th_rank + is_complex = True integration_volume_ = 0 if integration_volume == 'hemisphere': integration_volume_=1 self.scheme = clib.MRS_create_averaging_scheme(integration_density, - allow_4th_rank, 9, integration_volume_) + allow_4th_rank, 9, integration_volume_, is_complex) @property def interpolation(self): diff --git a/src/mrsimulator/simulator/config.py b/src/mrsimulator/simulator/config.py index a79f08422..e2d02b622 100644 --- a/src/mrsimulator/simulator/config.py +++ b/src/mrsimulator/simulator/config.py @@ -146,6 +146,7 @@ class ConfigSimulator(Parseable): decompose_spectrum: Literal["none", "spin_system"] = "none" isotropic_interpolation: Literal["linear", "gaussian"] = "linear" custom_sampling: Optional[CustomSampling] = None + is_complex: bool = True class Config: extra = "forbid" diff --git a/src/mrsimulator/simulator/tests/test_config.py b/src/mrsimulator/simulator/tests/test_config.py index 5242d6ce1..41113cd27 100644 --- a/src/mrsimulator/simulator/tests/test_config.py +++ b/src/mrsimulator/simulator/tests/test_config.py @@ -93,6 +93,7 @@ def test_config(): "name": None, "description": None, "label": None, + "is_complex": True, } assert a.config.get_int_dict() == { @@ -102,6 +103,7 @@ def test_config(): "integration_volume": 1, "integration_density": 20, "isotropic_interpolation": 1, + "is_complex": True, } assert b != a @@ -123,6 +125,7 @@ def test_config(): "name": None, "description": None, "label": None, + "is_complex": True, } assert a.config.get_int_dict() == { @@ -132,6 +135,7 @@ def test_config(): "integration_volume": 2, "integration_density": 20, "isotropic_interpolation": 1, + "is_complex": True, } assert b != a From 2588b55df8432ab4bc5245f56f2d37aef2baddb3 Mon Sep 17 00:00:00 2001 From: Deepansh Srivastava <21365911+deepanshs@users.noreply.github.com> Date: Sat, 21 Sep 2024 13:49:56 -0400 Subject: [PATCH 2/3] update pytest version in CI --- .../workflows/continuous-integration-pip.yml | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/.github/workflows/continuous-integration-pip.yml b/.github/workflows/continuous-integration-pip.yml index fdd3c6dfc..2938fe0f3 100644 --- a/.github/workflows/continuous-integration-pip.yml +++ b/.github/workflows/continuous-integration-pip.yml @@ -69,7 +69,9 @@ jobs: run: python setup.py develop - name: Test with pytest - run: pytest --cov=./ --cov-report=xml + run: | + python -m pip install pytest -U + pytest --cov=./ --cov-report=xml - name: Upload coverage uses: codecov/codecov-action@v4.5.0 @@ -103,7 +105,9 @@ jobs: run: python setup.py develop - name: Test with pytest - run: pytest --cov=./ --cov-report=xml + run: | + python -m pip install pytest -U + pytest --cov=./ --cov-report=xml - name: Upload coverage uses: codecov/codecov-action@v4.5.0 @@ -137,7 +141,9 @@ jobs: run: python setup.py develop - name: Test with pytest - run: pytest --cov=./ --cov-report=xml + run: | + python -m pip install pytest -U + pytest --cov=./ --cov-report=xml - name: Upload coverage uses: codecov/codecov-action@v4.5.0 @@ -152,6 +158,7 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + - name: Setup Miniconda uses: conda-incubator/setup-miniconda@v3 env: @@ -166,14 +173,19 @@ jobs: - run: | conda --version which python + - name: Build and install package from source shell: pwsh run: | conda --version which python python setup.py develop + - name: Test with pytest shell: pwsh - run: pytest --cov=./ --cov-report=xml + run: | + python -m pip install pytest -U + pytest --cov=./ --cov-report=xml + - name: Upload coverage uses: codecov/codecov-action@v4.5.0 From 19bcc8d87479fe6f30107dc8406254f8d568139d Mon Sep 17 00:00:00 2001 From: deepanshs <21365911+deepanshs@users.noreply.github.com> Date: Sat, 21 Sep 2024 14:45:02 -0400 Subject: [PATCH 3/3] doc string for is_complex attribute --- src/mrsimulator/simulator/config.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/mrsimulator/simulator/config.py b/src/mrsimulator/simulator/config.py index e2d02b622..93b673c77 100644 --- a/src/mrsimulator/simulator/config.py +++ b/src/mrsimulator/simulator/config.py @@ -128,6 +128,10 @@ class ConfigSimulator(Parseable): A CustomSampling object specifying the coordinates and weights used in powder averaging. + is_complex: bool + When True, the simulation computes both real and imaginary components of the + signal. When False, only the real component is computed. Default is True. + Example -------