@@ -324,15 +324,15 @@ def __getitem__(self, sli):
324324 raise ValueError ("unhandled ndim in SigMFFile.__getitem__(); this shouldn't happen" )
325325 return ray [0 ] if isinstance (sli , int ) else ray # return element instead of 1-element array
326326
327- def _get_start_offset (self ):
328- """
329- Return the offset of the first sample.
330- """
331- return self .get_global_field (self .START_OFFSET_KEY , 0 )
332-
333327 def get_num_channels (self ):
334- """Returns integer number of channels if present, otherwise 1"""
335- return self .get_global_field (self .NUM_CHANNELS_KEY , 1 )
328+ """Return integer number of channels."""
329+ warnings .warn (
330+ "get_num_channels() is deprecated and will be removed in a future version of sigmf. "
331+ "Use the 'num_channels' attribute instead." ,
332+ DeprecationWarning ,
333+ stacklevel = 2 ,
334+ )
335+ return self .num_channels
336336
337337 def _is_conforming_dataset (self ):
338338 """
@@ -383,9 +383,11 @@ def set_metadata(self, metadata):
383383 else :
384384 raise SigMFError ("Unable to interpret provided metadata." )
385385
386- # if num_channels missing, default to 1
386+ # ensure fields required for parsing are present or use defaults
387387 if self .get_global_field (self .NUM_CHANNELS_KEY ) is None :
388388 self .set_global_field (self .NUM_CHANNELS_KEY , 1 )
389+ if self .get_global_field (self .START_OFFSET_KEY ) is None :
390+ self .set_global_field (self .START_OFFSET_KEY , 0 )
389391
390392 # set version to current implementation
391393 self .set_global_field (self .VERSION_KEY , __specification__ )
@@ -423,10 +425,8 @@ def add_capture(self, start_index, metadata=None):
423425 If there is already capture info for this index, metadata will be merged
424426 with the existing metadata, overwriting keys if they were previously set.
425427 """
426- if start_index < self ._get_start_offset ():
427- raise SigMFAccessError (
428- "`start_index` {} must be >= the global start index {}" .format (start_index , self ._get_start_offset ())
429- )
428+ if start_index < self .offset :
429+ raise SigMFAccessError ("Capture start_index cannot be less than dataset start offset." )
430430 capture_list = self ._metadata [self .CAPTURE_KEY ]
431431 new_capture = metadata or {}
432432 new_capture [self .START_INDEX_KEY ] = start_index
@@ -452,16 +452,13 @@ def get_captures(self):
452452
453453 def get_capture_info (self , index ):
454454 """
455- Returns a dictionary containing all the capture information at sample
456- 'index'.
455+ Returns a dictionary containing all the capture information at sample index.
457456 """
458- if index < self ._get_start_offset ():
459- raise SigMFAccessError (
460- "`start_index` {} must be >= the global start index {}" .format (index , self ._get_start_offset ())
461- )
457+ if index < self .offset :
458+ raise SigMFAccessError ("Sample index cannot be less than dataset start offset." )
462459 captures = self ._metadata .get (self .CAPTURE_KEY , [])
463460 if len (captures ) == 0 :
464- raise SigMFAccessError ("No captures are present! " )
461+ raise SigMFAccessError ("No captures in metadata. " )
465462 cap_info = captures [0 ]
466463 for capture in captures :
467464 if capture [self .START_INDEX_KEY ] > index :
@@ -494,9 +491,7 @@ def get_capture_byte_boundarys(self, index):
494491 prev_start_sample = 0
495492 for ii , capture in enumerate (self .get_captures ()):
496493 start_byte += capture .get (self .HEADER_BYTES_KEY , 0 )
497- start_byte += (
498- (self .get_capture_start (ii ) - prev_start_sample ) * self .get_sample_size () * self .get_num_channels ()
499- )
494+ start_byte += (self .get_capture_start (ii ) - prev_start_sample ) * self .get_sample_size () * self .num_channels
500495 prev_start_sample = self .get_capture_start (ii )
501496 if ii >= index :
502497 break
@@ -508,19 +503,16 @@ def get_capture_byte_boundarys(self, index):
508503 end_byte += (
509504 (self .get_capture_start (index + 1 ) - self .get_capture_start (index ))
510505 * self .get_sample_size ()
511- * self .get_num_channels ()
506+ * self .num_channels
512507 )
513508 return (start_byte , end_byte )
514509
515510 def add_annotation (self , start_index , length = None , metadata = None ):
516511 """
517512 Insert annotation at start_index with length (if != None).
518513 """
519-
520- if start_index < self ._get_start_offset ():
521- raise SigMFAccessError (
522- "`start_index` {} must be >= the global start index {}" .format (start_index , self ._get_start_offset ())
523- )
514+ if start_index < self .offset :
515+ raise SigMFAccessError ("Annotation start_index cannot be less than dataset start offset." )
524516
525517 new_annot = metadata or {}
526518 new_annot [self .START_INDEX_KEY ] = start_index
@@ -574,7 +566,7 @@ def get_sample_size(self):
574566 Determines the size of a sample, in bytes, from the datatype of this set.
575567 For complex data, a 'sample' includes both the real and imaginary part.
576568 """
577- return dtype_info (self .get_global_field ( self . DATATYPE_KEY ) )["sample_size" ]
569+ return dtype_info (self .datatype )["sample_size" ]
578570
579571 def _count_samples (self ):
580572 """
@@ -595,18 +587,14 @@ def _count_samples(self):
595587 else :
596588 file_bytes = 0
597589 sample_bytes = file_bytes - self .get_global_field (self .TRAILING_BYTES_KEY , 0 ) - header_bytes
598- sample_size = self .get_sample_size () # size of a sample in bytes
599- num_channels = self .get_num_channels ()
600- sample_count = sample_bytes // sample_size // num_channels
601- if sample_bytes % (sample_size * num_channels ) != 0 :
590+ total_sample_size = self .get_sample_size () * self .num_channels
591+ sample_count , remainder = divmod (sample_bytes , total_sample_size )
592+ if remainder :
602593 warnings .warn (
603- f"Data source does not contain an integer number of samples across channels. "
604- "It may be invalid data."
594+ "Data source does not contain an integer number of samples across channels, it may be invalid."
605595 )
606596 if self ._get_sample_count_from_annotations () > sample_count :
607- warnings .warn (
608- f"Data source ends before the final annotation in the corresponding SigMF metadata."
609- )
597+ warnings .warn ("Data source ends before the final annotation in the corresponding SigMF metadata." )
610598 self .sample_count = sample_count
611599 return sample_count
612600
@@ -673,7 +661,7 @@ def set_data_file(
673661
674662 dtype = dtype_info (self .get_global_field (self .DATATYPE_KEY ))
675663 self .is_complex_data = dtype ["is_complex" ]
676- num_channels = self .get_num_channels ()
664+ num_channels = self .num_channels
677665 self .ndim = 1 if (num_channels < 2 ) else 2
678666
679667 complex_int_separates = dtype ["is_complex" ] and dtype ["is_fixedpoint" ]
@@ -769,7 +757,7 @@ def read_samples_in_capture(self, index=0, autoscale=True):
769757 Samples are returned as an array of float or complex, with number of dimensions equal to NUM_CHANNELS_KEY.
770758 """
771759 cb = self .get_capture_byte_boundarys (index )
772- if (cb [1 ] - cb [0 ]) % (self .get_sample_size () * self .get_num_channels () ):
760+ if (cb [1 ] - cb [0 ]) % (self .get_sample_size () * self .num_channels ):
773761 warnings .warn (
774762 f"Capture `{ index } ` in `{ self .data_file } ` does not contain "
775763 "an integer number of samples across channels. It may be invalid."
@@ -808,11 +796,11 @@ def read_samples(self, start_index=0, count=-1, autoscale=True, raw_components=F
808796 raise SigMFFileError ("Cannot read samples from a metadata only distribution." )
809797 else :
810798 raise SigMFFileError ("No signal data file has been associated with the metadata." )
811- first_byte = start_index * self .get_sample_size () * self .get_num_channels ()
799+ first_byte = start_index * self .get_sample_size () * self .num_channels
812800
813801 if not self ._is_conforming_dataset ():
814802 warnings .warn (f"Recording dataset appears non-compliant, resulting data may be erroneous" )
815- return self ._read_datafile (first_byte , count * self .get_num_channels () , autoscale , False )
803+ return self ._read_datafile (first_byte , count * self .num_channels , autoscale , False )
816804
817805 def _read_datafile (self , first_byte , nitems , autoscale , raw_components ):
818806 """
@@ -827,7 +815,7 @@ def _read_datafile(self, first_byte, nitems, autoscale, raw_components):
827815 component_size = dtype ["component_size" ]
828816
829817 data_type_out = np .dtype ("f4" ) if not self .is_complex_data else np .dtype ("f4, f4" )
830- num_channels = self .get_num_channels ()
818+ num_channels = self .num_channels
831819
832820 if self .data_file is not None :
833821 fp = open (self .data_file , "rb" )
0 commit comments