-
Notifications
You must be signed in to change notification settings - Fork 45
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
Moseq Pipeline #1056
base: master
Are you sure you want to change the base?
Moseq Pipeline #1056
Conversation
…t for Pose-dependent analysis
Check out this pull request on See visual diffs & provide feedback on Jupyter Notebooks. Powered by ReviewNB |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Took a first pass on the behavior subpackage - Can continue review tomorrow
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good so far!
comments=pos_obj.comments, | ||
description=pos_obj.description, | ||
) | ||
if isinstance(pos_nwb["dlc_position"], pd.DataFrame): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I would migrate these to a separate method to clean up the indenting, something like declare_pos_analysis_file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@CBroz1, reorganized this make function. Let me know if it looks cleaner to you
Co-authored-by: Chris Broz <[email protected]>
I've now merged in the main branch and have tested it working with a dependency on |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add the dependencies to the pyproject.toml and environment.yml?
Yeah. Do we want them in the default dependencies or should they be their own version similar to how we do the DLC ones? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did another pass here with some comments. Are pytests in the scope of this PR, or do we want to hold off?
src/spyglass/behavior/moseq.py
Outdated
# increment param name | ||
if new_name is None: | ||
# increment the extension number | ||
if model_key["model_params_name"][:-1].endswith("_extension"): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this be avoided by adding a pk field for extension that's an int with a default value of 0?
@@ -686,6 +686,30 @@ def get_interval_list_name_from_epoch(nwb_file_name: str, epoch: int) -> str: | |||
return interval_names[0] | |||
|
|||
|
|||
def get_position_interval_epoch( | |||
nwb_file_name: str, position_interval_name: str |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nwb_file_name: str, position_interval_name: str | |
nwb_file_name: str, position_interval_name: str, limit=1 |
query = PositionIntervalMap * TaskEpoch & key | ||
if query: | ||
return query.fetch1("epoch") | ||
return None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Allows you to try N times, whatever you set the default value of limit to
query = PositionIntervalMap * TaskEpoch & key | |
if query: | |
return query.fetch1("epoch") | |
return None | |
return get_position_interval_epoch(limit=limit-1) if limit else None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't need to try more than twice. The second attempt is just after ensuring that all epoch intervals have been mapped to a position interval. That wouldn't change with further attempts
@@ -409,6 +409,16 @@ def fetch_dataframe(self, *attrs, **kwargs) -> pd.DataFrame: | |||
axis=1, | |||
) | |||
|
|||
def fetch_video_path(self): | |||
"""Return the video path for pose estimate |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Normally, we pass key as an arg for this kind of thing. It's not clear to me why you break the pattern here. If no arg, it could be a property, yeah? If kept, I'd add example use to the docstring
"""Return the video path for pose estimate | |
"""Return the video path for pose estimate | |
>>> (DLCPoseEstimation & key).fetch_video_path() |
|
||
def fetch_video_path(self): | ||
"""Return the video path for pose estimate | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above note on break from key-as-arg convention
@@ -269,6 +294,27 @@ def evaluate_pose_estimation(cls, key): | |||
} | |||
return sub_thresh_percent_dict | |||
|
|||
def fetch_pose_dataframe(self): | |||
"""fetches the pose data from the pose estimation table | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See above note on break from key-as-arg convention
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one I think is reasonable as-is. It matches the convention we use for fetch1_dataframe
or fetch_nwb
A user will need a DLC project in place to use MoSeq, right? I think I might rename our 'dlc' optional dependency to 'position' and moseq dependencies in there - not sure which I prefer across the following:
|
Co-authored-by: Chris Broz <[email protected]>
I may lean towards keeping them separate. You don't strictly need DLC in your environment to run the moseq pipeline.
|
Description
Implementation of moseq withing spyglass pipelines.
PositionOutput
PositionOutput.get_pose_dataframe
to allow fetching of full pose rather than centroid for appropriate pipelines.PoseGroup
used to combine multiple epochs of pose data into a training set (analagous toPositionGroup
in decoding pipeline)MoseqModelParams
MoseqModel
for reuse and extended trainingMoseqModelSelection
combinesPoseGroup
andmodel parametersMoseqModel
trains model and stores in external project fileMoseqSyllable
(and it's selction table) apply a trained model to an entry fromPositionOutput
AnalysisNwbfile
entryAdded utility function
get_position_interval_epoch
My To-dos
PositionOutput
Checklist:
CITATION.cff
alter
snippet for release notes.CHANGELOG.md
with PR number and description.