Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Immutable params #101

Merged
merged 14 commits into from
Oct 28, 2020
Merged

Immutable params #101

merged 14 commits into from
Oct 28, 2020

Conversation

lawhead
Copy link
Collaborator

@lawhead lawhead commented Oct 27, 2020

Overview

In the current workflow, any edits to the configuration for a session overwrite the default parameters. This makes it problematic to upgrade BciPy since this file often gets updated with new configuration options. This same file is used for both defining which parameters are available and their default values, as well as the configuration used for the current session.

This PR separates out these two concepts so that the default parameters.json file never gets overridden when configuration a session. The workflow has been modified so that users in the RSVPKeyboard GUI interface can select an existing parameters file. If they attempt to edit the configuration without first selecting experiment parameters, a new parameters file is created by copying the default params.

Ticket

https://www.pivotaltracker.com/story/show/175193758

Contributions

  • Modified RSVPKeyboard GUI to change the workflow for selecting and editing a parameters file. The configured file is passed to both the params_form for editing and bci_main for starting a session.
  • Added a command line argument to bci_main to accept a parameters file location.
  • Added functionality for copying a parameters file.
  • Created a new Parameters class which extends dict. Usage throughout the codebase for accessing configuration is unchanged, but it retains metadata and can be saved as a JSON file in our expected serialization format. It also performs validation of configuration parameters.

Test

  • Run the unit tests to ensure parameter functionality is unchanged.
  • In the RSVPKeyboard GUI:
    • Attempt to configure parameters when none has been selected. A new parameters file with the current timestamp should be created. After starting a calibration session, the parameters file in the data folder should match the new params file. The parameter_location property should point to the new file.
    • Load an existing parameters file.

@lawhead lawhead requested a review from tab-cmd October 27, 2020 16:36
Copy link
Contributor

@tab-cmd tab-cmd left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A few comments to address. Let's get time with one of the clinical team members (Betts, Deirdre, or Dan) to review the GUI changes.


from tkinter.filedialog import askopenfilename, askdirectory

log = logging.getLogger(__name__)

DEFAULT_PARAMETERS_PATH = 'bcipy/parameters/parameters.json'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like we should pull this from from bcipy.helpers.parameters?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, good point. I'll clean that up.

def cast_value(value):
"""Cast Value.
def copy_parameters(path: str = DEFAULT_PARAMETERS_PATH,
destination: str = 'bcipy/parameters/') -> str:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's make this a constant or derived from DEFAULT_PARAMETERS_PATH

@@ -12,7 +13,7 @@ class TestSave(unittest.TestCase):
def setUp(self):
# set up the needed paths and initial data save structure

self.data_save_path = 'data/'
self.data_save_path = tempfile.mkdtemp()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

DEFAULT_PARAMETERS_PATH = 'bcipy/parameters/parameters.json'


class Parameters(dict):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes me really happy. I like the parameters being a class that can handle itself.

except Exception:
raise ValueError(f'Could not cast {actual_value} to {actual_type}')
now = datetime.now()
month = str(now.month).rjust(2, "0")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's cleaner to use strftime for filenames with datetimes. I use it in helpers/save

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I'll look at that.

frame.Show()
app.MainLoop()


if __name__ == '__main__':
main()
import argparse
from bcipy.helpers.load import DEFAULT_PARAMETERS_PATH
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd be okay loading from bcipy.helpers.parameters

size=14)
loading_box.Add(self.loaded_from)
loading_box.AddSpacer(10)
# loading_box.AddSpacer(5)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feel free to remove if commented out code isn't needed

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, good catch.

@@ -45,8 +73,9 @@ def launch_bci_main(self, event: wx.Event) -> None:
username = self.comboboxes[0].GetValue().replace(" ", "_")
experiment_type = event.GetEventObject().GetId()
mode = 'RSVP'
cmd = 'python bci_main.py -m {} -t {} -u {}'.format(
mode, experiment_type, username)
# TODO: add -p flag and use configured parameter_location
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks like you're doing that?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, yep. I'll remove this.

import itertools
import os
import subprocess

import wx

from bcipy.gui.gui_main import BCIGui
from bcipy.helpers.load import load_json_parameters
from bcipy.helpers.load import load_json_parameters, copy_parameters
from bcipy.helpers.load import DEFAULT_PARAMETERS_PATH
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd take this from helpers/parameters or keep it on the same line

@lawhead lawhead merged commit dfa2e2e into 1.4.3 Oct 28, 2020
@tab-cmd tab-cmd mentioned this pull request Jan 20, 2021
4 tasks
@lawhead lawhead deleted the immutable-params branch January 29, 2021 22:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants