spring cleaning: removing bugs and code smells#261
Conversation
1b15
commented
Mar 5, 2024
- addresses Parameters provided in examples (and default parameters) does not perform BOLD simulation correctly #250 and Example files appear to be broken #254
- fixes inconsistencies and unexpected behaviour in the implementation and interaction of chunking, continuing runs, bold, and appending outputs
- improves maintainability by removing various code smells (e.g., low cohesion because of global bold parameter, repeated implementation of the same output saving code, etc)
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #261 +/- ##
==========================================
+ Coverage 90.93% 91.07% +0.13%
==========================================
Files 65 65
Lines 5206 5172 -34
==========================================
- Hits 4734 4710 -24
+ Misses 472 462 -10
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
caglorithm
left a comment
There was a problem hiding this comment.
Thank you very much for this awesome PR. Please have a look at the comments I left.
The only thing I can see is that continue_run might not behave as expected and that there is a change of the time axis in storeOutputsAndStates.
| if self.BOLD.shape[1] == 0: | ||
| # add new data | ||
| self.t_BOLD = t_BOLD_resampled | ||
| self.BOLD = BOLD_resampled | ||
| elif append is True: | ||
| # append new data to old data | ||
| self.t_BOLD = np.hstack((self.t_BOLD, t_BOLD_resampled)) | ||
| self.BOLD = np.hstack((self.BOLD, BOLD_resampled)) | ||
| else: | ||
| # overwrite old data | ||
| self.t_BOLD = t_BOLD_resampled | ||
| self.BOLD = BOLD_resampled | ||
|
|
There was a problem hiding this comment.
You seem to have the append=True case, why?
There was a problem hiding this comment.
The functionality for saving outputs is already in models/model.py.
| self.outputs = dotdict({}) | ||
| # reinitialize bold model | ||
| if self.params.get("bold"): | ||
| if self.boldInitialized: |
There was a problem hiding this comment.
Does this do the same thing as before? Reads like: if it is initialized, initialize it.
There was a problem hiding this comment.
The difference is that BOLD is now only initialized at the beginning of the first run. One only needs to clear the bold state with re-initialization if it has been initialized before.
| if not hasattr(self, "t"): | ||
| raise ValueError("You tried using continue_run=True on the first run.") |
There was a problem hiding this comment.
Why do we have to error here? The user could user continue_run=True in the first call as well.
There was a problem hiding this comment.
addressed this in the latest commit
| data = data[:, :: self.sample_every] | ||
| else: | ||
| raise ValueError(f"Don't know how to subsample data of shape {data.shape}.") | ||
| if data.shape[-1] >= self.params["duration"] - self.startindt: |
There was a problem hiding this comment.
Does this if clause prevent any previous case to run?
There was a problem hiding this comment.
This catches unintended subsampling of BOLD.
| if continue_run: | ||
| self.setInitialValuesToLastState() | ||
| else: |
There was a problem hiding this comment.
We would like to allow continue_run even in the case if there hasn't been any previous run.
There was a problem hiding this comment.
addressed this in the latest commit
| self.setOutput("t", results.time.values, append=append, removeICs=False) | ||
| self.setStateVariables("t", results.time.values) |
There was a problem hiding this comment.
We previously had different time axis behaviours for model and multimodel:
- for regular models, the time axis always started at 0 because it was reset for every chunk unless it was appended
- for multimodels, the time axis started at
self.start_tfrom continued runs
We adopted the multimodel behaviour with a more elegant implementation without self.start_t.
| # set start t for next run for the last value now | ||
| self.start_t = self.t[-1] | ||
| if not hasattr(self, "t"): | ||
| raise ValueError("You tried using continue_run=True on the first run.") |
There was a problem hiding this comment.
| raise ValueError("You tried using continue_run=True on the first run.") | |
| raise ValueError("You tried using `continue_run=True` on the first run.") |
There was a problem hiding this comment.
thank you Vasco, I forgot to make the suggested change in the multimodel
caglorithm
left a comment
There was a problem hiding this comment.
LGTM, amazing work, thank you