diff --git a/idelib/dataset.py b/idelib/dataset.py index 521e2a1..5956123 100644 --- a/idelib/dataset.py +++ b/idelib/dataset.py @@ -471,29 +471,46 @@ def hasSession(self, sessionId): return False if sessionId is None: return True - return sessionId >= 0 and sessionId < len(self.sessions) - - - def getPlots(self, subchannels=True, plots=True, debug=True, sort=True): + return 0 <= sessionId < len(self.sessions) + + + def getPlots(self, subchannels=True, plots=True, debug=True, sort=True, + visibility=0): """ Get all plotable data sources: sensor SubChannels and/or Plots. :keyword subchannels: Include subchannels if `True`. :keyword plots: Include Plots if `True`. :keyword debug: If `False`, exclude debugging/diagnostic channels. - :keyword sort: Sort the plots by name if `True`. - """ + :keyword sort: Sort the plots by name if `True`. + :keyword visibility: The plots' maximum level of visibility, + for display purposes. Standard visibility ranges: + * 0: Standard data sources. Always visible by default. + * 10: Optionally visible, of interest but only in certain situations. + * 20: Hidden by default, but possibly of use to the user. + * 30: Hidden by default, channel used indirectly (but human readable). + * 40: Hidden by default, channel used indirectly (not very human readable). + * 50: Diagnostic, always hide. Accessible via the idelib API. + """ + def test(x): + return debug or (x.visibility <= visibility + and not x.name.startswith("DEBUG")) + result = [] - test = lambda x: debug or not x.name.startswith("DEBUG") - if plots: - result = [x for x in self.plots.values() if test(x)] + if subchannels: for c in self._channels.values(): for i in range(len(c.subchannels)): subc = c.getSubChannel(i) - if test(subc): - result.append(subc) + if not test(subc): + continue + result.append(subc) + + if plots: + result.extend(x for x in self.plots.values() if test(x)) + if sort: result.sort(key=lambda x: x.displayName) + return result @@ -704,7 +721,7 @@ def __init__(self, dataset, channelId=None, parser=None, sensor=None, self.dataset = dataset self.sampleRate = sampleRate self.attributes = attributes - + self._unitsStr = None self.cache = bool(cache) @@ -947,13 +964,13 @@ class SubChannel(Channel): def __init__(self, parent, subchannelId, name=None, units=('', ''), transform=None, displayRange=None, sensorId=None, - warningId=None, axisName=None, attributes=None, color=None): + warningId=None, axisName=None, attributes=None, color=None, + visibility=0): """ Constructor. This should generally be done indirectly via `Channel.addSubChannel()`. - :param sensor: The parent sensor. - :param channelId: The channel's ID, unique within the file. - :param parser: The channel's payload data parser. + :param parent: The parent sensor. + :param subchannelId: The channel's ID, unique within the file. :keyword name: A custom name for this channel. :keyword units: The units measured in this channel, used if units are not explicitly indicated in the Channel's SubChannels. A @@ -973,6 +990,9 @@ def __init__(self, parent, subchannelId, name=None, units=('', ''), name is "Accelerometer X (low-g)"). :keyword attributes: A dictionary of arbitrary attributes, e.g. ``Attribute`` elements parsed from the file. + :keyword visibility: The subchannel's level of visibility, for + display purposes. The lower the value, the more 'visible' the + subchannel. """ self.id = subchannelId self.parent = parent @@ -981,6 +1001,7 @@ def __init__(self, parent, subchannelId, name=None, units=('', ''), self.dataset = parent.dataset self.axisName = axisName self.attributes = attributes + self.visibility = visibility self._unitsStr = None @@ -996,7 +1017,7 @@ def __init__(self, parent, subchannelId, name=None, units=('', ''), else: self.axisName = name - # XXX: HACK HACK HACK REMOVE ME REMOVE ME + # HACK: Display tweak for names generated by certain FwRev if self.name == "Control Pad P": self.name = "Control Pad Pressure" elif self.name == "Control Pad T": @@ -2848,7 +2869,7 @@ class Plot(Transformable): """ def __init__(self, source, plotId, name=None, transform=None, units=None, - attributes=None): + attributes=None, visibility=0): self.source = source self.id = plotId self.session = source.session @@ -2856,6 +2877,7 @@ def __init__(self, source, plotId, name=None, transform=None, units=None, self.name = source.path() if name is None else name self.units = source.units if units is None else units self.attributes = attributes + self.visibility = visibility self.setTransform(transform, update=False) diff --git a/idelib/parsers.py b/idelib/parsers.py index fe8177d..bf1a94f 100644 --- a/idelib/parsers.py +++ b/idelib/parsers.py @@ -1063,6 +1063,7 @@ class ChannelParser(ElementHandler): "SubChannelSensorRef": "sensorId", "SubChannelWarningRef": "warningId", "SubChannelPlotColor": "color", + "SubChannelVisibility": "visibility", # Generic attribute elements. "Attribute": "attributes" diff --git a/idelib/schemata/mide_ide.xml b/idelib/schemata/mide_ide.xml index d975dcb..7adeca2 100644 --- a/idelib/schemata/mide_ide.xml +++ b/idelib/schemata/mide_ide.xml @@ -140,7 +140,14 @@ Maximum valid sensor value; may be used for data validation or initial axis scaling during display. Reference to a Sensor ID. Allows the association between SubChannels and a physical sensor to be expressed. Reference to a warning range, i.e. another sensor measuring something that affects the results of this one. - Allow data channels to specify a visibility level; could have different visibility levels for e.g. 'advanced', 'on request' (channels which are not normally useful on their own, e.g. IRIG stream), 'hidden' (internal diagnostic or other dirty laundry). + Allow data channels to specify a visibility level. Inversely proportional to 'visibility.' + 0: Always visible (default) + 10: Optionally visible, things probably of interest to the user in certain situations + 20: Hide by default, but possibly of use to the user + 30: Hide by default, channel used indirectly (but human readable) + 40: Hide by default, channel used indirectly (not very human readable) + 50: Diagnostic, always hide. Accessible via the idelib API. + The RGB values of the default plotting color (3 bytes). Accuracy rank for sorting duplicate channels emitting the same data by accuracy. This is a unitless, arbitrary file- and type-local value. Higher values for channels with the same measurement are better, but values are not guaranteed to be consecutive and are not comparable across channels with different unit types. Effective precision of the channel payload, if different than implied by the native type resolution. Same format as TimeCodeScale. Mainly useful for time channels, which may be emitted as integer Unix epoch seconds for convenience but with actual precision greater than +/-0.5s.