Skip to content

Conversation

jacobagilbert
Copy link
Member

@jacobagilbert jacobagilbert commented Mar 23, 2022

This extension was written to support suggestive input as to how SigMF Recordings and Metadata should be presented visually to users. A basic example of how this could be used is here: miek/inspectrum#195 miek/inspectrum#208 which is just a quick proof of concept for how this might look.

There is no expectation that applications support all features of this, and the "simple" usage where an optional presentation:color field is added to annotations allows for the features in the above link. A much more descriptive set of features, presentation_style objects, are available that can be used to describe recommended presentation of entire classes of annotations or captures segments without requiring individual specification.

I believe this should be in-tree so as to make these field names common across applications and encourage adoption and convention.

The current implementation is blocked by #146 but this can be changed to work without it.

Jacob Gilbert added 2 commits March 21, 2022 10:54
direct use of unbounded key-value pair objects (dicts) does not work
well with libsigmf, using a list of pseudo-dicts.

### 0.1 The `color` datatype

The `color` datatype is a string which MUST be either 6 or 8 hexadecimal
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you consider also allowing strings from this well-defined set of color names? https://www.w3.org/TR/SVG11/types.html#ColorKeywords

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this would be ver nice overall but I am not sure if this is burdensome on applications implementing this. Interestingly the merge request with inspectrum does support this (thanks to QT's native support for it).

Open to any thoughts here, especially situations this would be a problem.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another thought (I'm not strongly advocating this, but I do like it) is to separate the color and the alpha into two separate fields. That would eliminate the RGBA vs ARGB issue, and simultaneously allow for alpha-izing named colors.

Inasmuch as the .sigmf-meta files are supposed to be "human readable", and inasmuch as I still have a hard time visually decoding hex color strings, named colors would be ... more understandable.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

human readability is a strongly beneficial reason to do this. Not sold on separate alpha but i see your use case...will think more. could be an optional that overrides AARRGGBB....

@bhilburn
Copy link
Contributor

I'm in favor of this, and looks good. I'd say get it going, but deprecate your version to something < v1.0.0. Get feedback from @miek and others and target a v1.0.0 release with next SigMF minor release.

Copy link
Contributor

@bhilburn bhilburn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deprecate the version

@gmabey
Copy link
Contributor

gmabey commented Oct 11, 2022 via email

@miek
Copy link
Contributor

miek commented Nov 8, 2022

I've thought about this a bunch and, while I really like the idea of being able to encode some visual information, I worry that this implementation will lead to people creating recordings that only work well with their favourite tool/theme/colour-map. For example, I plan to add options for other colour maps to inspectrum at some point and presentation parameters for annotations created now could be unreadable on other colour maps.

I'd much rather see some way to encode intent rather than specific colours/styles, and then visualisation tools can interpret that in a way that works with their theme. Perhaps the naming scheme from standard logging levels could work, with fatal/error/warn/info/etc.? There could also be a way to define extra named groups, to group similar packets together for example.

@777arc
Copy link
Member

777arc commented Apr 7, 2023

I'd much rather see some way to encode intent rather than specific colours/styles, and then visualisation tools can interpret that in a way that works with their theme. Perhaps the naming scheme from standard logging levels could work, with fatal/error/warn/info/etc.? There could also be a way to define extra named groups, to group similar packets together for example.

Great point, although I would rather see integers starting at 0 than fatal/error/warn/info, that way we don't have to all agree what each code means, plus the RFML folks will love integers. And it solves the group problem. Would be nice to at least standardize on green and red, e.g. have 0 = green and 1 = red and then past that it's whatever the tooling thinks looks good?

Then there's the question of how do we support both options, because in the end it would seem weird to not allow specifying a specific color...

@jacobagilbert
Copy link
Member Author

@miek Your input here is great, sorry I sat on this for so long. I'll definitely keep this in mind the next time I'm wondering why one of my inspectrum PRs hasn't been merged yet LOL!

I think your proposal makes a ton of sense and I'd like to figure out a way to capture that effectively. I have run into exactly the concern you raise repeatedly in my playing around with colored annotations in just the single default inspectrum colormap. Im wondering if we can identify a small set of features or annotation groups users would want to allow a tool to color. I think it needs to be a small enough set that its reasonable to find a set of annotation styles that coexist with a given colormap and are distinguishable.

I like taking inspiration from log levels, heres my first-pass take on this:

styles = {
  ALERT,    // should be visible immediately, regardless of the view settings of the dataset
  ERROR,    // should quickly draw attention and be styled in such a way to indicate a problem (e.g.: red)
  WARNING,  // upon inspection it should be obvious that this area may require additional inspection
  INFO,     // this is the standard annotation style
  DEBUG,    // this annotation is of lower importance than standard annotations
  USER_A,   //  \
  USER_B,   //  |
  USER_C,   //   > these styles should be visibly distinct but no relative importance is implied
  USER_D,   //  |
  USER_E    //  /
}

A number of questions:

  1. Does 10 styles seem like a lot?
  2. Should there be more user classes?
  3. Should the ability to specify suggestions or explicit colors still be included?

Also, as an aside:

For example, I plan to add options for other colour maps to inspectrum

🙌 🙌 I like to hear this, viridis cant come soon enough :) - Tammojan's suggestion in 204 of using tinycolormap seems like a pretty easy way to get Parula, Heat, Jet, Turbo, Hot, Gray, Magma, Inferno, Plasma, Viridis, Cividis, Github, Cubehelix, and HSV for the cost of adding a drop down, removing Jet from that list and adding a little interface glue.

@Teque5 Teque5 changed the base branch from sigmf-v1.x to main April 12, 2024 19:34
@777arc
Copy link
Member

777arc commented Nov 18, 2024

@jacobagilbert is going to remove some of the fields that havent been used, in order to get a minimal version merged in

@devnulling
Copy link

@Teque5 @jacobagilbert ping on this fellow

Comment on lines +31 to +35
It is RECOMMENDED that applications include support for hexadecimal and named
colors, however if support for one or the other is not possible, it is
permissable for a reasonable default to be used and the application to still be
SigMF Compliant since support for this extension is not required at all for
SigMF Compliance.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

strike: you cannot "MUST" a hex string and then say "we recommend to support something else in the consumer". That makes no sense. And named colors are a terrible idea, throughout, for a metadata format, to be 100% honest here.

Comment on lines +37 to +39
Note: RGBA is not compatible with QColor objects, which use ARGB. These must be
converted in QT applications!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strike. implementation detail.

Comment on lines +71 to +72
The `presentation_style` object is a JSON dictionary entry and is implemented
for dictionary emulation for efficient serialization:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure I understand this sentence at all. JSON doesn't know "dictionaries"; it speaks of "objects": What is emulated here?


|name|required|type|description|
|----|--------|----|-----------|
|`key`|true|string|Color of the fill of the annotation, this is generally used with defined alpha channel.|

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't this be of type color?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we sure this is supposed to be "color of the fill…"? It takes values of "VALID" and "INVALID" in the example

|`key`|true|string|Color of the fill of the annotation, this is generally used with defined alpha channel.|
|`style`|true|`presentation_style`|Color of the fill of the annotation, this is generally used with defined alpha channel.|

### 1.2 The `presentation_style` object

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move to "Data Types"

Applications implementing this extension will generally parse the `*_styles`
fields into a dictionary for easy reference.

### 1.1 The `style_entry` object

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move to "Data types"

objects. When describing a capture segment, the `key` field refers only to the
first key in the captures list.

### 1.1.1 The `display_type` field

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is a subtype, needs to be in data types

@remleduff
Copy link

remleduff commented Jul 31, 2025

I just wanted to recognize that this implicitly requires #146 also be approved.

With that, I think that using capture_tags in captures is much better than styling annotations by label. I think it would be generally more useful to add an annotation_tags member to annotations which allows semantic tagging (and styling as a side effect) of the annotation separately from its label.

information by short form name. This is a simple mechanism to prevent every
annotation or capture segment from defining these fields repeatedly. These
objects have keys that represent capture segments or annotation `label` fields
they apply to and values consisting of `presentation_style` objects.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this definition of key's semantic isn't very clear. It should mention that for captures it is keying by capture_tags and for annotations by label.

It may be too late to change this, but it might have been better to have separate "tag" field and "label" field requiring one of them to be specified.

(As I mention elsewhere) Keying annotations by label isn't really flexible enough imho, I think it would be better if there was also an annotation_tags field in annotations.


In a `capture_styles` object the `key` field MAY be underdetermined if there are
multiple `capture_tags`. The first entry in the `capture_tags` list for which
a `captures_styles` `key` exists SHOULD be used.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not honestly sure how inconvenient this "first wins" policy will be in practice.

(It's probably a bigger issue if annotation_tags were to be added, as I can think of several scenarios where an annotation might have several tags. It would be desirable to be able to "fix" the style to make it clear that it's both VALID and IGNORED or something.

In other words, I could imagine wanting the ability to key by "one_of" or "all_of" on the list of tags.)

Copy link

@dkozel dkozel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a few typos/errors that I've pointed out here.

However the much more substantive issue that I'll object to is the use of display styling in place of meaning. I agree there should be a mechanism for indicating that certain elements should be visually styled in a particular (though maybe not absolute) way.

Introducing visual styling to an element is/should be marking an annotation or capture as being part of some semantic group. The proposed capture_tags in #146 introduces the concept of tags as a way of linking meaning to elements and could be extended to annotation_tags.

Currently an annotation's label does this in part, but there are several reasons not to use it for display styling. There is room for adding more flexibility to users to mark multiple properties of an annotation (without adding a full schema extension) and tags are a viable route there. Label is a mature field which has developed specific meaning to many users and altering it's utility now would be invasive. Third, the decision of what property should be used to decide the display styling should be left as a standalone decision for users.

I was initially sold in on the idea of linking display styles to the _tag(s) value, but now am wondering if that becomes overloading functionality. Marcus raised the comparison with HTML element classes and CSS styling. I'm leaning towards having a single presentation:class optional per annotation or capture. In the global name space it should be required to define

"presentation:classes" : [
  {
    "presentation:class": "group1",
    "presentation:description": "Packets sent by users in the Demo group"
  }, ...
]

Then either in a separate .sigmf-style file or in the global section, have presentation:style definitions which refer to the classes. This decouples meaning from the styling details, allowing easy theming.

I can't think of a situation where the styling of a single annotation or capture should be manually set within the scope of the annotation. Styling an element should be used to convey meaning. If meaning is being conveyed it should be defined. If it's defined it should be done in a reusable way. Once it's defined in the global space it can be used for a single element or many. The ability to embed styling information inside of individual objects should be removed.

Thoughts?

I could see reversing the direction of reference such that a style file (or section) defines a set of available styles, and the presentation classes declare what style to use.

Part of my thinking is that the selection/definition of classes is very end-user/application specific, and the styling is also likely to be tool/environment specific.

The Recording would need to declare what Style file it is intended to be used with. Marcus brought up the idea of having the field support a URI, so styles could optionally be remotely hosted, distributed alongside the recordings, or embedded in tools.

I want to like the idea of defining a default set of style names, like the Log Levels and other attributes @miek mentioned, as long as there's a way of defining new styles and distributing them.

|name|required|type|description|
|----|--------|----|-----------|
|`capture_default`|false|`presentation_style`|Default style to be used for captures when a style is not specified.|
|`capture_styles`|false|list of `style_entry`|Color of the fill of the annotation, this is generally used with defined alpha channel.|
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Description should be "List of available display styles for captures"?

|`annotation_default`|false|`presentation_style`|Default style to be used for annotations when a style is not specified.|
|`annotation_styles`|false|list of `style_entry`|Color of the foreground captures segment display features.|

Both `capture_styles` and `annotation_styles` are JSON object containg style
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: containing

},
{
"key": "INVALID",
"stye": {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo: style

"captures": [
{
"core:sample_start": 0,
"core:capture_tags": ["VALID"],
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dependency on the currently non-merged addition to the core spec:
#146

|`capture_default`|false|`presentation_style`|Default style to be used for captures when a style is not specified.|
|`capture_styles`|false|list of `style_entry`|Color of the fill of the annotation, this is generally used with defined alpha channel.|
|`annotation_default`|false|`presentation_style`|Default style to be used for annotations when a style is not specified.|
|`annotation_styles`|false|list of `style_entry`|Color of the foreground captures segment display features.|
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Description should be "List of available display styles for annotations"?

@marcusmueller
Copy link

I like @dkozel's approach here, though I have to say that a separate .sigmf-style file sounds like something I'd avoid; especially since, well, citing myself, CSS already exists, and reinventing that wheel in JSON certainly isn't a great idea.

I'd lean towards having a global attribute that refers to the URI (not URL) of a separately available style (in whichever format) rather than inclusion in metadata; comparable to, say, how one references an XML namespace. Representation instructions are not metadata!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants