Skip to content
Closed
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
142 changes: 133 additions & 9 deletions sigmf/sigmffile.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

"""SigMFFile Object"""

from typing import Union
import codecs
import io
import json
Expand All @@ -31,7 +32,7 @@ class SigMFMetafile:
VALID_KEYS = {}

def __init__(self):
self.version = None
self._version = None
self.schema = None
self._metadata = None
self.shape = None
Expand Down Expand Up @@ -146,14 +147,38 @@ class SigMFFile(SigMFMetafile):
CAPTURE_KEY = "captures"
ANNOTATION_KEY = "annotations"
VALID_GLOBAL_KEYS = [
AUTHOR_KEY, COLLECTION_KEY, DATASET_KEY, DATATYPE_KEY, DATA_DOI_KEY, DESCRIPTION_KEY, EXTENSIONS_KEY,
GEOLOCATION_KEY, HASH_KEY, HW_KEY, LICENSE_KEY, META_DOI_KEY, METADATA_ONLY_KEY, NUM_CHANNELS_KEY, RECORDER_KEY,
SAMPLE_RATE_KEY, START_OFFSET_KEY, TRAILING_BYTES_KEY, VERSION_KEY
AUTHOR_KEY,
COLLECTION_KEY,
DATASET_KEY,
DATATYPE_KEY,
DATA_DOI_KEY,
DESCRIPTION_KEY,
EXTENSIONS_KEY,
GEOLOCATION_KEY,
HASH_KEY,
HW_KEY,
LICENSE_KEY,
META_DOI_KEY,
METADATA_ONLY_KEY,
NUM_CHANNELS_KEY,
RECORDER_KEY,
SAMPLE_RATE_KEY,
START_OFFSET_KEY,
TRAILING_BYTES_KEY,
VERSION_KEY,
]
VALID_CAPTURE_KEYS = [DATETIME_KEY, FREQUENCY_KEY, HEADER_BYTES_KEY, GLOBAL_INDEX_KEY, START_INDEX_KEY]
VALID_ANNOTATION_KEYS = [
COMMENT_KEY, FHI_KEY, FLO_KEY, GENERATOR_KEY, LABEL_KEY, LAT_KEY, LENGTH_INDEX_KEY, LON_KEY, START_INDEX_KEY,
UUID_KEY
COMMENT_KEY,
FHI_KEY,
FLO_KEY,
GENERATOR_KEY,
LABEL_KEY,
LAT_KEY,
LENGTH_INDEX_KEY,
LON_KEY,
START_INDEX_KEY,
UUID_KEY,
]
VALID_KEYS = {GLOBAL_KEY: VALID_GLOBAL_KEYS, CAPTURE_KEY: VALID_CAPTURE_KEYS, ANNOTATION_KEY: VALID_ANNOTATION_KEYS}

Expand Down Expand Up @@ -262,6 +287,100 @@ def _is_conforming_dataset(self):
# if we get here, the file exists and is conforming
return True

@property
def datatype(self) -> str:
"""Fetches the datatype."""
return self.get_global_field("core:datatype")

@property
def sample_rate(self) -> float:
"""Fetches the sample_rate in Hz."""
return float(self.get_global_field("core:sample_rate"))

@property
def version(self) -> str:
"""Fetches the version."""
return self.get_global_field("core:version")

@version.setter
def version(self, v):
self.set_global_field("core:version", v)

@property
def author(self) -> Union[str, None]:
"""Fetches the author."""
return self.get_global_field("core:author")

@property
def collection(self) -> Union[str, None]:
"""Fetches the collection."""
return self.get_global_field("core:collection")

@property
def dataset(self) -> Union[str, None]:
"""Fetches the dataset."""
return self.get_global_field("core:dataset")

@property
def data_doi(self) -> Union[str, None]:
"""Fetches the author."""
return self.get_global_field("core:data_doi")

@property
def description(self) -> Union[str, None]:
"""Fetches the description."""
return self.get_global_field("core:description")

@property
def hw(self) -> Union[str, None]:
"""Fetches the author."""
return self.get_global_field("core:hw")

@property
def license(self) -> Union[str, None]:
"""Fetches the license."""
return self.get_global_field("core:license")

@property
def metadata_only(self) -> Union[bool, None]:
"""Fetches the metadata_only."""
return self.get_global_field("core:metadata_only")

@property
def meta_doi(self) -> Union[str, None]:
"""Fetches the author."""
return self.get_global_field("core:meta_doi")

@property
def num_channels(self) -> Union[int, None]:
"""Fetches the num_channels."""
return self.get_global_field("core:num_channels", 1)

@property
def offset(self) -> Union[int, None]:
"""Fetches the offset."""
return self.get_global_field("core:offset", 0)

@property
def recorder(self) -> Union[str, None]:
"""Fetches the recorder."""
return self.get_global_field("core:recorder")

@property
def sha512(self) -> Union[str, None]:
"""Fetches the sha512."""
return self.get_global_field("core:sha512")

@property
def trailing_bytes(self) -> Union[int, None]:
"""Fetches the trailing bytes."""
return self.get_global_field("core:trailing_bytes")

@property
def geolocation(self):
"""Fetches the geolocation."""
return self.get_global_field("core:geolocation")

def get_schema(self):
"""
Return a schema object valid for the current metadata
Expand Down Expand Up @@ -768,7 +887,9 @@ class SigMFCollection(SigMFMetafile):
]
VALID_KEYS = {COLLECTION_KEY: VALID_COLLECTION_KEYS}

def __init__(self, metafiles: list = None, metadata: dict = None, base_path=None, skip_checksums: bool = False) -> None:
def __init__(
self, metafiles: list = None, metadata: dict = None, base_path=None, skip_checksums: bool = False
) -> None:
"""
Create a SigMF Collection object.

Expand Down Expand Up @@ -1046,6 +1167,7 @@ def fromarchive(archive_path, dir=None, skip_checksum=False):
access SigMF archives without extracting them.
"""
from .archivereader import SigMFArchiveReader

return SigMFArchiveReader(archive_path, skip_checksum=skip_checksum).sigmffile


Expand Down Expand Up @@ -1119,8 +1241,10 @@ def get_sigmf_filenames(filename):
# suffix, because the filename might contain '.' characters which are part
# of the filename rather than an extension.
sigmf_suffixes = [
SIGMF_DATASET_EXT, SIGMF_METADATA_EXT,
SIGMF_ARCHIVE_EXT, SIGMF_COLLECTION_EXT,
SIGMF_DATASET_EXT,
SIGMF_METADATA_EXT,
SIGMF_ARCHIVE_EXT,
SIGMF_COLLECTION_EXT,
]
if stem_path.suffix in sigmf_suffixes:
with_suffix_path = stem_path
Expand Down