Skip to content

Commit b171eee

Browse files
author
Alexis Girault
committed
Consolidate DICOM entity classes and list tags in a dictionary
1 parent 003614e commit b171eee

File tree

2 files changed

+118
-148
lines changed

2 files changed

+118
-148
lines changed

examples/Dicom/src/dicomForm.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ function setupDicomForm(patientDict, callback) {
77
patientSelect.length = 1; // remove all options bar first
88
const patients = Array.from(patientDict.values())
99
patientDict.forEach((patient) => {
10-
const value = patient.name + " - " + patient.dateOfBirth
10+
const value = patient.patientName + " - " + patient.patientDateOfBirth
1111
patientSelect.options[patientSelect.options.length] = new Option(value, value);
1212
})
1313

@@ -18,7 +18,7 @@ function setupDicomForm(patientDict, callback) {
1818
const patientId = this.selectedIndex - 1
1919
const patient = patients[patientId]
2020
patient.studyDict.forEach((study) => {
21-
const value = study.description + " - " + study.date
21+
const value = study.studyDescription + " - " + study.studyDate
2222
studySelect.options[studySelect.options.length] = new Option(value, value);
2323
})
2424
}
@@ -33,7 +33,7 @@ function setupDicomForm(patientDict, callback) {
3333
const studyId = this.selectedIndex - 1
3434
const study = studies[studyId]
3535
study.serieDict.forEach((serie) => {
36-
const value = serie.description + " - " + serie.modality
36+
const value = serie.seriesDescription + " - " + serie.seriesModality
3737
serieSelect.options[serieSelect.options.length] = new Option(value, value);
3838
})
3939
}

examples/Dicom/src/index.js

Lines changed: 115 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,27 @@ import dicomParser from 'dicom-parser'
66
import setupDicomForm from './dicomForm'
77
import "regenerator-runtime/runtime";
88

9+
const DICOM_DICTIONARY = {
10+
patientId: 'x00100020',
11+
patientName: 'x00100010',
12+
patientDateOfBirth: 'x00100030',
13+
patientSex: 'x00100040',
14+
studyID: 'x00200010',
15+
studyUID: 'x0020000d',
16+
studyDate: 'x00080020',
17+
studyTime: 'x00080030',
18+
studyAccessionNumber: 'x00080050',
19+
studyDescription: 'x00081030',
20+
seriesNumber: 'x00200011',
21+
seriesUid: 'x0020000e',
22+
seriesDate: 'x00080021',
23+
seriesTime: 'x00080031',
24+
seriesModality: 'x00080060',
25+
seriesDescription: 'x0008103e',
26+
seriesProtocolName: 'x00181030',
27+
seriesBodyPart: 'x00180015',
28+
}
29+
930
const parseDICOMFiles = async (fileList) => {
1031
var patientDict = new Map()
1132

@@ -18,7 +39,8 @@ const parseDICOMFiles = async (fileList) => {
1839
const dicomMetaData = dicomParser.parseDicom(byteArray)
1940

2041
// Add to patientDict
21-
const patientId = dicomMetaData.string('x00100020')
42+
const tag = DICOMPatient.primaryTag
43+
const patientId = dicomMetaData.string(DICOM_DICTIONARY[tag])
2244
var patient = patientDict.get(patientId)
2345
if (patient === undefined) {
2446
console.log(`New patient ${patientId}`)
@@ -34,45 +56,65 @@ const parseDICOMFiles = async (fileList) => {
3456
return patientDict
3557
}
3658

37-
class DICOMPatient {
59+
class DICOMEntity {
3860
constructor() {
39-
this.id = undefined // x00100020
40-
this.name = undefined // x00100010
41-
this.dateOfBirth = undefined // x00100030
42-
this.sex = undefined // x00100040
43-
this.studyDict = new Map()
61+
this.checkTagsValidity() // could it be a static assertion instead?
4462
}
4563

46-
parseMetaData(dicomMetaData, file) {
47-
const id = dicomMetaData.string('x00100020')
48-
if (this.id === undefined) {
49-
this.id = id
50-
} else {
51-
console.assert(this.id === id, "Inconsistent id")
52-
}
64+
checkTagsValidity() {
65+
const tags = this.constructor.tags
66+
const primaryTag = this.constructor.primaryTag
67+
console.assert(
68+
tags.includes(primaryTag),
69+
`The primary tag ${primaryTag} is not listed in ${tags}`
70+
)
71+
tags.forEach((tag) => {
72+
console.assert(
73+
tag in DICOM_DICTIONARY,
74+
`The tag ${tag} is not defined in DICOM_DICTIONARY`
75+
)
76+
})
77+
}
5378

54-
const name = dicomMetaData.string('x00100010')
55-
if (this.name === undefined) {
56-
this.name = name
57-
} else {
58-
console.assert(this.name === name, "Inconsistent name")
59-
}
79+
extractTags(dicomMetaData) {
80+
const tags = this.constructor.tags
81+
const primaryTag = this.constructor.primaryTag
82+
tags.forEach((tag) => {
83+
const value = dicomMetaData.string(DICOM_DICTIONARY[tag])
84+
if (this[tag] === undefined) {
85+
this[tag] = value
86+
} else if (value != undefined) {
87+
console.assert(this[tag] === value, `Inconsistent value for ${tag} property of ${this[primaryTag]}`)
88+
}
89+
})
90+
}
91+
}
6092

61-
const dob = dicomMetaData.string('x00100030')
62-
if (this.dateOfBirth === undefined) {
63-
this.dateOfBirth = dob
64-
} else {
65-
console.assert(this.dateOfBirth === dob, "Inconsistent date of birth")
66-
}
93+
class DICOMPatient extends DICOMEntity {
94+
static get primaryTag() {
95+
return 'patientId'
96+
}
6797

68-
const sex = dicomMetaData.string('x00100040')
69-
if (this.sex === undefined) {
70-
this.sex = sex
71-
} else {
72-
console.assert(this.sex === sex, "Inconsistent sex")
98+
static get tags() {
99+
return [
100+
'patientId',
101+
'patientName',
102+
'patientDateOfBirth',
103+
'patientSex',
104+
]
73105
}
74106

75-
const studyId = dicomMetaData.string('x00200010')
107+
constructor() {
108+
super()
109+
this.studyDict = new Map()
110+
}
111+
112+
parseMetaData(dicomMetaData, file) {
113+
this.extractTags(dicomMetaData)
114+
115+
116+
const tag = DICOMStudy.primaryTag
117+
const studyId = dicomMetaData.string(DICOM_DICTIONARY[tag])
76118
var study = this.studyDict.get(studyId)
77119
if (study === undefined) {
78120
console.log(`new study ${studyId}`)
@@ -83,61 +125,33 @@ class DICOMPatient {
83125
}
84126
}
85127

86-
class DICOMStudy {
87-
constructor() {
88-
this.id = undefined // x00200010
89-
this.uid = undefined // x0020000d
90-
this.date = undefined // x00080020
91-
this.time = undefined // x00080030
92-
this.accessionNumber = undefined // x00080050
93-
this.description = undefined // x00081030
94-
this.serieDict = new Map()
95-
}
96-
97-
parseMetaData(dicomMetaData, file) {
98-
const id = dicomMetaData.string('x00200010')
99-
if (this.id === undefined) {
100-
this.id = id
101-
} else {
102-
console.assert(this.id === id, "Inconsistent id")
103-
}
104-
105-
const uid = dicomMetaData.string('x0020000d')
106-
if (this.uid === undefined) {
107-
this.uid = uid
108-
} else {
109-
console.assert(this.uid === uid, "Inconsistent uid")
110-
}
111128

112-
const date = dicomMetaData.string('x00080020')
113-
if (this.date === undefined) {
114-
this.date = date
115-
} else {
116-
console.assert(this.date === date, "Inconsistent date")
117-
}
129+
class DICOMStudy extends DICOMEntity {
130+
static get primaryTag() {
131+
return 'studyID'
132+
}
118133

119-
const time = dicomMetaData.string('x00080030')
120-
if (this.time === undefined) {
121-
this.time = time
122-
} else {
123-
console.assert(this.time === time, "Inconsistent time")
134+
static get tags() {
135+
return [
136+
'studyID',
137+
'studyUID',
138+
'studyDate',
139+
'studyTime',
140+
'studyAccessionNumber',
141+
'studyDescription',
142+
]
124143
}
125144

126-
const nbr = dicomMetaData.string('x00080050')
127-
if (this.accessionNumber === undefined) {
128-
this.accessionNumber = nbr
129-
} else {
130-
console.assert(this.accessionNumber === nbr, "Inconsistent accession number")
131-
}
145+
constructor() {
146+
super()
147+
this.serieDict = new Map()
148+
}
132149

133-
const description = dicomMetaData.string('x00081030')
134-
if (this.description === undefined) {
135-
this.description = description
136-
} else {
137-
console.assert(this.description === description, "Inconsistent description")
138-
}
150+
parseMetaData(dicomMetaData, file) {
151+
this.extractTags(dicomMetaData)
139152

140-
const serieNumber = dicomMetaData.string('x00200011')
153+
const tag = DICOMSerie.primaryTag
154+
const serieNumber = dicomMetaData.string(DICOM_DICTIONARY[tag])
141155
var serie = this.serieDict.get(serieNumber)
142156
if (serie === undefined) {
143157
console.log(`new serie ${serieNumber}`)
@@ -148,75 +162,31 @@ class DICOMStudy {
148162
}
149163
}
150164

151-
class DICOMSerie {
152-
constructor() {
153-
this.number = undefined // x00200011
154-
this.uid = undefined // x0020000e
155-
this.date = undefined // x00080021
156-
this.time = undefined // x00080031
157-
this.modality = undefined // x00080060
158-
this.description = undefined // x0008103e
159-
this.protocolName = undefined // x00181030
160-
this.bodyPart = undefined // x00180015
161-
this.files = []
165+
class DICOMSerie extends DICOMEntity {
166+
static get primaryTag() {
167+
return 'seriesNumber'
162168
}
163169

164-
parseMetaData(dicomMetaData, file) {
165-
const number = dicomMetaData.string('x00200011')
166-
if (this.number === undefined) {
167-
this.number = number
168-
} else {
169-
console.assert(this.number === number, "Inconsistent number")
170+
static get tags() {
171+
return [
172+
'seriesNumber',
173+
'seriesUid',
174+
'seriesDate',
175+
'seriesTime',
176+
'seriesModality',
177+
'seriesDescription',
178+
'seriesProtocolName',
179+
'seriesBodyPart',
180+
]
170181
}
171182

172-
const uid = dicomMetaData.string('x0020000e')
173-
if (this.uid === undefined) {
174-
this.uid = uid
175-
} else {
176-
console.assert(this.uid === uid, "Inconsistent number")
177-
}
178-
179-
const date = dicomMetaData.string('x00080021')
180-
if (this.date === undefined) {
181-
this.date = date
182-
} else {
183-
console.assert(this.date === date, "Inconsistent date")
184-
}
185-
186-
const time = dicomMetaData.string('x00080031')
187-
if (this.time === undefined) {
188-
this.time = time
189-
} else {
190-
console.assert(this.time === time, "Inconsistent time")
191-
}
192-
193-
const modality = dicomMetaData.string('x00080060')
194-
if (this.modality === undefined) {
195-
this.modality = modality
196-
} else {
197-
console.assert(this.modality === modality, "Inconsistent modality")
198-
}
199-
200-
const description = dicomMetaData.string('x0008103e')
201-
if (this.description === undefined) {
202-
this.description = description
203-
} else {
204-
console.assert(this.description === description, "Inconsistent description")
205-
}
206-
207-
const bodyPart = dicomMetaData.string('x00180015')
208-
if (this.bodyPart === undefined) {
209-
this.bodyPart = bodyPart
210-
} else {
211-
console.assert(this.bodyPart === bodyPart, "Inconsistent body part")
212-
}
183+
constructor() {
184+
super()
185+
this.files = []
186+
}
213187

214-
const protocolName = dicomMetaData.string('x00181030')
215-
if (this.protocolName === undefined) {
216-
this.protocolName = protocolName
217-
} else {
218-
console.assert(this.protocolName === protocolName, "Inconsistent protocol name")
219-
}
188+
parseMetaData(dicomMetaData, file) {
189+
this.extractTags(dicomMetaData)
220190

221191
this.files.push(file)
222192
}

0 commit comments

Comments
 (0)