From d53ddbb885f12f8e7ca72471eeb9840bb059ff03 Mon Sep 17 00:00:00 2001 From: Keigh Rim Date: Fri, 1 Mar 2024 05:51:34 -0500 Subject: [PATCH] generated files for 1.0.2 --- CHANGELOG.md | 3 + VERSION | 2 +- docs/1.0.2/index.md | 551 ++++++ docs/1.0.2/pi78oGjdT-annotated.jpg | Bin 0 -> 13400 bytes docs/1.0.2/pi78oGjdT.jpg | Bin 0 -> 12325 bytes docs/1.0.2/samples/bars-tones-slates/index.md | 33 + docs/1.0.2/samples/bars-tones-slates/raw.json | 96 + .../samples/east-tesseract-typing/index.md | 177 ++ .../samples/east-tesseract-typing/raw.json | 124 ++ .../everything/images/newshour-loud-dogs.jpg | Bin 0 -> 130723 bytes docs/1.0.2/samples/everything/index.md | 236 +++ docs/1.0.2/samples/everything/pbcore.md | 144 ++ docs/1.0.2/samples/everything/raw.json | 1563 +++++++++++++++++ docs/1.0.2/samples/everything/scripts/east.py | 53 + .../1.0.2/samples/everything/scripts/kaldi.py | 53 + docs/1.0.2/samples/everything/scripts/ner.py | 58 + .../samples/everything/scripts/pbcore.py | 132 ++ .../samples/everything/scripts/slates.py | 45 + .../samples/everything/scripts/tesseract.py | 36 + .../1.0.2/samples/everything/scripts/utils.py | 20 + .../samples/segmenter-kaldi-ner/index.md | 182 ++ .../samples/segmenter-kaldi-ner/raw.json | 247 +++ docs/1.0.2/schema/lif.json | 116 ++ docs/1.0.2/schema/mmif.json | 191 ++ docs/1.0.2/vocabulary/attypeversions.json | 1 + docs/1.0.2/vocabulary/css/lappsstyle.css | 503 ++++++ docs/1.0.2/vocabulary/index.html | 430 +++++ docs/_config.yml | 1 + docs/vocabulary/Alignment/v1/index.html | 8 +- docs/vocabulary/Annotation/v3/index.html | 201 +++ docs/vocabulary/AudioDocument/v1/index.html | 8 +- docs/vocabulary/BoundingBox/v2/index.html | 317 ++++ docs/vocabulary/Chapter/v3/index.html | 358 ++++ docs/vocabulary/Document/v1/index.html | 8 +- docs/vocabulary/ImageDocument/v1/index.html | 8 +- docs/vocabulary/Interval/v2/index.html | 292 +++ docs/vocabulary/Polygon/v2/index.html | 284 +++ docs/vocabulary/Region/v2/index.html | 237 +++ docs/vocabulary/Relation/v2/index.html | 213 +++ docs/vocabulary/Span/v2/index.html | 311 ++++ docs/vocabulary/TextDocument/v1/index.html | 8 +- docs/vocabulary/Thing/v1/index.html | 8 +- docs/vocabulary/TimeFrame/v3/index.html | 325 ++++ docs/vocabulary/TimePoint/v2/index.html | 273 +++ docs/vocabulary/VideoDocument/v1/index.html | 8 +- docs/vocabulary/VideoObject/v2/index.html | 273 +++ 46 files changed, 8122 insertions(+), 15 deletions(-) create mode 100644 docs/1.0.2/index.md create mode 100644 docs/1.0.2/pi78oGjdT-annotated.jpg create mode 100644 docs/1.0.2/pi78oGjdT.jpg create mode 100644 docs/1.0.2/samples/bars-tones-slates/index.md create mode 100644 docs/1.0.2/samples/bars-tones-slates/raw.json create mode 100644 docs/1.0.2/samples/east-tesseract-typing/index.md create mode 100644 docs/1.0.2/samples/east-tesseract-typing/raw.json create mode 100644 docs/1.0.2/samples/everything/images/newshour-loud-dogs.jpg create mode 100644 docs/1.0.2/samples/everything/index.md create mode 100644 docs/1.0.2/samples/everything/pbcore.md create mode 100644 docs/1.0.2/samples/everything/raw.json create mode 100644 docs/1.0.2/samples/everything/scripts/east.py create mode 100644 docs/1.0.2/samples/everything/scripts/kaldi.py create mode 100644 docs/1.0.2/samples/everything/scripts/ner.py create mode 100644 docs/1.0.2/samples/everything/scripts/pbcore.py create mode 100644 docs/1.0.2/samples/everything/scripts/slates.py create mode 100644 docs/1.0.2/samples/everything/scripts/tesseract.py create mode 100644 docs/1.0.2/samples/everything/scripts/utils.py create mode 100644 docs/1.0.2/samples/segmenter-kaldi-ner/index.md create mode 100644 docs/1.0.2/samples/segmenter-kaldi-ner/raw.json create mode 100644 docs/1.0.2/schema/lif.json create mode 100644 docs/1.0.2/schema/mmif.json create mode 100644 docs/1.0.2/vocabulary/attypeversions.json create mode 100644 docs/1.0.2/vocabulary/css/lappsstyle.css create mode 100644 docs/1.0.2/vocabulary/index.html create mode 100644 docs/vocabulary/Annotation/v3/index.html create mode 100644 docs/vocabulary/BoundingBox/v2/index.html create mode 100644 docs/vocabulary/Chapter/v3/index.html create mode 100644 docs/vocabulary/Interval/v2/index.html create mode 100644 docs/vocabulary/Polygon/v2/index.html create mode 100644 docs/vocabulary/Region/v2/index.html create mode 100644 docs/vocabulary/Relation/v2/index.html create mode 100644 docs/vocabulary/Span/v2/index.html create mode 100644 docs/vocabulary/TimeFrame/v3/index.html create mode 100644 docs/vocabulary/TimePoint/v2/index.html create mode 100644 docs/vocabulary/VideoObject/v2/index.html diff --git a/CHANGELOG.md b/CHANGELOG.md index 22065316..3b585370 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ The format is loosely based on [Keep a Changelog](http://keepachangelog.com/). L This file documents changes made to the MMIF specification. Version names used to start with `spec-` because the Python MMIF SDK was also maintained in this repository. Starting with version 0.2.2 the repository was split and the prefix was discarded. +## Version 1.0.2 - 2024-02-28 +- Added general properties (`label`, `labelset`, and `classification`) for recording classification results (https://github.com/clamsproject/mmif/issues/218). + ## Version 1.0.1 - 2024-02-07 - vocabulary types now have `similarTo` field to link similar type definitions as URI (https://github.com/clamsproject/mmif/issues/203). - updated `TimeFrame` definition to ease `frameType` value restrictions (https://github.com/clamsproject/mmif/issues/207). diff --git a/VERSION b/VERSION index 7dea76ed..6d7de6e6 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.0.1 +1.0.2 diff --git a/docs/1.0.2/index.md b/docs/1.0.2/index.md new file mode 100644 index 00000000..8426a0b4 --- /dev/null +++ b/docs/1.0.2/index.md @@ -0,0 +1,551 @@ +--- +layout: page +title: MMIF Specification +subtitle: Version 1.0.2 +--- + +MMIF is an annotation format for audiovisual media and associated text like transcripts and closed captions. It is a JSON-LD format used to transport data between CLAMS apps and is inspired by and partially based on LIF, the [LAPPS Interchange Format](https://wiki.lappsgrid.org/interchange/). MMIF is pronounced *mif* or *em-mif*, or, if you like to hum, *mmmmmif*. + +MMIF consists of two formal components in addition to this more informal specification: +1. The JSON schema: + - [https://mmif.clams.ai/1.0.2/schema/mmif.json](schema/mmif.json) +1. The Vocabularies (the type hierarchies): + - [https://mmif.clams.ai/1.0.2/vocabulary](vocabulary) + - [http://vocab.lappsgrid.org](http://vocab.lappsgrid.org) + +The JSON schema for MMIF defines the syntactic elements of MMIF which will be explained at length in ["structure" section](#the-structure-of-mmif-files). These specifications often refer to elements from the CLAMS and LAPPS Vocabularies which define concepts and their ontological relations, see ["vocabulary" section](#mmif-and-the-vocabularies) for notes on those vocabularies. + +Along with the formal specifications and documentation we also provide a reference implementation of MMIF. It is developed in the Python programming language, and it will be distributed via GitHub (as source code) as well as via the [Python Package Index](https://pypi.org/) (as a Python library). The package will function as a software development kit (SDK), that helps users (mostly developers) to easily use various features of MMIF in developing their own applications. + +We use [semantic versioning](https://semver.org/) with the `major.minor.patch` version scheme. All formal components (this document, the JSON schema and CLAMS vocabulary) share the same version number, while the `mmif-python` Python SDK shares `major` and `minor` numbers with the specification version. See the [versioning notes](../versioning) for more information on compatibility between different versions and how it plays out when chaining CLAMS apps in a pipeline. + +## Table of Contents +{:.no_toc} + +1. toc placeholder +{:toc} + +## The format of MMIF files +As mentioned, MMIF is JSON in essence. When serialized to a physical file, the file must use **Unicode** charset encoded in **UTF-8**. + +## The structure of MMIF files + +The [JSON schema](schema/mmif.json) formally define the syntactic structure of a MMIF file. This section is an informal companion to the schema and gives further information. + +In essence, a MMIF file represents two things: + +1. Media like texts, videos, images and audio recordings. We will call these *documents*. +2. Annotations over those media representing information that was added by CLAMS processing. + +Annotations are always stored separately from the media. They can be directly linked to a slice in the media (a string in a text, a shape in an image, or a time frame in a video or audio) or they can refer to other annotations, for example to specify relations between text strings. More specifically, a MMIF file contains some metadata, a list of media and a list of annotation views, where each view contains a list of annotation types like Segment, BoundingBox, VideoObject or NamedEntity. + +The top-level structure of a MMIF file is as follows: + +```json +{ + "metadata": { + "mmif": "http://mmif.clams.ai/1.0.2" }, + "documents": [ ], + "views": [ ] +} +``` + +The `metadata` property stores metadata associated with the file. It is not heavily used for now, but we do use it to store the MMIF version used in the document. The `mmif` metadata property is required. You are allowed to add any other metadata properties. + + + +### The *documents* property + +We assume that when a MMIF document is initialized it is given a list of media and each of these media is either an external file or a text string. These media are all imported into the MMIF file as documents of a certain type and the specifications for each medium/document is stored in the `documents` list. This list is read-only and cannot be extended after initialization. There are no limits on how many documents and how many documents of what types are in the list, but typically there will be just a few documents in there. + +Here is an example document list with a video and its transcript: + +```json +{ + "documents": [ + { + "@type": "http://mmif.clams.ai/vocabulary/VideoDocument/v1", + "properties": { + "id": "m1", + "mime": "video/mpeg", + "location": "file:///var/archive/video-0012.mp4" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "m2", + "mime": "text/plain", + "location": "file:///var/archive/transcript-0012.txt" } + } + ] +} +``` + +The `@type` key has a special meaning in JSON-LD and it is used to define the type of data structure. In MMIF, the value should be a URL that points to a description of the type of document. Above we have a video and a text document and those types are described at [http://mmif.clams.ai/vocabulary/VideoDocument](vocabulary/VideoDocument) and [http://mmif.clams.ai/vocabulary/TextDocument](vocabulary/TextDocument) respectively. Currently, four document types are defined: *VideoDocument*, *TextDocument*, *ImageDocument* and *AudioDocument*. + +The description also lists the properties that can be used for a type, and above we have the `id`, `mime` and `location` properties, used for the document identifier, the document's MIME type and the location of the document, which is a URL. Should the document be a local file then the `file://` scheme must be used. Alternatively, and for text only, the document could be inline, in which case the element is represented as in the `text` property in LIF, using a JSON [value object](http://www.w3.org/TR/json-ld/#dfn-value-object) containing a `@value` key and optionally a `@language` key: + +``` json +{ + "documents": [ + { + "@type": "http://mmif.clams.ai/vocabulary/VideoDocument/v1", + "properties": { + "id": "m1", + "mime": "video/mpeg", + "location": "file:///var/archive/video-0012.mp4" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "m1", + "text": { + "@value": "Sue flew to Bloomington.", + "@language": "en" } } + } + ] +} +``` + +The value associated with `@value` is a string and the value associated with `@language` follows the rules in [BCP47](http://www.w3.org/TR/json-ld/#bib-bcp47), which for our current purposes boils down to using the two-character ISO 639 code. With inline text no MIME type is needed. + + + + +### The *views* property + +This is where all the annotations and associated metadata live. Views contain structured information about documents but are separate from those documents. The value of `views` is a JSON-LD array of view objects where each view specifies what documents the annotation is over, what information it contains and what app created that information. To that end, each view has four properties: `id`, `metadata` and `annotations`. + +```json +{ + "views": [ + { + "id": "v1", + "metadata": { }, + "annotations": [ ] + } + ] +} +``` + +Each view has a unique identifier. Annotation elements in the view have identifiers unique to the view and these elements can be uniquely referred to from outside the view by using the view identifier and the annotation element identifier, separated by a colon. For example, if the view above has an annotation with identifier "a8" then it can be referred to from outside the view by using "v1:a8". + +Here are a few general principles relevant to views: + +1. There is no limit to the number of views. +2. Apps may create as many new views as they want. +3. Apps may not change or add information to existing views, that is, views are read-only, which has many advantages at the cost of some redundancy. Since views are read-only, apps may not overwrite or delete information in existing views. This holds for the view’s metadata as well as the annotations. +4. Annotations in views have identifiers that are unique to the view. Views have identifiers that uniquely define them relative to other views. + +We now describe the metadata and the annotations. + + + +#### The *view's metadata* property + +This property contains information about the annotations in a view. Here is an example for a view over a video with medium identifier "m1" with segments added by the CLAMS bars-and-tones application: + +```json +{ + "app": "http://apps.clams.ai/bars-and-tones/1.0.5", + "timestamp": "2020-05-27T12:23:45", + "contains": { + "http://mmif.clams.ai/vocabulary/TimeFrame/v3": { + "timeUnit": "seconds", + "document": "m1" + } + }, + "parameters": {"threshold": "0.5", "not-defined-parameter": "some-value"}, +} +``` + +The `timestamp` key stores when the view was created by the application. This is using the ISO 8601 format where the T separates the date from the time of the day. The timestamp can also be used to order views, which is significant because by default arrays in JSON-LD are not ordered. + +The `app` key contains an identifier that specifies what application created the view. The identifier must be a URL form, and HTTP webpage pointed by the URL should contain all app metadata information relevant for the application: description, configuration, input/output specifications and a more complete description of what output is created. The app identifier always includes a version number for the app. The metadata should also contain a link to the public code repository for the app (and that repository will actually maintain all the information in the URL). + +The `parameters` is a dictionary of runtime parameters and their *string* values, if any. The primary purpose of this dictionary is to record the parameters "as-is" for reproducibility and accountability. Note that CLAMS apps are developed to run as HTTP servers, expecting parameters to be passed as URL query strings. Hence, the values in the `parameters` dictionary are always strings or simple lists of strings. + +The `contains` dictionary has keys that refer to annotation objects in the CLAMS or LAPPS vocabulary, or user-defined objects. Namely, they indicate the kind of annotations that live in the view. The value of each of those keys is a JSON object which contains metadata specified for the annotation type. The example above has one key that indicates that the view contains *TimeFrame* annotations, and it gives two metadata values for that annotation type: + +1. The `document` key gives the identifier of the document that the annotations of that type in this view are over. As we will see later, annotations anchor into documents using keys like `start` and `end` and this property specifies what document that is. +2. The `timeUnit` key is set to "seconds" and this means that for each annotation the unit for the values in `start` and `end` are seconds. + +Every annotation type defined in the CLAMS vocabulary has two feature structures - `metadata` and `properties`. See [this definition of *TimeFrame*](vocabulary/TimeFrame/) type in the vocabulary for an example. As we see here, `contains` dictionary in a view's metadata is used to assign values to metadata keys. We'll see in the following section that individual annotation objects are used to assign values to `properties` keys. +{: .box-note} + +Note that when a property is set to some value in the `contains` in the view metadata then all annotations of that type should adhere to that value, in this case the `document` and `timeUnit` are set to *"m1"* and *"seconds"* respectively. In other words, the `contains` dictionary not only functions as an overview of the annotation types in this view, but also as a place for common metadata shared among annotations of a type. This is useful especially for `document` property, as in a single view, an app is likely to process only a limited number of source documents and resulting annotation objects will be anchored on those documents. It is technically possible for *TimeFrame* type to add `document` properties to individual annotation objects and overrule the metadata property, but this is not to be done without really good reasons. We get back to this later. + +For annotation types that are used to measure time (such as *TimePoint*, *TimeFrame*, or *VideoObject*), the unit of the measurement (`timeUnit`) must be specified in the `contains`. However, for objects that measure image regions (such as [*BoundingBox*](vocabulary/BoundingBox).`coordinates`), the *unit* is always assumed to be *pixels*. That is, a coordinate is numbers of pixels from a point in an image to the origin along all axes, where the origin (*(0,0)*) is always the top-left point of the image. Similarly, for objects that measure text spans (such as [*Span*](vocabulary/Span).start/end), the *unit* of counting characters must always be code points. As mentioned above, MMIF must be serialized to a UTF-8 Unicode file. +{: .box-note} + +Next section has more details on the interaction between the vocabulary and the metadata for the annotation types in the `contains` dictionary. + +When an app fails to process the input for any reason and produces an error, it can record the error in the `error` field, instead of in `contains`. When this happens, the annotation list of the view must remain empty. Here is an example of a view with an error. + +```json +{ + "id": "v1", + "metadata": { + "app": "http://apps.clams.ai/bars-and-tones/1.0.5", + "timestamp": "2020-05-27T12:23:45", + "error": { + "message": "FileNotFoundError: /data/input.mp4 from Document d1 is not found.", + "stackTrace": "Optionally, some-stack-traceback-information" + }, + "parameters": {} + }, + "annotations": [] +} +``` + +Finally, an app may produce one or more warnings and still successfully process input and create annotations. In that case one extra view is added that has no annotations and that instead of the `contains` field has a `warnings` field which presents the warning messages as a list of strings. + +```json +{ + "id": "v2", + "metadata": { + "app": "http://apps.clams.ai/bars-and-tones/1.0.5", + "timestamp": "2020-05-27T12:23:45", + "warnings": ["Missing parameter frameRate, using default value."], + "parameters": {} + }, + "annotations": [] +} +``` + + + +#### The *view's annotations* property + +The value of the `annotations` property on a view is a list of annotation objects. Here is an example of an annotation object: + +```json +{ + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "f1", + "start": 0, + "end": 5, + "label": "bars-and-tones" + } +} +``` + +The two required keys are `@type` and `properties`. As mentioned before, the `@type` key in JSON-LD is used to define the type of data structure. The `properties` dictionary typically contains the features defined for the annotation category as defined in the vocabularies at [CLAMS vocabulary ](vocabulary) or [LAPPS vocabulary](http://vocab.lappsgrid.org/). For example, for the *TimeFrame* annotation type the vocabulary includes the feature `label` as well as the inherited features `id`, `start` and `end`. Values should be as specified in the vocabulary, values typically are strings, identifiers and integers, or lists of strings, identifiers and integers, but can be more complex. + +The `id` key should have a value that is unique relative to all annotation elements in the view. Other annotations can refer to this identifier either with just the identifier (for example “s1”), or the identifier with a view identifier prefix (for example “v1:s1”). If there is no prefix, the current view is assumed. + +We will discuss more details on annotation type vocabularies in the ["vocabulary" section](#mmif-and-the-vocabularies). +{: .box-note} + +The annotations list is shallow, that is, all annotations in a view are in that list and annotations are not embedded inside other annotations. For example, LAPPS *Constituent* annotations will not contain other *Constituent* annotations. However, in the `properties` dictionary annotations can refer to other annotations using the identifiers of the other annotations. + +Here is another example of a view containing two bounding boxes created by the EAST text recognition app: + +```json +{ + "id": "v1", + "metadata": { + "app": "http://apps.clams.io/east/1.0.4", + "timestamp": "2020-05-27T12:23:45", + "contains": { + "http://mmif.clams.ai/vocabulary/BoundingBox/v2": { + "document": "image3" + } + } + }, + "annotations": [ + { "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb0", + "coordinates": [[10,20], [60,20], [10,50], [60,50]] } + }, + { "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb1", + "coordinates": [[90,40], [110,40], [90,80], [110,80]] } + } + ] +} +``` + +Note how the `coordinates` property is a list of lists where each embedded list is a pair of an x-coordinate and a y-coordinate. + + + + +### Views with documents + +We have seen that an initial set of media is added to the MMIF `documents` list and that applications then create views from those documents. But some applications are special in that they create text from audiovisual data and the annotations they create are similar to the documents in the `documents` list in that they could be the starting point for a text processing chain. For example, Tesseract can take a bounding box in an image and generate text from it and a Named Entity Recognition (NER) component can take the text and extract entities, just like it would from a transcript or other text document in the `documents` list. + +Let's use an example of an image of a barking dog where a region of the image has been recognized by the EAST application as an image box containing text (image taken from [http://clipart-library.com/dog-barking-clipart.html](http://clipart-library.com/dog-barking-clipart.html)): + +yelp + +The result of this processing is a MMIF document with an image document and a view that contains a *BoundingBox* annotation where the bounding box has the `label` property set to "text": + +```json +{ + "documents": [ + { + "@type": "http://mmif.clams.ai/vocabulary/ImageDocument/v1", + "properties": { + "id": "m1", + "mime": "image/jpeg", + "location": "file:///var/archive/image-0012.jpg" } + } + ], + "views": [ + { + "id": "v1", + "metadata": { + "app": "http://mmif.clams.ai/apps/east/0.2.2", + "contains": { + "http://mmif.clams.ai/vocabulary/BoundingBox/v2": { + "document": "m1" } } + }, + "annotations": [ + { + "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb1", + "coordinates": [[10,20], [40,20], [10,30], [40,30]], + "label": "text" } + } + ] + } + ] +} +``` + +Tesseract will then add a view to this MMIF document that contains a text document as well as an *Alignment* type that specifies that the text document is aligned with the bounding box from view "v1". + +```json +{ + "id": "v2", + "metadata": { + "app": "http://mmif.clams.ai/apps/tesseract/0.2.2", + "contains": { + "http://mmif.clams.ai/vocabulary/TextDocument/v1" : {}, + "http://mmif.clams.ai/vocabulary/Alignment/v1": {} } + }, + "annotations": [ + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td1", + "text": { + "@value": "yelp" } } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "source": "v1:bb1", + "target": "td1" } + } + ] +} +``` + +The text document annotation is the same kind of objects as the text document objects in the toplevel `documents` property, it has the same type and uses the same properties. Notice also that the history of the text document, namely that it was derived from a particular bounding box in a particular image, can be traced via the alignment of the text document with the bounding box. + +An alternative for using an alignment would be to use a `textSource` property on the document or perhaps to reuse the `location` property. That would require less space, but would introduce another ways to align annotations. +{: .box-note} + +Now this text document can be input to language processing. An NER component will not do anything interesting with this text so let's say we have a semantic typing component that has *"dog-sound"* as one of its categories. That hypothetical semantic typing component would add a new view to the list. That semantic typing component would add a new view to the list: + +```json +{ + "id": "v3", + "metadata": { + "app": "http://mmif.clams.ai/apps/semantic-typer/0.2.4", + "contains": { + "http://vocab.lappsgrid.org/SemanticTag": { + "document": "v2:td1" } } + }, + "annotations": [ + { + "@type": "http://vocab.lappsgrid.org/SemanticTag", + "properties": { + "id": "st1", + "category": "dog-sound", + "start": 0, + "end": 4 } + } + ] +} +``` + +This view encodes that the span from character offset 0 to character offset 4 contains a semantic tag and that the category is "dog-sound". This type can be traced to *TextDocument* "td1" in view "v2" via the `document` metadata property, and from there to the bounding box in the image. + +See ["examples" section](#mmif-examples) with the MMIF examples for a more realistic and larger example. + +We are here abstracting away from how the actual processing would proceed since we are focusing on the representation. In short, the CLAMS platform knows what kind of input an application requires and it would now that an NLP application requires a *TextDocument* to run on and it knows how to find all instance of *TextDocument* in a MMIF file. +{: .box-note} + + + + +### Multiple text documents in a view + +The image with the dog in the previous section just had a bounding box for the part of the image with the word *yelp*, but there were three other image regions that could have been input to OCR as well. With more boxes we just add more text documents and more alignments, here shown for one additional box: + +```json +{ + "id": "v2", + "metadata": { + "app": "http://mmif.clams.ai/apps/tesseract/1.0.2", + "contains": { + "http://mmif.clams.ai/vocabulary/TextDocument/v1": {}, + "http://mmif.clams.ai/vocabulary/Alignment/v1": {} } + }, + "annotations": [ + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td1", + "text": { + "@value": "yelp" } } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "source": "v1:bb1", + "target": "td1" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td2", + "text": { + "@value": "woof" } } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "source": "v1:bb2", + "target": "td2" } + } + ] +} +``` + +This of course assumes that view "v1" has a bounding box identified by "v1:bb2". + +Now if you run the semantic tagger you would get tags with the category set to "dog-sound": + +```json +{ + "id": "v3", + "metadata": { + "app": "http://mmif.clams.ai/apps/semantic-typer/0.2.4", + "contains": { + "http://mmif.clams.ai/vocabulary/SemanticTag/v1": {} } + }, + "annotations": [ + { + "@type": "http://mmif.clams.ai/vocabulary/SemanticTag/v1", + "properties": { + "id": "st1", + "category": "dog-sound", + "document": "V2:td1", + "start": 0, + "end": 4 } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/SemanticTag/v1", + "properties": { + "id": "st2", + "category": "dog-sound", + "document": "V2:td2", + "start": 0, + "end": 4 } + } + ] +} +``` + +Notice how the document to which the *SemanticTag* annotations point is not expressed by the metadata `document` property but by individual `document` properties on each semantic tag. This is unavoidable when we have multiple text documents that can be input to language processing. + +The above glances over the problem that we need some way for Tesseract to know what bounding boxes to take. We can do that by either introducing some kind of type or use the `app` property in the metadata or maybe by introducing a subtype for BoundingBox like TextBox. In general, we may need to solve what we never really solved for LAPPS which is what view should be used as input for an application. +{: .box-note} + + + +## MMIF and the Vocabularies + +The structure of MMIF files is defined in the [schema](schema/mmif.json) and described in this document. But the semantics of what is expressed in the views are determined by the [CLAMS Vocabulary](vocabulary). Each annotation in a view has two fields: `@type` and `properties`. The value of the first one is typically an annotation type from the vocabulary. Here is a *BoundingBox* annotation as an example: + +```json +{ + "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb1", + "coordinates": [[0,0], [10,0], [0,10], [10,10]] + } +} +``` + +The value of `@type` refers to the URL [http://mmif.clams.ai/vocabulary/BoundingBox/v2](vocabulary/BoundingBox) which is a page in the published vocabulary. That page will spell out the definition of *BoundingBox* as well as list all properties defined for it, whether inherited or not. On the page we can see that `id` is a required property inherited from *Annotation* and that `coordinates` is a required property of *BoundingBox*. Both are expressed in the `properties` dictionary above. The page also says that there is an optional property `timePoint`, but it is not used above. + +You might also have noticed by now that these URL-formatted values to this key end with some version number (e.g. `/v1`), which is different from the version of this document. That is because each individual annotation type (and document type in `documents` list) has its own version independent of the MMIF version. The independent versioning of annotation types enables type checking mechanism in CLAMS pipelines. See [versioning notes](../versioning) for more details. + +As displayed in the vocabulary, annotation types are hierarchically structured with `is-a` inheritance relations. That is, all properties from a parent type are *inherited* to their children. The top-level type in the CLAMS vocabulary is [http://mmif.clams.ai/vocabulary/Annotation](vocabulary/Annotation), and it can be generally used for attaching a piece of information (annotation) to a source document, using `document` property to indicate the source document. If an annotation is specifically about (or derived from) a part of the document (for example, a certain sentence in the text or a certain area of the image, etc.), one should consider one of the *Annotation*'s children that can anchor to the part that suits semantics and purpose of the annotation. Again, the annotation object can (and probably should) use the `document` property with a source document identifier, as long as the type is a sub-type of the *Annotation*. We will see concrete examples in the below. + +The [http://mmif.clams.ai/vocabulary/Thing](vocabulary/Thing) type is designed only as a placeholder and is not intended to be used to represent actual annotations. +{: .box-note} + +The vocabulary also defines `metadata` properties. For example, the optional property `timeUnit` can be used for a *TimeFrame* to specify what unit is used for the start and end time points in instances of *TimeFrame*. This property is not expressed in the annotation but in the metadata of the view with the annotation type in the `contains` dictionary: + +As aforementioned, the *Annotation* type and its children can put the source document identifier in the `contains` dictionary, using `document` metadata property. Namely, there are two ways to express the source document of annotations: at individual object level or at the view level. Unless there is a good reason to specify document information for each and every annotation objects, using the view-level representation is recommended to save space when the MMIF is serialized to a JSON file. +{: .box-warning} + +```json +{ + "metadata": { + "app": "http://apps.clams.ai/some_time_segmentation_app/1.0.3", + "timestamp": "2020-05-27T12:23:45", + "contains": { + "http://mmif.clams.ai/vocabulary/TimeFrame/v3": { + "document": "m12", + "timeUnit": "milliseconds" } } + } +} +``` + +Annotations in a MMIF file often refer to the LAPPS Vocabulary at [http://vocab.lappsgrid.org](http://vocab.lappsgrid.org). In that case, the annotation type in `@type` will refer to a URL just as with CLAMS annotation types, the only difference is that the URL will be in the LAPPS Vocabulary. Properties and metadata properties of LAPPS annotation types are defined and used the same way as described above for CLAMS types. + +Using a LAPPS type is actually an instance of the more general notion that the value of `@type` can be any URL (actually, any IRI). You can use any annotation category defined elsewhere, for example, you can use categories defined by the creator of an application or categories from other vocabularies. Here is an example with a type from [https://schema.org](https://schema.org): + +```json +{ + "@type": "https://schema.org/Clip", + "properties": { + "id": "clip-29", + "actor": "Geena Davis" + } +} +``` + +This assumes that [https://schema.org/Clip](https://schema.org/Clip) defines all the features used in the `properties` dictionary. One little disconnect here is that in MMIF we insist on each annotation having an identifier in the `id` property and as it happens [https://schema.org](https://schema.org) does not define an `id` attribute, although it does define `identifier`. + +The CLAMS Platform does not require that a URL like [https://schema.org/Clip](https://schema.org/Clip) actually exists, but if it doesn't users of an application that creates the *Clip* type will not know exactly what the application creates. + + + +## MMIF Examples + +To finish off this document we provide some examples of complete MMIF documents: + + +| example | description | +| --------------------------------------------------------- | ------------------------------------------------------------ | +| [bars-tones-slates](samples/bars-tones-slates) | A couple of time frames and some minimal text processing on a transcript. | +| [east-tesseract-typing](samples/east-tesseract-typing) | EAST text box recognition followed by Tesseract OCR and semantic typing. | +| [segmenter-kaldi-ner](samples/segmenter-kaldi-ner) | Audio segmentation followed by Kaldi speech recognition and NER. | +| [everything](samples/everything) | A big MMIF example with various multimodal AI apps for video/audio as well as text. | + +Each example has some comments and a link to a raw JSON file. + +As we move along integrating new applications, other examples will be added with other kinds of annotation types. + diff --git a/docs/1.0.2/pi78oGjdT-annotated.jpg b/docs/1.0.2/pi78oGjdT-annotated.jpg new file mode 100644 index 0000000000000000000000000000000000000000..88875a55f27d8324e8018832af4d4300e0fad1bc GIT binary patch literal 13400 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 K|FZs?g<2Ucc+0sBOwHb4(_g< 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 + +In addition, there are three views, one created by EAST, one by Tesseract and one by a semantic typing component. We now give fragments of the four relevant parts of the MMIF file, each with some comments. + +To see the full example scroll down to the end or open the [raw json file](raw.json). + +### Fragment 1: the documents list + +```json +{ + "documents": [ + { + "@type": "http://mmif.clams.ai/vocabulary/ImageDocument/v1", + "properties": { + "id": "m1", + "mime": "image/jpg", + "location": "/var/archive/image-fido-barks.jpg" } + } + ] +} +``` +This is simply just a list with one *ImageDocument* which points at the file with the barking dog image. + +### Fragment 2: the EAST view + +Here are the metadata in this view: + +```json +{ + "app": "http://mmif.clams.ai/apps/east/0.2.1", + "contains": { + "http://mmif.clams.ai/1.0.2/BoundingBox": { + "timeUnit": "pixels", + "document": "m1" } } +} +``` + +It simply says that EAST created the view and that all bounding box annotations are over document "m1" using pixels as the unit. + +And here is the annotations list: + + +```json +[ + { + "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb1", + "coordinates": [[10,20], [40,20], [10,30], [40,30]], + "label": "text" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb2", + "coordinates": [[210,220], [240,220], [210,230], [240,230]], + "label": "text" } + } +] +``` + +EAST has found two text boxes: one for "Arf" and one for "yelp" (although after EAST runs we do not know yet what the actual text is). Text boxes are encoded simply by specifying what the type of the bounding box is. For the sake of a somewhat smaller example file we are assuming here that EAST does not find text boxes when the text slants down. Note also that the coordinates are made up and bear little relation to what the real coordinates are. + +### Fragment 3: the Tesseract view + +Metadata: + +```json +{ + "app": "http://mmif.clams.ai/apps/tesseract/0.2.1", + "contains": { + "http://mmif.clams.ai/0.1.0/vocabulary/TextDocument": {}, + "http://mmif.clams.ai/0.1.0/vocabulary/Alignment": {} } +} +``` + +Tesseract creates text documents from bounding boxes with type equal to "text" and creates alignment relations between the documents and the boxes. The interesting thing here is compared to the metadata for the view created by EAST is that here no *document* metadata property is defined. This is because neither *TextDocument* nor *Alignment* need to be directly anchored into a document. + +Annotations list: + +```json +[ + { + "@type": "http://mmif.clams.ai/0.1.0/vocabulary/TextDocument", + "properties": { + "id": "td1", + "text": { + "@value": "Arf" } } + }, + { + "@type": "http://mmif.clams.ai/0.1.0/vocabulary/Alignment", + "properties": { + "id": "a1", + "source": "v1:bb1", + "target": "td1" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td2", + "text": { + "@value": "yelp" } } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a2", + "source": "v1:bb2", + "target": "td2" } + } +] +``` + +The text documents just have identifiers and store the text, they themselves are not aware of where they came from. The alignments link the text documents to bounding boxes in the view created by EAST. + +### Fragment 4: the Semantic Typer view + +Metadata: + +```json +{ + "app": "http://mmif.clams.ai/apps/semantic-typer/0.2.4", + "contains": { + "http://mmif.clams.ai/vocabulary/SemanticTag/v1": {} }, +} + +``` + +Nothing spectacular here. Like the previous view no *document* property is used, but in this case it is because the semantic tags in the annotation list each refer to a different document. + +Annotations list: + +```json +[ + { + "@type": "http://mmif.clams.ai/vocabulary/SemanticTag/v1", + "properties": { + "id": "st1", + "category": "dog-sound", + "document": "V2:td1", + "start": 0, + "end": 4 } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/SemanticTag/v1", + "properties": { + "id": "st2", + "category": "dog-sound", + "document": "V2:td2", + "start": 0, + "end": 4 } + } +] +``` + +Now each annotation needs to have its own *document* property so we know what documents each semantic tag is anchored to. + + + +## Full MMIF File + +```json +{% include_relative raw.json %} +``` + diff --git a/docs/1.0.2/samples/east-tesseract-typing/raw.json b/docs/1.0.2/samples/east-tesseract-typing/raw.json new file mode 100644 index 00000000..cbeaea0d --- /dev/null +++ b/docs/1.0.2/samples/east-tesseract-typing/raw.json @@ -0,0 +1,124 @@ +{ + "metadata": { + "mmif": "http://mmif.clams.ai/1.0.2" + }, + "documents": [ + { + "@type": "http://mmif.clams.ai/vocabulary/ImageDocument/v1", + "properties": { + "id": "m1", + "mime": "image/jpeg", + "location": "file:///var/archive/image-fido-barks.jpg" + } + } + ], + "views": [ + { + "id": "v1", + "metadata": { + "app": "http://mmif.clams.ai/apps/east/0.2.1", + "contains": { + "http://mmif.clams.ai/vocabulary/BoundingBox/v2": { + "timeUnit": "pixels", + "document": "m1" + } + } + }, + "annotations": [ + { + "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb1", + "coordinates": [ [10, 20], [40, 20], [10, 30], [40, 30] ], + "label": "text" + } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb2", + "coordinates": [ [210, 220], [240, 220], [210, 230], [240, 230] ], + "label": "text" + } + } + ] + }, + { + "id": "v2", + "metadata": { + "app": "http://mmif.clams.ai/apps/tesseract/0.2.1", + "contains": { + "http://mmif.clams.ai/0.1.0/TextDocument": {}, + "http://mmif.clams.ai/0.1.0/Alignment": {} + } + }, + "annotations": [ + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td1", + "text": { + "@value": "Arf" + } + } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a1", + "source": "v1:bb1", + "target": "td1" + } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td2", + "text": { + "@value": "yelp" + } + } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a2", + "source": "v1:bb2", + "target": "td2" + } + } + ] + }, + { + "id": "v3", + "metadata": { + "app": "http://mmif.clams.ai/apps/semantic-typer/0.2.4", + "contains": { + "http://mmif.clams.ai/vocabulary/SemanticTag/v1": {} + } + }, + "annotations": [ + { + "@type": "http://mmif.clams.ai/vocabulary/SemanticTag/v1", + "properties": { + "id": "st1", + "category": "dog-sound", + "document": "V2:td1", + "start": 0, + "end": 4 + } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/SemanticTag/v1", + "properties": { + "id": "st2", + "category": "dog-sound", + "document": "V2:td2", + "start": 0, + "end": 4 + } + } + ] + } + ] +} diff --git a/docs/1.0.2/samples/everything/images/newshour-loud-dogs.jpg b/docs/1.0.2/samples/everything/images/newshour-loud-dogs.jpg new file mode 100644 index 0000000000000000000000000000000000000000..6c7c3cadbfe259d5a9bdb3f7a53afe3aea8b4181 GIT binary patch literal 130723 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 literal 0 HcmV?d00001 diff --git a/docs/1.0.2/samples/everything/index.md b/docs/1.0.2/samples/everything/index.md new file mode 100644 index 00000000..91cf3756 --- /dev/null +++ b/docs/1.0.2/samples/everything/index.md @@ -0,0 +1,236 @@ +--- +layout: page +title: MMIF Specification +subtitle: Version 1.0.2 +--- + +# Example: Everything and the kitchen sink + +To see the full example scroll down to the end or open the [raw json file](raw.json). + +This is an example with a bunch of different annotations created by a variety of tools. For the input we have a short totally made up video which starts with some bars-and-tone and a simple slate. Those are followed by about a dozen seconds of a talking head followed by an image of a barking dog. + + + +The timeline includes markers for seconds. In the views below all anchors will be using milliseconds. + +We apply the following processing tools: + +1. Bars-and-tone extraction +1. Slate extraction +1. Audio segmentation +1. Kaldi speech recognition and alignment +1. EAST text box recognition +1. Tesseract OCR +1. Named entity recognition +1. Slate parsing + +Following now are short explanations of some frgaments of the full MMIF file, some application output was explained in more detail in other examples, refer to those for more details. + +### Extracting time frames + +The first three steps are straightforward and all result in views with time frame annotations (views with id=v1, id=v2 and id=v3). The bars-and-tone and slate extraction applications each find one time frame and the audio segmenter finds two segments with the second one being a speech time frame that starts at about 5500ms from the start. + +```json +{ + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf2", + "frameType": "speech", + "start": 5500, + "end": 22000 } +} +``` + +This time frame will provide the input to Kaldi. + +### Kaldi speech recognition + +Kaldi creates one view (with id=v4) which has + +- a text document +- an alignment of that document with the speech time frame from the segmenter +- a list of tokens for the document +- a list of time frames corresponding to each token +- a list of alignments between the tokens and the time frames + +In the metadata it spells out that the offsets of all tokens are taken to be offsets in "td1", which is a text document in the same view. We can do this instead of the alternative (using the *document* property on all tokens) because all tokens are for the same text document. + +```json +{ + "app": "http://mmif.clams.ai/apps/kaldi/0.2.1", + "contains": { + "http://mmif.clams.ai/vocabulary/TextDocument/v1": {}, + "http://vocab.lappsgrid.org/Token": { + "document": "td1" }, + "http://mmif.clams.ai/vocabulary/TimeFrame/v3": { + "timeUnit": "milliseconds", + "document": "m1" }, + "http://mmif.clams.ai/vocabulary/Alignment/v1": {} + } +} +``` + +Note that a text document can refer to its text by either using the *text* property which contains the text verbatim or by referring to an external file using the *location* property, here we use the second approach: + +```json +{ + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td1", + "mime": "text/plain", + "location": "/var/processed/transcript-002.txt" } +} +``` + +For the sake of argument we assume perfect speech recognition, and the content of the external file is as follows. + +> Hello, this is Jim Lehrer with the NewsHour on PBS. In the nineteen eighties, barking dogs have increasingly become a problem in urban areas. + +This text is aligned with the second time frame from the segmenter. + +```json +{ + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a1", + "source": "v3:tf2", + "target": "td1" } +} +``` + +See the full example below for all the tokens, time frames for each token and the alignment between the token and the time frame. + +### EAST and Tesseract + +EAST adds bounding boxes anchored to the video document with id=m1: + +```json +{ + "app": "http://mmif.clams.ai/apps/east/0.2.1", + "contains": { + "http://mmif.clams.ai/1.0.2/BoundingBox": { "document": "m1" } +} +``` + +Let's assume that EAST runs on frames sampled from the video at 1 second intervals. For our example that means that EAST finds boxes at time offsets 3, 4, 5 and 21 seconds. Let's assume decent performance where EAST finds all the boxes in the slate and just the caption in the image (but not the barking sounds). Here is one example box annotation: + +```json +{ + "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb9", + "timePoint": 4000, + "coordinates": [[180, 110], [460, 110], [180, 170], [460, 170]], + "label": "text" } +} +``` + +Due to the nature of the input many of the bounding boxes will have identical or near-identical coordinates. For example, there are two more bounding boxes with the coordinates above, one for the box with time offset 3000 and one for the box with time offset 5000. + +Tesseract now runs on all those boxes and creates a text document for each of them. In doing so, it will add these to a new view: +* text documents from each text box +* alignment of that documents to their originating boxes + +Thus, the metadata of the new view would be: + + +```json +{ + "app": "http://mmif.clams.ai/apps/tesseract/0.4.4", + "contains": { + "http://mmif.clams.ai/vocabulary/TextDocument/v1": {}, + "http://mmif.clams.ai/vocabulary/Alignment/v1": { + "sourceType": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "targetType": "http://mmif.clams.ai/vocabulary/BoundingBox/v2" + } + } +} +``` + +Unlike the alignment annotations in the Kaldi view, Tesseract specifies types of both ends of the alignments in the `contains` metadata. This is only allowed because all alignment annotations in the view have the same source type and target types. This information can help, for example, machines search for certain alignments more quickly. +{: .box-note} + +Now the recognition results are recorded as text documents, here's one: + +```json +{ + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td1", + "text": { "@value": "DATE" } } +} +``` + +And here is the corresponding alignment from the bounding box to the text document: + +```json +{ + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a1", + "source": "v5:bb1", + "target": "td1" } +} +``` + +The source is in another view, hence the prefix on the identifier. + +### Named entity recognition + +After Kaldi and Tesseract have added text documents we now have all text extracted from audiovisual elements and we can run NLP tools like named entity recognizers over them. Each entity annotation refers to a text document, either the one in the Kaldi view or one of the documents in the Tesseract view, this examples refers to one of the documents in the Tesseract view: + +```json +{ + "@type": "http://vocab.lappsgrid.org/NamedEntity", + "properties": { + "id": "ne1", + "document": "v6:td2", + "start": 0, + "end": 10, + "category": "Date", + "text": "1982-05-12" } +} +``` + +Note that since there were three text boxes with the date and therefore three documents with the actual text, there are also three named entities for this date. + +### Slate parsing + +This section is somewhat speculative since we have not yet made any decisions on what the output of a slate paser will look like. + +Slate parsing applies to frames in the slate segment found in the slate view (id=v2) and uses several kinds of information obtained from two or three other views: + +- The EAST view has text bounding boxes with coordinates for all those boxes. +- The Tesseract view has the text values for all those boxes. +- The NER view has named entity classes for some of those text values, which may in some cases be useful for slate parsing. + +A minimal option for the slate parser is to create a particular semantic tag dat describes value fields in a slate. For that it may use the the category of the named entity that is anchored to the field or the text in adjacent field. For example, if we have the text "1982-05-12" and we know it was tagged as a *Date* then this may indicate that that value is the air time of the video. Similary, if that value occurs next to a text that has the text "DATE" in it we may also derive that the value was a *Date*. + +Here is the tag annotation on the same document as the named entity annotation above: + +```json +{ + "@type": "http://vocab.lappsgrid.org/SemanticTag", + "properties": { + "id": "st1", + "document": "v6:td2", + "start": 0, + "end": 10, + "tagName": "Date", + "text": "1982-05-12" } +} +``` + +Note that the *tagName* property has the same value as the *category* property on the named entity. This is a coincidence in that there is a named entity category *Date* as well as a slate category *Date*. + +Similar to what we saw for the named entities, there will be multiple versions of this data tag due to multiple text boxes with the same text. + + +## Full MMIF File + +```json +{% include_relative raw.json %} +``` + + diff --git a/docs/1.0.2/samples/everything/pbcore.md b/docs/1.0.2/samples/everything/pbcore.md new file mode 100644 index 00000000..9fa246e4 --- /dev/null +++ b/docs/1.0.2/samples/everything/pbcore.md @@ -0,0 +1,144 @@ +# MMIF and PBCore + +Some notes on the mappings of elements from the MMIF file in the "everything and the kitched sink" example to PBCore (see [index.md](index) and [raw.json](raw.json)). + +The relevant information that we have in MMIF is in the following types: + +1. Instances of *TimeFrame* with frameType "bars-and-tone" or "slate". These directly refer back to time slices in the video. +2. Instances of *SemanticTag* with tagName "Date", "Title", "Host" or "Producer". These can be traced back to the part of the video where the information was obtained (that is, the location of the slate), but this is not needed here because it is not required by PBCore (or even allowed in the PBCore elements that we would be using). +3. Instances of *NamedEntity* with category "Person", "Location" or "Organization". These do need to be traced back because we want to index on the locations in the video where a subject occurs. + +Tracing back to the source location requires some processing because while the information is available in the MMIF file it is not explicitly stated in the *NamedEntity* annotation. + +A note on collaboration on this. The CLAMS team could do one of the following: + +1. Provide code and an API that makes it easy to get the information from a MMIF file that is needed. +2. Create code that extracts the needed in formation from a MMIF file and outputs it in some kind of generic format. +3. Create code that extracts the information and creates PBCore output. + +Most of the work is in item 1 and that would be the minimal thing to do for CLAMS, but this document assumes for now that the CLAMS team also creates PBCore output. + +### Mappings from MMIF to PBCore + +The PBCore to be created has a top-level *pbcoreDescriptionDocument* element: + +```xml + + +``` + +Within this top-level element we may add the following sub elements: *pbcoreAssetDate*, *pbcoreTitle*, *pbcoreContributor*, *pbcoreSubject*, *pbcoreAnnotation* and *pbcoreDescription*. The examples below for the MMIF example file [raw.json](raw.json) are based on the descriptions in [http://pbcore.org/elements](http://pbcore.org/elements) and feedback from Kevin. + +To map the MMIF time frames we need a need an element that allows us to express the type and the start and end times. The only one I can see that is not obviously intended for other uses is *pbcoreDescription* (in an earlier version of this document I used *pbcorePart* which is really not appropriate). + +```xml + + +``` + +Instead of *descriptionType* it may be more appropriate to use *segmentType*, but from the descriptions given in [http://pbcore.org/elements/pbcoredescription](http://pbcore.org/elements/pbcoredescription) it is not really clear to me which one is best. Another question I have is whether the attribute values for start and end can be milliseconds from the beginning of the video. + +It was suggested that as an alternative we could use *instantiationTimeStart*, which can be repetaed: + +```xml +0 +2600 +2700 +5300 +``` + +This looks rather forced to me and would also require using a *pbcoreInstantiationDocument* toplevel tag I think, so I will for now dismiss this summarily. + +The semantic tags in MMIF have direct and unproblematic mappings to PBCore elements: + +Date → pbcoreAssetDate +Title → pbcoreTitle +Host → pbcoreContributor +Producer → pbcoreContributor + +```xml +1982-05-12 +``` + +```xml +Loud Dogs +``` + +```xml + + Jim Lehrer + Host + +``` + +```xml + + Sara Just + Producer + +``` + +For the named entities we can use *pbcoreSubject*: + +```xml +Jim Lehrer +``` + +```xml +PBS +``` + +```xml +New York +``` + +I am not sure how to spin the attributes so this here is my best guesstimate. Note that "Jim Lehrer" shows up both as a contributor and as a subject, the former because he was mentioned in the slate and the latter because his name was used in the transcript. + +The subject type is the entity category for all of these and the *ref* property is used to refer to some external authoritative source. + +Start and end time are in milliseconds. For the first two they are generated by finding the tokens in the transcript text documents (by comparing start and end character offsets) and then tracking those to the time frames that they are aligned with. + +For the third, we know the named entity occurs in some text document (created by Tesseract) and we track that document to the bounding box generated by EAST that the document is aligned with. That bounding box has a *timePoint* attribute that is used for both start and end time. Note that if there had be a second text box for the "Dog in New York" text (that is, if the time the image was displayed on screen was a little bit longer) then that box would have its own time point and the end time for "New York" would have been 22000. + +It is possible that there may be many instantiations of *pbcoreSubject*, for example for a common entity like Boston. There is some unease on having multiple elements for a single named entity, but it is not clear what to do about it (use other element? only have one instance?). For now, we will dump all entities in PBCore subject elements and see how that pans out. In general, it seems fairly easy to export relevant information from MMIF into PBCore without loss of information, and what is exported and what the exact landing spots are going to be can be driven by PBCore-specific reasons. + +Finally, here is all the above in one XML file, adding some identifier that we get from the input: + +```xml + + + 1982-05-12 + + SOME_ID + + Loud Dogs + + Jim Lehrer + + PBS + + New York + + + + + + + Jim Lehrer + Host + + + + Sara Just + Producer + + + +``` + diff --git a/docs/1.0.2/samples/everything/raw.json b/docs/1.0.2/samples/everything/raw.json new file mode 100644 index 00000000..f6e21787 --- /dev/null +++ b/docs/1.0.2/samples/everything/raw.json @@ -0,0 +1,1563 @@ +{ + + "metadata": { + "mmif": "http://mmif.clams.ai/1.0.2" + }, + + "documents": [ + { + "@type": "http://mmif.clams.ai/vocabulary/VideoDocument/v1", + "properties": { + "id": "m1", + "mime": "video/mpeg", + "location": "file:///var/archive/video-002.mp4" } + } + ], + + "views": [ + + { + "id": "v1", + "metadata": { + "app": "http://apps.clams.ai/bars-and-tones/1.0.5", + "timestamp": "2020-05-27T12:23:45", + "contains": { + "http://mmif.clams.ai/vocabulary/TimeFrame/v3": { + "document": "m1", + "timeUnit": "milliseconds" } + } + }, + "annotations": [ + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "s1", + "start": 0, + "end": 2600, + "frameType": "bars-and-tones" } + } + ] + }, + + { + "id": "v2", + "metadata": { + "app": "http://apps.clams.ai/slates/1.0.3", + "timestamp": "2020-05-27T12:23:45", + "contains": { + "http://mmif.clams.ai/vocabulary/TimeFrame/v3": { + "document": "m1", + "timeUnit": "milliseconds" } + } + }, + "annotations": [ + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "s1", + "start": 2700, + "end": 5300, + "frameType": "slate" } + } + ] + }, + + { + "id": "v3", + "metadata": { + "app": "http://mmif.clams.ai/apps/audio-segmenter/0.2.1", + "contains": { + "http://mmif.clams.ai/vocabulary/TimeFrame/v3": { + "timeUnit": "milliseconds", + "document": "m1" } + } + }, + "annotations": [ + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "frameType": "non-speech", + "id": "tf1", + "start": 0, + "end": 5500 } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf2", + "frameType": "speech", + "start": 5500, + "end": 22000 } + } + ] + }, + + { + "id": "v4", + "metadata": { + "app": "http://mmif.clams.ai/apps/kaldi/0.2.1", + "contains": { + "http://mmif.clams.ai/vocabulary/TextDocument/v1": {}, + "http://vocab.lappsgrid.org/Token": { + "document": "td1" }, + "http://mmif.clams.ai/vocabulary/TimeFrame/v3": { + "timeUnit": "milliseconds", + "document": "m1" }, + "http://mmif.clams.ai/vocabulary/Alignment/v1": {} + } + }, + "annotations": [ + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td1", + "mime": "text/plain", + "location": "file:///var/archive/transcript-002.txt" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a1", + "source": "v3:tf1", + "target": "td1" } + }, + { + "@type": "http://vocab.lappsgrid.org/Token", + "properties": { + "id": "t1", + "start": 0, + "end": 5, + "text": "Hello" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf1", + "start": 5500, + "end": 6085 } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a2", + "source": "tf1", + "target": "t1" } + }, + { + "@type": "http://vocab.lappsgrid.org/Token", + "properties": { + "id": "t2", + "start": 5, + "end": 6, + "text": "," } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf2", + "start": 6085, + "end": 6202 } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a3", + "source": "tf2", + "target": "t2" } + }, + { + "@type": "http://vocab.lappsgrid.org/Token", + "properties": { + "id": "t3", + "start": 7, + "end": 11, + "text": "this" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf3", + "start": 6319, + "end": 6787 } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a4", + "source": "tf3", + "target": "t3" } + }, + { + "@type": "http://vocab.lappsgrid.org/Token", + "properties": { + "id": "t4", + "start": 12, + "end": 14, + "text": "is" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf4", + "start": 6904, + "end": 7138 } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a5", + "source": "tf4", + "target": "t4" } + }, + { + "@type": "http://vocab.lappsgrid.org/Token", + "properties": { + "id": "t5", + "start": 15, + "end": 18, + "text": "Jim" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf5", + "start": 7255, + "end": 7606 } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a6", + "source": "tf5", + "target": "t5" } + }, + { + "@type": "http://vocab.lappsgrid.org/Token", + "properties": { + "id": "t6", + "start": 19, + "end": 25, + "text": "Lehrer" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf6", + "start": 7723, + "end": 8425 } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a7", + "source": "tf6", + "target": "t6" } + }, + { + "@type": "http://vocab.lappsgrid.org/Token", + "properties": { + "id": "t7", + "start": 26, + "end": 30, + "text": "with" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf7", + "start": 8542, + "end": 9010 } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a8", + "source": "tf7", + "target": "t7" } + }, + { + "@type": "http://vocab.lappsgrid.org/Token", + "properties": { + "id": "t8", + "start": 31, + "end": 34, + "text": "the" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf8", + "start": 9127, + "end": 9478 } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a9", + "source": "tf8", + "target": "t8" } + }, + { + "@type": "http://vocab.lappsgrid.org/Token", + "properties": { + "id": "t9", + "start": 35, + "end": 43, + "text": "NewsHour" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf9", + "start": 9595, + "end": 10531 } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a10", + "source": "tf9", + "target": "t9" } + }, + { + "@type": "http://vocab.lappsgrid.org/Token", + "properties": { + "id": "t10", + "start": 44, + "end": 46, + "text": "on" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf10", + "start": 10648, + "end": 10882 } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a11", + "source": "tf10", + "target": "t10" } + }, + { + "@type": "http://vocab.lappsgrid.org/Token", + "properties": { + "id": "t11", + "start": 47, + "end": 50, + "text": "PBS" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf11", + "start": 10999, + "end": 11350 } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a12", + "source": "tf11", + "target": "t11" } + }, + { + "@type": "http://vocab.lappsgrid.org/Token", + "properties": { + "id": "t12", + "start": 50, + "end": 51, + "text": "." } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf12", + "start": 11350, + "end": 11467 } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a13", + "source": "tf12", + "target": "t12" } + }, + { + "@type": "http://vocab.lappsgrid.org/Token", + "properties": { + "id": "t13", + "start": 52, + "end": 54, + "text": "In" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf13", + "start": 11584, + "end": 11818 } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a14", + "source": "tf13", + "target": "t13" } + }, + { + "@type": "http://vocab.lappsgrid.org/Token", + "properties": { + "id": "t14", + "start": 55, + "end": 58, + "text": "the" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf14", + "start": 11935, + "end": 12286 } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a15", + "source": "tf14", + "target": "t14" } + }, + { + "@type": "http://vocab.lappsgrid.org/Token", + "properties": { + "id": "t15", + "start": 59, + "end": 67, + "text": "nineteen" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf15", + "start": 12403, + "end": 13339 } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a16", + "source": "tf15", + "target": "t15" } + }, + { + "@type": "http://vocab.lappsgrid.org/Token", + "properties": { + "id": "t16", + "start": 68, + "end": 76, + "text": "eighties" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf16", + "start": 13456, + "end": 14392 } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a17", + "source": "tf16", + "target": "t16" } + }, + { + "@type": "http://vocab.lappsgrid.org/Token", + "properties": { + "id": "t17", + "start": 76, + "end": 77, + "text": "," } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf17", + "start": 14392, + "end": 14509 } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a18", + "source": "tf17", + "target": "t17" } + }, + { + "@type": "http://vocab.lappsgrid.org/Token", + "properties": { + "id": "t18", + "start": 78, + "end": 85, + "text": "barking" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf18", + "start": 14626, + "end": 15445 } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a19", + "source": "tf18", + "target": "t18" } + }, + { + "@type": "http://vocab.lappsgrid.org/Token", + "properties": { + "id": "t19", + "start": 86, + "end": 90, + "text": "dogs" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf19", + "start": 15562, + "end": 16030 } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a20", + "source": "tf19", + "target": "t19" } + }, + { + "@type": "http://vocab.lappsgrid.org/Token", + "properties": { + "id": "t20", + "start": 91, + "end": 95, + "text": "have" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf20", + "start": 16147, + "end": 16615 } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a21", + "source": "tf20", + "target": "t20" } + }, + { + "@type": "http://vocab.lappsgrid.org/Token", + "properties": { + "id": "t21", + "start": 96, + "end": 108, + "text": "increasingly" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf21", + "start": 16732, + "end": 18136 } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a22", + "source": "tf21", + "target": "t21" } + }, + { + "@type": "http://vocab.lappsgrid.org/Token", + "properties": { + "id": "t22", + "start": 109, + "end": 115, + "text": "become" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf22", + "start": 18253, + "end": 18955 } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a23", + "source": "tf22", + "target": "t22" } + }, + { + "@type": "http://vocab.lappsgrid.org/Token", + "properties": { + "id": "t23", + "start": 116, + "end": 117, + "text": "a" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf23", + "start": 19072, + "end": 19189 } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a24", + "source": "tf23", + "target": "t23" } + }, + { + "@type": "http://vocab.lappsgrid.org/Token", + "properties": { + "id": "t24", + "start": 118, + "end": 125, + "text": "problem" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf24", + "start": 19306, + "end": 20125 } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a25", + "source": "tf24", + "target": "t24" } + }, + { + "@type": "http://vocab.lappsgrid.org/Token", + "properties": { + "id": "t25", + "start": 126, + "end": 128, + "text": "in" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf25", + "start": 20242, + "end": 20476 } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a26", + "source": "tf25", + "target": "t25" } + }, + { + "@type": "http://vocab.lappsgrid.org/Token", + "properties": { + "id": "t26", + "start": 129, + "end": 134, + "text": "urban" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf26", + "start": 20593, + "end": 21178 } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a27", + "source": "tf26", + "target": "t26" } + }, + { + "@type": "http://vocab.lappsgrid.org/Token", + "properties": { + "id": "t27", + "start": 135, + "end": 140, + "text": "areas" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf27", + "start": 21295, + "end": 21880 } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a28", + "source": "tf27", + "target": "t27" } + }, + { + "@type": "http://vocab.lappsgrid.org/Token", + "properties": { + "id": "t28", + "start": 140, + "end": 141, + "text": "." } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf28", + "start": 21880, + "end": 21997 } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a29", + "source": "tf28", + "target": "t28" } + } + ] + }, + + { + "id": "v5", + "metadata": { + "app": "http://mmif.clams.ai/apps/east/0.2.1", + "contains": { + "http://mmif.clams.ai/vocabulary/BoundingBox/v2": { + "document": "m1" } + } + }, + "annotations": [ + { + "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb1", + "timePoint": 3000, + "coordinates": [[180, 110], [460, 110], [180, 170], [460, 170]], + "label": "text" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb2", + "timePoint": 3000, + "coordinates": [[660, 110], [1250, 110], [660, 170], [1250, 170]], + "label": "text" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb3", + "timePoint": 3000, + "coordinates": [[180, 320], [460, 320], [180, 380], [460, 380]], + "label": "text" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb4", + "timePoint": 3000, + "coordinates": [[660, 320], [1210, 320], [660, 380], [1210, 380]], + "label": "text" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb5", + "timePoint": 3000, + "coordinates": [[180, 520], [460, 520], [180, 580], [460, 580]], + "label": "text" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb6", + "timePoint": 3000, + "coordinates": [[660, 520], [1200, 520], [660, 580], [1200, 580]], + "label": "text" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb7", + "timePoint": 3000, + "coordinates": [[180, 750], [470, 750], [180, 810], [470, 810]], + "label": "text" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb8", + "timePoint": 3000, + "coordinates": [[660, 750], [1180, 750], [660, 810], [1180, 810]], + "label": "text" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb9", + "timePoint": 4000, + "coordinates": [[180, 110], [460, 110], [180, 170], [460, 170]], + "label": "text" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb10", + "timePoint": 4000, + "coordinates": [[660, 110], [1250, 110], [660, 170], [1250, 170]], + "label": "text" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb11", + "timePoint": 4000, + "coordinates": [[180, 320], [460, 320], [180, 380], [460, 380]], + "label": "text" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb12", + "timePoint": 4000, + "coordinates": [[660, 320], [1210, 320], [660, 380], [1210, 380]], + "label": "text" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb13", + "timePoint": 4000, + "coordinates": [[180, 520], [460, 520], [180, 580], [460, 580]], + "label": "text" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb14", + "timePoint": 4000, + "coordinates": [[660, 520], [1200, 520], [660, 580], [1200, 580]], + "label": "text" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb15", + "timePoint": 4000, + "coordinates": [[180, 750], [470, 750], [180, 810], [470, 810]], + "label": "text" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb16", + "timePoint": 4000, + "coordinates": [[660, 750], [1180, 750], [660, 810], [1180, 810]], + "label": "text" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb17", + "timePoint": 5000, + "coordinates": [[180, 110], [460, 110], [180, 170], [460, 170]], + "label": "text" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb18", + "timePoint": 5000, + "coordinates": [[660, 110], [1250, 110], [660, 170], [1250, 170]], + "label": "text" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb19", + "timePoint": 5000, + "coordinates": [[180, 320], [460, 320], [180, 380], [460, 380]], + "label": "text" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb20", + "timePoint": 5000, + "coordinates": [[660, 320], [1210, 320], [660, 380], [1210, 380]], + "label": "text" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb21", + "timePoint": 5000, + "coordinates": [[180, 520], [460, 520], [180, 580], [460, 580]], + "label": "text" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb22", + "timePoint": 5000, + "coordinates": [[660, 520], [1200, 520], [660, 580], [1200, 580]], + "label": "text" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb23", + "timePoint": 5000, + "coordinates": [[180, 750], [470, 750], [180, 810], [470, 810]], + "label": "text" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb24", + "timePoint": 5000, + "coordinates": [[660, 750], [1180, 750], [660, 810], [1180, 810]], + "label": "text" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/BoundingBox/v2", + "properties": { + "id": "bb25", + "timePoint": 21000, + "coordinates": [[150, 810], [1120, 810], [150, 870], [1120, 870]], + "label": "text" } + } + ] + }, + + { + "id": "v6", + "metadata": { + "app": "http://mmif.clams.ai/apps/tesseract/0.2.1", + "contains": { + "http://mmif.clams.ai/vocabulary/TextDocument/v1": {}, + "http://mmif.clams.ai/vocabulary/Alignment/v1": { + "sourceType": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "targetType": "http://mmif.clams.ai/vocabulary/BoundingBox/v2" + } + } + }, + "annotations": [ + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td1", + "text": { "@value": "DATE" } } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a1", + "source": "v5:bb1", + "target": "td1" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td2", + "text": { "@value": "1982-05-12" } } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a2", + "source": "v5:bb2", + "target": "td2" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td3", + "text": { "@value": "TITLE" } } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a3", + "source": "v5:bb3", + "target": "td3" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td4", + "text": { "@value": "Loud Dogs" } } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a4", + "source": "v5:bb4", + "target": "td4" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td5", + "text": { "@value": "HOST" } } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a5", + "source": "v5:bb5", + "target": "td5" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td6", + "text": { "@value": "Jim Lehrer" } } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a6", + "source": "v5:bb6", + "target": "td6" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td7", + "text": { "@value": "PROD" } } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a7", + "source": "v5:bb7", + "target": "td7" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td8", + "text": { "@value": "Sara Just" } } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a8", + "source": "v5:bb8", + "target": "td8" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td9", + "text": { "@value": "DATE" } } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a9", + "source": "v5:bb9", + "target": "td9" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td10", + "text": { "@value": "1982-05-12" } } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a10", + "source": "v5:bb10", + "target": "td10" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td11", + "text": { "@value": "TITLE" } } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a11", + "source": "v5:bb11", + "target": "td11" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td12", + "text": { "@value": "Loud Dogs" } } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a12", + "source": "v5:bb12", + "target": "td12" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td13", + "text": { "@value": "HOST" } } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a13", + "source": "v5:bb13", + "target": "td13" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td14", + "text": { "@value": "Jim Lehrer" } } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a14", + "source": "v5:bb14", + "target": "td14" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td15", + "text": { "@value": "PROD" } } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a15", + "source": "v5:bb15", + "target": "td15" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td16", + "text": { "@value": "Sara Just" } } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a16", + "source": "v5:bb16", + "target": "td16" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td17", + "text": { "@value": "DATE" } } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a17", + "source": "v5:bb17", + "target": "td17" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td18", + "text": { "@value": "1982-05-12" } } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a18", + "source": "v5:bb18", + "target": "td18" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td19", + "text": { "@value": "TITLE" } } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a19", + "source": "v5:bb19", + "target": "td19" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td20", + "text": { "@value": "Loud Dogs" } } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a20", + "source": "v5:bb20", + "target": "td20" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td21", + "text": { "@value": "HOST" } } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a21", + "source": "v5:bb21", + "target": "td21" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td22", + "text": { "@value": "Jim Lehrer" } } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a22", + "source": "v5:bb22", + "target": "td22" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td23", + "text": { "@value": "PROD" } } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a23", + "source": "v5:bb23", + "target": "td23" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td24", + "text": { "@value": "Sara Just" } } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a24", + "source": "v5:bb24", + "target": "td24" } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td25", + "text": { "@value": "Dog in New York" } } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a25", + "source": "v5:bb25", + "target": "td25" } + } + ] + }, + + { + "id": "v7", + "metadata": { + "app": "http://apps.clams.ai/spacy-ner/0.2.1", + "contains": { + "http://vocab.lappsgrid.org/NamedEntity": {} + } + }, + "annotations": [ + { + "@type": "http://vocab.lappsgrid.org/NamedEntity", + "properties": { + "id": "ne1", + "document": "v6:td2", + "start": 0, + "end": 10, + "category": "Date", + "text": "1982-05-12" } + }, + { + "@type": "http://vocab.lappsgrid.org/NamedEntity", + "properties": { + "id": "ne2", + "document": "v6:td6", + "start": 0, + "end": 10, + "category": "Person", + "text": "Jim Lehrer" } + }, + { + "@type": "http://vocab.lappsgrid.org/NamedEntity", + "properties": { + "id": "ne3", + "document": "v6:td8", + "start": 0, + "end": 9, + "category": "Person", + "text": "Sara Just" } + }, + { + "@type": "http://vocab.lappsgrid.org/NamedEntity", + "properties": { + "id": "ne4", + "document": "v6:td10", + "start": 0, + "end": 10, + "category": "Date", + "text": "1982-05-12" } + }, + { + "@type": "http://vocab.lappsgrid.org/NamedEntity", + "properties": { + "id": "ne5", + "document": "v6:td14", + "start": 0, + "end": 10, + "category": "Person", + "text": "Jim Lehrer" } + }, + { + "@type": "http://vocab.lappsgrid.org/NamedEntity", + "properties": { + "id": "ne6", + "document": "v6:td16", + "start": 0, + "end": 9, + "category": "Person", + "text": "Sara Just" } + }, + { + "@type": "http://vocab.lappsgrid.org/NamedEntity", + "properties": { + "id": "ne7", + "document": "v6:td18", + "start": 0, + "end": 10, + "category": "Date", + "text": "1982-05-12" } + }, + { + "@type": "http://vocab.lappsgrid.org/NamedEntity", + "properties": { + "id": "ne8", + "document": "v6:td22", + "start": 0, + "end": 10, + "category": "Person", + "text": "Jim Lehrer" } + }, + { + "@type": "http://vocab.lappsgrid.org/NamedEntity", + "properties": { + "id": "ne9", + "document": "v6:td24", + "start": 0, + "end": 9, + "category": "Person", + "text": "Sara Just" } + }, + { + "@type": "http://vocab.lappsgrid.org/NamedEntity", + "properties": { + "id": "ne10", + "document": "v6:td25", + "start": 7, + "end": 15, + "category": "Location", + "text": "New York" } + }, + { + "@type": "http://vocab.lappsgrid.org/NamedEntity", + "properties": { + "id": "ne11", + "document": "v4:td1", + "start": 15, + "end": 25, + "category": "Person", + "text": "Jim Lehrer" } + }, + { + "@type": "http://vocab.lappsgrid.org/NamedEntity", + "properties": { + "id": "ne12", + "document": "v4:td1", + "start": 47, + "end": 50, + "category": "Organization", + "text": "PBS" } + } + ] + }, + + { + "id": "v8", + "metadata": { + "app": "http://apps.clams.ai/slate-parser/1.0.2", + "timestamp": "2020-05-27T12:23:45", + "contains": { + "http://vocab.lappsgrid.org/SemanticTag": {} + } + }, + "annotations": [ + { + "@type": "http://vocab.lappsgrid.org/SemanticTag", + "properties": { + "id": "st1", + "document": "v6:td2", + "start": 0, + "end": 10, + "tagName": "Date", + "text": "1982-05-12" } + }, + { + "@type": "http://vocab.lappsgrid.org/SemanticTag", + "properties": { + "id": "st2", + "document": "v6:td4", + "start": 0, + "end": 9, + "tagName": "Title", + "text": "Loud Dogs" } + }, + { + "@type": "http://vocab.lappsgrid.org/SemanticTag", + "properties": { + "id": "st3", + "document": "v6:td6", + "start": 0, + "end": 10, + "tagName": "Host", + "text": "Jim Lehrer" } + }, + { + "@type": "http://vocab.lappsgrid.org/SemanticTag", + "properties": { + "id": "st4", + "document": "v6:td8", + "start": 0, + "end": 9, + "tagName": "Producer", + "text": "Sara Just" } + }, + { + "@type": "http://vocab.lappsgrid.org/SemanticTag", + "properties": { + "id": "st5", + "document": "v6:td10", + "start": 0, + "end": 10, + "tagName": "Date", + "text": "1982-05-12" } + }, + { + "@type": "http://vocab.lappsgrid.org/SemanticTag", + "properties": { + "id": "st6", + "document": "v6:td12", + "start": 0, + "end": 9, + "tagName": "Title", + "text": "Loud Dogs" } + }, + { + "@type": "http://vocab.lappsgrid.org/SemanticTag", + "properties": { + "id": "st7", + "document": "v6:td14", + "start": 0, + "end": 10, + "tagName": "Host", + "text": "Jim Lehrer" } + }, + { + "@type": "http://vocab.lappsgrid.org/SemanticTag", + "properties": { + "id": "st8", + "document": "v6:td16", + "start": 0, + "end": 9, + "tagName": "Producer", + "text": "Sara Just" } + }, + { + "@type": "http://vocab.lappsgrid.org/SemanticTag", + "properties": { + "id": "st9", + "document": "v6:td18", + "start": 0, + "end": 10, + "tagName": "Date", + "text": "1982-05-12" } + }, + { + "@type": "http://vocab.lappsgrid.org/SemanticTag", + "properties": { + "id": "st10", + "document": "v6:td20", + "start": 0, + "end": 9, + "tagName": "Title", + "text": "Loud Dogs" } + }, + { + "@type": "http://vocab.lappsgrid.org/SemanticTag", + "properties": { + "id": "st11", + "document": "v6:td22", + "start": 0, + "end": 10, + "tagName": "Host", + "text": "Jim Lehrer" } + }, + { + "@type": "http://vocab.lappsgrid.org/SemanticTag", + "properties": { + "id": "st12", + "document": "v6:td24", + "start": 0, + "end": 9, + "tagName": "Producer", + "text": "Sara Just" } + } + ] + } + + ] +} diff --git a/docs/1.0.2/samples/everything/scripts/east.py b/docs/1.0.2/samples/everything/scripts/east.py new file mode 100644 index 00000000..87140ec1 --- /dev/null +++ b/docs/1.0.2/samples/everything/scripts/east.py @@ -0,0 +1,53 @@ +"""east.py + +Utility script to create the bounding boxes of the EAST view in the example. + +""" + +from utils import print_annotation + + +slate_box_coordinates = [ + + [[180, 110], [460, 110], [180, 170], [460, 170]], # DATE + [[660, 110], [1250, 110], [660, 170], [1250, 170]], + + [[180, 320], [460, 320], [180, 380], [460, 380]], # TITLE + [[660, 320], [1210, 320], [660, 380], [1210, 380]], + + [[180, 520], [460, 520], [180, 580], [460, 580]], # HOST + [[660, 520], [1200, 520], [660, 580], [1200, 580]], + + [[180, 750], [470, 750], [180, 810], [470, 810]], # PROP + [[660, 750], [1180, 750], [660, 810], [1180, 810]] + +] + +fido_box_coordinates = [[150, 810], [1120, 810], [150, 870], [1120, 870]] + + + + + +if __name__ == '__main__': + + count = 0 + for time_offset in 3000, 4000, 5000: + for coordinates in slate_box_coordinates: + count += 1 + box_id = 'bb%s' % count + print_annotation( + "http://mmif.clams.ai/0.2.0/vocabulary/BoundingBox", + [('id', box_id), + ('timePoint', time_offset), + ('coordinates', coordinates), + ('label', 'text')]) + + count += 1 + box_id = 'bb%s' % count + print_annotation( + "http://mmif.clams.ai/0.2.0/vocabulary/BoundingBox", + [('id', box_id), + ('timePoint', 21000), + ('coordinates', fido_box_coordinates), + ('label', 'text')]) diff --git a/docs/1.0.2/samples/everything/scripts/kaldi.py b/docs/1.0.2/samples/everything/scripts/kaldi.py new file mode 100644 index 00000000..8ed4a062 --- /dev/null +++ b/docs/1.0.2/samples/everything/scripts/kaldi.py @@ -0,0 +1,53 @@ +"""kaldi.py + +Utility script to create the tokens, time frames and alignments of the Kaldi +view in the example. + +""" + +from utils import print_annotation + + +TOKENS = "Hello, this is Jim Lehrer with the NewsHour on PBS. In the nineteen eighties, barking dogs have increasingly become a problem in urban areas.".split() + + +# Calculating time offsets from text offsets +FIRST_TEXT_OFFSET = 0 +LAST_TEXT_OFFSET = 141 +FIRST_TIME_OFFSET = 5500 +LAST_TIME_OFFSET = 22000 +STEP = int((LAST_TIME_OFFSET - FIRST_TIME_OFFSET) / LAST_TEXT_OFFSET) + + +def gather_annotations(): + offset = 0 + token_annotations = [] + for token in TOKENS: + if token[-1] in ',.': + token_annotations.append((offset, offset + len(token) - 1, token[:-1])) + token_annotations.append((offset + len(token) - 1, offset + len(token), token[-1])) + else: + token_annotations.append((offset, offset + len(token), token)) + offset += len(token) + 1 + return token_annotations + + +if __name__ == '__main__': + + count = 0 + for p1, p2, token in gather_annotations(): + count += 1 + token_id = 't%s' % count + frame_id = 'tf%s' % count + align_id = 'a%s' % (count + 1) + frame_p1 = FIRST_TIME_OFFSET + p1 * STEP + frame_p2 = FIRST_TIME_OFFSET + p2 * STEP + print_annotation( + "http://vocab.lappsgrid.org/Token", + [('id', token_id), ('start', p1), ('end', p2), ('text', token)]) + print_annotation( + "http://mmif.clams.ai/0.2.0/vocabulary/TimeFrame", + [('id', frame_id), ('start', frame_p1), ('end', frame_p2)]) + print_annotation( + "http://mmif.clams.ai/0.2.0/vocabulary/Alignment", + [('id', align_id), ('source', frame_id), ('target', token_id)]) diff --git a/docs/1.0.2/samples/everything/scripts/ner.py b/docs/1.0.2/samples/everything/scripts/ner.py new file mode 100644 index 00000000..fc2bc807 --- /dev/null +++ b/docs/1.0.2/samples/everything/scripts/ner.py @@ -0,0 +1,58 @@ +"""ner.py + +Utility script to create the named entities of the NER view in the example. + +Tracking entities back to times (done manually): + +Jim Lehrer v4 t5 td1:15-18 --> tf4 7255-7606 + v4 t6 td1:19-25 --> tf5 7723-8425 + +PBS v4 t11 td1:47-50 --> tf11 10999-11350 + +New York v7 ne10 v6:td25:7-16 + v6 td25 text: "Dog in New York" --> v5:bb25 + v5 bb25 timePoint: 21000 +""" + +from utils import print_annotation + + +# Entities from the text documents, again some repetition. +entities = [ + ('1982-05-12', 'Date', 'v6:td2'), + ('Jim Lehrer', 'Person', 'v6:td6'), + ('Sara Just', 'Person', 'v6:td8'), + ('1982-05-12', 'Date', 'v6:td10'), + ('Jim Lehrer', 'Person', 'v6:td14'), + ('Sara Just', 'Person', 'v6:td16'), + ('1982-05-12', 'Date', 'v6:td18'), + ('Jim Lehrer', 'Person', 'v6:td22'), + ('Sara Just', 'Person', 'v6:td24'), + ('New York', 'Location', 'v6:td25', 7, 15), + ('Jim Lehrer', 'Person', 'v4:td1', 15, 25), + ('PBS', 'Organization', 'v4:td1', 47, 50) ] + + +if __name__ == '__main__': + + count = 0 + for entity in entities: + count += 1 + ner_id = 'ne%s' % count + text = entity[0] + cat = entity[1] + document = entity[2] + if len(entity) == 5: + start = entity[3] + end = entity[4] + else: + start = 0 + end = len(text) + print_annotation( + "http://vocab.lappsgrid.org/NamedEntity", + [('id', ner_id), + ('document', document), + ('start', start), + ('end', end), + ('category', cat), + ('text', text)]) diff --git a/docs/1.0.2/samples/everything/scripts/pbcore.py b/docs/1.0.2/samples/everything/scripts/pbcore.py new file mode 100644 index 00000000..3d7638f3 --- /dev/null +++ b/docs/1.0.2/samples/everything/scripts/pbcore.py @@ -0,0 +1,132 @@ +"""pbcore.py + +Script to experiment with exporting information from a MMIF file into PBCore. + +See ../pbcore.md for a description. + +""" + +import sys +import json + + +CONTRIBUTOR_TYPES = ('Host', 'Producer') +TITLE_TYPE = 'Title' +DATE_TYPE = 'Date' + +TAG_TYPE = 'http://vocab.lappsgrid.org/SemanticTag' + +ENTITY_TYPE = 'http://vocab.lappsgrid.org/NamedEntity' +ENTITY_CATEGORY = 'Person' + + +class MMIF(object): + + """Simplistic MMIF class, will be deprecated when the MMIF SDK is stable.""" + + def __init__(self, fname): + self.json = json.load(open(infile)) + self.metadata = self.json['metadata'] + self.documents = self.json['documents'] + self.views = [View(self, view) for view in self.json['views']] + + def get_view(self, view_id): + for view in self.views: + if view.id == view_id: + return view + + +class View(object): + + def __init__(self, mmif, json_obj): + self.mmif = mmif + self.id = json_obj['id'] + self.metadata = json_obj['metadata'] + self.annotations = [Annotation(self, anno) for anno in json_obj['annotations']] + + def __str__(self): + return "" % (self.id, self.metadata['app']) + + def get_document(self, annotation): + return ( + annotation.get_property('document') + or self.metatdata['contains'][annotation.type]['document']) + + def get_entities(self): + entities = {} + for anno in self.annotations: + if anno.type == ENTITY_TYPE: + entity = anno.get_property('text') + cat = anno.get_property('category') + doc = self.get_document(anno) + p1 = anno.get_property('start') + p2 = anno.get_property('end') + entities.setdefault(cat, {}) + entities[cat].setdefault(entity, []).append((entity, doc, p1, p2, anno, anno)) + return entities + + def get_persons(self): + persons = [] + for anno in self.annotations: + if (anno.type == ENTITY_TYPE + and anno.get_property('category') == ENTITY_CATEGORY): + persons.append(anno) + return persons + + def get_contributors(self): + """Pull all contributors from the slate parser view.""" + contributors = {} + for anno in self.annotations: + tagname = anno.get_property('tagName') + if anno.type == TAG_TYPE and tagname in CONTRIBUTOR_TYPES: + contributors.setdefault(tagname, set()).add(anno.get_property('text')) + return contributors + + +class Annotation(object): + + def __init__(self, view, json_obj): + self.view = view + self.type = json_obj['@type'] + self.id = json_obj['properties']['id'] + self.properties = json_obj['properties'] + + def get_property(self, prop): + return self.properties.get(prop) + + +def print_entities(entities): + for cat in entities: + for entity in entities[cat]: + print("%-16s%-15s" % (cat, entity), end='') + for spec in entities[cat][entity]: + anchor = "%s-%s-%s" % (spec[1], spec[2], spec[3]) + print(anchor, end=' ') + print() + + +if __name__ == '__main__': + + infile = sys.argv[1] + mmif = MMIF(infile) + + bt_view = mmif.get_view("v1") + ner_view = mmif.get_view("v7") + tags_view = mmif.get_view("v8") + + print(bt_view) + print(ner_view) + print(tags_view) + + entities = ner_view.get_entities() + persons = ner_view.get_persons() + #locations = ner_view.get_locations() + + contributors = tags_view.get_contributors() + #date = tags_view.get_date() + #title = tags_view.get_date() + + print_entities(entities) + + print(persons) + print(contributors) diff --git a/docs/1.0.2/samples/everything/scripts/slates.py b/docs/1.0.2/samples/everything/scripts/slates.py new file mode 100644 index 00000000..77c2230c --- /dev/null +++ b/docs/1.0.2/samples/everything/scripts/slates.py @@ -0,0 +1,45 @@ +"""slates.py + +Utility script to create the semantic tags of the slate parser view in the +example. + +""" + +from utils import print_annotation + + +# Tags from the text documents for the slates, again some repetition. Very +# similar to the named entities, but with the title added and non-slate entities +# removed. +tags = [ + ('1982-05-12', 'Date', 'v6:td2'), + ('Loud Dogs', 'Title', 'v6:td4'), + ('Jim Lehrer', 'Host', 'v6:td6'), + ('Sara Just', 'Producer', 'v6:td8'), + ('1982-05-12', 'Date', 'v6:td10'), + ('Loud Dogs', 'Title', 'v6:td12'), + ('Jim Lehrer', 'Host', 'v6:td14'), + ('Sara Just', 'Producer', 'v6:td16'), + ('1982-05-12', 'Date', 'v6:td18'), + ('Loud Dogs', 'Title', 'v6:td20'), + ('Jim Lehrer', 'Host', 'v6:td22'), + ('Sara Just', 'Producer', 'v6:td24') ] + + +if __name__ == '__main__': + + count = 0 + for tag in tags: + count += 1 + tag_id = 'st%s' % count + text, cat, document = tag + start = 0 + end = len(text) + print_annotation( + "http://vocab.lappsgrid.org/SemanticTag", + [('id', tag_id), + ('document', document), + ('start', start), + ('end', end), + ('tagName', cat), + ('text', text)]) diff --git a/docs/1.0.2/samples/everything/scripts/tesseract.py b/docs/1.0.2/samples/everything/scripts/tesseract.py new file mode 100644 index 00000000..57f98530 --- /dev/null +++ b/docs/1.0.2/samples/everything/scripts/tesseract.py @@ -0,0 +1,36 @@ +"""tesseract.py + +Utility script to create the text documents and alignments of the EAST view in +the example. + +""" + +from utils import print_annotation + + +# These are lined up in order of the bounding boxes from EAST. Notice the +# repetition reflecting that identical bounding boxes form three time points +text_values = [ + 'DATE', '1982-05-12', 'TITLE', 'Loud Dogs', 'HOST', 'Jim Lehrer', 'PROD', 'Sara Just', + 'DATE', '1982-05-12', 'TITLE', 'Loud Dogs', 'HOST', 'Jim Lehrer', 'PROD', 'Sara Just', + 'DATE', '1982-05-12', 'TITLE', 'Loud Dogs', 'HOST', 'Jim Lehrer', 'PROD', 'Sara Just', + 'Dog in New York' ] + + +if __name__ == '__main__': + + count = 0 + for text in text_values: + count += 1 + box_id = 'v5:bb%s' % count + text_id = 'td%s' % count + align_id = 'a%s' % count + print_annotation( + "http://mmif.clams.ai/0.2.0/vocabulary/TextDocument", + [('id', text_id), + ('text-@value', text)]) + print_annotation( + "http://mmif.clams.ai/0.2.0/vocabulary/Alignment", + [('id', align_id), + ('source', box_id), + ('target', text_id)]) diff --git a/docs/1.0.2/samples/everything/scripts/utils.py b/docs/1.0.2/samples/everything/scripts/utils.py new file mode 100644 index 00000000..ee203644 --- /dev/null +++ b/docs/1.0.2/samples/everything/scripts/utils.py @@ -0,0 +1,20 @@ + +def print_annotation(attype, properties): + print(" {") + print(' "@type": "%s",' % attype) + print(' "properties": {') + for prop, value in properties[:-1]: + print_property(prop, value) + for prop, value in properties[-1:]: + print_property(prop, value, last=True) + print(" },") + + +def print_property(prop, value, last=False): + eol = ' }' if last else ',' + if type(value) in (int, list): + print(' "%s": %s%s' % (prop, value, eol)) + elif prop == 'text-@value': + print(' "text": { "@value": "%s" }%s' % (value, eol)) + else: + print(' "%s": "%s"%s' % (prop, value, eol)) diff --git a/docs/1.0.2/samples/segmenter-kaldi-ner/index.md b/docs/1.0.2/samples/segmenter-kaldi-ner/index.md new file mode 100644 index 00000000..f5471d20 --- /dev/null +++ b/docs/1.0.2/samples/segmenter-kaldi-ner/index.md @@ -0,0 +1,182 @@ +--- +layout: page +title: MMIF Specification +subtitle: Version 1.0.2 +--- + +# Example: Segmenter, Kaldi and NER + +This example contains one audio document and three views: one created by the audio segmenter, one created by Kaldi and one created by a named entity recognizer. + +We now give fragments of the three views, each with some comments. + +To see the full example scroll down to the end or open the [raw json file](raw.json). + +### Fragment 1: the Segmenter view + +Metadata: + +```json +{ + "app": "http://mmif.clams.ai/apps/audio-segmenter/0.2.1", + "contains": { + "http://mmif.clams.ai/vocabulary/TimeFrame/v3": { + "timeUnit": "milliseconds", + "document": "m1" } +} +``` + +All time frames in the view are anchored to document "m1" and milliseconds are used for the unit. + +Partial annotations list: + +```json +[ + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf1", + "frameType": "speech", + "start": 17, + "end": 132 } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "frameType": "non-speech", + "id": "tf2", + "start": 132, + "end": 194 } + } +] +``` + +Two of the three time frames are shown here: one for a speech segment and one for a non-speech segment. Only the speech frames are input to Kaldi. + +### Fragment 2: the Kaldi view + +Metadata: + +```json +{ + "app": "http://mmif.clams.ai/apps/kaldi/0.2.1", + "contains": { + "http://mmif.clams.ai/vocabulary/TextDocument/v1": {}, + "http://vocab.lappsgrid.org/Token": {}, + "http://mmif.clams.ai/vocabulary/TimeFrame/v3": { + "timeUnit": "milliseconds", + "document": "m1" }, + "http://mmif.clams.ai/vocabulary/Alignment/v1": {} } +} +``` + +Kaldi creates five kinds of annotations: + +1. Text documents for each speech time frame. +2. Tokens for each text document. +3. Time frames that correspond to each token, these time frames are all anchored to document "m1". +4. Alignments from speech frames to text documents, the speech frames were created by the segmenter. +5. Alignments from time frames to tokens. + +The annotations list has two documents, one shown here: + +```json +{ + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td1", + "text": { + "@value": "Fido barks" } } +} +``` + +This document does not know it's history, but Kaldi also creates an alignment that spells out what time frame the document is aligned to: + +```json +{ + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a1", + "source": "v1:tf1", + "target": "td1" } +} +``` + +Each document is tokenized, here showing one token from the document above: + +```json +{ + "@type": "http://vocab.lappsgrid.org/vocabulary/Token", + "id": "t1", + "properties": { + "document": "v2:td1", + "start": 0, + "end": 4, + "text": "Fido" } +} +``` + +Note how the token uses the *document* property to specify what document this is an annotation of. This has to be specified for each token because the Kaldi view has more than one text document. + +The token is associated with a time frame in document "m1": + +```json +{ + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf1", + "start": 17, + "end": 64 } +} +``` + +And the token and time frame are linked by an alignment: + +```json +{ + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a2", + "source": "tf1", + "target": "t1" } +} +``` + +If Kaldi had run on the entire document (not using just speech frames) then the result could be a bit different in that there would be just one text document and the token metadata in the view could specify that so tokens would not have individual *document* properties. + +### Fragment 3: the NET view + +Metadata: + +```json +{ + "app": "http://mmif.clams.ai/apps/stanford-ner/0.2.1", + "contains": { + "http://vocab.lappsgrid.org/NamedEntity": {} } +} +``` + +One of the two named entity annotations: + +```json +{ + "@type": "http://vocab.lappsgrid.org/NamedEntity", + "properties": { + "id": "ne1", + "document": "v2:td1", + "start": 0, + "end": 4, + "category": "Person", + "word": "Fido" } +} +``` + +Notice how the entity anchors to one of the document created by Kaldi. + + + +## Full MMIF File + +```json +{% include_relative raw.json %} +``` diff --git a/docs/1.0.2/samples/segmenter-kaldi-ner/raw.json b/docs/1.0.2/samples/segmenter-kaldi-ner/raw.json new file mode 100644 index 00000000..1772ee18 --- /dev/null +++ b/docs/1.0.2/samples/segmenter-kaldi-ner/raw.json @@ -0,0 +1,247 @@ +{ + "metadata": { + "mmif": "http://mmif.clams.ai/1.0.2" + }, + "documents": [ + { + "@type": "http://mmif.clams.ai/vocabulary/AudioDocument/v1", + "properties": { + "id": "m1", + "mime": "audio/mpeg", + "location": "file:///var/archive/audio-002.mp3" + } + } + ], + "views": [ + { + "id": "v1", + "metadata": { + "app": "http://mmif.clams.ai/apps/audio-segmenter/0.2.1", + "contains": { + "http://mmif.clams.ai/vocabulary/TimeFrame/v3": { + "timeUnit": "milliseconds", + "document": "m1" + } + } + }, + "annotations": [ + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf1", + "frameType": "speech", + "start": 17, + "end": 132 + } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "frameType": "non-speech", + "id": "tf2", + "start": 132, + "end": 194 + } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf3", + "frameType": "speech", + "start": 194, + "end": 342 + } + } + ] + }, + { + "id": "v2", + "metadata": { + "app": "http://mmif.clams.ai/apps/kaldi/0.2.1", + "contains": { + "http://mmif.clams.ai/vocabulary/TextDocument/v1": {}, + "http://vocab.lappsgrid.org/Token": {}, + "http://mmif.clams.ai/vocabulary/TimeFrame/v3": { + "timeUnit": "milliseconds", + "document": "m1" + }, + "http://mmif.clams.ai/vocabulary/Alignment/v1": {} + } + }, + "annotations": [ + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td1", + "text": { + "@value": "Fido barks" + } + } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a1", + "source": "v1:tf1", + "target": "td1" + } + }, + { + "@type": "http://vocab.lappsgrid.org/Token", + "properties": { + "id": "t1", + "document": "v2:td1", + "start": 0, + "end": 4, + "text": "Fido" + } + }, + { + "@type": "http://vocab.lappsgrid.org/Token", + "properties": { + "id": "t2", + "document": "v2:td1", + "start": 5, + "end": 10, + "text": "barks" + } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf1", + "start": 17, + "end": 64 + } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf2", + "start": 65, + "end": 132 + } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a2", + "source": "tf1", + "target": "t1" + } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a3", + "source": "tf2", + "target": "t2" + } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TextDocument/v1", + "properties": { + "id": "td2", + "textSource": "v1:tf3", + "text": { + "@value": "Fluffy sleeps" + } + } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a4", + "source": "v1:tf3", + "target": "td2" + } + }, + { + "@type": "http://vocab.lappsgrid.org/Token", + "properties": { + "id": "t3", + "document": "v2:td2", + "start": 0, + "end": 6, + "text": "Fluffy" + } + }, + { + "@type": "http://vocab.lappsgrid.org/Token", + "properties": { + "id": "t4", + "document": "v2:td2", + "start": 7, + "end": 13, + "text": "sleeps" + } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf3", + "start": 194, + "end": 240 + } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/TimeFrame/v3", + "properties": { + "id": "tf4", + "start": 241, + "end": 342 + } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a5", + "source": "tf3", + "target": "t3" + } + }, + { + "@type": "http://mmif.clams.ai/vocabulary/Alignment/v1", + "properties": { + "id": "a5", + "source": "tf4", + "target": "t4" + } + } + ] + }, + { + "id": "v3", + "metadata": { + "app": "http://mmif.clams.ai/apps/stanford-ner/0.2.1", + "contains": { + "http://vocab.lappsgrid.org/NamedEntity": {} + } + }, + "annotations": [ + { + "@type": "http://vocab.lappsgrid.org/NamedEntity", + "properties": { + "id": "ne1", + "document": "v2:td1", + "start": 0, + "end": 4, + "category": "Person", + "word": "Fido" + } + }, + { + "@type": "http://vocab.lappsgrid.org/NamedEntity", + "properties": { + "id": "ne2", + "document": "v2:td2", + "start": 0, + "end": 6, + "category": "Person", + "word": "Fluffy" + } + } + ] + } + ] +} diff --git a/docs/1.0.2/schema/lif.json b/docs/1.0.2/schema/lif.json new file mode 100644 index 00000000..bf02f031 --- /dev/null +++ b/docs/1.0.2/schema/lif.json @@ -0,0 +1,116 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "LAPPS Interchange Format", + "description": "The JSON-LD objects exchanged by LAPPS web services.", + "type": "object", + "additionalProperties": false, + "properties": { + "@context": { + "oneOf": [ + { + "type": "object", + "additionalProperties": true + }, + { + "type": "string", + "format": "uri" + } + ] + }, + "@vocab": { + "type": "string", + "format": "uri" + }, + "text": { + "type": "object", + "properties": { + "@value": { + "type": "string" + }, + "@language": { + "type": "string" + } + }, + "required": [ + "@value" + ], + "additionalProperties": false + }, + "metadata": { + "$ref": "#/definitions/map" + }, + "views": { + "type": "array", + "items": { + "$ref": "#/definitions/view" + } + } + }, + "definitions": { + "map": { + "type": "object", + "additionalProperties": true + }, + "view": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "metadata": { + "$ref": "#/definitions/map" + }, + "annotations": { + "$ref": "#/definitions/annotations" + } + }, + "additionalProperties": false, + "required": [ + "id", + "annotations" + ] + }, + "annotations": { + "type": "array", + "items": { + "$ref": "#/definitions/annotation" + } + }, + "annotation": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "@type": { + "type": "string" + }, + "type": { + "type": "string" + }, + "label": { + "type": "string" + }, + "start": { + "type": "integer", + "minimum": -1 + }, + "end": { + "type": "integer", + "minimum": -1 + }, + "features": { + "$ref": "#/definitions/map" + }, + "metadata": { + "$ref": "#/definitions/map" + } + }, + "required": [ + "id", + "@type" + ], + "additionalProperties": false + } + } +} diff --git a/docs/1.0.2/schema/mmif.json b/docs/1.0.2/schema/mmif.json new file mode 100644 index 00000000..0a7e968f --- /dev/null +++ b/docs/1.0.2/schema/mmif.json @@ -0,0 +1,191 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Multi-Media Interchange Format", + "description": "The JSON-LD objects exchanged by CLAMS services.", + "type": "object", + "additionalProperties": false, + "properties": { + "metadata": { + "$ref": "#/definitions/mmifMetadata" + }, + "documents": { + "type": "array", + "items": { + "$ref": "#/definitions/annotation" + }, + "minLength": 1 + }, + "views": { + "type": "array", + "items": { + "$ref": "#/definitions/view" + } + } + }, + "required": [ + "metadata", + "documents", + "views" + ], + "definitions": { + "strStrMap": { + "type": "object", + "patternProperties": { + ".+": { + "anyOf": [ + {"type": "string"}, + {"type": "array", "items": { "type": "string" }} + ] + } + } + }, + "mmifMetadata": { + "type": "object", + "properties": { + "mmif": { + "type": "string", + "format": "uri", + "minLength": 7 + } + }, + "required": [ + "mmif" + ] + }, + "viewMetadata": { + "type": "object", + "properties": { + "timestamp": { + "type": "string", + "format": "date-time" + }, + "app": { + "type": "string", + "format": "uri", + "minLength": 7 + }, + "contains": { + "type": "object", + "additionalProperties": false, + "patternProperties": { + "^https?:\/\/": { + "type": "object" + } + } + }, + "error": { + "type": "object", + "properties": { + "message": { + "type": "string", + "minLength": 1 + }, + "stackTrace": { + "type": "string" + } + }, + "required": ["message"] + }, + "warnings": { + "type": "array", + "items": { + "type": "string" + }, + "minLength": 1 + }, + "parameters": { + "$ref": "#/definitions/strStrMap" + } + }, + "oneOf": [ + { + "required": [ + "app", + "contains" + ] + }, + { + "required": [ + "app", + "warnings" + ] + }, + { + "required": [ + "app", + "error" + ] + } + ] + }, + "text": { + "type": "object", + "properties": { + "@value": { + "type": "string" + }, + "@language": { + "type": "string" + } + }, + "additionalProperties": false, + "required": [ + "@value" + ] + }, + "view": { + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + }, + "metadata": { + "$ref": "#/definitions/viewMetadata" + }, + "annotations": { + "type": "array", + "items": { + "$ref": "#/definitions/annotation" + } + } + }, + "additionalProperties": false, + "required": [ + "id", + "metadata", + "annotations" + ] + }, + "annotation": { + "type": "object", + "properties": { + "@type": { + "type": "string", + "minLength": 1 + }, + "properties": { + "$ref": "#/definitions/annotationProperties" + } + }, + "required": [ + "@type", + "properties" + ], + "additionalProperties": false + }, + "annotationProperties": { + "type": "object", + "properties": { + "id": { + "type": "string", + "minLength": 1 + } + }, + "required": [ + "id" + ] + } + } +} + diff --git a/docs/1.0.2/vocabulary/attypeversions.json b/docs/1.0.2/vocabulary/attypeversions.json new file mode 100644 index 00000000..254bae12 --- /dev/null +++ b/docs/1.0.2/vocabulary/attypeversions.json @@ -0,0 +1 @@ +{"Thing": "v1", "Annotation": "v3", "Region": "v2", "TimePoint": "v2", "Interval": "v2", "Span": "v2", "TimeFrame": "v3", "Chapter": "v3", "Polygon": "v2", "BoundingBox": "v2", "VideoObject": "v2", "Relation": "v2", "Document": "v1", "VideoDocument": "v1", "AudioDocument": "v1", "ImageDocument": "v1", "TextDocument": "v1", "Alignment": "v1"} \ No newline at end of file diff --git a/docs/1.0.2/vocabulary/css/lappsstyle.css b/docs/1.0.2/vocabulary/css/lappsstyle.css new file mode 100644 index 00000000..582de8f8 --- /dev/null +++ b/docs/1.0.2/vocabulary/css/lappsstyle.css @@ -0,0 +1,503 @@ +.fixed { + width: 15%; +} + +.col1 { + width: 25%; +} +td { + vertical-align: top; +} + +.definition { + padding-right: 10px; +} + +ul.tree { list-style:none; } +.hidden { display: none; } + +.property { + font-size: 90%; + font-style: italic; + color: #105010; +} +.index { + margin-top: 1em; + text-align: left; + font-size: 110%; + margin-bottom: 1em; +} +.deprecated { text-decoration: line-through; } + + +/* -- page structure -- */ +#container +{ + width: 100%; + text-align: left; + margin: 0; + background: #fff; +} +#intro +{ + position: relative; +} +#mainContent +{ + /* margin: 0 50px 15px 50px; */ + padding-bottom: 5px; + border-bottom: solid 1px #CCCCCC; + text-align: left; + font-size: small; +} + +#mainContent, #footer { + /* max-width: 960px; + min-width: 350px; */ + margin: 0 auto; +} +#footer +{ + text-align: right; + font-size: x-small; +} + +/* -- general -- */ +body +{ + color: #3A4956; + font-size: 75%; + font-family: "Lucida Grande" , "Lucida Sans Unicode" , Verdana, Tahoma, Arial, sans-serif; + line-height: 160%; + margin: 0; + padding: 0; +} +code +{ + font-family: Courier, monospace; +} +p.head, h1 +{ + font: bold 24px Helvetica, Arial, sans-serif; + color: #336699; + letter-spacing: -1px; + margin: 1em 0 0 0; +} +h2 +{ + /* border-top: 1px solid #336699; */ + padding-top: 5px; + clear: both; + color: #336699; + font: normal 18px Helvetica, Arial, sans-serif; + margin: 1em 0 0 0; +} +h3 +{ + font-size: 12px; + color: #660000; + margin: 1em 0 0 0; + position: relative; + top: 8px; +} +hr +{ + border: none; + height: 1px; + background: #ccc; + margin: 2em 0 4em 0; +} +p +{ + margin: 1em 0 0 0; +} +pre +{ + font-family: Courier, monospace; + font-size: 120%; + background: #E1E1E1; + width: auto; + padding: 5px 5px 5px 10px; + margin: 1em 0 0 0; + text-align: left; + overflow: auto; +} + +/* -- header/title -- */ +#pageHeader +{ + width: 100%; + height: 80px; + background: #336699; + position: top; +} +#pageHeader h1 +{ + color: #fff; + margin: 0 0 5px 40px; + /* font: bold Helvetica, Arial, sans-serif; */ + font-weight: bold; + font-family: Helvetica, Arial, sans-serif; + letter-spacing: -1px; +} +#pageHeader h2 { + color: #fff; + margin-left: 40px; + text-shadow: 0 2px 0 #510000; +} + +#pageHeader a:link, #pageHeader a:hover, #pageHeader a:visited +{ + color: #fff; + background-color: #336699; + text-decoration: none; +} + + +/* -- nav bar -- */ +#selectionbar +{ + color: #fff; + height: 46px; + background: #660000; + font-size: 90%; +} +#selectionbar ul +{ + margin: 0; + padding: 1em 1em 0 0; +} +#selectionbar li +{ + display: inline; + list-style: none; +} +#selectionbar a:link, #selectionbar a:visited +{ + color: #fff; + display: block; + float: right; + padding: 1px 9px 3px 6px; + margin: 0 6px; + text-decoration: none; +} +#selectionbar a:hover +{ + color: #FFEE99; + background-color: transparent; +} +#selectionbar .activelink a +{ + background: #336699; +} +#selectionbar .activelink a:hover +{ + color: #fff; + background-color: #336699; + cursor: default; +} + + +/* -- main content -- */ +#mainContent +{ + font-size: 100%; +} +#mainContent ul li +{ + list-style: inherit; + padding: 0 0 0 5px; + margin: 0; +} +#mainContent a:link +{ + color: #660000; + text-decoration: none; + border-bottom: dotted 1px #660000; +} +#mainContent a:visited +{ + color: #336699; + text-decoration: none; + border-bottom: dotted 1px #336699; +} +#mainContent a:hover +{ + border-bottom: none; + color: #fff; + background-color: #660000; + text-decoration: none; +} +#mainContent blockquote +{ + padding: 0 0 0 15px; + margin: 10px 0 10px 15px; + width: auto; + float: right; + border-left: thin dotted #000; +} + + +/* -- faq -- */ +.faq p, .faq pre, .faq ul, .faq table, .faq +{ + margin: .5em 0 0 50px; + padding-top: 0px; + padding-bottom: 2px; + color: #3A4956; +} + +.faq h1 +{ + margin-bottom: 1em; +} +.faq ul, .faq ol +{ + padding-left: 30px; + margin-left: 50px; +} +#mainContent .question +{ + font-weight: bold; + margin: 1.5em 0 0 0; + padding-top: 0px; + padding-bottom: 2px; +} + +/* -- types -- */ +table.definition-table +{ + margin: 1em 0 0 0; + border: 1px solid #98A0A6; + width: 100%; + border-collapse: collapse; +} +.definition-table th +{ + text-align: left; + background: #C7CBCE; + padding-left: 5px; +} +.definition-table td +{ + padding: 0 5px 2px 5px; + margin: 0; + vertical-align: top; + border: 1px solid #98A0A6; + border-collapse: collapse; +} +.definition-table td p +{ + padding: 0 0 .6em 0; + margin: 0; +} +.definition-table td ul +{ + padding-top: 0; + margin-top: 0; +} +.definition-table tr.alt +{ + background: #E9EAEB; +} +div.attrib +{ + padding-bottom: 1em; +} + +/* -- hierarchy -- */ +table.h, .h tr, .h td +{ + border: none; + margin: 0; + padding: 0; + border-collapse: collapse +} +.h .space +{ + width: 20px +} +.h .bar +{ + background-color: #000; + width: 1px +} +.h .tc +{ + text-indent: -21px; + padding-left: 21px +} + +/* -- links --*/ +a.path:link {color:silver;text-decoration:none;} +a.path:visited {color:silver;text-decoration:none;} +a.path:hover {color:gray;text-decoration:none;} + + +a.two:link {color:#333333;text-decoration:none;} +a.two:visited {color:#333333;text-decoration:none;} +a.two:hover {color:gray;text-decoration:none;} + +a.inherited-property:link {color:#336699;text-decoration:none;} +a.inherited-property:visited {color:#336699;text-decoration:none;} +a.inherited-property:hover {color:gray;text-decoration:none;} + +a.sameas:link {color:#336699;text-decoration:none;} +a.sameas:visited {color:#336699;text-decoration:none;} +a.sameas:hover {color:gray;text-decoration:none;} + +#arial1 { + font-family: Arial, Helvetica, sans-serif; + color: #333333; + font-size: small; +} + +tbody { + font-size: small; +} + +pre { + font-size: small; + background-color: #dddddd; + border-radius: 5px; +} + +#element +{ + font-size: x-large; + color: #336699; + font-weight: bold; +} + +#properties { + color: #336699; +} + +#prop-table { + width: 1126px; + height: 27px; +} + +#col1 { + width: 188px; +} + +#col2 { + width: 160px; +} + +#col3 { + width: 500px; +} + +#col4 { + width: 278px; +} + +#headrow { + background-color: #cccccc; + font-weight: bold; +} + + + +/* -- other -- */ +.backtotop, .faq .backtotop +{ + float: right; + clear: both; + padding: 3em 0 0 4em; + padding: 0; + font-size: 90%; +} +.date, .faq .date +{ + color: #BFC3C7; + text-align: right; + font-size: x-small; + clear: both; + padding-top: 4em; +} +.required +{ + text-align: right; + float: right; +} +.version +{ + color: #BFC3C7; + text-align: right; + font-size: x-small; + clear: both; + padding-top: 1em; +} + +#selectionbar ul +{ + float: right; + padding: 10px 0; +} +#mainContent, #footer, .wrapper { + /* max-width: 960px; */ + min-width: 350px; + margin: 0 auto !important; + padding: 0 70px; +} +#pageHeader h1 { + position:relative; + top: 25px; left: -40px; + text-shadow: 0 2px 0 #510000; + pointer-events: none; + padding: 0 40px; +} +#selectionbar ul { + margin: 0 auto; + display: block; +} +#cse-search-form { + float: right; + margin-top:-20px; + width: 248px !important; +} +.gsc-input input.gsc-input { background: #FFF !important;} + +@media all and (max-width: 720px) { + #pageHeader { + height: 120px; + } + #cse-search-form { + margin-left: 15px; + margin-top: 20px; + } +} + + +/* -- extras -- */ + +input.gsc-input { + border-color: #660000; + color: #333333; + font-family: "Lucida Grande" , "Lucida Sans Unicode" , Verdana, Tahoma, Arial, sans-serif; + font-size: 11px; + padding: 3px; + width: 99%; +} +input.gsc-search-button { + background-color: #660000; + border-color: #660000; + color: #fff; + font-family: inherit; + font-size: 11px; + font-weight: normal; + padding: 2px 8px; + text-shadow: none; +} +.gsc-input input.gsc-input { + background: none repeat scroll 0% 0% white !important; + border-color: #660000; + padding: 3px; + width: 99%; +} +.gsc-clear-button { + display: none; +} diff --git a/docs/1.0.2/vocabulary/index.html b/docs/1.0.2/vocabulary/index.html new file mode 100644 index 00000000..a7c4e6eb --- /dev/null +++ b/docs/1.0.2/vocabulary/index.html @@ -0,0 +1,430 @@ + + + + + CLAMS Vocabulary + + + +

+
+ +
+
+

+ + The CLAMS Vocabulary defines an ontology of terms for a core of objects and features exchanged amongst tools that process multi-media data. It is based on the LAPPS Web Service Exchange Vocabulary at + + + http://vocab.lappsgrid.org. + + + The vocabulary is being developed bottom-up on an as-needed basis for use in the development of the CLAMS platform. + + + In the hierarchy below annotation types are printed with the properties defined for them, metadata properties are printed between square brackets. + +

+
+ + + + + + + + + + +
+ + Thing (v1) + + + : id + +
+ + + + + + + + + + + + + +
+ + Annotation (v3) + + + : [document, labelset, labelsetUri] + + + : document, label, classifications + +
+ + + + + + + + + + + + + +
+ + Region (v2) + + + : [timeUnit] + +
+ + + + + + + + + + + + + +
+ + TimePoint (v2) + + + : timePoint + +
+ + + +
+ + + + + + + + + + +
+ + Interval (v2) + + + : start, end, targets + +
+ + + + + + + + + + + + + +
+ + Span (v2) + +
+ + + +
+ + + + + + + + + + +
+ + TimeFrame (v3) + + + : frameType + +
+ + + + + + + + + + + + + +
+ + Chapter (v3) + + + : title + +
+ + + +
+
+
+ + + + + + + + + + +
+ + Polygon (v2) + + + : coordinates, timePoint + +
+ + + + + + + + + + + + + +
+ + BoundingBox (v2) + + + : boxType + +
+ + + +
+
+ + + + + + + + + + +
+ + VideoObject (v2) + + + : polygons + +
+ + + +
+
+ + + + + + + + + + +
+ + Relation (v2) + +
+ + + +
+
+ + + + + + + + + + +
+ + Document (v1) + + + : location, mime + +
+ + + + + + + + + + + + + +
+ + VideoDocument (v1) + +
+ + + +
+ + + + + + + + + + +
+ + AudioDocument (v1) + +
+ + + +
+ + + + + + + + + + +
+ + ImageDocument (v1) + +
+ + + +
+ + + + + + + + + + +
+ + TextDocument (v1) + + + : text + +
+ + + +
+
+ + + + + + + + + + +
+ + Alignment (v1) + + + : [sourceType, targetType] + + + : source, target + +
+ + + +
+
+
+
+
+ + + \ No newline at end of file diff --git a/docs/_config.yml b/docs/_config.yml index 7e0687ab..62d5b15d 100644 --- a/docs/_config.yml +++ b/docs/_config.yml @@ -21,6 +21,7 @@ navbar-links: CLAMS: "https://clams.ai" # a new version will be added here by build.py VERSIONS: + - 1.0.2: '1.0.2' - 1.0.1: '1.0.1' - 1.0.0: '1.0.0' - 0.5.0: '0.5.0' diff --git a/docs/vocabulary/Alignment/v1/index.html b/docs/vocabulary/Alignment/v1/index.html index e30c518c..58c3941d 100644 --- a/docs/vocabulary/Alignment/v1/index.html +++ b/docs/vocabulary/Alignment/v1/index.html @@ -32,6 +32,10 @@

1.0.1 + , + + 1.0.2 +

@@ -216,7 +220,7 @@

- + \ No newline at end of file diff --git a/docs/vocabulary/Annotation/v3/index.html b/docs/vocabulary/Annotation/v3/index.html new file mode 100644 index 00000000..f6d91f39 --- /dev/null +++ b/docs/vocabulary/Annotation/v3/index.html @@ -0,0 +1,201 @@ + + + + + Annotation + + + +
+
+ +
+
+
+

+ included in: + + 1.0.2 + +

+
+

+ + Thing + + + > + + + Annotation + +

+
+ + + + + + + + + +
+ + Definition + + + Any kind of information added to a document. If an annotation is specific to a region over the primary data or a relation over such regions, specific sub-types should be used instead of this high-level type. +
+ + URI + + + + http://mmif.clams.ai/vocabulary/Annotation/v3 + +
+

+ Metadata +

+ + + + + + + + + + + + + + + + + + + + + +
+ Property + + Type + + Description +
+ document + + ID + + The identifier of the document that the annotation is over. This has to be defined either at the metadata level, in which case it has scope over all annotations of the same type in a view, or at the instance level, in which it has scope over just the single annotation. +
+ labelset + + List of Strings + + When an annotation object contains results of a classification task, this metadata is used to specify the label values used in classification. Individual annotations then must have label property that is one of the values in this list.

[Note] Annotations from a classifier app must have this metadata or labelsetUri metadata.

[Note] Not all of labels specified in the labelset must occur in the output annotations. For example, a labelset can contain a catch-all negative label, but if the negative label can be not interesting enough to keep in the output annotation. +
+ labelsetUri + + String + + A URI to an externally defined labelset. Since the labelset metadata is a list of simple strings, this URI can be used to point to a more detailed definition of the labelset. This can be a JSON-LD document or a SKOS concept scheme, for example.

[Note] Annotations from a classifier app must have this metadata or labelset metadata. +
+

+ Properties +

+ + + + + + + + + + + + + + + + + + + + + +
+ Property + + Type + + Description +
+ document + + ID + + The identifier of the document that the annotation is over. +
+ label + + String + + A label given to this object by a classifier. The value must be a simple string value of the label and must be one of the values defined in the labelset or labelsetUri annotation metadata.

[Note] Annotations from a classifier app must have this property. +
+ classifications + + Map from String to Number + + A map from label values to their "score" numbers provided by a classifier. The score can be probability, similarity, confidence, or any other real number that was used to determine the label value.

[Optional] on top of the label property. However when this property is used, the label property must be one of the keys and the keys must match to the values defined in the labelset + or labelsetUri annotation metadata. +
+

+ Properties from Thing +

+ + + + + + + + + + + +
+ Property + + Type + + Description +
+ id + + ID + + A unique identifier for the annotation or document. Uniqueness is relative to the view the annotation is in or the list of documents at the top level of a MMIF file. + + [Required] + +
+
+
+
+ + + \ No newline at end of file diff --git a/docs/vocabulary/AudioDocument/v1/index.html b/docs/vocabulary/AudioDocument/v1/index.html index 6669d0d2..6c9b6934 100644 --- a/docs/vocabulary/AudioDocument/v1/index.html +++ b/docs/vocabulary/AudioDocument/v1/index.html @@ -32,6 +32,10 @@

1.0.1 + , + + 1.0.2 +

@@ -184,7 +188,7 @@

- + \ No newline at end of file diff --git a/docs/vocabulary/BoundingBox/v2/index.html b/docs/vocabulary/BoundingBox/v2/index.html new file mode 100644 index 00000000..d1987f15 --- /dev/null +++ b/docs/vocabulary/BoundingBox/v2/index.html @@ -0,0 +1,317 @@ + + + + + BoundingBox + + + +
+
+ +
+
+
+

+ included in: + + 1.0.2 + +

+
+

+ + Thing + + + > + + + Annotation + + + > + + + Region + + + > + + + Polygon + + + > + + + BoundingBox + +

+
+ + + + + + + + + +
+ + Definition + + + A rectangular object in an image or video. At the moment it does not have features that would not make any sense on its parent type Polygon so technically we can do without BoundingBox, but it was introduced because the term is in widespread use. +
+ + URI + + + + http://mmif.clams.ai/vocabulary/BoundingBox/v2 + +
+

+ Metadata +

+

+ Metadata from Region +

+ + + + + + + + + + + +
+ Property + + Type + + Description +
+ timeUnit + + String + + Specifies which unit of time the measurement is based. Can be *seconds* or *milliseconds*, or in case of annotations on a VideoDocument, *frames*. +
+

+ Metadata from Annotation +

+ + + + + + + + + + + + + + + + + + + + + +
+ Property + + Type + + Description +
+ document + + ID + + The identifier of the document that the annotation is over. This has to be defined either at the metadata level, in which case it has scope over all annotations of the same type in a view, or at the instance level, in which it has scope over just the single annotation. +
+ labelset + + List of Strings + + When an annotation object contains results of a classification task, this metadata is used to specify the label values used in classification. Individual annotations then must have label property that is one of the values in this list.

[Note] Annotations from a classifier app must have this metadata or labelsetUri metadata.

[Note] Not all of labels specified in the labelset must occur in the output annotations. For example, a labelset can contain a catch-all negative label, but if the negative label can be not interesting enough to keep in the output annotation. +
+ labelsetUri + + String + + A URI to an externally defined labelset. Since the labelset metadata is a list of simple strings, this URI can be used to point to a more detailed definition of the labelset. This can be a JSON-LD document or a SKOS concept scheme, for example.

[Note] Annotations from a classifier app must have this metadata or labelset metadata. +
+

+ Properties +

+ + + + + + + + + + + +
+ Property + + Type + + Description +
+ boxType + + String + + The type of BoundingBox. Mostly used for text boxes where we use the value text.

No longer encouraged to use, and instead label property should replace this property. +
+

+ Properties from Polygon +

+ + + + + + + + + + + + + + + + +
+ Property + + Type + + Description +
+ coordinates + + List of pairs + + The coordinates of the polygon, taking the top-left of the image as the origin (0,0). Unit used to measure the distance is the number of pixels. + + [Required] + +
+ timePoint + + Integer + + If on a video stream, the TimePoint that the BoundingBox occurs in. +
+

+ Properties from Annotation +

+ + + + + + + + + + + + + + + + + + + + + +
+ Property + + Type + + Description +
+ document + + ID + + The identifier of the document that the annotation is over. +
+ label + + String + + A label given to this object by a classifier. The value must be a simple string value of the label and must be one of the values defined in the labelset or labelsetUri annotation metadata.

[Note] Annotations from a classifier app must have this property. +
+ classifications + + Map from String to Number + + A map from label values to their "score" numbers provided by a classifier. The score can be probability, similarity, confidence, or any other real number that was used to determine the label value.

[Optional] on top of the label property. However when this property is used, the label property must be one of the keys and the keys must match to the values defined in the labelset + or labelsetUri annotation metadata. +
+

+ Properties from Thing +

+ + + + + + + + + + + +
+ Property + + Type + + Description +
+ id + + ID + + A unique identifier for the annotation or document. Uniqueness is relative to the view the annotation is in or the list of documents at the top level of a MMIF file. + + [Required] + +
+
+
+
+ + + \ No newline at end of file diff --git a/docs/vocabulary/Chapter/v3/index.html b/docs/vocabulary/Chapter/v3/index.html new file mode 100644 index 00000000..103fb61e --- /dev/null +++ b/docs/vocabulary/Chapter/v3/index.html @@ -0,0 +1,358 @@ + + + + + Chapter + + + +
+
+ +
+
+
+

+ included in: + + 1.0.2 + +

+
+

+ + Thing + + + > + + + Annotation + + + > + + + Region + + + > + + + Interval + + + > + + + TimeFrame + + + > + + + Chapter + +

+
+ + + + + + + + + +
+ + Definition + + + Example case for when we do not want to use Segment with a specific segmentType or if we want to introduce special properties. +
+ + URI + + + + http://mmif.clams.ai/vocabulary/Chapter/v3 + +
+

+ Metadata +

+

+ Metadata from Region +

+ + + + + + + + + + + +
+ Property + + Type + + Description +
+ timeUnit + + String + + Specifies which unit of time the measurement is based. Can be *seconds* or *milliseconds*, or in case of annotations on a VideoDocument, *frames*. +
+

+ Metadata from Annotation +

+ + + + + + + + + + + + + + + + + + + + + +
+ Property + + Type + + Description +
+ document + + ID + + The identifier of the document that the annotation is over. This has to be defined either at the metadata level, in which case it has scope over all annotations of the same type in a view, or at the instance level, in which it has scope over just the single annotation. +
+ labelset + + List of Strings + + When an annotation object contains results of a classification task, this metadata is used to specify the label values used in classification. Individual annotations then must have label property that is one of the values in this list.

[Note] Annotations from a classifier app must have this metadata or labelsetUri metadata.

[Note] Not all of labels specified in the labelset must occur in the output annotations. For example, a labelset can contain a catch-all negative label, but if the negative label can be not interesting enough to keep in the output annotation. +
+ labelsetUri + + String + + A URI to an externally defined labelset. Since the labelset metadata is a list of simple strings, this URI can be used to point to a more detailed definition of the labelset. This can be a JSON-LD document or a SKOS concept scheme, for example.

[Note] Annotations from a classifier app must have this metadata or labelset metadata. +
+

+ Properties +

+ + + + + + + + + + + +
+ Property + + Type + + Description +
+ title + + String + + Title of the chapter +
+

+ Properties from TimeFrame +

+ + + + + + + + + + + +
+ Property + + Type + + Description +
+ frameType + + String + + The type of TimeFrame. Possible values include, but are not limited to, bars, tones, bars-and-tones, speech, noise, music, slate, chyron, lower-third, credits, and other.

No longer encouraged to use, instead label property should replace this property. +
+

+ Properties from Interval +

+ + + + + + + + + + + + + + + + + + + + + +
+ Property + + Type + + Description +
+ start + + Integer + + The starting offset in the primary data. This point is inclusive. For time intervals, the unit is determined by the *timeUnit* metadata key. For text intervals, the unit is Unicode code point. +
+ end + + Integer + + The ending offset in the primary data. This point is exclusive. For time intervals, the unit is determined by the *timeUnit* metadata key. For text intervals, the unit is Unicode code point. +
+ targets + + List of IDs + + IDs of a sequence of annotations covering the region of primary data referred to by this annotation. Used as an alternative to *start* and *end* to point to component annotations (for example a token sequence) rather than directly into primary data, or to link two or more annotations (for example in a coreference annotation). +
+

+ Properties from Annotation +

+ + + + + + + + + + + + + + + + + + + + + +
+ Property + + Type + + Description +
+ document + + ID + + The identifier of the document that the annotation is over. +
+ label + + String + + A label given to this object by a classifier. The value must be a simple string value of the label and must be one of the values defined in the labelset or labelsetUri annotation metadata.

[Note] Annotations from a classifier app must have this property. +
+ classifications + + Map from String to Number + + A map from label values to their "score" numbers provided by a classifier. The score can be probability, similarity, confidence, or any other real number that was used to determine the label value.

[Optional] on top of the label property. However when this property is used, the label property must be one of the keys and the keys must match to the values defined in the labelset + or labelsetUri annotation metadata. +
+

+ Properties from Thing +

+ + + + + + + + + + + +
+ Property + + Type + + Description +
+ id + + ID + + A unique identifier for the annotation or document. Uniqueness is relative to the view the annotation is in or the list of documents at the top level of a MMIF file. + + [Required] + +
+
+
+
+ + + \ No newline at end of file diff --git a/docs/vocabulary/Document/v1/index.html b/docs/vocabulary/Document/v1/index.html index a58cac8a..d11bf3c3 100644 --- a/docs/vocabulary/Document/v1/index.html +++ b/docs/vocabulary/Document/v1/index.html @@ -32,6 +32,10 @@

1.0.1 + , + + 1.0.2 +

@@ -175,7 +179,7 @@

- + \ No newline at end of file diff --git a/docs/vocabulary/ImageDocument/v1/index.html b/docs/vocabulary/ImageDocument/v1/index.html index 7e9d2700..35587487 100644 --- a/docs/vocabulary/ImageDocument/v1/index.html +++ b/docs/vocabulary/ImageDocument/v1/index.html @@ -32,6 +32,10 @@

1.0.1 + , + + 1.0.2 +

@@ -184,7 +188,7 @@

- + \ No newline at end of file diff --git a/docs/vocabulary/Interval/v2/index.html b/docs/vocabulary/Interval/v2/index.html new file mode 100644 index 00000000..efd94302 --- /dev/null +++ b/docs/vocabulary/Interval/v2/index.html @@ -0,0 +1,292 @@ + + + + + Interval + + + +
+
+ +
+
+
+

+ included in: + + 1.0.2 + +

+
+

+ + Thing + + + > + + + Annotation + + + > + + + Region + + + > + + + Interval + +

+
+ + + + + + + + + +
+ + Definition + + + An annotation over an interval of linear primary data, either a text, a video or audio stream. An Interval may be defined by pointing directly into primary data (by using start and end offsets) or by linking to one or more other Annotations with the targets property. This annotation type is intended to be an abstract type and typically one of the sub types will be used. +
+ + URI + + + + http://mmif.clams.ai/vocabulary/Interval/v2 + +
+

+ Metadata +

+

+ Metadata from Region +

+ + + + + + + + + + + +
+ Property + + Type + + Description +
+ timeUnit + + String + + Specifies which unit of time the measurement is based. Can be *seconds* or *milliseconds*, or in case of annotations on a VideoDocument, *frames*. +
+

+ Metadata from Annotation +

+ + + + + + + + + + + + + + + + + + + + + +
+ Property + + Type + + Description +
+ document + + ID + + The identifier of the document that the annotation is over. This has to be defined either at the metadata level, in which case it has scope over all annotations of the same type in a view, or at the instance level, in which it has scope over just the single annotation. +
+ labelset + + List of Strings + + When an annotation object contains results of a classification task, this metadata is used to specify the label values used in classification. Individual annotations then must have label property that is one of the values in this list.

[Note] Annotations from a classifier app must have this metadata or labelsetUri metadata.

[Note] Not all of labels specified in the labelset must occur in the output annotations. For example, a labelset can contain a catch-all negative label, but if the negative label can be not interesting enough to keep in the output annotation. +
+ labelsetUri + + String + + A URI to an externally defined labelset. Since the labelset metadata is a list of simple strings, this URI can be used to point to a more detailed definition of the labelset. This can be a JSON-LD document or a SKOS concept scheme, for example.

[Note] Annotations from a classifier app must have this metadata or labelset metadata. +
+

+ Properties +

+ + + + + + + + + + + + + + + + + + + + + +
+ Property + + Type + + Description +
+ start + + Integer + + The starting offset in the primary data. This point is inclusive. For time intervals, the unit is determined by the *timeUnit* metadata key. For text intervals, the unit is Unicode code point. +
+ end + + Integer + + The ending offset in the primary data. This point is exclusive. For time intervals, the unit is determined by the *timeUnit* metadata key. For text intervals, the unit is Unicode code point. +
+ targets + + List of IDs + + IDs of a sequence of annotations covering the region of primary data referred to by this annotation. Used as an alternative to *start* and *end* to point to component annotations (for example a token sequence) rather than directly into primary data, or to link two or more annotations (for example in a coreference annotation). +
+

+ Properties from Annotation +

+ + + + + + + + + + + + + + + + + + + + + +
+ Property + + Type + + Description +
+ document + + ID + + The identifier of the document that the annotation is over. +
+ label + + String + + A label given to this object by a classifier. The value must be a simple string value of the label and must be one of the values defined in the labelset or labelsetUri annotation metadata.

[Note] Annotations from a classifier app must have this property. +
+ classifications + + Map from String to Number + + A map from label values to their "score" numbers provided by a classifier. The score can be probability, similarity, confidence, or any other real number that was used to determine the label value.

[Optional] on top of the label property. However when this property is used, the label property must be one of the keys and the keys must match to the values defined in the labelset + or labelsetUri annotation metadata. +
+

+ Properties from Thing +

+ + + + + + + + + + + +
+ Property + + Type + + Description +
+ id + + ID + + A unique identifier for the annotation or document. Uniqueness is relative to the view the annotation is in or the list of documents at the top level of a MMIF file. + + [Required] + +
+
+
+
+ + + \ No newline at end of file diff --git a/docs/vocabulary/Polygon/v2/index.html b/docs/vocabulary/Polygon/v2/index.html new file mode 100644 index 00000000..fa289721 --- /dev/null +++ b/docs/vocabulary/Polygon/v2/index.html @@ -0,0 +1,284 @@ + + + + + Polygon + + + +
+
+ +
+
+
+

+ included in: + + 1.0.2 + +

+
+

+ + Thing + + + > + + + Annotation + + + > + + + Region + + + > + + + Polygon + +

+
+ + + + + + + + + +
+ + Definition + + + A polygon in an image or video. This is a two-dimensional object so if this occurs in a video it will be anchored to a particular frame or time point in the video. +
+ + URI + + + + http://mmif.clams.ai/vocabulary/Polygon/v2 + +
+

+ Metadata +

+

+ Metadata from Region +

+ + + + + + + + + + + +
+ Property + + Type + + Description +
+ timeUnit + + String + + Specifies which unit of time the measurement is based. Can be *seconds* or *milliseconds*, or in case of annotations on a VideoDocument, *frames*. +
+

+ Metadata from Annotation +

+ + + + + + + + + + + + + + + + + + + + + +
+ Property + + Type + + Description +
+ document + + ID + + The identifier of the document that the annotation is over. This has to be defined either at the metadata level, in which case it has scope over all annotations of the same type in a view, or at the instance level, in which it has scope over just the single annotation. +
+ labelset + + List of Strings + + When an annotation object contains results of a classification task, this metadata is used to specify the label values used in classification. Individual annotations then must have label property that is one of the values in this list.

[Note] Annotations from a classifier app must have this metadata or labelsetUri metadata.

[Note] Not all of labels specified in the labelset must occur in the output annotations. For example, a labelset can contain a catch-all negative label, but if the negative label can be not interesting enough to keep in the output annotation. +
+ labelsetUri + + String + + A URI to an externally defined labelset. Since the labelset metadata is a list of simple strings, this URI can be used to point to a more detailed definition of the labelset. This can be a JSON-LD document or a SKOS concept scheme, for example.

[Note] Annotations from a classifier app must have this metadata or labelset metadata. +
+

+ Properties +

+ + + + + + + + + + + + + + + + +
+ Property + + Type + + Description +
+ coordinates + + List of pairs + + The coordinates of the polygon, taking the top-left of the image as the origin (0,0). Unit used to measure the distance is the number of pixels. + + [Required] + +
+ timePoint + + Integer + + If on a video stream, the TimePoint that the BoundingBox occurs in. +
+

+ Properties from Annotation +

+ + + + + + + + + + + + + + + + + + + + + +
+ Property + + Type + + Description +
+ document + + ID + + The identifier of the document that the annotation is over. +
+ label + + String + + A label given to this object by a classifier. The value must be a simple string value of the label and must be one of the values defined in the labelset or labelsetUri annotation metadata.

[Note] Annotations from a classifier app must have this property. +
+ classifications + + Map from String to Number + + A map from label values to their "score" numbers provided by a classifier. The score can be probability, similarity, confidence, or any other real number that was used to determine the label value.

[Optional] on top of the label property. However when this property is used, the label property must be one of the keys and the keys must match to the values defined in the labelset + or labelsetUri annotation metadata. +
+

+ Properties from Thing +

+ + + + + + + + + + + +
+ Property + + Type + + Description +
+ id + + ID + + A unique identifier for the annotation or document. Uniqueness is relative to the view the annotation is in or the list of documents at the top level of a MMIF file. + + [Required] + +
+
+
+
+ + + \ No newline at end of file diff --git a/docs/vocabulary/Region/v2/index.html b/docs/vocabulary/Region/v2/index.html new file mode 100644 index 00000000..88462cff --- /dev/null +++ b/docs/vocabulary/Region/v2/index.html @@ -0,0 +1,237 @@ + + + + + Region + + + +
+
+ +
+
+
+

+ included in: + + 1.0.2 + +

+
+

+ + Thing + + + > + + + Annotation + + + > + + + Region + +

+
+ + + + + + + + + +
+ + Definition + + + An annotation over a region in primary data where primary data can be a text, an image, an audio stream or a video streem. Typically one of the sub types of this will be used. +
+ + URI + + + + http://mmif.clams.ai/vocabulary/Region/v2 + +
+

+ Metadata +

+ + + + + + + + + + + +
+ Property + + Type + + Description +
+ timeUnit + + String + + Specifies which unit of time the measurement is based. Can be *seconds* or *milliseconds*, or in case of annotations on a VideoDocument, *frames*. +
+

+ Metadata from Annotation +

+ + + + + + + + + + + + + + + + + + + + + +
+ Property + + Type + + Description +
+ document + + ID + + The identifier of the document that the annotation is over. This has to be defined either at the metadata level, in which case it has scope over all annotations of the same type in a view, or at the instance level, in which it has scope over just the single annotation. +
+ labelset + + List of Strings + + When an annotation object contains results of a classification task, this metadata is used to specify the label values used in classification. Individual annotations then must have label property that is one of the values in this list.

[Note] Annotations from a classifier app must have this metadata or labelsetUri metadata.

[Note] Not all of labels specified in the labelset must occur in the output annotations. For example, a labelset can contain a catch-all negative label, but if the negative label can be not interesting enough to keep in the output annotation. +
+ labelsetUri + + String + + A URI to an externally defined labelset. Since the labelset metadata is a list of simple strings, this URI can be used to point to a more detailed definition of the labelset. This can be a JSON-LD document or a SKOS concept scheme, for example.

[Note] Annotations from a classifier app must have this metadata or labelset metadata. +
+

+ Properties +

+

+ Properties from Annotation +

+ + + + + + + + + + + + + + + + + + + + + +
+ Property + + Type + + Description +
+ document + + ID + + The identifier of the document that the annotation is over. +
+ label + + String + + A label given to this object by a classifier. The value must be a simple string value of the label and must be one of the values defined in the labelset or labelsetUri annotation metadata.

[Note] Annotations from a classifier app must have this property. +
+ classifications + + Map from String to Number + + A map from label values to their "score" numbers provided by a classifier. The score can be probability, similarity, confidence, or any other real number that was used to determine the label value.

[Optional] on top of the label property. However when this property is used, the label property must be one of the keys and the keys must match to the values defined in the labelset + or labelsetUri annotation metadata. +
+

+ Properties from Thing +

+ + + + + + + + + + + +
+ Property + + Type + + Description +
+ id + + ID + + A unique identifier for the annotation or document. Uniqueness is relative to the view the annotation is in or the list of documents at the top level of a MMIF file. + + [Required] + +
+
+
+
+ + + \ No newline at end of file diff --git a/docs/vocabulary/Relation/v2/index.html b/docs/vocabulary/Relation/v2/index.html new file mode 100644 index 00000000..18d4fc5e --- /dev/null +++ b/docs/vocabulary/Relation/v2/index.html @@ -0,0 +1,213 @@ + + + + + Relation + + + +
+
+ +
+
+
+

+ included in: + + 1.0.2 + +

+
+

+ + Thing + + + > + + + Annotation + + + > + + + Relation + +

+
+ + + + + + + + + +
+ + Definition + + + Any relationship between two or more annotation types. For texts could be a grammatical relation such as subject-object, a semantic relation between meanings or roles, or a temporal relation indicating the simultaneity or ordering in time of events or states. For image regions and video objects this could involve spatial relations or part-whole relations. +
+ + URI + + + + http://mmif.clams.ai/vocabulary/Relation/v2 + +
+

+ Metadata +

+

+ Metadata from Annotation +

+ + + + + + + + + + + + + + + + + + + + + +
+ Property + + Type + + Description +
+ document + + ID + + The identifier of the document that the annotation is over. This has to be defined either at the metadata level, in which case it has scope over all annotations of the same type in a view, or at the instance level, in which it has scope over just the single annotation. +
+ labelset + + List of Strings + + When an annotation object contains results of a classification task, this metadata is used to specify the label values used in classification. Individual annotations then must have label property that is one of the values in this list.

[Note] Annotations from a classifier app must have this metadata or labelsetUri metadata.

[Note] Not all of labels specified in the labelset must occur in the output annotations. For example, a labelset can contain a catch-all negative label, but if the negative label can be not interesting enough to keep in the output annotation. +
+ labelsetUri + + String + + A URI to an externally defined labelset. Since the labelset metadata is a list of simple strings, this URI can be used to point to a more detailed definition of the labelset. This can be a JSON-LD document or a SKOS concept scheme, for example.

[Note] Annotations from a classifier app must have this metadata or labelset metadata. +
+

+ Properties +

+

+ Properties from Annotation +

+ + + + + + + + + + + + + + + + + + + + + +
+ Property + + Type + + Description +
+ document + + ID + + The identifier of the document that the annotation is over. +
+ label + + String + + A label given to this object by a classifier. The value must be a simple string value of the label and must be one of the values defined in the labelset or labelsetUri annotation metadata.

[Note] Annotations from a classifier app must have this property. +
+ classifications + + Map from String to Number + + A map from label values to their "score" numbers provided by a classifier. The score can be probability, similarity, confidence, or any other real number that was used to determine the label value.

[Optional] on top of the label property. However when this property is used, the label property must be one of the keys and the keys must match to the values defined in the labelset + or labelsetUri annotation metadata. +
+

+ Properties from Thing +

+ + + + + + + + + + + +
+ Property + + Type + + Description +
+ id + + ID + + A unique identifier for the annotation or document. Uniqueness is relative to the view the annotation is in or the list of documents at the top level of a MMIF file. + + [Required] + +
+
+
+
+ + + \ No newline at end of file diff --git a/docs/vocabulary/Span/v2/index.html b/docs/vocabulary/Span/v2/index.html new file mode 100644 index 00000000..39b54d38 --- /dev/null +++ b/docs/vocabulary/Span/v2/index.html @@ -0,0 +1,311 @@ + + + + + Span + + + +
+
+ +
+
+
+

+ included in: + + 1.0.2 + +

+
+

+ + Thing + + + > + + + Annotation + + + > + + + Region + + + > + + + Interval + + + > + + + Span + +

+
+ + + + + + + + + + + + + +
+ + Definition + + + An annotation over a region in primary text data. A Span may be defined by pointing directly into primary data (by using start and end offsets) or by linking to one or more other Annotations with the targets property. +
+ + URI + + + + http://mmif.clams.ai/vocabulary/Span/v2 + +
+ Similar to + + + http://vocab.lappsgrid.org/Region + +
+

+ Metadata +

+

+ Metadata from Region +

+ + + + + + + + + + + +
+ Property + + Type + + Description +
+ timeUnit + + String + + Specifies which unit of time the measurement is based. Can be *seconds* or *milliseconds*, or in case of annotations on a VideoDocument, *frames*. +
+

+ Metadata from Annotation +

+ + + + + + + + + + + + + + + + + + + + + +
+ Property + + Type + + Description +
+ document + + ID + + The identifier of the document that the annotation is over. This has to be defined either at the metadata level, in which case it has scope over all annotations of the same type in a view, or at the instance level, in which it has scope over just the single annotation. +
+ labelset + + List of Strings + + When an annotation object contains results of a classification task, this metadata is used to specify the label values used in classification. Individual annotations then must have label property that is one of the values in this list.

[Note] Annotations from a classifier app must have this metadata or labelsetUri metadata.

[Note] Not all of labels specified in the labelset must occur in the output annotations. For example, a labelset can contain a catch-all negative label, but if the negative label can be not interesting enough to keep in the output annotation. +
+ labelsetUri + + String + + A URI to an externally defined labelset. Since the labelset metadata is a list of simple strings, this URI can be used to point to a more detailed definition of the labelset. This can be a JSON-LD document or a SKOS concept scheme, for example.

[Note] Annotations from a classifier app must have this metadata or labelset metadata. +
+

+ Properties +

+

+ Properties from Interval +

+ + + + + + + + + + + + + + + + + + + + + +
+ Property + + Type + + Description +
+ start + + Integer + + The starting offset in the primary data. This point is inclusive. For time intervals, the unit is determined by the *timeUnit* metadata key. For text intervals, the unit is Unicode code point. +
+ end + + Integer + + The ending offset in the primary data. This point is exclusive. For time intervals, the unit is determined by the *timeUnit* metadata key. For text intervals, the unit is Unicode code point. +
+ targets + + List of IDs + + IDs of a sequence of annotations covering the region of primary data referred to by this annotation. Used as an alternative to *start* and *end* to point to component annotations (for example a token sequence) rather than directly into primary data, or to link two or more annotations (for example in a coreference annotation). +
+

+ Properties from Annotation +

+ + + + + + + + + + + + + + + + + + + + + +
+ Property + + Type + + Description +
+ document + + ID + + The identifier of the document that the annotation is over. +
+ label + + String + + A label given to this object by a classifier. The value must be a simple string value of the label and must be one of the values defined in the labelset or labelsetUri annotation metadata.

[Note] Annotations from a classifier app must have this property. +
+ classifications + + Map from String to Number + + A map from label values to their "score" numbers provided by a classifier. The score can be probability, similarity, confidence, or any other real number that was used to determine the label value.

[Optional] on top of the label property. However when this property is used, the label property must be one of the keys and the keys must match to the values defined in the labelset + or labelsetUri annotation metadata. +
+

+ Properties from Thing +

+ + + + + + + + + + + +
+ Property + + Type + + Description +
+ id + + ID + + A unique identifier for the annotation or document. Uniqueness is relative to the view the annotation is in or the list of documents at the top level of a MMIF file. + + [Required] + +
+
+
+
+ + + \ No newline at end of file diff --git a/docs/vocabulary/TextDocument/v1/index.html b/docs/vocabulary/TextDocument/v1/index.html index 710cca5a..75aa1534 100644 --- a/docs/vocabulary/TextDocument/v1/index.html +++ b/docs/vocabulary/TextDocument/v1/index.html @@ -32,6 +32,10 @@

1.0.1 + , + + 1.0.2 +

@@ -208,7 +212,7 @@

- + \ No newline at end of file diff --git a/docs/vocabulary/Thing/v1/index.html b/docs/vocabulary/Thing/v1/index.html index 63a6e89e..a79a653e 100644 --- a/docs/vocabulary/Thing/v1/index.html +++ b/docs/vocabulary/Thing/v1/index.html @@ -32,6 +32,10 @@

1.0.1 + , + + 1.0.2 +

@@ -131,7 +135,7 @@

- + \ No newline at end of file diff --git a/docs/vocabulary/TimeFrame/v3/index.html b/docs/vocabulary/TimeFrame/v3/index.html new file mode 100644 index 00000000..dfc5c3c4 --- /dev/null +++ b/docs/vocabulary/TimeFrame/v3/index.html @@ -0,0 +1,325 @@ + + + + + TimeFrame + + + +
+
+ +
+
+
+

+ included in: + + 1.0.2 + +

+
+

+ + Thing + + + > + + + Annotation + + + > + + + Region + + + > + + + Interval + + + > + + + TimeFrame + +

+
+ + + + + + + + + +
+ + Definition + + + A temporal interval in an audio or video stream. This is similar to the term segment used in audio processing, but that term has a different meaning in the image and video community. +
+ + URI + + + + http://mmif.clams.ai/vocabulary/TimeFrame/v3 + +
+

+ Metadata +

+

+ Metadata from Region +

+ + + + + + + + + + + +
+ Property + + Type + + Description +
+ timeUnit + + String + + Specifies which unit of time the measurement is based. Can be *seconds* or *milliseconds*, or in case of annotations on a VideoDocument, *frames*. +
+

+ Metadata from Annotation +

+ + + + + + + + + + + + + + + + + + + + + +
+ Property + + Type + + Description +
+ document + + ID + + The identifier of the document that the annotation is over. This has to be defined either at the metadata level, in which case it has scope over all annotations of the same type in a view, or at the instance level, in which it has scope over just the single annotation. +
+ labelset + + List of Strings + + When an annotation object contains results of a classification task, this metadata is used to specify the label values used in classification. Individual annotations then must have label property that is one of the values in this list.

[Note] Annotations from a classifier app must have this metadata or labelsetUri metadata.

[Note] Not all of labels specified in the labelset must occur in the output annotations. For example, a labelset can contain a catch-all negative label, but if the negative label can be not interesting enough to keep in the output annotation. +
+ labelsetUri + + String + + A URI to an externally defined labelset. Since the labelset metadata is a list of simple strings, this URI can be used to point to a more detailed definition of the labelset. This can be a JSON-LD document or a SKOS concept scheme, for example.

[Note] Annotations from a classifier app must have this metadata or labelset metadata. +
+

+ Properties +

+ + + + + + + + + + + +
+ Property + + Type + + Description +
+ frameType + + String + + The type of TimeFrame. Possible values include, but are not limited to, bars, tones, bars-and-tones, speech, noise, music, slate, chyron, lower-third, credits, and other.

No longer encouraged to use, instead label property should replace this property. +
+

+ Properties from Interval +

+ + + + + + + + + + + + + + + + + + + + + +
+ Property + + Type + + Description +
+ start + + Integer + + The starting offset in the primary data. This point is inclusive. For time intervals, the unit is determined by the *timeUnit* metadata key. For text intervals, the unit is Unicode code point. +
+ end + + Integer + + The ending offset in the primary data. This point is exclusive. For time intervals, the unit is determined by the *timeUnit* metadata key. For text intervals, the unit is Unicode code point. +
+ targets + + List of IDs + + IDs of a sequence of annotations covering the region of primary data referred to by this annotation. Used as an alternative to *start* and *end* to point to component annotations (for example a token sequence) rather than directly into primary data, or to link two or more annotations (for example in a coreference annotation). +
+

+ Properties from Annotation +

+ + + + + + + + + + + + + + + + + + + + + +
+ Property + + Type + + Description +
+ document + + ID + + The identifier of the document that the annotation is over. +
+ label + + String + + A label given to this object by a classifier. The value must be a simple string value of the label and must be one of the values defined in the labelset or labelsetUri annotation metadata.

[Note] Annotations from a classifier app must have this property. +
+ classifications + + Map from String to Number + + A map from label values to their "score" numbers provided by a classifier. The score can be probability, similarity, confidence, or any other real number that was used to determine the label value.

[Optional] on top of the label property. However when this property is used, the label property must be one of the keys and the keys must match to the values defined in the labelset + or labelsetUri annotation metadata. +
+

+ Properties from Thing +

+ + + + + + + + + + + +
+ Property + + Type + + Description +
+ id + + ID + + A unique identifier for the annotation or document. Uniqueness is relative to the view the annotation is in or the list of documents at the top level of a MMIF file. + + [Required] + +
+
+
+
+ + + \ No newline at end of file diff --git a/docs/vocabulary/TimePoint/v2/index.html b/docs/vocabulary/TimePoint/v2/index.html new file mode 100644 index 00000000..a368ba1a --- /dev/null +++ b/docs/vocabulary/TimePoint/v2/index.html @@ -0,0 +1,273 @@ + + + + + TimePoint + + + +
+
+ +
+
+
+

+ included in: + + 1.0.2 + +

+
+

+ + Thing + + + > + + + Annotation + + + > + + + Region + + + > + + + TimePoint + +

+
+ + + + + + + + + +
+ + Definition + + + A time point in an audio or video stream. +
+ + URI + + + + http://mmif.clams.ai/vocabulary/TimePoint/v2 + +
+

+ Metadata +

+

+ Metadata from Region +

+ + + + + + + + + + + +
+ Property + + Type + + Description +
+ timeUnit + + String + + Specifies which unit of time the measurement is based. Can be *seconds* or *milliseconds*, or in case of annotations on a VideoDocument, *frames*. +
+

+ Metadata from Annotation +

+ + + + + + + + + + + + + + + + + + + + + +
+ Property + + Type + + Description +
+ document + + ID + + The identifier of the document that the annotation is over. This has to be defined either at the metadata level, in which case it has scope over all annotations of the same type in a view, or at the instance level, in which it has scope over just the single annotation. +
+ labelset + + List of Strings + + When an annotation object contains results of a classification task, this metadata is used to specify the label values used in classification. Individual annotations then must have label property that is one of the values in this list.

[Note] Annotations from a classifier app must have this metadata or labelsetUri metadata.

[Note] Not all of labels specified in the labelset must occur in the output annotations. For example, a labelset can contain a catch-all negative label, but if the negative label can be not interesting enough to keep in the output annotation. +
+ labelsetUri + + String + + A URI to an externally defined labelset. Since the labelset metadata is a list of simple strings, this URI can be used to point to a more detailed definition of the labelset. This can be a JSON-LD document or a SKOS concept scheme, for example.

[Note] Annotations from a classifier app must have this metadata or labelset metadata. +
+

+ Properties +

+ + + + + + + + + + + +
+ Property + + Type + + Description +
+ timePoint + + Integer + + The starting offset in the stream. + + [Required] + +
+

+ Properties from Annotation +

+ + + + + + + + + + + + + + + + + + + + + +
+ Property + + Type + + Description +
+ document + + ID + + The identifier of the document that the annotation is over. +
+ label + + String + + A label given to this object by a classifier. The value must be a simple string value of the label and must be one of the values defined in the labelset or labelsetUri annotation metadata.

[Note] Annotations from a classifier app must have this property. +
+ classifications + + Map from String to Number + + A map from label values to their "score" numbers provided by a classifier. The score can be probability, similarity, confidence, or any other real number that was used to determine the label value.

[Optional] on top of the label property. However when this property is used, the label property must be one of the keys and the keys must match to the values defined in the labelset + or labelsetUri annotation metadata. +
+

+ Properties from Thing +

+ + + + + + + + + + + +
+ Property + + Type + + Description +
+ id + + ID + + A unique identifier for the annotation or document. Uniqueness is relative to the view the annotation is in or the list of documents at the top level of a MMIF file. + + [Required] + +
+
+
+
+ + + \ No newline at end of file diff --git a/docs/vocabulary/VideoDocument/v1/index.html b/docs/vocabulary/VideoDocument/v1/index.html index 79aaf257..d337ecc1 100644 --- a/docs/vocabulary/VideoDocument/v1/index.html +++ b/docs/vocabulary/VideoDocument/v1/index.html @@ -32,6 +32,10 @@

1.0.1 + , + + 1.0.2 +

@@ -184,7 +188,7 @@

- + \ No newline at end of file diff --git a/docs/vocabulary/VideoObject/v2/index.html b/docs/vocabulary/VideoObject/v2/index.html new file mode 100644 index 00000000..1e0268f2 --- /dev/null +++ b/docs/vocabulary/VideoObject/v2/index.html @@ -0,0 +1,273 @@ + + + + + VideoObject + + + +
+
+ +
+
+
+

+ included in: + + 1.0.2 + +

+
+

+ + Thing + + + > + + + Annotation + + + > + + + Region + + + > + + + VideoObject + +

+
+ + + + + + + + + +
+ + Definition + + + A sequence of Polygons, where each Polygon is associated with a TimePoint. So a VideoObject is in effect a sequence of image objects at certain time points. +
+ + URI + + + + http://mmif.clams.ai/vocabulary/VideoObject/v2 + +
+

+ Metadata +

+

+ Metadata from Region +

+ + + + + + + + + + + +
+ Property + + Type + + Description +
+ timeUnit + + String + + Specifies which unit of time the measurement is based. Can be *seconds* or *milliseconds*, or in case of annotations on a VideoDocument, *frames*. +
+

+ Metadata from Annotation +

+ + + + + + + + + + + + + + + + + + + + + +
+ Property + + Type + + Description +
+ document + + ID + + The identifier of the document that the annotation is over. This has to be defined either at the metadata level, in which case it has scope over all annotations of the same type in a view, or at the instance level, in which it has scope over just the single annotation. +
+ labelset + + List of Strings + + When an annotation object contains results of a classification task, this metadata is used to specify the label values used in classification. Individual annotations then must have label property that is one of the values in this list.

[Note] Annotations from a classifier app must have this metadata or labelsetUri metadata.

[Note] Not all of labels specified in the labelset must occur in the output annotations. For example, a labelset can contain a catch-all negative label, but if the negative label can be not interesting enough to keep in the output annotation. +
+ labelsetUri + + String + + A URI to an externally defined labelset. Since the labelset metadata is a list of simple strings, this URI can be used to point to a more detailed definition of the labelset. This can be a JSON-LD document or a SKOS concept scheme, for example.

[Note] Annotations from a classifier app must have this metadata or labelset metadata. +
+

+ Properties +

+ + + + + + + + + + + +
+ Property + + Type + + Description +
+ polygons + + List of IDs + + The Polygons that make up the object. + + [Required] + +
+

+ Properties from Annotation +

+ + + + + + + + + + + + + + + + + + + + + +
+ Property + + Type + + Description +
+ document + + ID + + The identifier of the document that the annotation is over. +
+ label + + String + + A label given to this object by a classifier. The value must be a simple string value of the label and must be one of the values defined in the labelset or labelsetUri annotation metadata.

[Note] Annotations from a classifier app must have this property. +
+ classifications + + Map from String to Number + + A map from label values to their "score" numbers provided by a classifier. The score can be probability, similarity, confidence, or any other real number that was used to determine the label value.

[Optional] on top of the label property. However when this property is used, the label property must be one of the keys and the keys must match to the values defined in the labelset + or labelsetUri annotation metadata. +
+

+ Properties from Thing +

+ + + + + + + + + + + +
+ Property + + Type + + Description +
+ id + + ID + + A unique identifier for the annotation or document. Uniqueness is relative to the view the annotation is in or the list of documents at the top level of a MMIF file. + + [Required] + +
+
+
+
+ + + \ No newline at end of file