Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions bidsphysio.acq2bids/bidsphysio/acq2bids/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
need to also bump up the version of the dependencies
"""

__version__ ="21.06.24"
__version__ ="21.07.01"
__author__ = "Pablo Velasco"
__author_email__ = "pablo.velasco@nyu.edu"
__url__ = "https://github.com/cbinyu/bidsphysio"
Expand All @@ -24,8 +24,8 @@
PYTHON_REQUIRES = ">=3.6"

REQUIRES = [
'bidsphysio.base>=21.5.27',
'bidsphysio.session>=21.06.24',
'bidsphysio.base>=21.07.01',
'bidsphysio.session>=21.07.01',
'bioread[mat]>=2.0.0',
]

Expand Down
2 changes: 1 addition & 1 deletion bidsphysio.base/bidsphysio/base/info.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ ="21.06.24"
__version__ ="21.07.01"
__author__ = "Pablo Velasco, Chrysa Papadaniil"
__author_email__ = "pablo.velasco@nyu.edu"
__url__ = "https://github.com/cbinyu/bidsphysio"
Expand Down
6 changes: 3 additions & 3 deletions bidsphysio.dcm2bids/bidsphysio/dcm2bids/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
need to also bump up the version of the dependencies
"""

__version__ = "21.06.24"
__version__ = "21.07.01"
__author__ = "Pablo Velasco"
__author_email__ = "pablo.velasco@nyu.edu"
__url__ = "https://github.com/cbinyu/bidsphysio"
Expand All @@ -24,8 +24,8 @@
PYTHON_REQUIRES = ">=3.6"

REQUIRES = [
'bidsphysio.base >= 1.4.0',
'bidsphysio.session >= 1.4.0',
'bidsphysio.base >= 21.07.01',
'bidsphysio.session >= 21.07.01',
'numpy >= 1.17.1',
'pydicom >= 1.4.1',
]
Expand Down
8 changes: 4 additions & 4 deletions bidsphysio.edf2bids/bidsphysio/edf2bids/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
need to also bump up the version of the dependencies
"""

__version__ ="21.06.24"
__version__ ="21.07.01"
__author__ = "Chrysa Papadaniil"
__author_email__ = "chrysa@nyu.edu"
__url__ = "https://github.com/cbinyu/bidsphysio"
Expand All @@ -24,9 +24,9 @@
PYTHON_REQUIRES = ">=3.6"

REQUIRES = [
'bidsphysio.base>=21.5.18',
'bidsphysio.session>=21.5.18',
'bidsphysio.events>=21.5.27',
'bidsphysio.base>=21.07.01',
'bidsphysio.session>=21.07.01',
'bidsphysio.events>=21.07.01',
'pyedfread',
'h5py>=2.9.0',
'Cython>=0.29.13',
Expand Down
2 changes: 1 addition & 1 deletion bidsphysio.events/bidsphysio/events/info.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ ="21.06.24"
__version__ ="21.07.01"
__author__ = "Chrysa Papadaniil, Pablo Velasco"
__author_email__ = "chrysa@nyu.edu"
__url__ = "https://github.com/cbinyu/bidsphysio"
Expand Down
4 changes: 2 additions & 2 deletions bidsphysio.physio2bids/bidsphysio/physio2bids/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
need to also bump up the version of the dependencies
"""

__version__ ="21.06.24"
__version__ ="21.07.01"
__author__ = "Pablo Velasco"
__author_email__ = "pablo.velasco@nyu.edu"
__url__ = "https://github.com/cbinyu/bidsphysio"
Expand All @@ -24,7 +24,7 @@
PYTHON_REQUIRES = ">=3.6"

REQUIRES = [
'bidsphysio >= 4.3.3',
'bidsphysio >= 21.07.01',
]

TESTS_REQUIRES = [
Expand Down
4 changes: 2 additions & 2 deletions bidsphysio.pmu2bids/bidsphysio/pmu2bids/info.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
need to also bump up the version of the dependencies
"""

__version__ ="21.06.24"
__version__ ="21.07.01"
__author__ = "Pablo Velasco"
__author_email__ = "pablo.velasco@nyu.edu"
__url__ = "https://github.com/cbinyu/bidsphysio"
Expand All @@ -24,7 +24,7 @@
PYTHON_REQUIRES = ">=3.6"

REQUIRES = [
'bidsphysio.base >= 1.3.1',
'bidsphysio.base >= 21.07.01',
]

TESTS_REQUIRES = [
Expand Down
119 changes: 112 additions & 7 deletions bidsphysio.pmu2bids/bidsphysio/pmu2bids/pmu2bidsphysio.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ def readpmu(physio_file, softwareVersion=None, verbose=False):
"""

# Check for known software versions:
knownVersions = ['VB15A', 'VE11C', 'VBX']
knownVersions = ['XA30', 'VB15A', 'VE11C', 'VBX']

if not (
softwareVersion in knownVersions or
Expand All @@ -199,7 +199,9 @@ def readpmu(physio_file, softwareVersion=None, verbose=False):
# try to read all new versions, if successful, return the results.
# If unsuccessful, it will print a warning and try the next versionToTest
try:
if sv == 'VE11C':
if sv == 'XA30':
return readXA30Cpmu(physio_file)
elif sv == 'VE11C':
return readVE11Cpmu(physio_file)
elif sv == 'VB15A':
return readVB15Apmu(physio_file)
Expand Down Expand Up @@ -306,6 +308,104 @@ def readVE11Cpmu(physio_file, forceRead=False):

return physio_type, MDHTime, sampling_rate, physio_signal

def readXA30Cpmu(physio_file, forceRead=False):
"""
Function to read the physiological signal from a XA30 Siemens PMU physio file

Parameters
----------
physio_file : str
path to a file with a Siemens PMU recording
forceRead : bool
flag indicating to read the file whether the format seems correct or not

Returns
-------
physio_type : str
type of physiological recording
MDHTime : list
list of two integers indicating the time in ms since last midnight.
MDHTime[0] gives the start of the recording
MDHTime[1] gives the end of the recording
sampling_rate : int
number of samples per second
physio_signal : list of int
signal proper. NaN indicate points for which there was no recording
(the scanner found a trigger in the signal)
"""

# Read the file, splitting by lines and removing the "newline" (and any blank space)
# at the end of the line:
lines = [line.rstrip() for line in open(physio_file)]

# According to Siemens (IDEA documentation), the sampling rate is 2.5ms for all signals:
sampling_rate = int(400) # 1000/2.5

# For that first line, different information regions are bound by "5002 and "6002".
# Find them:
s = re.split('5002(.*?)6002', lines[0])
if len(s) == 1:
# we failed to find even one "5002 ... 6002" group.
raise PMUFormatError(
'File %r does not seem to be a valid XA30 PMU file',
physio_file,
'5002(.*?)6002',
s[0]
)

# The first group contains the triggering method, gate open and close times, etc for
# compatibility with previous versions. Ignore it.
# The second group tells us the type of signal ('RESP', 'PULS', etc.)
try:
physio_type = re.search('LOGVERSION_([A-Z]*)', s[1]).group(1)
log_version = re.findall(r'\d+', s[1])[0]
except AttributeError:
print('Could not find type of recording for ' + physio_file)
if not forceRead:
raise PMUFormatError(
'File %r does not seem to be a valid XA30 PMU file',
physio_file,
'LOGVERSION_([A-Z]*)',
s[1]
)
else:
print('Setting recording type to "Unknown"')
physio_type = "Unknown"
# (continue reading the file)

if len(s) <= 5:
raise PMUFormatError(
'There is a very high chance %r is a VE11C file...',
physio_file
)

raw_signal = ''

if log_version == '1':
# The third and following groups give us the physio signal itself.
for ii in range(2, len(s), 2):
raw_signal = raw_signal + s[ii][1:]

raw_signal = raw_signal.split(' ')
physio_signal = parserawPMUsignal(raw_signal)

elif log_version == '3' and physio_type == 'RESP':
# we have five signals interleaved, we only need the first
for ii in range(10, len(s), 2):
raw_signal = raw_signal + s[ii][1:]

raw_signal = raw_signal.split(' ')
physio_signal = parserawPMUsignal(raw_signal)

n_channels = 5
physio_signal = physio_signal[::n_channels]

# The rest of the lines have statistics about the signals, plus start and finish times.
# Get timing:
MPCUTime, MDHTime = getPMUtiming(lines[1:])

return physio_type, MDHTime, sampling_rate, physio_signal


def readVB15Apmu(physio_file, forceRead=False):
"""
Expand Down Expand Up @@ -552,9 +652,14 @@ def parserawPMUsignal(signal):

# Values "5000" and "6000" indicate "trigger on" and "trigger off", respectively, so they
# are not a real physio_signal value. So replace them with NaN:
for idx, v in enumerate(signal):
if v == 5000 or v == 6000:
signal[idx] = float('NaN')
#for idx, v in enumerate(signal):
# if v == 5000 or v == 6000:
# signal[idx] = float('NaN')

# Values "5000" and "6000" indicate "trigger on" and "trigger off", respectively, so they
# are not a real physio_signal value. Here we exclude them.
signal = [x for x in signal if str(x) != '5000']
signal = [x for x in signal if str(x) != '6000']

return signal

Expand All @@ -563,7 +668,7 @@ def testSamplingRate(
sampling_rate=0,
Nsamples=0,
logTimes=[0,0],
tolerance=0.1
tolerance=0.2
):
"""
Function to test if the sampling rate is correct.
Expand Down Expand Up @@ -601,7 +706,7 @@ def testSamplingRate(
def main():

# Parse command line arguments
parser = argparse.ArgumentParser(description='Convert Siemens physiology files to BIDS-compliant physiology recording')
parser = argparse.ArgumentParser(description='Convert Siemens physiology files to BIDS-compliant physiology recording.')
parser.add_argument('-i', '--infiles', nargs='+', required=True, help='.puls or .resp physio file(s)')
parser.add_argument('-b', '--bidsprefix', required=True, help='Prefix of the BIDS file. It should match the _bold.nii.gz')
parser.add_argument('-v', '--verbose', action="store_true", default=False, help='verbose screen output')
Expand Down
7 changes: 7 additions & 0 deletions bidsphysio.pmu2bids/tests/data/pmu_XA30_cardiac.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"Columns": [
"cardiac"
],
"SamplingFrequency": 400,
"StartTime": 63115152.0
}
17 changes: 17 additions & 0 deletions bidsphysio.pmu2bids/tests/data/pmu_XA30_cardiac.puls

Large diffs are not rendered by default.

Loading