diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml index c8d8415..2ed017a 100644 --- a/.github/workflows/pull_request.yml +++ b/.github/workflows/pull_request.yml @@ -29,26 +29,6 @@ jobs: run: | pre-commit run -a - test_code_python3p8: - runs-on: ubuntu-latest - strategy: - matrix: - python-version: ["3.8"] - steps: - - uses: actions/checkout@v4 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v3 - with: - python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install .[dev] - - name: Test code - run: | - mkdir test_report - tox - test_code_and_coverage_report_python3p11: runs-on: ubuntu-latest diff --git a/.gitignore b/.gitignore index 98d2f25..822119d 100644 --- a/.gitignore +++ b/.gitignore @@ -57,6 +57,7 @@ coverage.xml *.cover .hypothesis/ .pytest_cache/ +test_report/ # Translations *.mo diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 436b570..453b6d6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,5 +1,5 @@ # Default image, if not specified -image: "python:3.8" +image: "python:3.11" stages: - Static Analysis @@ -96,34 +96,34 @@ mypy: - test_report/cov_report expire_in: 1 hour -tox-3.6: - extends: ".tox" - stage: "Test" - image: "python:3.6" - rules: - - if: '$CI_COMMIT_TAG' - when: always - -tox-3.7: - extends: ".tox" - stage: "Test" - image: "python:3.7" +#tox-3.7: +# extends: ".tox" +# stage: "Test" +# image: "python:3.7" # rules: # - if: '$CI_COMMIT_TAG' # when: always -tox-3.8: +tox-3.9: extends: ".tox" stage: "Test" - image: "python:3.8" + image: "python:3.9" rules: - if: '$CI_COMMIT_TAG' when: always -tox-3.9: +tox-3.11: extends: ".tox" stage: "Test" - image: "python:3.9" + image: "python:3.11" + +#tox-3.13: +# extends: ".tox" +# stage: "Test" +# image: "python:3.13" +# rules: +# - if: '$CI_COMMIT_TAG' +# when: always # tox_slowtests: @@ -153,7 +153,7 @@ tox-3.9: # needs: [] test_report: - needs: ["tox-3.9"] + needs: ["tox-3.11"] stage: Publish test report image: name: oberonamsterdam/wkhtmltopdf diff --git a/docs/content/api.rst b/docs/content/api.rst index 177f89a..078fe18 100644 --- a/docs/content/api.rst +++ b/docs/content/api.rst @@ -39,7 +39,7 @@ LPUPropagation lpu.lpu_propagation.LPUPropagation.propagate_random lpu.lpu_propagation.LPUPropagation.propagate_systematic lpu.lpu_propagation.LPUPropagation.propagate_cov - lpu.lpu_propagation.LPUPropagation.propagate_flattened_cov + lpu.lpu_propagation.LPUPropagation.propagate_cov_flattened lpu.lpu_propagation.LPUPropagation.process_jacobian Digital Effects Tables diff --git a/punpy/_version.py b/punpy/_version.py index 5c4105c..9e604c0 100644 --- a/punpy/_version.py +++ b/punpy/_version.py @@ -1 +1 @@ -__version__ = "1.0.1" +__version__ = "1.0.7" diff --git a/punpy/digital_effects_table/measurement_function.py b/punpy/digital_effects_table/measurement_function.py index 8298df4..2212366 100644 --- a/punpy/digital_effects_table/measurement_function.py +++ b/punpy/digital_effects_table/measurement_function.py @@ -337,18 +337,24 @@ def propagate_ds( repeat_dim_err_corrs=repeat_dim_err_corrs, ) + if not include_corr: + ds_vars = copy.deepcopy(list(template.keys())) + for key in ds_vars: + if key[:8] == "err_corr": + template.pop(key) + # create dataset template ds_out = obsarray.create_ds(template, self.sizes_dict) # add trivial first dimension to so we can loop over output_vars later if self.output_vars == 1: - if u_rand_y is not None: + if isinstance(u_rand_y, np.ndarray): u_rand_y = u_rand_y[None, ...] - if u_syst_y is not None: + if isinstance(u_syst_y, np.ndarray): u_syst_y = u_syst_y[None, ...] - if u_stru_y is not None: + if isinstance(u_stru_y, np.ndarray): u_stru_y = u_stru_y[None, ...] - if corr_stru_y is not None: + if isinstance(corr_stru_y, np.ndarray): corr_stru_y = corr_stru_y[None, ...] # loop through measurands @@ -364,7 +370,7 @@ def propagate_ds( ucomp_sys = "u_sys_" + self.yvariable[i] ucomp_str = "u_str_" + self.yvariable[i] - if u_rand_y is None: + if not isinstance(u_rand_y, np.ndarray): ds_out = self.templ.remove_unc_component( ds_out, self.yvariable[i], ucomp_ran ) @@ -374,7 +380,7 @@ def propagate_ds( else: ds_out[ucomp_ran].values = u_rand_y[i] - if u_syst_y is None: + if not isinstance(u_syst_y, np.ndarray): ds_out = self.templ.remove_unc_component( ds_out, self.yvariable[i], ucomp_sys ) @@ -384,7 +390,7 @@ def propagate_ds( else: ds_out[ucomp_sys].values = u_syst_y[i] - if u_stru_y is None: + if not isinstance(u_stru_y, np.ndarray): ds_out = self.templ.remove_unc_component( ds_out, self.yvariable[i], @@ -405,10 +411,6 @@ def propagate_ds( i, use_ds_out_pre_unmodified, ) - else: - ds_out.drop("err_corr_str_" + self.yvariable[i]) - - # ds_out.drop("err_corr_str_between") if (ds_out_pre is not None) and not use_ds_out_pre_unmodified: self.templ.join_with_preexisting_ds( @@ -500,6 +502,12 @@ def propagate_ds_total( repeat_dim_err_corrs=repeat_dim_err_corrs, ) + if not include_corr: + ds_vars = copy.deepcopy(list(template.keys())) + for key in ds_vars: + if key[:8] == "err_corr": + template.pop(key) + # create dataset template ds_out = obsarray.create_ds(template, self.sizes_dict) @@ -537,18 +545,6 @@ def propagate_ds_total( use_ds_out_pre_unmodified, ) - else: - if len(self.str_corr_dims) == 1: - ds_out.drop("err_corr_tot_" + self.yvariable[i]) - else: - for ii in range(len(self.str_corr_dims)): - ds_out.drop( - "err_corr_tot_" - + self.yvariable[i] - + "_" - + self.str_corr_dims[ii] - ) - if (ds_out_pre is not None) and not use_ds_out_pre_unmodified: self.templ.join_with_preexisting_ds( ds_out, ds_out_pre, drop=self.yvariable[i] @@ -645,6 +641,12 @@ def propagate_ds_specific( simple_systematic=simple_systematic, ) + if not include_corr: + ds_vars = copy.deepcopy(list(template.keys())) + for key in ds_vars: + if key[:8] == "err_corr": + template.pop(key) + # create dataset template ds_out = obsarray.create_ds(template, self.sizes_dict) @@ -805,7 +807,7 @@ def propagate_ds_all( include_corr=include_corr, ) - def run(self, *args, expand=False): + def run_meas_function(self, *args, expand=False): """ Function to calculate the measurand by running input quantities through measurement function. @@ -1219,7 +1221,7 @@ def _check_sizes_and_run(self, *args, expand=False, ds_out_pre=None): "punpy.MeasurementFunction: When using a measurement function with multiple measurands with different shapes, you cannot set parallel_cores to 0 (the default) when creating the prop object." ) - # define dictionary with dimension sizes (needs to be done before self.run() when expand==True) + # define dictionary with dimension sizes (needs to be done before self.run_meas_function() when expand==True) if self.sizes_dict is None and expand: self.sizes_dict = {} for i in range(self.output_vars): @@ -1239,7 +1241,7 @@ def _check_sizes_and_run(self, *args, expand=False, ds_out_pre=None): continue # run the measurement function - y = self.run(*args, expand=expand) + y = self.run_meas_function(*args, expand=expand) if self.output_vars == 1: y = y[None, ...] diff --git a/punpy/digital_effects_table/tests/propagate_ds_example.nc b/punpy/digital_effects_table/tests/propagate_ds_example.nc index e564481..774aace 100644 Binary files a/punpy/digital_effects_table/tests/propagate_ds_example.nc and b/punpy/digital_effects_table/tests/propagate_ds_example.nc differ diff --git a/punpy/digital_effects_table/tests/test_measurement_function.py b/punpy/digital_effects_table/tests/test_measurement_function.py index 4337458..aaa4b35 100644 --- a/punpy/digital_effects_table/tests/test_measurement_function.py +++ b/punpy/digital_effects_table/tests/test_measurement_function.py @@ -141,7 +141,7 @@ def test_gaslaw(self): ) ds_y_tot = gl.propagate_ds_total(ds) - prop = MCPropagation(3000, dtype="float32", verbose=False) + prop = MCPropagation(1000, dtype="float32", verbose=False) gl = IdealGasLaw( prop, ["pressure", "temperature", "n_moles"], @@ -156,10 +156,10 @@ def test_gaslaw(self): ) npt.assert_allclose(ds_y["volume"].values, volume, rtol=0.002) - npt.assert_allclose(ds_y["u_ran_volume"].values, u_ran_volume, rtol=0.08) - npt.assert_allclose(ds_y["u_sys_volume"].values, u_sys_volume, rtol=0.08) - npt.assert_allclose(ds_y["u_str_volume"].values, u_str_volume, rtol=0.08) - npt.assert_allclose(ds_y["u_str_volume"].values, u_str_volume, rtol=0.08) + npt.assert_allclose(ds_y["u_ran_volume"].values, u_ran_volume, rtol=0.1) + npt.assert_allclose(ds_y["u_sys_volume"].values, u_sys_volume, rtol=0.1) + npt.assert_allclose(ds_y["u_str_volume"].values, u_str_volume, rtol=0.1) + npt.assert_allclose(ds_y["u_str_volume"].values, u_str_volume, rtol=0.1) npt.assert_allclose( ds_y.unc["volume"].total_unc().values, u_tot_volume, rtol=0.12 ) @@ -349,7 +349,7 @@ def test_hypernets(self): ) hmf.setup(0.1) - y = hmf.run(calib_data, L0data.variables, L0data) + y = hmf.run_meas_function(calib_data, L0data.variables, L0data) u_y_rand = hmf.propagate_random(L0data, calib_data) print(u_y_rand) # print(u_y_rand,L0data) @@ -427,7 +427,7 @@ def test_hypernets_repeat_dim(self): corr_dims=-99, ) hmf.setup(0.1) - y = hmf.run(calib_data, L0data) + y = hmf.run_meas_function(calib_data, L0data) u_y_rand = hmf.propagate_random(L0data, calib_data) # print(list(L1data.variables)) mask = np.where( diff --git a/punpy/lpu/lpu_propagation.py b/punpy/lpu/lpu_propagation.py index 3f5c8ea..4215b59 100644 --- a/punpy/lpu/lpu_propagation.py +++ b/punpy/lpu/lpu_propagation.py @@ -424,7 +424,7 @@ def propagate_standard( return_Jacobian, ) - def propagate_flattened_cov( + def propagate_cov_flattened( self, func, x, diff --git a/punpy/mc/mc_propagation.py b/punpy/mc/mc_propagation.py index d04eb5a..fc63527 100644 --- a/punpy/mc/mc_propagation.py +++ b/punpy/mc/mc_propagation.py @@ -999,7 +999,7 @@ def _perform_checks( count = 0 for i in range(len(x)): if u_x[i] is None: - if hasattr(x[i], "__len__"): + if hasattr(x[i], "shape"): u_x[i] = np.zeros(x[i].shape) else: u_x[i] = 0.0 @@ -1519,6 +1519,10 @@ def run_samples( [ np.any(np.isfinite(MC_y[i][ivar])) for ivar in range(output_vars) + if ( + hasattr(MC_y[i][ivar], "__len__") + and (len(MC_y[i][ivar]) > 0) + ) ] ) ], @@ -1533,6 +1537,10 @@ def run_samples( [ np.any(np.isfinite(MC_y[i][ivar])) for ivar in range(output_vars) + if ( + hasattr(MC_y[i][ivar], "__len__") + and (len(MC_y[i][ivar]) > 0) + ) ] ) ], @@ -1549,6 +1557,10 @@ def run_samples( [ np.all(np.isfinite(MC_y[i][ivar])) for ivar in range(output_vars) + if ( + hasattr(MC_y[i][ivar], "__len__") + and (len(MC_y[i][ivar]) > 0) + ) ] ) ], @@ -1563,6 +1575,10 @@ def run_samples( [ np.all(np.isfinite(MC_y[i][ivar])) for ivar in range(output_vars) + if ( + hasattr(MC_y[i][ivar], "__len__") + and (len(MC_y[i][ivar]) > 0) + ) ] ) ], @@ -1667,14 +1683,18 @@ def process_samples( complex_shapes = False if complex_shapes: - MC_y2 = np.empty(output_vars, dtype=object) u_func = np.empty(output_vars, dtype=object) for i in range(output_vars): - MC_y2[i] = np.empty((self.MCsteps,) + yshapes[i]) - for j in range(self.MCsteps): - MC_y2[i][j] = MC_y[j, i] - u_func[i] = np.std(np.array(MC_y2[i]), axis=0, dtype=self.dtype) + u_func[i] = np.std( + np.array(list(MC_y[:, i])), axis=0, dtype=self.dtype + ) + + # for i in range(output_vars): + # MC_y2[i] = np.empty((self.MCsteps,) + yshapes[i]) + # for j in range(self.MCsteps): + # MC_y2[i][j] = MC_y[j, i] + # u_func[i] = np.std(np.array(MC_y2[i]), axis=0, dtype=self.dtype) else: u_func = np.std(MC_y, axis=0, dtype=self.dtype) @@ -1728,7 +1748,10 @@ def process_samples( if fixed_corr is None: if complex_shapes: corr_ys[i] = cm.calculate_corr( - MC_y2[i], corrdims, PD_corr, self.dtype + np.array(list(MC_y[:, i])), + corrdims, + PD_corr, + self.dtype, ) else: corr_ys[i] = cm.calculate_corr( diff --git a/quality_documentation/QualityDocumentation.tex b/quality_documentation/QualityDocumentation.tex index 2f0c395..4e50d66 100644 --- a/quality_documentation/QualityDocumentation.tex +++ b/quality_documentation/QualityDocumentation.tex @@ -110,13 +110,15 @@ \section{Test report}\label{testreport} \clearpage } -\part*{User Manual} -\phantomsection -\addcontentsline{toc}{part}{User Manual} -\appendix -\label{UserManual} -\def\maketitle{} -\def\tableofcontents{} -\input{./latex/user_manual.tex} + +%\part*{User Manual} +%\usepackage{./latex/sphinxmanual} +%\phantomsection +%\addcontentsline{toc}{part}{User Manual} +%\appendix +%\label{UserManual} +%\def\maketitle{} +%\def\tableofcontents{} +%\input{./latex/user_manual.tex} \end{document} diff --git a/quality_documentation/base/CookiecutterMacros.tex b/quality_documentation/base/CookiecutterMacros.tex index f21a2b6..4877311 100644 --- a/quality_documentation/base/CookiecutterMacros.tex +++ b/quality_documentation/base/CookiecutterMacros.tex @@ -3,4 +3,5 @@ \verbdef\authorname{Pieter De Vis} \verbdef\authoremail{pieter.de.vis@npl.co.uk} \newcommand{\packagedescription}{The punpy module is a Python software package to propagate random, structured and systematic uncertainties through a given measurement function.} -\newcommand{\sil}{sil3} \ No newline at end of file +\newcommand{\sil}{sil3} +\newcommand{\sphinxAtStartPar}{\hspace{0}} \ No newline at end of file diff --git a/setup.py b/setup.py index a8a51f8..0f0e89b 100644 --- a/setup.py +++ b/setup.py @@ -35,8 +35,8 @@ def read(filename): long_description=read("README.md"), packages=find_packages(exclude=("tests",)), install_requires=[ - "comet_maths>=1.0.1", - "obsarray>=1.0.1", + "comet_maths>=1.0.5", + "obsarray>=1.0.2", ], extras_require={ "dev": [ diff --git a/tox.ini b/tox.ini index 972d0d5..8edb4bc 100644 --- a/tox.ini +++ b/tox.ini @@ -15,5 +15,4 @@ deps = pytest-html pytest-cov commands = - pytest --html=test_report/report.html - pytest --cov-report html:test_report/cov_report --cov=punpy \ No newline at end of file + pytest --html=test_report/report.html --cov-report html:test_report/cov_report --cov=punpy \ No newline at end of file