girder_large_image_annotation.models package

Submodules

girder_large_image_annotation.models.annotation module

class girder_large_image_annotation.models.annotation.Annotation(*args, **kwargs)[source]

Bases: AccessControlledModel

This model is used to represent an annotation that is associated with an item. The annotation can contain any number of annotationelements, which are included because they reference this annotation as a parent. The annotation acts like these are a native part of it, though they are each stored as independent models to (eventually) permit faster spatial searching.

class Skill(value)[source]

Bases: Enum

An enumeration.

EXPERT = 'expert'
NOVICE = 'novice'
baseFields = ('_id', 'itemId', 'creatorId', 'created', 'updated', 'updatedId', 'public', 'publicFlags', 'groups')
createAnnotation(item, creator, annotation, public=None)[source]
deleteMetadata(annotation, fields)[source]

Delete metadata on an annotation. A ValidationException is thrown if the metadata field names contain a period (‘.’) or begin with a dollar sign (‘$’).

Parameters:
  • annotation (dict) – The annotation to delete metadata from.

  • fields – An array containing the field names to delete from the annotation’s meta field

Returns:

the annotation document

findAnnotatedImages(imageNameFilter=None, creator=None, user=None, level=2, force=None, offset=0, limit=0, sort=None, **kwargs)[source]

Find images associated with annotations.

The list returned by this function is paginated and filtered by access control using the standard girder kwargs.

Parameters:
  • imageNameFilter – A string used to filter images by name. An image name matches if it (or a subtoken) begins with this string. Subtokens are generated by splitting by the regex [\W_]+ This filter is case-insensitive.

  • creator – Filter by a user who is the creator of the annotation.

geojson(annotation)[source]

Yield an annotation as geojson generator.

Parameters:

annotation – The annotation to delete metadata from.

Yields:

geojson. General annotation properties are added to the first feature under the annotation tag.

getVersion(annotationId, version, user=None, force=False, *args, **kwargs)[source]

Get an annotation history version. This reconstructs the original annotation.

Parameters:
  • annotationId – the annotation to get history for.

  • version – the specific version to get.

  • user – the Girder user. If the user is not an admin, they must have read access on the item and the item must exist.

  • force – if True, don’t get the user access.

idRegex = re.compile('^[0-9a-f]{24}$')
initialize()[source]

Subclasses should override this and set the name of the collection as self.name. Also, they should set any indexed fields that they require.

injectAnnotationGroupSet(annotation)[source]
load(id, region=None, getElements=True, *args, **kwargs)[source]

Load an annotation, adding all or a subset of the elements to it.

Parameters:
  • region – if present, a dictionary restricting which annotations are returned. See annotationelement.getElements.

  • getElements – if False, don’t get elements associated with this annotation.

Returns:

the matching annotation or none.

numberInstance = (<class 'int'>, <class 'float'>)
remove(annotation, *args, **kwargs)[source]

When removing an annotation, remove all element associated with it. This overrides the collection delete_one method so that all of the triggers are fired as expected and cancelling from an event will work as needed.

Parameters:

annotation – the annotation document to remove.

removeOldAnnotations(remove=False, minAgeInDays=30, keepInactiveVersions=5)[source]

Remove annotations that (a) have no item or (b) are inactive and at least (1) a minimum age in days and (2) not the most recent inactive versions. Also remove any annotation elements that don’t have associated annotations and are a minimum age in days.

Parameters:
  • remove – if False, just report on what would be done. If true, actually remove the annotations and compact the collections.

  • minAgeInDays – only work on annotations that are at least this old. This must be greater than or equal to 7.

  • keepInactiveVersions – keep at least this many inactive versions of any annotation, regardless of age.

revertVersion(id, version=None, user=None, force=False)[source]

Revert to a previous version of an annotation.

Parameters:
  • id – the annotation id.

  • version – the version to revert to. None reverts to the previous version. If the annotation was deleted, this is the most recent version.

  • user – the user doing the reversion.

  • force – if True don’t authenticate the user with the associated item access.

save(annotation, *args, **kwargs)[source]

When saving an annotation, override the collection insert_one and replace_one methods so that we don’t save the elements with the main annotation. Still use the super class’s save method, so that all of the triggers are fired as expected and cancelling and modifications can be done as needed.

Because Mongo doesn’t support transactions, a version number is stored with the annotation and with the associated elements. This is used to add the new elements first, then update the annotation, and delete the old elements. The allows version integrity if another thread queries the annotation at the same time.

Parameters:

annotation – the annotation document to save.

Returns:

the saved document. If it is a new document, the _id has been added.

setAccessList(doc, access, save=False, **kwargs)[source]

The super class’s setAccessList function can save a document. However, annotations which have not loaded elements lose their elements when this occurs, because the validation step of the save function adds an empty element list. By using an update instead of a save, this prevents the problem.

setMetadata(annotation, metadata, allowNull=False)[source]

Set metadata on an annotation. A ValidationException is thrown in the cases where the metadata JSON object is badly formed, or if any of the metadata keys contains a period (‘.’).

Parameters:
  • annotation (dict) – The annotation to set the metadata on.

  • metadata (dict) – A dictionary containing key-value pairs to add to the annotations meta field

  • allowNull – Whether to allow null values to be set in the annotation’s metadata. If set to False or omitted, a null value will cause that metadata field to be deleted.

Returns:

the annotation document

updateAnnotation(annotation, updateUser=None)[source]

Update an annotation.

Parameters:
  • annotation – the annotation document to update.

  • updateUser – the user who is creating the update.

Returns:

the annotation document that was updated.

validate(doc)[source]

Models should implement this to validate the document before it enters the database. It must return the document with any necessary filters applied, or throw a ValidationException if validation of the document fails.

Parameters:

doc (dict) – The document to validate before saving to the collection.

validatorAnnotation = Draft6Validator(schema={'$schema': 'http://json-...a.org/schema#', 'additionalProperties': False, 'properties': {'attributes': {'additionalProperties': True, 'description': 'Subjective t...entire image.', 'title': 'Image Attributes', 'type': 'object'}, 'description': {'type': 'string'}, 'display': {'properties': {'visible': {'description': 'This advises...is displayed.', 'enum': ['new', True, False], 'type': ['boolean', 'string']}}, 'type': 'object'}, 'elements': {'description': 'Subjective t...atial region.', 'items': {'anyOf': [{'additionalProperties': False, 'description': 'The first po... of the arrow', 'properties': {...}, 'required': [...], ...}, {'additionalProperties': False, 'properties': {...}, 'required': [...], 'type': 'object'}, {'additionalProperties': False, 'decription': 'normal is th...ise specified', 'properties': {...}, 'required': [...], ...}, {'additionalProperties': False, 'description': 'ColorRange a... rangeValues.', 'properties': {...}, 'required': [...], ...}, {'additionalProperties': False, 'description': 'ColorRange a...rrespondence.', 'properties': {...}, 'required': [...], ...}, {'additionalProperties': False, 'properties': {...}, 'required': [...], 'type': 'object'}, ...]}, 'title': 'Image Markup', 'type': 'array'}, ...}, 'type': 'object'}, format_checker=None)
validatorAnnotationElement = Draft6Validator(schema={'anyOf': [{'additionalProperties': False, 'description': 'The first po... of the arrow', 'properties': {'fillColor': {'pattern': '^(#([0-9a-fA...\.|)\\d+\\))$', 'type': 'string'}, 'group': {'type': 'string'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {...}, 'fontSize': {...}, 'value': {...}, 'visibility': {...}}, 'required': ['value'], 'type': 'object'}, ...}, 'required': ['points', 'type'], ...}, {'additionalProperties': False, 'properties': {'center': {'description': 'An X, Y, Z c...e upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, ...}, 'fillColor': {'pattern': '^(#([0-9a-fA...\.|)\\d+\\))$', 'type': 'string'}, 'group': {'type': 'string'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, ...}, 'required': ['center', 'radius', 'type'], 'type': 'object'}, {'additionalProperties': False, 'decription': 'normal is th...ise specified', 'properties': {'center': {'description': 'An X, Y, Z c...e upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, ...}, 'fillColor': {'pattern': '^(#([0-9a-fA...\.|)\\d+\\))$', 'type': 'string'}, 'group': {'type': 'string'}, 'height': {'minimum': 0, 'type': 'number'}, ...}, 'required': ['center', 'height', 'type', 'width'], ...}, {'additionalProperties': False, 'description': 'ColorRange a... rangeValues.', 'properties': {'colorRange': {'description': 'A list of colors', 'items': {'pattern': '^(#([0-9a-fA...\.|)\\d+\\))$', 'type': 'string'}, 'type': 'array'}, 'dx': {'description': 'grid spacing...e x direction', 'type': 'number'}, 'dy': {'description': 'grid spacing...e y direction', 'type': 'number'}, 'gridWidth': {'description': 'The number o...h of the grid', 'minimum': 1, 'type': 'integer'}, ...}, 'required': ['gridWidth', 'type', 'values'], ...}, {'additionalProperties': False, 'description': 'ColorRange a...rrespondence.', 'properties': {'colorRange': {'description': 'A list of colors', 'items': {'pattern': '^(#([0-9a-fA...\.|)\\d+\\))$', 'type': 'string'}, 'type': 'array'}, 'group': {'type': 'string'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {...}, 'fontSize': {...}, 'value': {...}, 'visibility': {...}}, 'required': ['value'], 'type': 'object'}, ...}, 'required': ['points', 'type'], ...}, {'additionalProperties': False, 'properties': {'center': {'description': 'An X, Y, Z c...e upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, ...}, 'fillColor': {'pattern': '^(#([0-9a-fA...\.|)\\d+\\))$', 'type': 'string'}, 'group': {'type': 'string'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, ...}, 'required': ['center', 'type'], 'type': 'object'}, ...]}, format_checker=None)
versionList(annotationId, user=None, limit=0, offset=0, sort=(('_version', -1),), force=False)[source]

List annotation history entries for a specific annotationId. Only annotations that belong to an existing item that the user is allowed to view are included. If the user is an admin, all annotations will be included.

Parameters:
  • annotationId – the annotation to get history for.

  • user – the Girder user.

  • limit – maximum number of history entries to return.

  • offset – skip this many entries.

  • sort – the sort method used. Defaults to reverse _id.

  • force – if True, don’t authenticate the user.

Yields:

the entries in the list

class girder_large_image_annotation.models.annotation.AnnotationSchema[source]

Bases: object

annotationElementSchema = {'anyOf': [{'additionalProperties': False, 'description': 'The first point is the head of the arrow', 'properties': {'fillColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'group': {'type': 'string'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'lineColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'lineWidth': {'minimum': 0, 'type': 'number'}, 'points': {'items': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'maxItems': 2, 'minItems': 2, 'type': 'array'}, 'type': {'enum': ['arrow'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}}, 'required': ['points', 'type'], 'type': 'object'}, {'additionalProperties': False, 'properties': {'center': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'fillColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'group': {'type': 'string'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'lineColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'lineWidth': {'minimum': 0, 'type': 'number'}, 'radius': {'minimum': 0, 'type': 'number'}, 'type': {'enum': ['circle'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}}, 'required': ['center', 'radius', 'type'], 'type': 'object'}, {'additionalProperties': False, 'decription': 'normal is the positive z-axis unless otherwise specified', 'properties': {'center': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'fillColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'group': {'type': 'string'}, 'height': {'minimum': 0, 'type': 'number'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'lineColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'lineWidth': {'minimum': 0, 'type': 'number'}, 'normal': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'rotation': {'description': 'radians counterclockwise around normal', 'type': 'number'}, 'type': {'enum': ['ellipse'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}, 'width': {'minimum': 0, 'type': 'number'}}, 'required': ['center', 'height', 'type', 'width'], 'type': 'object'}, {'additionalProperties': False, 'description': 'ColorRange and rangeValues should have a one-to-one correspondence except for stepped contours where rangeValues needs one more entry than colorRange.  minColor and maxColor are the colors applies to values beyond the ranges in rangeValues.', 'properties': {'colorRange': {'description': 'A list of colors', 'items': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'type': 'array'}, 'dx': {'description': 'grid spacing in the x direction', 'type': 'number'}, 'dy': {'description': 'grid spacing in the y direction', 'type': 'number'}, 'gridWidth': {'description': 'The number of values across the width of the grid', 'minimum': 1, 'type': 'integer'}, 'group': {'type': 'string'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'interpretation': {'enum': ['heatmap', 'contour', 'choropleth'], 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'maxColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'minColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'normalizeRange': {'description': 'If true, rangeValues are on a scale of 0 to 1 and map to the minimum and maximum values on the data.  If false (the default), the rangeValues are the actual data values.', 'type': 'boolean'}, 'origin': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'radius': {'description': 'radius used for heatmap interpretation', 'exclusiveMinimum': 0, 'type': 'number'}, 'rangeValues': {'description': 'A weakly monotonic list of range values', 'items': {'type': 'number'}, 'type': 'array'}, 'stepped': {'type': 'boolean'}, 'type': {'enum': ['griddata'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}, 'values': {'description': 'The values of the grid.  This must have a multiple of gridWidth entries', 'items': {'type': 'number'}, 'type': 'array'}}, 'required': ['gridWidth', 'type', 'values'], 'type': 'object'}, {'additionalProperties': False, 'description': 'ColorRange and rangeValues should have a one-to-one correspondence.', 'properties': {'colorRange': {'description': 'A list of colors', 'items': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'type': 'array'}, 'group': {'type': 'string'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'normalizeRange': {'description': 'If true, rangeValues are on a scale of 0 to 1 and map to the minimum and maximum values on the data.  If false (the default), the rangeValues are the actual data values.', 'type': 'boolean'}, 'points': {'items': {'description': 'An X, Y, Z, value coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 4, 'minItems': 4, 'name': 'CoordinateWithValue', 'type': 'array'}, 'type': 'array'}, 'radius': {'exclusiveMinimum': 0, 'type': 'number'}, 'rangeValues': {'description': 'A weakly monotonic list of range values', 'items': {'type': 'number'}, 'type': 'array'}, 'scaleWithZoom': {'description': 'If true, scale the size of points with the zoom level of the map.', 'type': 'boolean'}, 'type': {'enum': ['heatmap'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}}, 'required': ['points', 'type'], 'type': 'object'}, {'additionalProperties': False, 'properties': {'center': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'fillColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'group': {'type': 'string'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'lineColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'lineWidth': {'minimum': 0, 'type': 'number'}, 'type': {'enum': ['point'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}}, 'required': ['center', 'type'], 'type': 'object'}, {'additionalProperties': False, 'properties': {'closed': {'description': 'polyline is open if closed flag is not specified', 'type': 'boolean'}, 'fillColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'group': {'type': 'string'}, 'holes': {'description': 'If closed is true, this is a list of polylines that are treated as holes in the base polygon. These should not cross each other and should be contained within the base polygon.', 'items': {'items': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'minItems': 3, 'type': 'array'}, 'type': 'array'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'lineColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'lineWidth': {'minimum': 0, 'type': 'number'}, 'points': {'items': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'minItems': 2, 'type': 'array'}, 'type': {'enum': ['polyline'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}}, 'required': ['points', 'type'], 'type': 'object'}, {'additionalProperties': False, 'decription': 'normal is the positive z-axis unless otherwise specified', 'properties': {'center': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'fillColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'group': {'type': 'string'}, 'height': {'minimum': 0, 'type': 'number'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'lineColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'lineWidth': {'minimum': 0, 'type': 'number'}, 'normal': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'rotation': {'description': 'radians counterclockwise around normal', 'type': 'number'}, 'type': {'enum': ['rectangle'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}, 'width': {'minimum': 0, 'type': 'number'}}, 'required': ['center', 'height', 'type', 'width'], 'type': 'object'}, {'additionalProperties': False, 'decription': 'normal is the positive z-axis unless otherwise specified', 'properties': {'center': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'fillColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'group': {'type': 'string'}, 'height': {'minimum': 0, 'type': 'number'}, 'heightSubdivisions': {'minimum': 1, 'type': 'integer'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'lineColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'lineWidth': {'minimum': 0, 'type': 'number'}, 'normal': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'rotation': {'description': 'radians counterclockwise around normal', 'type': 'number'}, 'type': {'enum': ['rectanglegrid'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}, 'width': {'minimum': 0, 'type': 'number'}, 'widthSubdivisions': {'minimum': 1, 'type': 'integer'}}, 'required': ['center', 'height', 'heightSubdivisions', 'type', 'width', 'widthSubdivisions'], 'type': 'object'}, {'additionalProperties': False, 'description': 'An image overlay on top of the base resource.', 'properties': {'girderId': {'description': 'Girder item ID containing the image to overlay.', 'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'group': {'type': 'string'}, 'hasAlpha': {'description': 'If true, the image is treated assuming it has an alpha channel.', 'type': 'boolean'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'opacity': {'description': 'Default opacity for this image overlay. Must be between 0 and 1. Defaults to 1.', 'maximum': 1, 'minimum': 0, 'type': 'number'}, 'transform': {'description': 'Specification for an affine transform of the image overlay. Includes a 2D transform matrix, an X offset and a Y offset.', 'properties': {'matrix': {'description': 'A 2D matrix representing the transform of an image overlay.', 'items': {'maxItems': 2, 'minItems': 2, 'type': 'array'}, 'maxItems': 2, 'minItems': 2, 'type': 'array'}, 'xoffset': {'type': 'number'}, 'yoffset': {'type': 'number'}}, 'type': 'object'}, 'type': {'enum': ['image'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}}, 'required': ['girderId', 'type'], 'type': 'object'}, {'additionalProperties': False, 'description': 'A tiled pixelmap to overlay onto a base resource.', 'properties': {'boundaries': {'description': 'True if the pixelmap doubles pixel values such that even values are the fill and odd values the are stroke of each superpixel. If true, the length of the values array should be half of the maximum value in the pixelmap.', 'type': 'boolean'}, 'categories': {'description': 'An array used to map between the values array and color values. Can also contain semantic information for color values.', 'items': {'additionalProperties': False, 'properties': {'description': {'description': 'A more detailed explanation of the meaining of this category.', 'type': 'string'}, 'fillColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'label': {'description': 'A string representing the semantic meaning of regions of the map with the corresponding color.', 'type': 'string'}, 'strokeColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}}, 'required': ['fillColor'], 'type': 'object'}, 'type': 'array'}, 'girderId': {'description': 'Girder item ID containing the image to overlay.', 'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'group': {'type': 'string'}, 'hasAlpha': {'description': 'If true, the image is treated assuming it has an alpha channel.', 'type': 'boolean'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'opacity': {'description': 'Default opacity for this image overlay. Must be between 0 and 1. Defaults to 1.', 'maximum': 1, 'minimum': 0, 'type': 'number'}, 'transform': {'description': 'Specification for an affine transform of the image overlay. Includes a 2D transform matrix, an X offset and a Y offset.', 'properties': {'matrix': {'description': 'A 2D matrix representing the transform of an image overlay.', 'items': {'maxItems': 2, 'minItems': 2, 'type': 'array'}, 'maxItems': 2, 'minItems': 2, 'type': 'array'}, 'xoffset': {'type': 'number'}, 'yoffset': {'type': 'number'}}, 'type': 'object'}, 'type': {'enum': ['pixelmap'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}, 'values': {'description': 'An array where the indices correspond to pixel values in the pixel map image and the values are used to look up the appropriate color in the categories property.', 'items': {'type': 'integer'}, 'type': 'array'}}, 'required': ['boundaries', 'categories', 'girderId', 'type', 'values'], 'type': 'object'}]}
annotationSchema = {'$schema': 'http://json-schema.org/schema#', 'additionalProperties': False, 'properties': {'attributes': {'additionalProperties': True, 'description': 'Subjective things that apply to the entire image.', 'title': 'Image Attributes', 'type': 'object'}, 'description': {'type': 'string'}, 'display': {'properties': {'visible': {'description': 'This advises viewers on when the annotation should be shown.  If "new" (the default), show the annotation when it is first added to the system.  If false, don\'t show the annotation by default.  If true, show the annotation when the item is displayed.', 'enum': ['new', True, False], 'type': ['boolean', 'string']}}, 'type': 'object'}, 'elements': {'description': 'Subjective things that apply to a spatial region.', 'items': {'anyOf': [{'additionalProperties': False, 'description': 'The first point is the head of the arrow', 'properties': {'fillColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'group': {'type': 'string'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'lineColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'lineWidth': {'minimum': 0, 'type': 'number'}, 'points': {'items': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'maxItems': 2, 'minItems': 2, 'type': 'array'}, 'type': {'enum': ['arrow'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}}, 'required': ['points', 'type'], 'type': 'object'}, {'additionalProperties': False, 'properties': {'center': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'fillColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'group': {'type': 'string'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'lineColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'lineWidth': {'minimum': 0, 'type': 'number'}, 'radius': {'minimum': 0, 'type': 'number'}, 'type': {'enum': ['circle'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}}, 'required': ['center', 'radius', 'type'], 'type': 'object'}, {'additionalProperties': False, 'decription': 'normal is the positive z-axis unless otherwise specified', 'properties': {'center': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'fillColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'group': {'type': 'string'}, 'height': {'minimum': 0, 'type': 'number'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'lineColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'lineWidth': {'minimum': 0, 'type': 'number'}, 'normal': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'rotation': {'description': 'radians counterclockwise around normal', 'type': 'number'}, 'type': {'enum': ['ellipse'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}, 'width': {'minimum': 0, 'type': 'number'}}, 'required': ['center', 'height', 'type', 'width'], 'type': 'object'}, {'additionalProperties': False, 'description': 'ColorRange and rangeValues should have a one-to-one correspondence except for stepped contours where rangeValues needs one more entry than colorRange.  minColor and maxColor are the colors applies to values beyond the ranges in rangeValues.', 'properties': {'colorRange': {'description': 'A list of colors', 'items': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'type': 'array'}, 'dx': {'description': 'grid spacing in the x direction', 'type': 'number'}, 'dy': {'description': 'grid spacing in the y direction', 'type': 'number'}, 'gridWidth': {'description': 'The number of values across the width of the grid', 'minimum': 1, 'type': 'integer'}, 'group': {'type': 'string'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'interpretation': {'enum': ['heatmap', 'contour', 'choropleth'], 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'maxColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'minColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'normalizeRange': {'description': 'If true, rangeValues are on a scale of 0 to 1 and map to the minimum and maximum values on the data.  If false (the default), the rangeValues are the actual data values.', 'type': 'boolean'}, 'origin': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'radius': {'description': 'radius used for heatmap interpretation', 'exclusiveMinimum': 0, 'type': 'number'}, 'rangeValues': {'description': 'A weakly monotonic list of range values', 'items': {'type': 'number'}, 'type': 'array'}, 'stepped': {'type': 'boolean'}, 'type': {'enum': ['griddata'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}, 'values': {'description': 'The values of the grid.  This must have a multiple of gridWidth entries', 'items': {'type': 'number'}, 'type': 'array'}}, 'required': ['gridWidth', 'type', 'values'], 'type': 'object'}, {'additionalProperties': False, 'description': 'ColorRange and rangeValues should have a one-to-one correspondence.', 'properties': {'colorRange': {'description': 'A list of colors', 'items': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'type': 'array'}, 'group': {'type': 'string'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'normalizeRange': {'description': 'If true, rangeValues are on a scale of 0 to 1 and map to the minimum and maximum values on the data.  If false (the default), the rangeValues are the actual data values.', 'type': 'boolean'}, 'points': {'items': {'description': 'An X, Y, Z, value coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 4, 'minItems': 4, 'name': 'CoordinateWithValue', 'type': 'array'}, 'type': 'array'}, 'radius': {'exclusiveMinimum': 0, 'type': 'number'}, 'rangeValues': {'description': 'A weakly monotonic list of range values', 'items': {'type': 'number'}, 'type': 'array'}, 'scaleWithZoom': {'description': 'If true, scale the size of points with the zoom level of the map.', 'type': 'boolean'}, 'type': {'enum': ['heatmap'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}}, 'required': ['points', 'type'], 'type': 'object'}, {'additionalProperties': False, 'properties': {'center': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'fillColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'group': {'type': 'string'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'lineColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'lineWidth': {'minimum': 0, 'type': 'number'}, 'type': {'enum': ['point'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}}, 'required': ['center', 'type'], 'type': 'object'}, {'additionalProperties': False, 'properties': {'closed': {'description': 'polyline is open if closed flag is not specified', 'type': 'boolean'}, 'fillColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'group': {'type': 'string'}, 'holes': {'description': 'If closed is true, this is a list of polylines that are treated as holes in the base polygon. These should not cross each other and should be contained within the base polygon.', 'items': {'items': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'minItems': 3, 'type': 'array'}, 'type': 'array'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'lineColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'lineWidth': {'minimum': 0, 'type': 'number'}, 'points': {'items': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'minItems': 2, 'type': 'array'}, 'type': {'enum': ['polyline'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}}, 'required': ['points', 'type'], 'type': 'object'}, {'additionalProperties': False, 'decription': 'normal is the positive z-axis unless otherwise specified', 'properties': {'center': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'fillColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'group': {'type': 'string'}, 'height': {'minimum': 0, 'type': 'number'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'lineColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'lineWidth': {'minimum': 0, 'type': 'number'}, 'normal': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'rotation': {'description': 'radians counterclockwise around normal', 'type': 'number'}, 'type': {'enum': ['rectangle'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}, 'width': {'minimum': 0, 'type': 'number'}}, 'required': ['center', 'height', 'type', 'width'], 'type': 'object'}, {'additionalProperties': False, 'decription': 'normal is the positive z-axis unless otherwise specified', 'properties': {'center': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'fillColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'group': {'type': 'string'}, 'height': {'minimum': 0, 'type': 'number'}, 'heightSubdivisions': {'minimum': 1, 'type': 'integer'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'lineColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'lineWidth': {'minimum': 0, 'type': 'number'}, 'normal': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'rotation': {'description': 'radians counterclockwise around normal', 'type': 'number'}, 'type': {'enum': ['rectanglegrid'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}, 'width': {'minimum': 0, 'type': 'number'}, 'widthSubdivisions': {'minimum': 1, 'type': 'integer'}}, 'required': ['center', 'height', 'heightSubdivisions', 'type', 'width', 'widthSubdivisions'], 'type': 'object'}, {'additionalProperties': False, 'description': 'An image overlay on top of the base resource.', 'properties': {'girderId': {'description': 'Girder item ID containing the image to overlay.', 'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'group': {'type': 'string'}, 'hasAlpha': {'description': 'If true, the image is treated assuming it has an alpha channel.', 'type': 'boolean'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'opacity': {'description': 'Default opacity for this image overlay. Must be between 0 and 1. Defaults to 1.', 'maximum': 1, 'minimum': 0, 'type': 'number'}, 'transform': {'description': 'Specification for an affine transform of the image overlay. Includes a 2D transform matrix, an X offset and a Y offset.', 'properties': {'matrix': {'description': 'A 2D matrix representing the transform of an image overlay.', 'items': {'maxItems': 2, 'minItems': 2, 'type': 'array'}, 'maxItems': 2, 'minItems': 2, 'type': 'array'}, 'xoffset': {'type': 'number'}, 'yoffset': {'type': 'number'}}, 'type': 'object'}, 'type': {'enum': ['image'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}}, 'required': ['girderId', 'type'], 'type': 'object'}, {'additionalProperties': False, 'description': 'A tiled pixelmap to overlay onto a base resource.', 'properties': {'boundaries': {'description': 'True if the pixelmap doubles pixel values such that even values are the fill and odd values the are stroke of each superpixel. If true, the length of the values array should be half of the maximum value in the pixelmap.', 'type': 'boolean'}, 'categories': {'description': 'An array used to map between the values array and color values. Can also contain semantic information for color values.', 'items': {'additionalProperties': False, 'properties': {'description': {'description': 'A more detailed explanation of the meaining of this category.', 'type': 'string'}, 'fillColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'label': {'description': 'A string representing the semantic meaning of regions of the map with the corresponding color.', 'type': 'string'}, 'strokeColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}}, 'required': ['fillColor'], 'type': 'object'}, 'type': 'array'}, 'girderId': {'description': 'Girder item ID containing the image to overlay.', 'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'group': {'type': 'string'}, 'hasAlpha': {'description': 'If true, the image is treated assuming it has an alpha channel.', 'type': 'boolean'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'opacity': {'description': 'Default opacity for this image overlay. Must be between 0 and 1. Defaults to 1.', 'maximum': 1, 'minimum': 0, 'type': 'number'}, 'transform': {'description': 'Specification for an affine transform of the image overlay. Includes a 2D transform matrix, an X offset and a Y offset.', 'properties': {'matrix': {'description': 'A 2D matrix representing the transform of an image overlay.', 'items': {'maxItems': 2, 'minItems': 2, 'type': 'array'}, 'maxItems': 2, 'minItems': 2, 'type': 'array'}, 'xoffset': {'type': 'number'}, 'yoffset': {'type': 'number'}}, 'type': 'object'}, 'type': {'enum': ['pixelmap'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}, 'values': {'description': 'An array where the indices correspond to pixel values in the pixel map image and the values are used to look up the appropriate color in the categories property.', 'items': {'type': 'integer'}, 'type': 'array'}}, 'required': ['boundaries', 'categories', 'girderId', 'type', 'values'], 'type': 'object'}]}, 'title': 'Image Markup', 'type': 'array'}, 'name': {'minLength': 1, 'type': 'string'}}, 'type': 'object'}
arrowShapeSchema = {'additionalProperties': False, 'description': 'The first point is the head of the arrow', 'properties': {'fillColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'group': {'type': 'string'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'lineColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'lineWidth': {'minimum': 0, 'type': 'number'}, 'points': {'items': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'maxItems': 2, 'minItems': 2, 'type': 'array'}, 'type': {'enum': ['arrow'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}}, 'required': ['points', 'type'], 'type': 'object'}
baseElementSchema = {'additionalProperties': True, 'properties': {'group': {'type': 'string'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'type': {'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}}, 'required': ['type'], 'type': 'object'}
baseRectangleShapeSchema = {'additionalProperties': True, 'decription': 'normal is the positive z-axis unless otherwise specified', 'properties': {'center': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'fillColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'group': {'type': 'string'}, 'height': {'minimum': 0, 'type': 'number'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'lineColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'lineWidth': {'minimum': 0, 'type': 'number'}, 'normal': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'rotation': {'description': 'radians counterclockwise around normal', 'type': 'number'}, 'type': {'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}, 'width': {'minimum': 0, 'type': 'number'}}, 'required': ['center', 'height', 'type', 'width'], 'type': 'object'}
baseShapeSchema = {'additionalProperties': True, 'properties': {'group': {'type': 'string'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'lineColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'lineWidth': {'minimum': 0, 'type': 'number'}, 'type': {'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}}, 'required': ['type'], 'type': 'object'}
circleShapeSchema = {'additionalProperties': False, 'properties': {'center': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'fillColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'group': {'type': 'string'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'lineColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'lineWidth': {'minimum': 0, 'type': 'number'}, 'radius': {'minimum': 0, 'type': 'number'}, 'type': {'enum': ['circle'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}}, 'required': ['center', 'radius', 'type'], 'type': 'object'}
colorRangeSchema = {'description': 'A list of colors', 'items': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'type': 'array'}
colorSchema = {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}
coordSchema = {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}
coordValueSchema = {'description': 'An X, Y, Z, value coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 4, 'minItems': 4, 'name': 'CoordinateWithValue', 'type': 'array'}
ellipseShapeSchema = {'additionalProperties': False, 'decription': 'normal is the positive z-axis unless otherwise specified', 'properties': {'center': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'fillColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'group': {'type': 'string'}, 'height': {'minimum': 0, 'type': 'number'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'lineColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'lineWidth': {'minimum': 0, 'type': 'number'}, 'normal': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'rotation': {'description': 'radians counterclockwise around normal', 'type': 'number'}, 'type': {'enum': ['ellipse'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}, 'width': {'minimum': 0, 'type': 'number'}}, 'required': ['center', 'height', 'type', 'width'], 'type': 'object'}
griddataSchema = {'additionalProperties': False, 'description': 'ColorRange and rangeValues should have a one-to-one correspondence except for stepped contours where rangeValues needs one more entry than colorRange.  minColor and maxColor are the colors applies to values beyond the ranges in rangeValues.', 'properties': {'colorRange': {'description': 'A list of colors', 'items': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'type': 'array'}, 'dx': {'description': 'grid spacing in the x direction', 'type': 'number'}, 'dy': {'description': 'grid spacing in the y direction', 'type': 'number'}, 'gridWidth': {'description': 'The number of values across the width of the grid', 'minimum': 1, 'type': 'integer'}, 'group': {'type': 'string'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'interpretation': {'enum': ['heatmap', 'contour', 'choropleth'], 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'maxColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'minColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'normalizeRange': {'description': 'If true, rangeValues are on a scale of 0 to 1 and map to the minimum and maximum values on the data.  If false (the default), the rangeValues are the actual data values.', 'type': 'boolean'}, 'origin': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'radius': {'description': 'radius used for heatmap interpretation', 'exclusiveMinimum': 0, 'type': 'number'}, 'rangeValues': {'description': 'A weakly monotonic list of range values', 'items': {'type': 'number'}, 'type': 'array'}, 'stepped': {'type': 'boolean'}, 'type': {'enum': ['griddata'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}, 'values': {'description': 'The values of the grid.  This must have a multiple of gridWidth entries', 'items': {'type': 'number'}, 'type': 'array'}}, 'required': ['gridWidth', 'type', 'values'], 'type': 'object'}
groupSchema = {'type': 'string'}
heatmapSchema = {'additionalProperties': False, 'description': 'ColorRange and rangeValues should have a one-to-one correspondence.', 'properties': {'colorRange': {'description': 'A list of colors', 'items': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'type': 'array'}, 'group': {'type': 'string'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'normalizeRange': {'description': 'If true, rangeValues are on a scale of 0 to 1 and map to the minimum and maximum values on the data.  If false (the default), the rangeValues are the actual data values.', 'type': 'boolean'}, 'points': {'items': {'description': 'An X, Y, Z, value coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 4, 'minItems': 4, 'name': 'CoordinateWithValue', 'type': 'array'}, 'type': 'array'}, 'radius': {'exclusiveMinimum': 0, 'type': 'number'}, 'rangeValues': {'description': 'A weakly monotonic list of range values', 'items': {'type': 'number'}, 'type': 'array'}, 'scaleWithZoom': {'description': 'If true, scale the size of points with the zoom level of the map.', 'type': 'boolean'}, 'type': {'enum': ['heatmap'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}}, 'required': ['points', 'type'], 'type': 'object'}
labelSchema = {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}
overlaySchema = {'additionalProperties': False, 'description': 'An image overlay on top of the base resource.', 'properties': {'girderId': {'description': 'Girder item ID containing the image to overlay.', 'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'group': {'type': 'string'}, 'hasAlpha': {'description': 'If true, the image is treated assuming it has an alpha channel.', 'type': 'boolean'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'opacity': {'description': 'Default opacity for this image overlay. Must be between 0 and 1. Defaults to 1.', 'maximum': 1, 'minimum': 0, 'type': 'number'}, 'transform': {'description': 'Specification for an affine transform of the image overlay. Includes a 2D transform matrix, an X offset and a Y offset.', 'properties': {'matrix': {'description': 'A 2D matrix representing the transform of an image overlay.', 'items': {'maxItems': 2, 'minItems': 2, 'type': 'array'}, 'maxItems': 2, 'minItems': 2, 'type': 'array'}, 'xoffset': {'type': 'number'}, 'yoffset': {'type': 'number'}}, 'type': 'object'}, 'type': {'enum': ['image'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}}, 'required': ['girderId', 'type'], 'type': 'object'}
pixelmapCategorySchema = {'additionalProperties': False, 'properties': {'description': {'description': 'A more detailed explanation of the meaining of this category.', 'type': 'string'}, 'fillColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'label': {'description': 'A string representing the semantic meaning of regions of the map with the corresponding color.', 'type': 'string'}, 'strokeColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}}, 'required': ['fillColor'], 'type': 'object'}
pixelmapSchema = {'additionalProperties': False, 'description': 'A tiled pixelmap to overlay onto a base resource.', 'properties': {'boundaries': {'description': 'True if the pixelmap doubles pixel values such that even values are the fill and odd values the are stroke of each superpixel. If true, the length of the values array should be half of the maximum value in the pixelmap.', 'type': 'boolean'}, 'categories': {'description': 'An array used to map between the values array and color values. Can also contain semantic information for color values.', 'items': {'additionalProperties': False, 'properties': {'description': {'description': 'A more detailed explanation of the meaining of this category.', 'type': 'string'}, 'fillColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'label': {'description': 'A string representing the semantic meaning of regions of the map with the corresponding color.', 'type': 'string'}, 'strokeColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}}, 'required': ['fillColor'], 'type': 'object'}, 'type': 'array'}, 'girderId': {'description': 'Girder item ID containing the image to overlay.', 'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'group': {'type': 'string'}, 'hasAlpha': {'description': 'If true, the image is treated assuming it has an alpha channel.', 'type': 'boolean'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'opacity': {'description': 'Default opacity for this image overlay. Must be between 0 and 1. Defaults to 1.', 'maximum': 1, 'minimum': 0, 'type': 'number'}, 'transform': {'description': 'Specification for an affine transform of the image overlay. Includes a 2D transform matrix, an X offset and a Y offset.', 'properties': {'matrix': {'description': 'A 2D matrix representing the transform of an image overlay.', 'items': {'maxItems': 2, 'minItems': 2, 'type': 'array'}, 'maxItems': 2, 'minItems': 2, 'type': 'array'}, 'xoffset': {'type': 'number'}, 'yoffset': {'type': 'number'}}, 'type': 'object'}, 'type': {'enum': ['pixelmap'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}, 'values': {'description': 'An array where the indices correspond to pixel values in the pixel map image and the values are used to look up the appropriate color in the categories property.', 'items': {'type': 'integer'}, 'type': 'array'}}, 'required': ['boundaries', 'categories', 'girderId', 'type', 'values'], 'type': 'object'}
pointShapeSchema = {'additionalProperties': False, 'properties': {'center': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'fillColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'group': {'type': 'string'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'lineColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'lineWidth': {'minimum': 0, 'type': 'number'}, 'type': {'enum': ['point'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}}, 'required': ['center', 'type'], 'type': 'object'}
polylineShapeSchema = {'additionalProperties': False, 'properties': {'closed': {'description': 'polyline is open if closed flag is not specified', 'type': 'boolean'}, 'fillColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'group': {'type': 'string'}, 'holes': {'description': 'If closed is true, this is a list of polylines that are treated as holes in the base polygon. These should not cross each other and should be contained within the base polygon.', 'items': {'items': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'minItems': 3, 'type': 'array'}, 'type': 'array'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'lineColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'lineWidth': {'minimum': 0, 'type': 'number'}, 'points': {'items': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'minItems': 2, 'type': 'array'}, 'type': {'enum': ['polyline'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}}, 'required': ['points', 'type'], 'type': 'object'}
rangeValueSchema = {'description': 'A weakly monotonic list of range values', 'items': {'type': 'number'}, 'type': 'array'}
rectangleGridShapeSchema = {'additionalProperties': False, 'decription': 'normal is the positive z-axis unless otherwise specified', 'properties': {'center': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'fillColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'group': {'type': 'string'}, 'height': {'minimum': 0, 'type': 'number'}, 'heightSubdivisions': {'minimum': 1, 'type': 'integer'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'lineColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'lineWidth': {'minimum': 0, 'type': 'number'}, 'normal': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'rotation': {'description': 'radians counterclockwise around normal', 'type': 'number'}, 'type': {'enum': ['rectanglegrid'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}, 'width': {'minimum': 0, 'type': 'number'}, 'widthSubdivisions': {'minimum': 1, 'type': 'integer'}}, 'required': ['center', 'height', 'heightSubdivisions', 'type', 'width', 'widthSubdivisions'], 'type': 'object'}
rectangleShapeSchema = {'additionalProperties': False, 'decription': 'normal is the positive z-axis unless otherwise specified', 'properties': {'center': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'fillColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'group': {'type': 'string'}, 'height': {'minimum': 0, 'type': 'number'}, 'id': {'pattern': '^[0-9a-f]{24}$', 'type': 'string'}, 'label': {'additionalProperties': False, 'properties': {'color': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'fontSize': {'exclusiveMinimum': 0, 'type': 'number'}, 'value': {'type': 'string'}, 'visibility': {'enum': ['hidden', 'always', 'onhover'], 'type': 'string'}}, 'required': ['value'], 'type': 'object'}, 'lineColor': {'pattern': '^(#([0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})|rgb\\(\\d+,\\s*\\d+,\\s*\\d+\\)|rgba\\(\\d+,\\s*\\d+,\\s*\\d+,\\s*(\\d?\\.|)\\d+\\))$', 'type': 'string'}, 'lineWidth': {'minimum': 0, 'type': 'number'}, 'normal': {'description': 'An X, Y, Z coordinate tuple, in base layer pixel coordinates, where the origin is the upper-left.', 'items': {'type': 'number'}, 'maxItems': 3, 'minItems': 3, 'name': 'Coordinate', 'type': 'array'}, 'rotation': {'description': 'radians counterclockwise around normal', 'type': 'number'}, 'type': {'enum': ['rectangle'], 'type': 'string'}, 'user': {'additionalProperties': True, 'type': 'object'}, 'width': {'minimum': 0, 'type': 'number'}}, 'required': ['center', 'height', 'type', 'width'], 'type': 'object'}
transformArray = {'description': 'A 2D matrix representing the transform of an image overlay.', 'items': {'maxItems': 2, 'minItems': 2, 'type': 'array'}, 'maxItems': 2, 'minItems': 2, 'type': 'array'}
userSchema = {'additionalProperties': True, 'type': 'object'}
girder_large_image_annotation.models.annotation.extendSchema(base, add)[source]

girder_large_image_annotation.models.annotationelement module

class girder_large_image_annotation.models.annotationelement.Annotationelement(*args, **kwargs)[source]

Bases: Model

bboxKeys = {'bottom': ('bbox.lowy', '$lt'), 'details': ('bbox.details', None), 'high': ('bbox.lowz', '$lt'), 'left': ('bbox.highx', '$gte'), 'low': ('bbox.highz', '$gte'), 'minimumSize': ('bbox.size', '$gte'), 'right': ('bbox.lowx', '$lt'), 'size': ('bbox.size', None), 'top': ('bbox.highy', '$gte')}
getElementGroupSet(annotation)[source]
getElements(annotation, region=None)[source]

Given an annotation, fetch the elements from the database and add them to it.

When a region is used to request specific element, the following keys can be specified:

left, right, top, bottom, low, high:

the spatial area where elements are located, all in pixels. If an element’s bounding box is at least partially within the requested area, that element is included.

minimumSize:

the minimum size of an element to return.

sort, sortdir:

standard sort options. The sort key can include size and details.

limit:

limit the total number of elements by this value. Defaults to no limit.

offset:

the offset within the query to start returning values. If maxDetails is used, to get subsequent sets of elements, the offset needs to be increased by the actual number of elements returned from a previous query, which will vary based on the details of the elements.

maxDetails:

if specified, limit the total number of elements by the sum of their details values. This is applied in addition to limit. The sum of the details values of the elements may exceed maxDetails slightly (the sum of all but the last element will be less than maxDetails, but the last element may exceed the value).

centroids:

if specified and true, only return the id, center of the bounding box, and bounding box size for each element.

Parameters:
  • annotation – the annotation to get elements for. Modified.

  • region – if present, a dictionary restricting which annotations are returned.

getNextVersionValue()[source]

Maintain a version number. This is a single sequence that can be used to ensure we have the correct set of elements for an annotation.

Returns:

an integer version number that is strictly increasing.

initialize()[source]

Subclasses should override this and set the name of the collection as self.name. Also, they should set any indexed fields that they require.

removeElements(annotation)[source]

Remove all elements related to the specified annotation.

Parameters:

annotation – the annotation to remove elements from.

removeOldElements(annotation, oldversion=None)[source]

Remove all elements related to the specified annotation.

Parameters:
  • annotation – the annotation to remove elements from.

  • oldversion – if present, remove versions up to this number. If none, remove versions earlier than the version in the annotation record.

removeWithQuery(query)[source]

Remove all documents matching a given query from the collection. For safety reasons, you may not pass an empty query.

Note: this does NOT return a Mongo DeleteResult.

Parameters:

query (dict) – The search query for documents to delete, see general MongoDB docs for “find()”

saveElementAsFile(annotation, entries)[source]

If an element has a large points or values array, save that array to an attached file.

Parameters:
  • annotation – the parent annotation.

  • entries – the database entries document. Modified.

updateElementChunk(elements, chunk, chunkSize, annotation, now)[source]

Update the database for a chunk of elements. See the updateElements method for details.

updateElements(annotation)[source]

Given an annotation, extract the elements from it and update the database of them.

Parameters:

annotation – the annotation to save elements for. Modified.

yieldElements(annotation, region=None, info=None)[source]

Given an annotation, fetch the elements from the database.

When a region is used to request specific element, the following keys can be specified:

left, right, top, bottom, low, high:

the spatial area where elements are located, all in pixels. If an element’s bounding box is at least partially within the requested area, that element is included.

minimumSize:

the minimum size of an element to return.

sort, sortdir:

standard sort options. The sort key can include size and details.

limit:

limit the total number of elements by this value. Defaults to no limit.

offset:

the offset within the query to start returning values. If maxDetails is used, to get subsequent sets of elements, the offset needs to be increased by the actual number of elements returned from a previous query, which will vary based on the details of the elements.

maxDetails:

if specified, limit the total number of elements by the sum of their details values. This is applied in addition to limit. The sum of the details values of the elements may exceed maxDetails slightly (the sum of all but the last element will be less than maxDetails, but the last element may exceed the value).

centroids:

if specified and true, only return the id, center of the bounding box, and bounding box size for each element.

bbox:

if specified and true and centroids are not specified, add _bbox to each element with the bounding box record.

Parameters:
  • annotation – the annotation to get elements for. Modified.

  • region – if present, a dictionary restricting which annotations are returned.

  • info – an optional dictionary that will be modified with additional query information, including count (total number of available elements), returned (number of elements in response), maxDetails (as specified by the region dictionary), details (sum of details returned), limit (as specified by region), centroids (a boolean based on the region specification).

Returns:

a list of elements. If centroids were requested, each entry is a list with str(id), x, y, size. Otherwise, each entry is the element record.

Module contents