Skip to content

Commit 7aad3d2

Browse files
committed
work on custom annotation labels
1 parent d8a389c commit 7aad3d2

File tree

1 file changed

+27
-56
lines changed

1 file changed

+27
-56
lines changed

wfdb/readwrite/annotations.py

Lines changed: 27 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -122,14 +122,15 @@ def wrann(self, writefs=False)
122122
# Standardize the format of the custom_labels field
123123
self.standardize_custom_labels()
124124

125+
# Create the label map used in this annotaion
126+
self.create_label_map()
127+
125128
# Check the cohesion of fields
126129
self.check_field_cohesion(present_label_fields)
127130

128-
self.create_label_map()
129-
130131
# Calculate the label_store field if necessary
131-
if present_label_fields[0] != 'label_store':
132-
self.label_store =
132+
if 'label_store' not in present_label_fields:
133+
convert_label_attribute(source_field=present_label_fields[0], target_field='label_store')
133134

134135
# Write the header file using the specified fields
135136
self.wrannfile(writefs=writefs)
@@ -244,31 +245,6 @@ def checkfield(self, field):
244245
if bool(re.search('[\t\n\r\f\v]', description[i])):
245246
raise ValueError('The description values of the '+field+' field must not contain tabs or newlines')
246247

247-
248-
249-
250-
251-
# ------------------------------------------------
252-
253-
254-
# If the item is not a df, convert it first (if valid)
255-
if not isinstance(item, pd.DataFrame):
256-
if set([len(i) for i in item]) == {2}:
257-
item = label_pairs_to_df(item)
258-
elif set([len(i) for i in item]) == {3}:
259-
item = label_triplets_to_df(item)
260-
else:
261-
raise ValueError(''.join(['If the '+field+' field is an array-like object, its subelements',
262-
' must be one of the following:\n- tuple triplets storing: ',
263-
'(label_store symbol, description)\n- tuple pairs storing: ',
264-
'(symbol, description)']))
265-
266-
267-
268-
# ------------------------------------------------
269-
270-
271-
272248
# The string fields
273249
elif field in ['symbol', 'description', 'aux_note']:
274250
uniq_elements = set(item)
@@ -316,9 +292,8 @@ def checkfield(self, field):
316292
raise ValueError("The 'num' field must only contain non-negative integers up to 127")
317293

318294
return
319-
320295

321-
296+
322297
def check_field_cohesion(self, present_label_fields):
323298
"""
324299
Check that the content and structure of different fields are consistent
@@ -332,22 +307,18 @@ def check_field_cohesion(self, present_label_fields):
332307
if len(getattr(self, field)) != nannots:
333308
raise ValueError("The lengths of the 'sample' and '"+field+"' fields do not match")
334309

335-
# Deal with label fields.
336-
337-
if self.custom_labels is None:
338-
defined_values = set(ann_label_table[field].values)
339-
else:
340-
# If this runs successfully, custom_labels is now a df
341-
self.checkfield(custom_labels)
342-
defined_values = set(ann_label_table[field].values).intersection(set(self.custom_labels[field].values))
343-
344-
# Ensure all fields are defined by standard WFDB annotation labels or custom labels
345-
if set(getattr(self, field)) - defined_values != set():
346-
raise ValueError('\n'.join('\nThe '+field+' field contains elements not encoded in the stardard WFDB annotation labels or this object\'s custom_labels field',
347-
'To see the standard WFDB annotation labels, call: show_ann_labels()',
348-
'To transfer non-encoded symbol items into the aux_note field call: self.sym_to_aux()',
349-
'To define custom labels, set the custom_labels field as a list of tuple triplets with format: (label_store, symbol, description)'))
310+
# Ensure all label fields are defined by the label map. This has to be checked because
311+
# it is possible the user defined (or lack of) custom_labels does not capture all the
312+
# labels present.
313+
for field in present_label_fields:
314+
defined_values = self.__label_map__[field].values
315+
if set(getattr(self, field)) - defined_values != {}:
316+
raise ValueError('\n'.join('\nThe '+field+' field contains elements not encoded in the stardard WFDB annotation labels or this object\'s custom_labels field',
317+
'To see the standard WFDB annotation labels, call: show_ann_labels()',
318+
'To transfer non-encoded symbol items into the aux_note field, call: self.sym_to_aux()',
319+
'To define custom labels, set the custom_labels field as a list of tuple triplets with format: (label_store, symbol, description)'))
350320

321+
return
351322

352323

353324
def standardize_custom_labels(self):
@@ -356,7 +327,8 @@ def standardize_custom_labels(self):
356327
3 column pandas df with ann_label_fields as columns.
357328
358329
Does nothing if there are no custom labels defined.
359-
330+
Does nothing if custom_labels is already a df with all 3 columns
331+
360332
If custom_labels is an iterable of pairs/triplets, this
361333
function will convert it into a df.
362334
@@ -535,8 +507,7 @@ def create_label_map(self, inplace=True):
535507
label_map = ann_label_table.copy()
536508

537509
if self.custom_labels is not None:
538-
self.checkfield('custom_labels')
539-
510+
self.standardize_custom_labels()
540511
for i in self.custom_labels.index:
541512
label_map.loc[i] = self.custom_labels.loc[i]
542513

@@ -553,11 +524,11 @@ def wrannfile(self, writefs):
553524
"""
554525

555526
# Calculate the fs bytes to write if present and desired to write
556-
fs_bytes = self.get_fs_bytes()
527+
fs_bytes = self.calc_fs_bytes()
557528
# Calculate the custom_labels bytes to write if present
558-
cl_bytes = self.get_cl_bytes()
529+
cl_bytes = self.calc_cl_bytes()
559530
# Calculate the core field bytes to write
560-
core_bytes = self.get_core_bytes()
531+
core_bytes = self.calc_core_bytes()
561532

562533
# Write the file
563534
with open(self.recordname+'.'+self.extension, 'wb') as f:
@@ -567,7 +538,7 @@ def wrannfile(self, writefs):
567538
return
568539

569540
# Calculate the bytes written to the annotation file for the fs field
570-
def get_fs_bytes(self):
541+
def calc_fs_bytes(self):
571542

572543
if self.fs is None:
573544
return []
@@ -599,7 +570,7 @@ def get_fs_bytes(self):
599570
return np.array(data_bytes).astype('u1')
600571

601572
# Calculate the bytes written to the annotation file for the custom_labels field
602-
def get_cl_bytes(self):
573+
def calc_cl_bytes(self):
603574

604575
if self.custom_labels is None:
605576
return []
@@ -625,7 +596,7 @@ def get_cl_bytes(self):
625596

626597
return np.array(headbytes+custom_bytes+tailbytes).astype('u1')
627598

628-
def get_core_bytes(self):
599+
def calc_core_bytes(self):
629600
"""
630601
Convert all used annotation fields into bytes to write
631602
"""
@@ -708,7 +679,7 @@ def sym_to_aux(self):
708679
self.checkfield('symbol')
709680

710681
# Non-encoded symbols
711-
label_table_map = self.create_label_map()
682+
label_table_map = self.create_label_map(inplace=False)
712683
external_syms = set(self.symbol) - set(label_table_map['symbol'].values)
713684

714685
if external_syms == set():

0 commit comments

Comments
 (0)