Skip to content

Add base_datetime property #381

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

Merged
merged 6 commits into from
Jun 1, 2022
Merged
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
132 changes: 89 additions & 43 deletions wfdb/io/record.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,10 +183,13 @@ class BaseRecord(object):
The counter used at the start of the file.
sig_len : int, optional
The total length of the signal.
base_time : str, optional
A string of the record's start time in 24h 'HH:MM:SS(.ms)' format.
base_date : str, optional
A string of the record's start date in 'DD/MM/YYYY' format.
base_time : datetime.time, optional
The time of day at the beginning of the record.
base_date : datetime.date, optional
The date at the beginning of the record.
base_datetime : datetime.datetime, optional
The date and time at the beginning of the record, equivalent to
`datetime.combine(base_date, base_time)`.
comments : list, optional
A list of string comments to be written to the header file.
sig_name : str, optional
Expand All @@ -205,6 +208,7 @@ def __init__(
sig_len=None,
base_time=None,
base_date=None,
base_datetime=None,
comments=None,
sig_name=None,
):
Expand All @@ -214,11 +218,42 @@ def __init__(
self.counter_freq = counter_freq
self.base_counter = base_counter
self.sig_len = sig_len
self.base_time = base_time
self.base_date = base_date
if base_datetime is not None:
if base_time is not None:
raise TypeError(
"cannot specify both base_time and base_datetime"
)
if base_date is not None:
raise TypeError(
"cannot specify both base_date and base_datetime"
)
self.base_datetime = base_datetime
else:
self.base_time = base_time
self.base_date = base_date
self.comments = comments
self.sig_name = sig_name

@property
def base_datetime(self):
if self.base_date is None or self.base_time is None:
return None
else:
return datetime.datetime.combine(
date=self.base_date, time=self.base_time
)

@base_datetime.setter
def base_datetime(self, value):
if value is None:
self.base_date = None
self.base_time = None
elif isinstance(value, datetime.datetime) and value.tzinfo is None:
self.base_date = value.date()
self.base_time = value.time()
else:
raise TypeError(f"invalid base_datetime value: {value!r}")

def check_field(self, field, required_channels="all"):
"""
Check whether a single field is valid in its basic form. Does
Expand Down Expand Up @@ -530,12 +565,7 @@ def _adjust_datetime(self, sampfrom):
if sampfrom:
dt_seconds = sampfrom / self.fs
if self.base_date and self.base_time:
self.base_datetime = datetime.datetime.combine(
self.base_date, self.base_time
)
self.base_datetime += datetime.timedelta(seconds=dt_seconds)
self.base_date = self.base_datetime.date()
self.base_time = self.base_datetime.time()
# We can calculate the time even if there is no date
elif self.base_time:
tmp_datetime = datetime.datetime.combine(
Expand Down Expand Up @@ -601,10 +631,13 @@ class Record(BaseRecord, _header.HeaderMixin, _signal.SignalMixin):
The counter used at the start of the file.
sig_len : int, optional
The total length of the signal.
base_time : str, optional
A string of the record's start time in 24h 'HH:MM:SS(.ms)' format.
base_date : str, optional
A string of the record's start date in 'DD/MM/YYYY' format.
base_time : datetime.time, optional
The time of day at the beginning of the record.
base_date : datetime.date, optional
The date at the beginning of the record.
base_datetime : datetime.datetime, optional
The date and time at the beginning of the record, equivalent to
`datetime.combine(base_date, base_time)`.
file_name : str, optional
The name of the file used for analysis.
fmt : list, optional
Expand Down Expand Up @@ -661,6 +694,7 @@ def __init__(
sig_len=None,
base_time=None,
base_date=None,
base_datetime=None,
file_name=None,
fmt=None,
samps_per_frame=None,
Expand All @@ -682,16 +716,17 @@ def __init__(
# have this field. Even n_seg = 1 makes the header a multi-segment
# header.
super(Record, self).__init__(
record_name,
n_sig,
fs,
counter_freq,
base_counter,
sig_len,
base_time,
base_date,
comments,
sig_name,
record_name=record_name,
n_sig=n_sig,
fs=fs,
counter_freq=counter_freq,
base_counter=base_counter,
sig_len=sig_len,
base_time=base_time,
base_date=base_date,
base_datetime=base_datetime,
comments=comments,
sig_name=sig_name,
)

self.p_signal = p_signal
Expand Down Expand Up @@ -901,10 +936,13 @@ class MultiRecord(BaseRecord, _header.MultiHeaderMixin):
The counter used at the start of the file.
sig_len : int, optional
The total length of the signal.
base_time : str, optional
A string of the record's start time in 24h 'HH:MM:SS(.ms)' format.
base_date : str, optional
A string of the record's start date in 'DD/MM/YYYY' format.
base_time : datetime.time, optional
The time of day at the beginning of the record.
base_date : datetime.date, optional
The date at the beginning of the record.
base_datetime : datetime.datetime, optional
The date and time at the beginning of the record, equivalent to
`datetime.combine(base_date, base_time)`.
seg_name : str, optional
The name of the segment.
seg_len : int, optional
Expand Down Expand Up @@ -943,6 +981,7 @@ def __init__(
sig_len=None,
base_time=None,
base_date=None,
base_datetime=None,
seg_name=None,
seg_len=None,
comments=None,
Expand All @@ -951,16 +990,17 @@ def __init__(
):

super(MultiRecord, self).__init__(
record_name,
n_sig,
fs,
counter_freq,
base_counter,
sig_len,
base_time,
base_date,
comments,
sig_name,
record_name=record_name,
n_sig=n_sig,
fs=fs,
counter_freq=counter_freq,
base_counter=base_counter,
sig_len=sig_len,
base_time=base_time,
base_date=base_date,
base_datetime=base_datetime,
comments=comments,
sig_name=sig_name,
)

self.layout = layout
Expand Down Expand Up @@ -5009,6 +5049,7 @@ def wrsamp(
comments=None,
base_time=None,
base_date=None,
base_datetime=None,
write_dir="",
):
"""
Expand Down Expand Up @@ -5053,10 +5094,13 @@ def wrsamp(
A list of integers specifying the digital baseline.
comments : list, optional
A list of string comments to be written to the header file.
base_time : str, optional
A string of the record's start time in 24h 'HH:MM:SS(.ms)' format.
base_date : str, optional
A string of the record's start date in 'DD/MM/YYYY' format.
base_time : datetime.time, optional
The time of day at the beginning of the record.
base_date : datetime.date, optional
The date at the beginning of the record.
base_datetime : datetime.datetime, optional
The date and time at the beginning of the record, equivalent to
setting both `base_date` and `base_time`.
write_dir : str, optional
The directory in which to write the files.

Expand Down Expand Up @@ -5114,6 +5158,7 @@ def wrsamp(
comments=comments,
base_time=base_time,
base_date=base_date,
base_datetime=base_datetime,
)
# Compute optimal fields to store the digital signal, carry out adc,
# and set the fields.
Expand All @@ -5132,6 +5177,7 @@ def wrsamp(
comments=comments,
base_time=base_time,
base_date=base_date,
base_datetime=base_datetime,
)
# Use d_signal to set the fields directly
record.set_d_features()
Expand Down