Skip to content

Commit

Permalink
feat: ✨ Update reports module (#1136)
Browse files Browse the repository at this point in the history
* fix: 🚸 change 'max_nfev' from 1000 to None

This change goes back to `None` to allow `lmfit` to allows again to evualte the required number of fits based on the proposed model.

* feat: ✨ Add `warnings` for informing about fitting exceptions

* feat: ✨ Add fit insights to fit report

* ci: 💚 Update release file path in labeler.yml

* ci: 💚 Remove unused codeowners in labeler.yml

* Revert "ci: 💚 Remove unused codeowners in labeler.yml"

This reverts commit 5845c02.

* ci: ⬇️ Update labeler version back to `v4`

* Revert "ci: ⬇️ Update labeler version back to `v4`"

This reverts commit e4767aa.

* feat: ✨ Switch to default value for max iterations

* ci: ♻️ Update labeler.yml to v5 standard

* from tools import transform_numpy_dictionary

* fix: 🐛 condition for setting computional message

* ci: 💚 Update labeler.yml with changed file patterns

* test: ✅ Add `np.int64` for converting to int
  • Loading branch information
Anselmoo authored Jan 21, 2024
1 parent 9640b42 commit 675efa8
Show file tree
Hide file tree
Showing 9 changed files with 271 additions and 57 deletions.
102 changes: 65 additions & 37 deletions .github/labeler.yml
Original file line number Diff line number Diff line change
@@ -1,54 +1,82 @@
root:
- changed-files:
- any-glob-to-any-file: '*'
codeowners:
- .github/CODEOWNERS
- changed-files:
- any-glob-to-any-file: .github/CODEOWNERS
codespaces:
- .devcontainer/**
- changed-files:
- any-glob-to-any-file: .devcontainer/**
dependencies:
- poetry.lock
- github/dependabot.yml
- changed-files:
- any-glob-to-any-file:
- poetry.lock
- github/dependabot.yml
documentation:
- docs/**
- Examples/**
- mkdocs.yml
- README.md
- INSTALLATION.md
- changed-files:
- any-glob-to-any-file:
- docs/**
- Examples/**
- mkdocs.yml
- README.md
- INSTALLATION.md
forms:
- .github/ISSUE_TEMPLATE/**
- .github/pull_request_template.md
- changed-files:
- any-glob-to-any-file:
- .github/ISSUE_TEMPLATE/**
- .github/pull_request_template.md
github-actions:
- .github/workflows/**
- changed-files:
- any-glob-to-any-file: .github/workflows/**
pre-commit:
- .pre-commit-config.yaml
- .pre-commit-hooks.yaml
- changed-files:
- any-glob-to-any-file:
- .pre-commit-config.yaml
- .pre-commit-hooks.yaml
python:
- "spectrafit/**/*.py"
- changed-files:
- any-glob-to-any-file: "spectrafit/**/*.py"
testing:
- "spectrafit/**/test_*.py"
- changed-files:
- any-glob-to-any-file: "spectrafit/**/test_*.py"
docker:
- Dockerfile
- .dockerignore
- .devcontainer/Dockerfile
- changed-files:
- any-glob-to-any-file:
- Dockerfile
- .dockerignore
- .devcontainer/Dockerfile
release:
- "spectrafit/__init__.py"
- changed-files:
- any-glob-to-any-file: spectrafit/__init__.py
vendor:
- vendor/**
- changed-files:
- any-glob-to-any-file: vendor/**
maintenance:
- .gitignore
- .github/dependabot.yml
- .github/release-drafter.yml
- .github/labeler.yml
- .github/workflows/label.yml
- .sonarcloud.properties
- .pre-commit-config.yaml
- .prettierignore
- .pylintrc
- .sonarcloud.properties
- .sourcery.yaml
- "pyproject.toml"
- changed-files:
- any-glob-to-any-file:
- .gitignore
- .github/dependabot.yml
- .github/release-drafter.yml
- .github/labeler.yml
- .github/workflows/label.yml
- .sonarcloud.properties
- .pre-commit-config.yaml
- .prettierignore
- .pylintrc
- .sonarcloud.properties
- .sourcery.yaml
- "pyproject.toml"
license:
- LICENSE
- changed-files:
- any-glob-to-any-file:
- LICENSE
- THIRD_PARTY_LICENSES
security:
- SECURITY.md
- changed-files:
- any-glob-to-any-file: SECURITY.md
code-of-conduct:
- CODE_OF_CONDUCT.md
- changed-files:
- any-glob-to-any-file: CODE_OF_CONDUCT.md
changelog:
- CHANGELOG.md
- changed-files:
- any-glob-to-any-file: CHANGELOG.md
4 changes: 4 additions & 0 deletions spectrafit/api/report_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ class SolverAPI(BaseModel):
default={},
description="Error bar comment if values reach initial value or boundary",
)
computional: Dict[str, Any] = Field(
...,
description="Computional information like number of function evaluations",
)


class OutputAPI(BaseModel):
Expand Down
2 changes: 1 addition & 1 deletion spectrafit/api/tools_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class SolverModelsAPI(BaseModel):
description="Minimizer options",
)
optimizer: Dict[str, Any] = Field(
default={"max_nfev": 1000, "method": "leastsq"},
default={"max_nfev": None, "method": "leastsq"},
description="Optimzer options",
)

Expand Down
11 changes: 5 additions & 6 deletions spectrafit/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -753,7 +753,7 @@ def model_check(self, model: str) -> None:
model (str): Model name.
Raises:
KeyError: If the model is not supported.
NotImplementedError: If the model is not implemented.
"""
if model.split("_")[0] not in self.__models__:
raise NotImplementedError(f"{model} is not supported!")
Expand Down Expand Up @@ -1532,12 +1532,11 @@ def __call__(self) -> Tuple[Minimizer, Any]:
**self.args_solver["minimizer"],
)

return (
minimizer,
minimizer.minimize(
**self.args_solver["optimizer"],
),
result = minimizer.minimize(
**self.args_solver["optimizer"],
)
self.args_solver["optimizer"]["max_nfev"] = minimizer.max_nfev
return minimizer, result

@staticmethod
def solve_local_fitting(
Expand Down
31 changes: 27 additions & 4 deletions spectrafit/plugins/notebook.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
from spectrafit.models import SolverModels
from spectrafit.tools import PostProcessing
from spectrafit.tools import PreProcessing
from spectrafit.tools import exclude_none_dictionary
from spectrafit.tools import transform_numpy_dictionary
from spectrafit.utilities.transformer import list2dict


Expand Down Expand Up @@ -595,6 +597,15 @@ def get_linear_correlation(self) -> Dict[str, Any]:
"""
return self.args_out["linear_correlation"]

@property
def get_computional(self) -> Dict[str, Any]:
"""Get the computational time.
Returns:
Dict[str, Any]: Computational time as dictionary.
"""
return self.args_out["fit_insights"]["computional"]

@property
def settings_conf_interval(self) -> Union[bool, Dict[str, Any]]:
"""Confidence interval settings.
Expand Down Expand Up @@ -705,7 +716,7 @@ def make_input_contribution(self) -> InputAPI:
global_fitting=self.settings_global_fitting,
confidence_interval=self.settings_conf_interval,
configurations=self.settings_configurations,
settings_solver_models=self.settings_solver_models.dict(
settings_solver_models=self.settings_solver_models.model_dump(
exclude_none=True
),
),
Expand All @@ -728,6 +739,7 @@ def make_solver_contribution(self) -> SolverAPI:
covariance_matrix=self.get_covariance_matrix,
variables=self.get_variables,
errorbars=self.get_errorbars,
computional=self.get_computional,
)

@property
Expand All @@ -742,15 +754,26 @@ def make_output_contribution(self) -> OutputAPI:
def __call__(self) -> Dict[str, Any]:
"""Get the complete report as dictionary.
!!! info "About the report and `exclude_none_dictionary`"
The report is generated by using the `ReportAPI` class, which is a
`Pydantic`-definition of the report. The `Pydantic`-definition is
converted to a dictionary by using the `.model_dump()` option of `Pydantic`.
The `recursive_exclude_none` function is used to remove all `None` values
from the dictionary, which are hidden in the nested dictionaries.
Returns:
Dict[str, Any]: Report as dictionary by using the `.dict()` option of
pydantic. `None` is excluded.
"""
return ReportAPI(
report = ReportAPI(
input=self.make_input_contribution,
solver=self.make_solver_contribution,
output=self.make_output_contribution,
).dict(exclude_none=True)
).model_dump(exclude_none=True)
report = exclude_none_dictionary(report)
report = transform_numpy_dictionary(report)
return report


class SpectraFitNotebook(DataFramePlot, DataFrameDisplay, ExportResults):
Expand Down Expand Up @@ -1129,7 +1152,7 @@ def solver_model(
"column": list(self.df.columns),
"autopeak": self.autopeak,
**list2dict(peak_list=self.initial_model),
**self.settings_solver_models.dict(),
**self.settings_solver_models.model_dump(),
},
)(),
)()
Expand Down
1 change: 1 addition & 0 deletions spectrafit/plugins/test/test_notebook.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ def args_out_fixture() -> Dict[str, Any]:
"error_a": {"value": 1, "std": 2},
"error_b": {"value": 3, "std": 4},
},
"computional": {"optmizer": "leastsq", "nfev": 1000},
},
"descriptive_statistic": pd.DataFrame({"mean": [1, 2], "std": [1, 2]}).to_dict(
orient="list"
Expand Down
Loading

0 comments on commit 675efa8

Please sign in to comment.