private buildAnnotationGroupModel()

in pathology/viewer/src/services/dicom-annotations.service.ts [734:812]


  private buildAnnotationGroupModel(
    annotationGroup: AnnotationGroup, pixelSize: PixelSize): DicomModel {
    const annotationGroupModel: DicomModel = {
      [DicomTag.ANNOTATION_GROUP_NUMBER]:
        dicomAttr('US', [annotationGroup.idNumber]),
      [DicomTag.ANNOTATION_GROUP_UID]: dicomAttr(
        'UI', annotationGroup.annotationGroupUid || this.generateUUID()),
      [DicomTag.ANNOTATION_GROUP_LABEL]:
        dicomAttr('LO', annotationGroup.annotationGroupLabel),
      [DicomTag.ANNOTATION_GROUP_DESCRIPTION]:
        dicomAttr('UT', annotationGroup.annotationGroupDescription),
      [DicomTag.ANNOTATION_GROUP_GENERATION_TYPE]:
        dicomAttr('CS', annotationGroup.annotationGroupGenerationType),
    } as DicomModel;

    if (annotationGroup.annotationPropertyCategoryCodeSequence?.length) {
      annotationGroupModel[DicomTag
        .ANNOTATION_PROPERTY_CATEGORY_CODE_SEQUENCE] =
        dicomAttr(
          'SQ',
          [this.buildAnnotationPropertyCategoryCodeModel(
            annotationGroup.annotationPropertyCategoryCodeSequence[0])]);
    } else {
      // Use default category
      // dicom.nema.org/medical/dicom/current/output/chtml/part03/chapter_8.html#sect_8.1

      const defaultCategory = {
        '00080100': dicomAttr('SH', '91723000'),  // Anatomical structure
        '00080102': dicomAttr('SH', 'SCT'),       // SNOMED CT code
        '00080104': dicomAttr('LO', 'Anatomical structure'),
      };
      annotationGroupModel[DicomTag
        .ANNOTATION_PROPERTY_CATEGORY_CODE_SEQUENCE] =
        dicomAttr('SQ', [defaultCategory]);
    }

    // Hardcode a generic label until we give such option in to the user.
    // The comment provided by the user represents the text meaning.
    const propertyTypeCodeSequence = {
      '00080100':
        dicomAttr('SH', '395538009'),    // Microscopic specimen observation
      '00080102': dicomAttr('SH', 'SCT'),  // SNOMED CT code
      '00080104': dicomAttr('LO', annotationGroup.annotationGroupDescription),
    };
    annotationGroupModel[DicomTag.ANNOTATION_PROPERTY_TYPE_CODE_SEQUENCE] =
      dicomAttr('SQ', [propertyTypeCodeSequence]);

    annotationGroupModel[DicomTag.GRAPHIC_TYPE] =
      dicomAttr('CS', annotationGroup.graphicType);

    const pixelCoordinates = metersToPixelsWithYFlip(
      annotationGroup.pointCoordinatesData, pixelSize);
    const base64Coordinates = numberArrayToInlineBinary(
      Float32Array,
      isPolygonClockwise(pixelCoordinates) ?
        pixelCoordinates :
        flipPointOrder(pixelCoordinates));
    annotationGroupModel[DicomTag.POINT_COORDINATES_DATA] = {
      'InlineBinary': base64Coordinates,
      'vr': 'OF'
    } as Attribute;

    const longPrimitivePointIndexList =
      annotationGroup.longPrimitivePointIndexList;
    const base64LongPrimitive =
      numberArrayToInlineBinary(Int32Array, longPrimitivePointIndexList);
    annotationGroupModel[DicomTag.LONG_PRIMITIVE_POINT_INDEX_LIST] = {
      'InlineBinary': base64LongPrimitive,
      'vr': 'OL'
    } as Attribute;

    annotationGroupModel[DicomTag.NUMBER_OF_ANNOTATIONS] =
      dicomAttr('UL', [longPrimitivePointIndexList.length]);

    annotationGroupModel[DicomTag.ANNOTATION_APPLIES_TO_ALL_OPTICAL_PATHS] =
      dicomAttr('CS', 'YES');

    return annotationGroupModel;
  }