Skip to content

Commit

Permalink
Merge branch 'develop' into T323_clean_logging
Browse files Browse the repository at this point in the history
  • Loading branch information
frisograce authored Aug 30, 2024
2 parents 7cec4df + a3e52bf commit 3550d2f
Show file tree
Hide file tree
Showing 83 changed files with 972 additions and 556 deletions.
2 changes: 2 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,11 @@ updates:
directory: "/"
schedule:
interval: "weekly"
target-branch: "develop"
open-pull-requests-limit: 0
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: "weekly"
target-branch: "develop"
open-pull-requests-limit: 0
32 changes: 32 additions & 0 deletions .github/release-drafter.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name-template: 'v$RESOLVED_VERSION 🌈'
tag-template: 'v$RESOLVED_VERSION'
categories:
- title: '🚀 Features'
labels:
- 'feature'
- 'enhancement'
- 'documentation'
- title: '🐛 Bug Fixes'
labels:
- 'fix'
- 'bugfix'
- 'bug'
- title: '🧰 Maintenance'
label: 'chore'
change-template: '- $TITLE @$AUTHOR (#$NUMBER)'
change-title-escapes: '\<*_&' # You can add # and @ to disable mentions, and add ` to disable code blocks.
version-resolver:
major:
labels:
- 'major'
minor:
labels:
- 'minor'
patch:
labels:
- 'patch'
default: patch
template: |
## Changes
$CHANGES
41 changes: 41 additions & 0 deletions .github/workflows/release-drafter.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: Release Drafter

on:
push:
# branches to consider in the event; optional, defaults to all
branches:
- main
# pull_request event is required only for autolabeler
# pull_request:
# Only following types are handled by the action, but one can default to all as well
# types: [ opened, reopened, synchronize ]
# pull_request_target event is required for autolabeler to support PRs from forks
# pull_request_target:
# types: [opened, reopened, synchronize]

permissions:
contents: read

jobs:
update_release_draft:
permissions:
# write permission is required to create a github release
contents: write
# write permission is required for autolabeler
# otherwise, read permission is required at least
pull-requests: read
runs-on: ubuntu-latest
steps:
# (Optional) GitHub Enterprise requires GHE_HOST variable set
#- name: Set GHE_HOST
# run: |
# echo "GHE_HOST=${GITHUB_SERVER_URL##https:\/\/}" >> $GITHUB_ENV

# Drafts your next Release notes as Pull Requests are merged into "main"
- uses: release-drafter/release-drafter@v6
# (Optional) specify config name to use, relative to .github/. Default: release-drafter.yml
# with:
# config-name: my-config.yml
# disable-autolabeler: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
25 changes: 14 additions & 11 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,25 @@ Once you reached out to us, you will be provided with the information on how to
In general the following steps are involved during a contribution:

### Contribution process
1. Create feature request / bug report on the [SIMPA issues page](https://github.com/IMSY-DKFZ/simpa/issues)
2. Discuss potential contribution with core development team
3. Fork the [SIMPA repository](https://github.com/IMSY-DKFZ/simpa)
4. Create feature branch from develop using the naming convention T<Issue#>_<FeatureName>,
where <Issue#> represent the number github assigned the created issue and <FeatureName> describes
1. Create feature request / bug report on the [SIMPA issues page](https://github.com/IMSY-DKFZ/simpa/issues)
2. Discuss potential contribution with core development team
3. Fork the [SIMPA repository](https://github.com/IMSY-DKFZ/simpa)
4. Make sure that you've installed all the optional dependencies by running `pip install .[docs,profile,testing]`
in the root directory of the repository.
5. Create feature branch from develop using the naming convention T<Issue#>_<FeatureName>,
where <Issue#> represents the number Github assigned the created issue and <FeatureName> describes
what is being developed in CamelCaseNotation.
Examples: `T13_FixSimulatorBug`, `T27_AddNewSimulator`
5. Perform test driven development on feature branch.
6. Perform test driven development on a feature branch.
A new implemented feature / a bug fix should be accompanied by a test.
Additionally, all previously existing tests must still pass after the contribution.
6. Run pre-commit hooks and make sure all hooks are passing.
7. If you want to benchmark your contributions please use the benchmarking bash script (see [benchmarking.md](docs/source/benchmarking.md) for more details).
8. Once development is finished, create a pull request including your changes.
7. Run pre-commit hooks and make sure all hooks are passing.
8. Please also make sure that you benchmark your contributions please use the benchmarking bash script (see [benchmarking.md](docs/source/benchmarking.md) for more details).
Please add the results to the PR and compare them to the current develop.
9. Once development is finished, create a pull request including your changes.
For more information on how to create pull request, see GitHub's [about pull requests](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests).
9. If there are conflicts between the simpa develop branch and your branch, you should update your feature branch with the simpa develop branch using a "merge" strategy instead of "rebase".
10. A member of the core development team will review your pull request and potentially require further changes
10. If there are conflicts between the simpa develop branch and your branch, you should update your feature branch with the simpa develop branch using a "merge" strategy instead of "rebase".
11. A member of the core development team will review your pull request and potentially require further changes
(see [Contribution review and integration](#contribution-review-and-integration)).
Once all remarks have been resolved, your changes will be merged into the develop branch.

Expand Down
24 changes: 16 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ The paper that introduces SIMPA including visualisations and explanations can be
* [Getting started](#getting-started)
* [Simulation examples](#simulation-examples)
* [Documentation](#documentation)
* [Reproducibility](#reproducibility)
* [Contributing](#how-to-contribute)
* [Performance profiling](#performance-profiling)
* [Troubleshooting](#troubleshooting)
Expand Down Expand Up @@ -56,7 +57,7 @@ The recommended way to install SIMPA is a manual installation from the GitHub re

Now open a python instance in the 'simpa' folder that you have just downloaded. Make sure that you have your preferred
virtual environment activated (we also recommend python 3.10)
1. `pip install .`
1. `pip install .` or `pip install -e .` for an editable mode.
2. Test if the installation worked by using `python` followed by `import simpa` then `exit()`

If no error messages arise, you are now setup to use SIMPA in your project.
Expand Down Expand Up @@ -140,10 +141,10 @@ settings.set_acoustic_settings(acoustic_settings)
settings.set_reconstruction_settings(reconstruction_settings)

# Set the simulation pipeline
simulation_pipeline = [sp.VolumeCreatorModule(settings),
sp.OpticalForwardModule(settings),
sp.AcousticForwardModule(settings),
sp.ReconstructionModule(settings)]
simulation_pipeline = [sp.VolumeCreationModule(settings),
sp.OpticalModule(settings),
sp.AcousticModule(settings),
sp.ReconstructionModule(settings)]

# Choose a PA device with device position in the volume
device = sp.CustomDevice()
Expand All @@ -152,6 +153,12 @@ device = sp.CustomDevice()
sp.simulate(simulation_pipeline, settings, device)
```

# Reproducibility

For reproducibility, we provide the exact version number including the commit hash in the simpa output file.
This can be accessed via `simpa.__version__` or by checking the tag `Tags.SIMPA_VERSION` in the output file.
This way, you can always trace back the exact version of the code that was used to generate the simulation results.

# Documentation

The updated version of the SIMPA documentation can be found at [https://simpa.readthedocs.io/en/develop](https://simpa.readthedocs.io/en/develop).
Expand All @@ -162,7 +169,8 @@ It is also easily possible to build the SIMPA documentation from scratch.
When the installation succeeded, and you want to make sure that you have the latest documentation
you should do the following steps in a command line:

1. Navigate to the `simpa/docs` directory
1. Make sure that you've installed the optional dependencies needed for the documentation by running `pip install .[docs]`
2. Navigate to the `simpa/docs` directory
2. If you would like the documentation to have the https://readthedocs.org/ style, type `pip install sphinx-rtd-theme`
3. Type `make html`
4. Open the `index.html` file in the `simpa/docs/build/html` directory with your favourite browser.
Expand All @@ -188,8 +196,8 @@ Please see the github guidelines for creating pull requests: [https://docs.githu
# Performance profiling

When changing the SIMPA core, e.g., by refactoring/optimizing, or if you are curious about how fast your machine runs
SIMPA, you can run the SIMPA [benchmarking scripts](simpa_examples/benchmarking/run_benchmarking.sh). It is recommended
to run:
SIMPA, you can run the SIMPA [benchmarking scripts](simpa_examples/benchmarking/run_benchmarking.sh). Make sure to install the necessary dependencies via
`pip install .[profile]` and then run:

```bash
bash ./run_benchmark.sh
Expand Down
10 changes: 6 additions & 4 deletions docs/source/benchmarking.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,14 @@ Here are some examples of how to use the script:
bash ./run_benchmark.sh -t -g -n 3
```

To read the csv you can use the following code:
To read the results, just click on the generated `benchmarking_data_frame_mean.md` file.
Or you can also read the csv with:
```python
import pandas as pd
my_simpa_dir = '/home/user/workspace/...'
benchmarking_results = pd.read_csv(my_simpa_dir + 'simpa/simpa_examples/benchmarking/benchmarking_data_frame_mean.csv')
display(benchmarking_results) # display works for ipynb - for py files use print(benchmarking_results)
from tabulate import tabulate
benchmarking_results = pd.read_csv('path/to/simpa/simpa_examples/benchmarking/benchmarking_data_frame_mean.csv')
print(tabulate(benchmarking_results))
# or use display(benchmarking_results) which works for ipynb
```

The expected outcome should look something similar to the below:
Expand Down
16 changes: 11 additions & 5 deletions docs/source/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ The recommended way to install SIMPA is a manual installation from the GitHub re

Now open a python instance in the 'simpa' folder that you have just downloaded. Make sure that you have your preferred
virtual environment activated (we also recommend python 3.10)
1. `pip install .`
1. `pip install .` or `pip install -e .` for an editable mode.
2. Test if the installation worked by using `python` followed by `import simpa` then `exit()`

If no error messages arise, you are now setup to use SIMPA in your project.
Expand Down Expand Up @@ -104,10 +104,10 @@ settings.set_acoustic_settings(acoustic_settings)
settings.set_reconstruction_settings(reconstruction_settings)

# Set the simulation pipeline
simulation_pipeline = [sp.VolumeCreatorModule(settings),
sp.OpticalForwardModule(settings),
sp.AcousticForwardModule(settings),
sp.ReconstructionModule(settings)]
simulation_pipeline = [sp.VolumeCreationModule(settings),
sp.OpticalModule(settings),
sp.AcousticModule(settings),
sp.ReconstructionModule(settings)]

# Choose a PA device with device position in the volume
device = sp.CustomDevice()
Expand All @@ -116,3 +116,9 @@ device = sp.CustomDevice()
sp.simulate(simulation_pipeline, settings, device)
```

# Reproducibility

For reproducibility, we provide the exact version number including the commit hash in the simpa output file.
This can be accessed via `simpa.__version__` or by checking the tag `Tags.SIMPA_VERSION` in the output file.
This way, you can always trace back the exact version of the code that was used to generate the simulation results.

1 change: 1 addition & 0 deletions docs/source/simpa_examples.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ simpa\_examples
perform_image_reconstruction
perform_iterative_qPAI_reconstruction
segmentation_loader
three_vs_two_dimensional_simulation_example
14 changes: 8 additions & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,16 @@ dependencies = [

[project.optional-dependencies]
docs = [
"sphinx-rtd-theme>=2.0.0,<3.0.0",
"Sphinx>=5.1.1,<6.0.0",
"myst-parser>=0.18.0,<1.1"
"sphinx-rtd-theme>=2.0.0,<3.0.0", # Uses MIT-License (MIT compatible)
"Sphinx>=5.1.1,<6.0.0", # Uses BSD-License (MIT compatible)
"myst-parser>=0.18.0,<1.1" # Uses MIT-License (MIT compatible)
]
profile = [
"pytorch_memlab>=0.3.0,<0.4.0",
"line_profiler>=4.0.0,<5.0.0",
"memory_profiler>=0.61.0,<0.62.0"
"pytorch_memlab>=0.3.0", # Uses MIT-License (MIT compatible)
"line_profiler>=4.0.0", # Uses BSD-License (MIT compatible)
"memory_profiler>=0.61.0", # Uses BSD-License (MIT compatible)
"tabulate>=0.9.0" # Uses MIT-License (MIT compatible)

]
testing = [
"mdutils>=1.4.0", # Uses MIT-License (MIT compatible)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
# SPDX-FileCopyrightText: 2021 Janek Groehl
# SPDX-License-Identifier: MIT

from simpa.utils import Tags, Settings
from simpa.core.simulation_modules.reconstruction_module.reconstruction_utils import compute_image_dimensions
from simpa.utils import Tags, Settings, round_x5_away_from_zero
from simpa.utils.constants import property_tags, wavelength_independent_properties, toolkit_tags
from simpa.io_handling import load_data_field, save_data_field
from simpa.core.processing_components import ProcessingComponentBase
Expand Down Expand Up @@ -45,7 +46,10 @@ def run(self, device: DigitalDeviceTwinBase):
else:
field_of_view_mm = device.get_field_of_view_mm()
self.logger.debug(f"FOV (mm): {field_of_view_mm}")
field_of_view_voxels = np.round(field_of_view_mm / self.global_settings[Tags.SPACING_MM]).astype(np.int32)
_, _, _, xdim_start, xdim_end, ydim_start, ydim_end, zdim_start, zdim_end = compute_image_dimensions(
field_of_view_mm, self.global_settings[Tags.SPACING_MM], self.logger)
field_of_view_voxels = [xdim_start, xdim_end, zdim_start, zdim_end, ydim_start, ydim_end] # change ordering
field_of_view_voxels = [int(dim) for dim in field_of_view_voxels] # cast to int
self.logger.debug(f"FOV (voxels): {field_of_view_voxels}")

# In case it should be cropped from A to A, then crop from A to A+1
Expand All @@ -64,7 +68,7 @@ def run(self, device: DigitalDeviceTwinBase):
continue
try:
self.logger.debug(f"Cropping data field {data_field}...")
data_array = load_data_field(self.global_settings[Tags.SIMPA_OUTPUT_PATH], data_field, wavelength)
data_array = load_data_field(self.global_settings[Tags.SIMPA_OUTPUT_FILE_PATH], data_field, wavelength)

self.logger.debug(f"data array shape before cropping: {np.shape(data_array)}")
self.logger.debug(f"data array shape len: {len(np.shape(data_array))}")
Expand Down Expand Up @@ -101,6 +105,6 @@ def run(self, device: DigitalDeviceTwinBase):

self.logger.debug(f"data array shape after cropping: {np.shape(data_array)}")
# save
save_data_field(data_array, self.global_settings[Tags.SIMPA_OUTPUT_PATH], data_field, wavelength)
save_data_field(data_array, self.global_settings[Tags.SIMPA_OUTPUT_FILE_PATH], data_field, wavelength)

self.logger.info("Cropping field of view...[Done]")
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ def run(self, pa_device):
else:
wavelength = self.global_settings[Tags.WAVELENGTHS][0]
data_field = Tags.ITERATIVE_qPAI_RESULT
save_data_field(reconstructed_absorption, self.global_settings[Tags.SIMPA_OUTPUT_PATH],
save_data_field(reconstructed_absorption, self.global_settings[Tags.SIMPA_OUTPUT_FILE_PATH],
data_field, wavelength)

# save a list of all intermediate absorption (2-d only) updates in npy file if intended
Expand Down Expand Up @@ -224,13 +224,13 @@ def extract_initial_data_from_hdf5(self) -> Tuple[np.ndarray, np.ndarray, np.nda
wavelength = self.global_settings[Tags.WAVELENGTHS][0]
self.logger.debug(f"Wavelength: {wavelength}")
# get initial pressure and scattering
initial_pressure = load_data_field(self.global_settings[Tags.SIMPA_OUTPUT_PATH],
initial_pressure = load_data_field(self.global_settings[Tags.SIMPA_OUTPUT_FILE_PATH],
Tags.DATA_FIELD_INITIAL_PRESSURE,
wavelength)
scattering = load_data_field(self.global_settings[Tags.SIMPA_OUTPUT_PATH], Tags.DATA_FIELD_SCATTERING_PER_CM,
scattering = load_data_field(self.global_settings[Tags.SIMPA_OUTPUT_FILE_PATH], Tags.DATA_FIELD_SCATTERING_PER_CM,
wavelength)

anisotropy = load_data_field(self.global_settings[Tags.SIMPA_OUTPUT_PATH], Tags.DATA_FIELD_ANISOTROPY,
anisotropy = load_data_field(self.global_settings[Tags.SIMPA_OUTPUT_FILE_PATH], Tags.DATA_FIELD_ANISOTROPY,
wavelength)

# function returns the last iteration result as a numpy array and all iteration results in a list
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def run(self, device):
self.logger.debug(f"Noise model scale: {scale}")

wavelength = self.global_settings[Tags.WAVELENGTH]
data_array = load_data_field(self.global_settings[Tags.SIMPA_OUTPUT_PATH], data_field, wavelength)
data_array = load_data_field(self.global_settings[Tags.SIMPA_OUTPUT_FILE_PATH], data_field, wavelength)
data_tensor = torch.as_tensor(data_array, dtype=torch.float32, device=self.torch_device)
dist = torch.distributions.gamma.Gamma(torch.tensor(shape, dtype=torch.float32, device=self.torch_device),
torch.tensor(1.0/scale, dtype=torch.float32, device=self.torch_device))
Expand All @@ -65,6 +65,6 @@ def run(self, device):
assert_array_well_defined(data_tensor)

save_data_field(data_tensor.cpu().numpy().astype(np.float64, copy=False),
self.global_settings[Tags.SIMPA_OUTPUT_PATH], data_field, wavelength)
self.global_settings[Tags.SIMPA_OUTPUT_FILE_PATH], data_field, wavelength)

self.logger.info("Applying Gamma Noise Model...[Done]")
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def run(self, device):
self.logger.debug(f"Noise model non-negative: {non_negative}")

wavelength = self.global_settings[Tags.WAVELENGTH]
data_array = load_data_field(self.global_settings[Tags.SIMPA_OUTPUT_PATH], data_field, wavelength)
data_array = load_data_field(self.global_settings[Tags.SIMPA_OUTPUT_FILE_PATH], data_field, wavelength)
data_tensor = torch.as_tensor(data_array, dtype=torch.float32, device=self.torch_device)
dist = torch.distributions.normal.Normal(torch.tensor(mean, dtype=torch.float32, device=self.torch_device),
torch.tensor(std, dtype=torch.float32, device=self.torch_device))
Expand All @@ -72,6 +72,6 @@ def run(self, device):
if non_negative:
data_tensor[data_tensor < EPS] = EPS
save_data_field(data_tensor.cpu().numpy().astype(np.float64, copy=False),
self.global_settings[Tags.SIMPA_OUTPUT_PATH], data_field, wavelength)
self.global_settings[Tags.SIMPA_OUTPUT_FILE_PATH], data_field, wavelength)

self.logger.info("Applying Gaussian Noise Model...[Done]")
Loading

0 comments on commit 3550d2f

Please sign in to comment.