@@ -402,11 +402,23 @@ def get_annotations(self, index=None):
402
402
list of dict
403
403
Each dictionary contains one annotation for the sample at `index`.
404
404
'''
405
- return [
406
- x for x in self ._metadata .get (self .ANNOTATION_KEY , [])
407
- if index is None or (x [self .START_INDEX_KEY ] <= index
408
- and x [self .START_INDEX_KEY ] + x [self .LENGTH_INDEX_KEY ] > index )
409
- ]
405
+ annotations = self ._metadata .get (self .ANNOTATION_KEY , [])
406
+ if index is None :
407
+ return annotations
408
+
409
+ annotations_including_index = []
410
+ for annotation in annotations :
411
+ if index < annotation [self .START_INDEX_KEY ]:
412
+ # index is before annotation starts -> skip
413
+ continue
414
+ if self .LENGTH_INDEX_KEY in annotation :
415
+ # Annotation includes sample_count -> check end index
416
+ if index >= annotation [self .START_INDEX_KEY ] + annotation [self .LENGTH_INDEX_KEY ]:
417
+ # index is after annotation end -> skip
418
+ continue
419
+
420
+ annotations_including_index .append (annotation )
421
+ return annotations_including_index
410
422
411
423
def get_sample_size (self ):
412
424
"""
@@ -418,16 +430,13 @@ def get_sample_size(self):
418
430
def _count_samples (self ):
419
431
"""
420
432
Count, set, and return the total number of samples in the data file.
421
- If there is no data file but there are annotations, use the end index
422
- of the final annotation instead. If there are no annotations, use 0.
433
+ If there is no data file but there are annotations, use the sample_count
434
+ from the annotation with the highest end index. If there are no annotations,
435
+ use 0.
423
436
For complex data, a 'sample' includes both the real and imaginary part.
424
437
"""
425
- annotations = self .get_annotations ()
426
438
if self .data_file is None :
427
- if len (annotations ) > 0 :
428
- sample_count = annotations [- 1 ][self .START_INDEX_KEY ] + annotations [- 1 ][self .LENGTH_INDEX_KEY ]
429
- else :
430
- sample_count = 0
439
+ sample_count = self ._get_sample_count_from_annotations ()
431
440
else :
432
441
header_bytes = sum ([c .get (self .HEADER_BYTES_KEY , 0 ) for c in self .get_captures ()])
433
442
file_size = path .getsize (self .data_file ) if self .offset_and_size is None else self .offset_and_size [1 ]
@@ -438,12 +447,32 @@ def _count_samples(self):
438
447
if file_data_size % (sample_size * num_channels ) != 0 :
439
448
warnings .warn (f'File `{ self .data_file } ` does not contain an integer '
440
449
'number of samples across channels. It may be invalid data.' )
441
- if len ( annotations ) > 0 and annotations [ - 1 ][ self .START_INDEX_KEY ] + annotations [ - 1 ][ self . LENGTH_INDEX_KEY ] > sample_count :
450
+ if self ._get_sample_count_from_annotations () > sample_count :
442
451
warnings .warn (f'File `{ self .data_file } ` ends before the final annotation '
443
452
'in the corresponding SigMF metadata.' )
444
453
self .sample_count = sample_count
445
454
return sample_count
446
455
456
+ def _get_sample_count_from_annotations (self ):
457
+ """
458
+ Returns the number of samples based on annotation with highest end index.
459
+ NOTE: Annotations are ordered by START_INDEX_KEY and not end index, so we
460
+ need to go through all annotations
461
+ """
462
+ annon_sample_count = []
463
+ for annon in self .get_annotations ():
464
+ if self .LENGTH_INDEX_KEY in annon :
465
+ # Annotation with sample_count
466
+ annon_sample_count .append (annon [self .START_INDEX_KEY ] + annon [self .LENGTH_INDEX_KEY ])
467
+ else :
468
+ # Annotation without sample_count - sample count must be at least sample_start
469
+ annon_sample_count .append (annon [self .START_INDEX_KEY ])
470
+
471
+ if annon_sample_count :
472
+ return max (annon_sample_count )
473
+ else :
474
+ return 0
475
+
447
476
def calculate_hash (self ):
448
477
"""
449
478
Calculates the hash of the data file and adds it to the global section.
0 commit comments