Skip to content

Commit 61a3081

Browse files
feat: Add Additional Metadata Fields to Patient, Specimen and Segment Panels (#345)
* Address semantic release * Add new fields to patient, segment and specimen * Lint
1 parent f061971 commit 61a3081

5 files changed

Lines changed: 1883 additions & 36 deletions

File tree

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
"react-scripts": "5.0.0",
6868
"react-test-renderer": "^18.2.0",
6969
"retry": "^0.13.1",
70+
"semantic-release": "21.1.2",
7071
"sonarqube-scanner": "^4.3.0",
7172
"ts-standard": "^11.0.0",
7273
"typescript": "^4.7.4"

src/components/Patient.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ class Patient extends React.Component<PatientProps, {}> {
3232
{
3333
name: 'Birthdate',
3434
value: parseDate(this.props.metadata.PatientBirthDate)
35+
},
36+
{
37+
name: 'Age',
38+
value: (this.props.metadata as any).PatientAge
3539
}
3640
]
3741
return (

src/components/SegmentItem.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,13 +120,25 @@ class SegmentItem extends React.Component<SegmentItemProps, SegmentItemState> {
120120
{
121121
name: 'Algorithm Name',
122122
value: this.props.segment.algorithmName
123+
},
124+
{
125+
name: 'Algorithm Type',
126+
value: this.props.segment.algorithmType
123127
}
124128
]
125129

126130
/** Get segmentation type from metadata */
127131
const segmentationMetadata = this.props.metadata?.[0] as any
128132
const segmentationType = getSegmentationType(segmentationMetadata)
129133

134+
// Add SegmentationType from metadata if available
135+
if (segmentationMetadata?.SegmentationType !== undefined) {
136+
attributes.push({
137+
name: 'Segmentation Type',
138+
value: segmentationMetadata.SegmentationType
139+
})
140+
}
141+
130142
const settings = (
131143
<div>
132144
{segmentationType !== 'FRACTIONAL' && (

src/components/SpecimenItem.tsx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,20 @@ class SpecimenItem extends React.Component<SpecimenItemProps, {}> {
2323
if (this.props.metadata === undefined) {
2424
return null
2525
}
26+
2627
const specimenDescription = this.props.metadata.SpecimenDescriptionSequence[
2728
this.props.index
2829
]
30+
2931
const attributes: Attribute[] = []
32+
3033
if (specimenDescription.SpecimenShortDescription !== undefined) {
3134
attributes.push({
3235
name: 'Description',
3336
value: specimenDescription.SpecimenShortDescription
3437
})
3538
}
39+
3640
if (specimenDescription.PrimaryAnatomicStructureSequence !== undefined) {
3741
if (specimenDescription.PrimaryAnatomicStructureSequence.length > 0) {
3842
const structures = specimenDescription.PrimaryAnatomicStructureSequence
@@ -43,10 +47,23 @@ class SpecimenItem extends React.Component<SpecimenItemProps, {}> {
4347
}
4448
}
4549

50+
const structures = specimenDescription.PrimaryAnatomicStructureSequence
51+
const modifierSequence = structures.find(s => (s as any).PrimaryAnatomicStructureModifierSequence !== undefined)
52+
if (modifierSequence != null) {
53+
const modifiers: dcmjs.sr.coding.CodedConcept[] = (modifierSequence as any).PrimaryAnatomicStructureModifierSequence
54+
if (modifiers.length > 0) {
55+
attributes.push({
56+
name: 'Primary Anatomic Structure Modifier',
57+
value: modifiers.map((item: dcmjs.sr.coding.CodedConcept) => item.CodeMeaning).join(', ')
58+
})
59+
}
60+
}
61+
4662
// TID 8001 "Specimen Preparation"
4763
const preparationSteps: dmv.metadata.SpecimenPreparation[] = (
4864
specimenDescription.SpecimenPreparationSequence ?? []
4965
)
66+
5067
preparationSteps.forEach(
5168
(step: dmv.metadata.SpecimenPreparation, index: number): void => {
5269
step.SpecimenPreparationStepContentItemSequence.forEach((
@@ -65,6 +82,7 @@ class SpecimenItem extends React.Component<SpecimenItemProps, {}> {
6582
item.ConceptNameCodeSequence[0].CodingSchemeDesignator,
6683
meaning: item.ConceptNameCodeSequence[0].CodeMeaning
6784
})
85+
6886
if (item.ValueType === dcmjs.sr.valueTypes.ValueTypes.CODE) {
6987
item = item as dcmjs.sr.valueTypes.CodeContentItem
7088
const value = new dcmjs.sr.coding.CodedConcept({
@@ -73,6 +91,7 @@ class SpecimenItem extends React.Component<SpecimenItemProps, {}> {
7391
item.ConceptCodeSequence[0].CodingSchemeDesignator,
7492
meaning: item.ConceptCodeSequence[0].CodeMeaning
7593
})
94+
7695
if (!name.equals(SpecimenPreparationStepItems.PROCESSING_TYPE)) {
7796
if (
7897
name.equals(SpecimenPreparationStepItems.COLLECTION_METHOD)
@@ -127,8 +146,17 @@ class SpecimenItem extends React.Component<SpecimenItemProps, {}> {
127146
})
128147
}
129148
)
149+
150+
if ((this.props.metadata as any).AdmittingDiagnosesDescription !== undefined) {
151+
attributes.push({
152+
name: 'Admitting Diagnoses',
153+
value: (this.props.metadata as any).AdmittingDiagnosesDescription
154+
})
155+
}
156+
130157
const uid = specimenDescription.SpecimenUID
131158
const identifier = specimenDescription.SpecimenIdentifier
159+
132160
return (
133161
<Item
134162
uid={uid}

0 commit comments

Comments
 (0)