catalystneuro / neuroconv

Create NWB files by converting and combining neural data in proprietary formats and adding essential metadata.
https://neuroconv.readthedocs.io
BSD 3-Clause "New" or "Revised" License
51 stars 22 forks source link

[Bug]: Neuroconv issue with plexon files #1000

Closed ajcheng1 closed 1 month ago

ajcheng1 commented 2 months ago

What happened?

Apologies if this is not a bug, it may be something more on my end.

I slightly modified the program from the Plexon sorting data conversion (https://neuroconv.readthedocs.io/en/main/conversion_examples_gallery/sorting/plexon.html) and I was successfully able to convert a .plx file to a .nwb using example code #206 here (File_plexon_3) however I cannot replicate the same results with other .plx files.

I can't upload .plx files on github, but you are welcome to download it here https://plexon.com/software-downloads/#software-downloads-data-samples [Sample PLX File – Four Channel Demo]. I got a stream error from this .plx file but I am not sure how to specify a specific one I tried a .plx file from a MEA recording I did and I got a Error: list index out of range,

Steps to Reproduce

import pathlib
from datetime import datetime
from zoneinfo import ZoneInfo
import pytz
from neuroconv.datainterfaces import PlexonRecordingInterface
import spikeinterface

# Define file paths
file_path = pathlib.Path("C:\\Users\\Shado\\Downloads\\test.plx")
nwbfile_path = pathlib.Path("C:/Users/Shado/Downloads/test.nwb")

try:
    # Create interface
    interface = PlexonRecordingInterface(file_path=file_path, verbose=False)
    stream_id = "0"

    # Extract metadata
    metadata = interface.get_metadata()

    # Update session start time with timezone information
    session_start_time = metadata["NWBFile"]["session_start_time"]
    tz = pytz.timezone("US/Pacific")  # or use ZoneInfo("US/Pacific")
    session_start_time_tz = tz.localize(session_start_time)
    metadata["NWBFile"]["session_start_time"] = session_start_time_tz

    # Run conversion
    interface.run_conversion(nwbfile_path=nwbfile_path, metadata=metadata)

except Exception as e:
    print(f"Error: {e}")

Traceback

Names: ['Signals 0', 'Signals 1', 'Signals 2']
IDs: ['0', '1', '2']. Specify it with the 'stream_name' or 'stream_id' arguments

Operating System

Windows

Python Executable

Python

Python Version

3.9

Package Versions

annotated-types==0.7.0 asciitree==0.3.3 attrs==24.2.0 beautifulsoup4==4.12.2 blis==0.7.9 catalogue==2.0.8 certifi==2023.5.7 charset-normalizer==3.1.0 click==8.1.3 colorama==0.4.6 confection==0.0.4 cymem==2.0.7 docstring_parser==0.16 emoji==0.6.0 en-core-web-sm @ https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-3.5.0/en_core_web_sm-3.5.0-py3-none-any.whl et-xmlfile==1.1.0 fasteners==0.19 h5py==3.11.0 hdmf==3.14.3 hdmf_zarr==0.8.0 idna==3.4 Jinja2==3.1.2 joblib==1.2.0 jsonschema==4.23.0 jsonschema-specifications==2023.12.1 langcodes==3.3.0 MarkupSafe==2.1.3 murmurhash==1.0.9 neo==0.13.2 neuroconv==0.5.0 nltk==3.8.1 numcodecs==0.12.1 numpy==1.25.0 openpyxl==3.1.2 packaging==23.1 pandas==2.0.3 parse==1.20.2 pathy==0.10.2 preshed==3.0.8 probeinterface==0.2.23 psutil==6.0.0 pydantic==2.8.2 pydantic_core==2.20.1 pynwb==2.8.1 python-dateutil==2.8.2 pytz==2023.3 PyYAML==6.0.2 quantities==0.15.0 referencing==0.35.1 regex==2022.10.31 requests==2.31.0 rpds-py==0.20.0 ruamel.yaml==0.18.6 ruamel.yaml.clib==0.2.8 scipy==1.13.1 six==1.16.0 smart-open==6.3.0 soupsieve==2.4.1 spacy==3.5.3 spacy-legacy==3.0.12 spacy-loggers==1.0.4 spikeinterface==0.100.5 srsly==2.4.6 text2emotion==0.0.5 thinc==8.1.10 threadpoolctl==3.5.0 tqdm==4.64.1 typer==0.7.0 typing_extensions==4.6.3 tzdata==2023.3 urllib3==2.0.3 wasabi==1.1.2 zarr==2.18.2

Code of Conduct

CodyCBakerPhD commented 2 months ago

It's true we haven't exposed multi-stream control to either PlexonRecording or Sorting yet - mostly because we haven't seen any data like that to my knowledge and we usually want to make sure it works first before allowing that option

@h-mayorquin Should know much more about this

h-mayorquin commented 2 months ago

We will take a look into it.

h-mayorquin commented 2 months ago

Hi, @ajcheng1.

Short answer: The branch on #1013 with the branch of neo https://github.com/NeuralEnsemble/python-neo/pull/1524 should allow you to solve your problem. If you need to do it quickly you can go in that direction, if you can wait, we will merge all of this at some point but is summer and the developers of neo are mostly European so maybe it will take a bit : P

Long answer:

Yes, this is a limtation of our API that derives of some of the problems in the ecosystem. Two main points: 1) As @CodyCBakerPhD noted we don't expose the stream_id or stream_name in our interface. In this case, there are good reasons not to do it, plexon has some streams (e.g. auxiliar input) that should not be written as an ElectricalSeries so we should only constrain the data to be wideband data for plexon (this is done in #1013). If you know which stream your wideband data is, you can expose that yourself by modifying the same lines that #1013 in a local copy and run it. However, here comes the second problem.

2) The streams of plexon 1 are neither human friendly nor stable in neo. The PR https://github.com/NeuralEnsemble/python-neo/pull/1524 attempst to fix this and should make it through eventually.

There is a remaining issue that we don't know exactly what to do with the stream to which channels that are named 'V{x}" belongs to. I expect your channels to come from wideband and therefore to be named "WB{X}" in which case there won't be a problem but if you happen to know what channels named "V{x}" in plexon stand for this will help us to build better software

Best regards,