diff --git a/schemas/src/digital-objects/landmark.yaml b/schemas/src/digital-objects/landmark.yaml index 9bdcfd1..365b9cf 100644 --- a/schemas/src/digital-objects/landmark.yaml +++ b/schemas/src/digital-objects/landmark.yaml @@ -44,6 +44,9 @@ classes: - placements - extraction_set - rui_rank + slot_usage: + dimension_unit: + pattern: (centimeter|millimeter) SpatialObjectReference: class_uri: ccf:SpatialObjectReference @@ -52,7 +55,8 @@ classes: - Instance slots: - id - - file + - file_name + - file_url - file_subpath - file_format - placement @@ -64,6 +68,7 @@ classes: - Instance slots: - id + - source - target - x_scaling - y_scaling @@ -78,6 +83,15 @@ classes: - y_translation - z_translation - translation_unit + slot_usage: + scaling_unit: + pattern: ratio + rotation_unit: + pattern: degree + rotation_order: + pattern: XYZ + translation_unit: + pattern: (centimeter|millimeter) ExtractionSet: class_uri: ccf:ExtractionSet @@ -209,7 +223,6 @@ slots: owl: AnnotationProperty, AnnotationAssertion dimension_unit: required: true - range: DimensionUnitEnum annotations: owl: AnnotationProperty, AnnotationAssertion x_scaling: @@ -232,7 +245,6 @@ slots: owl: AnnotationProperty, AnnotationAssertion scaling_unit: required: true - range: ScalingUnitEnum annotations: owl: AnnotationProperty, AnnotationAssertion x_rotation: @@ -252,7 +264,6 @@ slots: owl: AnnotationProperty, AnnotationAssertion rotation_unit: required: true - range: RotationUnitEnum annotations: owl: AnnotationProperty, AnnotationAssertion rotation_order: @@ -276,12 +287,14 @@ slots: owl: AnnotationProperty, AnnotationAssertion translation_unit: required: true - range: TranslationUnitEnum annotations: owl: AnnotationProperty, AnnotationAssertion - file: + file_name: + required: true + annotations: + owl: AnnotationProperty, AnnotationAssertion + file_url: required: true - slot_uri: ccf:file_url annotations: owl: AnnotationProperty, AnnotationAssertion file_subpath: @@ -292,6 +305,13 @@ slots: required: true annotations: owl: AnnotationProperty, AnnotationAssertion + source: + required: false + slot_uri: ccf:placement_for + range: SpatialObjectReference + inlined: false + annotations: + owl: AnnotationProperty, AnnotationAssertion target: required: true slot_uri: ccf:placement_relative_to @@ -315,7 +335,7 @@ slots: owl: AnnotationProperty, AnnotationAssertion placements: required: false - slot_uri: ccf:has_placements + slot_uri: ccf:has_placement range: SpatialPlacement inlined: true multivalued: true diff --git a/src/normalization/normalize-landmark.js b/src/normalization/normalize-landmark.js index 212f663..33be256 100644 --- a/src/normalization/normalize-landmark.js +++ b/src/normalization/normalize-landmark.js @@ -62,7 +62,8 @@ async function processSpatialEntities(context, metadata, gltfFile, cache, crossw const baseIri = obj.iri; const name = obj.name; const separator = baseIri?.indexOf('#') === -1 ? '#' : '_' ?? '#'; - const { organOwnerSex, organLabel } = getOrganMetadata(name); + const organMetadata = getOrganMetadata(name); + const organLabel = getOrganLabel(organMetadata); const extractionSets = {}; const spatialEntities = Object.values(nodes) @@ -84,8 +85,8 @@ async function processSpatialEntities(context, metadata, gltfFile, cache, crossw } let parentIri = `${baseIri}${separator}parent`; - if (organOwnerSex) { - parentIri = `https://purl.humanatlas.io/graph/hra-ccf-body#VH${organOwnerSex}`; + if (organMetadata.sex) { + parentIri = `https://purl.humanatlas.io/graph/hra-ccf-body#VH${organMetadata.sex}`; } return { @@ -116,27 +117,25 @@ async function processSpatialEntities(context, metadata, gltfFile, cache, crossw label: `3D object of ${landmarkLabel}`, class_type: 'SpatialObjectReference', typeOf: ['SpatialObjectReference'], - file: gltfFile, + file_name: gltfFile.replace(/^.*[\\/]/, ''), + file_url: gltfFile, file_format: 'model/gltf-binary', file_subpath: node['@id'], - placement: { id: `${id}ObjPlacement`, label: `Local placement of ${landmarkLabel}`, class_type: 'SpatialPlacement', typeOf: ['SpatialPlacement'], + source: `${id}_obj`, target: id, - x_scaling: 1, y_scaling: 1, z_scaling: 1, scaling_unit: 'ratio', - x_rotation: -90, y_rotation: 0, z_rotation: 0, rotation_unit: 'degree', - x_translation: -T.x, y_translation: -T.y, z_translation: -T.z, @@ -151,17 +150,14 @@ async function processSpatialEntities(context, metadata, gltfFile, cache, crossw class_type: 'SpatialPlacement', typeOf: ['SpatialPlacement'], target: parentIri, - x_scaling: 1, y_scaling: 1, z_scaling: 1, scaling_unit: 'ratio', - x_rotation: 0, y_rotation: 0, z_rotation: 0, rotation_unit: 'degree', - x_translation: T.x, y_translation: T.y, z_translation: T.z, @@ -178,21 +174,22 @@ async function processSpatialEntities(context, metadata, gltfFile, cache, crossw }; } -function getOrganMetadata(name) { - const sex = name.includes('female') ? 'Female' : name.includes('male') ? 'Male' : undefined; - const side = name.includes('left') ? 'Left' : name.includes('right') ? 'Right' : undefined; - const bothSides = name.includes('both'); +function getOrganMetadata(doName) { + const sex = doName.includes('female') ? 'Female' : doName.includes('male') ? 'Male' : undefined; + const side = doName.includes('left') ? 'Left' : doName.includes('right') ? 'Right' : doName.includes('both') ? 'Both' : undefined; const exclude = new Set(['left', 'right', 'male', 'female', 'both', 'landmarks', 'extraction sites']); - const organName = name + const name = doName .split('-') .filter((n) => !exclude.has(n)) .join(' '); - const sideLabel = bothSides ? 'left and right' : side; - const organLabel = sideLabel ? `${sex} ${sideLabel} ${organName}` : `${sex} ${organName}`; + return { sex, side, name }; +} - return { organOwnerSex: sex, organLabel }; +function getOrganLabel({ sex, side, name }) { + const sideLabel = side && side === 'Both' ? 'Left and right' : side; + return sideLabel ? `${sex} ${sideLabel.toLowerCase()} ${name.toLowerCase()}` : `${sex} ${name.toLowerCase()}`; } function getLandmarkName(nodeId, crosswalk) {