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

Rob/mdanse trajectory filter #615

Open
wants to merge 63 commits into
base: protos
Choose a base branch
from

Conversation

RobBuchananCompPhys
Copy link
Collaborator

@RobBuchananCompPhys RobBuchananCompPhys commented Nov 28, 2024

Description of work
TODO:

(Probably don't need to solve all of these immediately - some may become issues for further work after this is completed)

UI

  • Odd crash occurs when returning to TrajectoryFilter job page from another job, error appears to be due to deleted grid layout components in the trajectory filter widget
  • Trajectory filter widget panel inputs move around alot in layout - will change to a grid layout for all input components to improve stability
  • Allow user to visualise the attenuated trajectory power spectrum alongside filter (currently non-enabled "Show attenuation" checkbox)
  • When x-axis is set to energy units, the axis contracts - this should remain the same scale as for frequency units

UI &/or Backend

  • Number of simulation frames post-filtering exceeds original frame count
  • Investigate cause of atoms collapsing to 'ugly blob' when certain filter variants (seems to be highpass and bandpass removing low frequency vibrations) are applied to trajectory
  • Ensure the Z- and S- domain representations of the transfer function polynomial are correct

Backend

  • Filter class and filter-variant child classes
  • Write metadata (filter configuration)

Tests

  • Basic unit tests for correct functioning of filter class
  • Full end-to-end test for a more complex molecular dynamics trajectory

Other

  • Ensure sensible default values for filters
  • Complete numpy docstrings for methods
  • Apply black formatting

Fixes
A list of fixes.

To test
Please describe the tests that were run to verify the changes.

@RobBuchananCompPhys RobBuchananCompPhys marked this pull request as ready for review December 16, 2024 10:51
@RobBuchananCompPhys RobBuchananCompPhys force-pushed the rob/mdanse-trajectory-filter branch from b24005c to 41b0d3e Compare February 4, 2025 14:47
Comment on lines +47 to +50
settings_dict = dict()
for setting, values in filter.default_settings.items():
settings_dict.update({setting: values["value"]})
return settings_dict
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
settings_dict = dict()
for setting, values in filter.default_settings.items():
settings_dict.update({setting: values["value"]})
return settings_dict
return {setting: values["value"] for setting, values in filter.default_settings.items()}

Will do and be faster.

Comment on lines +82 to +89
return (
'{ "filter": "'
+ f'{filter.__name__}"'
+ ", "
+ '"attributes": '
+ f"{json.dumps(settings)}"
+ "}"
)
Copy link
Collaborator

@oerc0122 oerc0122 Feb 4, 2025

Choose a reason for hiding this comment

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

Any particular reason to use json.dumps (i.e. do you need False -> false, None -> null)?

Suggested change
return (
'{ "filter": "'
+ f'{filter.__name__}"'
+ ", "
+ '"attributes": '
+ f"{json.dumps(settings)}"
+ "}"
)
return repr({"filter": filter.__name__, "attributes": settings})

If you need json.dumps

Suggested change
return (
'{ "filter": "'
+ f'{filter.__name__}"'
+ ", "
+ '"attributes": '
+ f"{json.dumps(settings)}"
+ "}"
)
return json.dumps({"filter": filter.__name__, "attributes": settings})

Alternatively, if you want this f-string style, why not

Suggested change
return (
'{ "filter": "'
+ f'{filter.__name__}"'
+ ", "
+ '"attributes": '
+ f"{json.dumps(settings)}"
+ "}"
)
return f'{{ "filter": "{filter.__name__}", "attributes": {json.dumps(settings)}}}'

settings_dict.update({setting: values["value"]})
return settings_dict

_settings = filter_default_attributes.__func__(object())
Copy link
Collaborator

Choose a reason for hiding this comment

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

Mixing class-level properties and methods will probably cause confusion in future.

Comment on lines +93 to +99
@property
def settings(self):
return self._settings

@settings.setter
def settings(self, settings: dict):
self._settings = settings
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why do these need to be @propertys if they behave like standard attributes? Are they over-ridden on inheritance?

dict_value = json.loads(value)

try:
{"filter", "attributes"} in set(dict_value.keys())
Copy link
Collaborator

Choose a reason for hiding this comment

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

Dictionary keys already behave like sets, no need to cast. Also, are you looking for:

Suggested change
{"filter", "attributes"} in set(dict_value.keys())
{"filter", "attributes"} < dict_value.keys()

response = filter.freq_response

# Lambda to resample and normalise input values
values = lambda a, new_len: signal.resample(a, new_len) * (a.max() ** (-1))
Copy link
Collaborator

Choose a reason for hiding this comment

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

Considered bad practice to assign a lambda.

Always use a def statement instead of an assignment statement that binds a lambda expression directly to an identifier

-- PEP-8

Comment on lines +429 to +432
if on:
self.bound_freq_widget.setEnabled(True)
return
self.bound_freq_widget.setEnabled(False)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
if on:
self.bound_freq_widget.setEnabled(True)
return
self.bound_freq_widget.setEnabled(False)
self.bound_freq_widget.setEnabled(on)

Copy link
Collaborator

Choose a reason for hiding this comment

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

In fact this function could just be:

      toggle_bound_frequencies = self.bound_freq_widget.setEnabled

Comment on lines +657 to +659
self._figure_info.append(f" ")
self._figure_info.append(f" ")

Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
self._figure_info.append(f" ")
self._figure_info.append(f" ")
self._figure_info.append(" ")
self._figure_info.append(" ")

{
key: filter.default_settings[key]["value"]
for key in missing
if key in defaults.keys()
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
if key in defaults.keys()
if key in defaults

Comment on lines +746 to +747
@staticmethod
def combine_attributes(filter: Filter, attributes: dict) -> dict:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Not sure why this isn't a method on Filter

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.

4 participants