dicom-curate 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/dist/esm/applyMappingsWorker.js +6 -1
- package/dist/esm/collectMappings.js +16 -9
- package/dist/esm/curateDict.js +2 -2
- package/dist/esm/curateOne.js +3 -3
- package/dist/esm/deidentifyPS315E.js +4 -1
- package/dist/esm/getParser.js +11 -1
- package/dist/esm/index.js +57 -37
- package/dist/esm/scanDirectoryWorker.js +25 -16
- package/dist/types/applyMappingsWorker.d.ts +8 -1
- package/dist/types/collectMappings.d.ts +1 -1
- package/dist/types/curateDict.d.ts +1 -1
- package/dist/types/curateOne.d.ts +7 -1
- package/dist/types/deidentifyPS315E.d.ts +1 -0
- package/dist/types/getParser.d.ts +1 -1
- package/dist/types/index.d.ts +3 -2
- package/dist/types/scanDirectoryWorker.d.ts +8 -0
- package/dist/types/serializeMappingOptions.d.ts +1 -5
- package/dist/types/types.d.ts +13 -2
- package/dist/umd/dicom-curate.umd.js +258 -219
- package/dist/umd/dicom-curate.umd.js.map +1 -1
- package/dist/umd/dicom-curate.umd.min.js +2 -2
- package/dist/umd/dicom-curate.umd.min.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -77,11 +77,11 @@ const columnMappings = extractColumnMappings([
|
|
|
77
77
|
{ subjectID: 'SubjectID2', blindedID: 'BlindedID2' },
|
|
78
78
|
])
|
|
79
79
|
|
|
80
|
-
curateOne(
|
|
80
|
+
curateOne({
|
|
81
81
|
fileInfo, // path, name, size, kind, blob
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
82
|
+
mappingOptions: { curationSpec, columnMappings },
|
|
83
|
+
})
|
|
84
|
+
|
|
85
85
|
|
|
86
86
|
// Cache clean-up responsibility, e.g. for consistent UID mapping in `retainUIDsOption: 'Off'` is with caller
|
|
87
87
|
clearCaches()
|
|
@@ -6,7 +6,12 @@ self.addEventListener('message', (event) => {
|
|
|
6
6
|
const { serializedMappingOptions } = event.data;
|
|
7
7
|
const mappingOptions = deserializeMappingOptions(serializedMappingOptions);
|
|
8
8
|
try {
|
|
9
|
-
curateOne(
|
|
9
|
+
curateOne({
|
|
10
|
+
fileInfo: event.data.fileInfo,
|
|
11
|
+
fileIndex: event.data.fileIndex,
|
|
12
|
+
outputDirectory: event.data.outputDirectory,
|
|
13
|
+
mappingOptions,
|
|
14
|
+
}).then((mapResults) => {
|
|
10
15
|
// Send finished message for completion
|
|
11
16
|
self.postMessage({
|
|
12
17
|
response: 'finished',
|
|
@@ -14,7 +14,7 @@ import deidentifyPS315E, { defaultPs315Options } from './deidentifyPS315E.js';
|
|
|
14
14
|
import getParser from './getParser.js';
|
|
15
15
|
import { specVersion } from './config/specVersion.js';
|
|
16
16
|
import { get as _get } from 'lodash';
|
|
17
|
-
export default function collectMappings(inputFilePath, dicomData, mappingOptions) {
|
|
17
|
+
export default function collectMappings(inputFilePath, inputFileIndex, dicomData, mappingOptions) {
|
|
18
18
|
var _a;
|
|
19
19
|
const mapResults = {
|
|
20
20
|
// original UID for this dicomData
|
|
@@ -33,13 +33,15 @@ export default function collectMappings(inputFilePath, dicomData, mappingOptions
|
|
|
33
33
|
let finalSpec = {
|
|
34
34
|
dicomPS315EOptions: defaultPs315Options,
|
|
35
35
|
inputPathPattern: '',
|
|
36
|
-
modifications
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
36
|
+
modifications(parser) {
|
|
37
|
+
return {
|
|
38
|
+
dicomHeader: {},
|
|
39
|
+
outputFilePathComponents: [
|
|
40
|
+
parser.protectUid(parser.getDicom('SeriesInstanceUID')),
|
|
41
|
+
parser.getFilePathComp(parser.FILENAME),
|
|
42
|
+
],
|
|
43
|
+
};
|
|
44
|
+
},
|
|
43
45
|
validation: () => ({ errors: [] }),
|
|
44
46
|
};
|
|
45
47
|
const _b = mappingOptions.curationSpec(), { modifications, validation } = _b, restSpec = __rest(_b, ["modifications", "validation"]);
|
|
@@ -54,8 +56,13 @@ export default function collectMappings(inputFilePath, dicomData, mappingOptions
|
|
|
54
56
|
if (!mappingOptions.skipValidation) {
|
|
55
57
|
finalSpec.validation = validation;
|
|
56
58
|
}
|
|
59
|
+
// protect filename if we de-identify
|
|
60
|
+
const finalFilePath = finalSpec.dicomPS315EOptions === 'Off'
|
|
61
|
+
? inputFilePath
|
|
62
|
+
: inputFilePath.slice(0, inputFilePath.lastIndexOf('/') + 1) +
|
|
63
|
+
`${String(inputFileIndex + 1).padStart(5, '0')}.dcm`;
|
|
57
64
|
// create a parser object to be used in the eval'ed mappingFunctions
|
|
58
|
-
const parser = getParser(finalSpec.inputPathPattern,
|
|
65
|
+
const parser = getParser(finalSpec.inputPathPattern, finalFilePath, naturalData, finalSpec.dicomPS315EOptions, mappingOptions.columnMappings, finalSpec.additionalData);
|
|
59
66
|
let modificationMap = finalSpec.modifications(parser);
|
|
60
67
|
// List all validation errors
|
|
61
68
|
mapResults.errors = finalSpec
|
package/dist/esm/curateDict.js
CHANGED
|
@@ -2,11 +2,11 @@ import * as dcmjs from 'dcmjs';
|
|
|
2
2
|
import collectMappings from './collectMappings.js';
|
|
3
3
|
import mapMetaheader from './mapMetaheader.js';
|
|
4
4
|
import { set as _set, unset as _unset, cloneDeep as _cloneDeep } from 'lodash';
|
|
5
|
-
export default function curateDict(inputFilePath, dicomData, mappingOptions) {
|
|
5
|
+
export default function curateDict(inputFilePath, inputFileIndex, dicomData, mappingOptions) {
|
|
6
6
|
//
|
|
7
7
|
// Collect the mappings and apply them to the data
|
|
8
8
|
//
|
|
9
|
-
const [naturalData, mapResults] = collectMappings(inputFilePath, dicomData, mappingOptions);
|
|
9
|
+
const [naturalData, mapResults] = collectMappings(inputFilePath, inputFileIndex, dicomData, mappingOptions);
|
|
10
10
|
for (let tagPath in mapResults.mappings) {
|
|
11
11
|
const [, operation, , mappedValue] = mapResults.mappings[tagPath];
|
|
12
12
|
switch (operation) {
|
package/dist/esm/curateOne.js
CHANGED
|
@@ -10,8 +10,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
10
10
|
import * as dcmjs from 'dcmjs';
|
|
11
11
|
import createNestedDirectories from './createNestedDirectories.js';
|
|
12
12
|
import curateDict from './curateDict.js';
|
|
13
|
-
export function curateOne(
|
|
14
|
-
return __awaiter(this,
|
|
13
|
+
export function curateOne(_a) {
|
|
14
|
+
return __awaiter(this, arguments, void 0, function* ({ fileInfo, fileIndex = 0, outputDirectory, mappingOptions, }) {
|
|
15
15
|
//
|
|
16
16
|
// First, read the dicom instance data from the file handle or blob
|
|
17
17
|
//
|
|
@@ -36,7 +36,7 @@ export function curateOne(fileInfo, outputDirectory, mappingOptions) {
|
|
|
36
36
|
};
|
|
37
37
|
return mapResults;
|
|
38
38
|
}
|
|
39
|
-
const { dicomData: mappedDicomData, mapResults: clonedMapResults } = curateDict(`${fileInfo.path}/${fileInfo.name}`, dicomData, mappingOptions);
|
|
39
|
+
const { dicomData: mappedDicomData, mapResults: clonedMapResults } = curateDict(`${fileInfo.path}/${fileInfo.name}`, fileIndex, dicomData, mappingOptions);
|
|
40
40
|
if (!mappingOptions.skipWrite) {
|
|
41
41
|
// Finally, write the results
|
|
42
42
|
const dirPath = clonedMapResults.outputFilePath
|
|
@@ -33,6 +33,9 @@ function temporalVr(vr) {
|
|
|
33
33
|
function removeRetiredPrefix(name) {
|
|
34
34
|
return name.startsWith('RETIRED_') ? name.slice(8) : name;
|
|
35
35
|
}
|
|
36
|
+
export function protectUid(uid, retainUIDsOption) {
|
|
37
|
+
return retainUIDsOption === 'Hashed' ? hashUid(uid) : replaceUid(uid);
|
|
38
|
+
}
|
|
36
39
|
const elementNamesToAlwaysKeepSet = new Set(elementNamesToAlwaysKeep);
|
|
37
40
|
// Special conditions for some PS3.15 E1.1 elements.
|
|
38
41
|
const ps315EElements = rawPs315EElements.map((elm) => {
|
|
@@ -235,7 +238,7 @@ export default function deidentifyPS315E({ naturalData, dicomPS315EOptions, date
|
|
|
235
238
|
// UID is not a known class UID.
|
|
236
239
|
!(uid in uidRegistryPS3_06_A1)) {
|
|
237
240
|
// UIDs that need to be mapped
|
|
238
|
-
const mappedUID =
|
|
241
|
+
const mappedUID = protectUid(uid, retainUIDsOption);
|
|
239
242
|
mapResults.mappings[attrPath] = [
|
|
240
243
|
uid,
|
|
241
244
|
'replace',
|
package/dist/esm/getParser.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as dcmjs from 'dcmjs';
|
|
2
|
+
import { protectUid as rawProtectUid } from './deidentifyPS315E.js';
|
|
2
3
|
import { getCsvMapping } from './csvMapping.js';
|
|
3
4
|
import { UniqueNumbers } from './UniqueNumbers.js';
|
|
4
5
|
export const FILEBASENAME = Symbol('fileBasename');
|
|
@@ -25,7 +26,15 @@ const { isUniqueInGroup, clearUniqueInGroupCache } = (function () {
|
|
|
25
26
|
};
|
|
26
27
|
})();
|
|
27
28
|
export { clearUniqueNumberCache, clearUniqueInGroupCache };
|
|
28
|
-
export default function getParser(inputPathPattern, inputFilePath, naturalData, columnMappings, additionalData) {
|
|
29
|
+
export default function getParser(inputPathPattern, inputFilePath, naturalData, dicomPS315EOptions, columnMappings, additionalData) {
|
|
30
|
+
function protectUid(uid) {
|
|
31
|
+
let protectedUid = uid;
|
|
32
|
+
if (dicomPS315EOptions !== 'Off') {
|
|
33
|
+
const { retainUIDsOption } = dicomPS315EOptions;
|
|
34
|
+
protectedUid = rawProtectUid(uid, retainUIDsOption);
|
|
35
|
+
}
|
|
36
|
+
return protectedUid;
|
|
37
|
+
}
|
|
29
38
|
function getDicom(attrName) {
|
|
30
39
|
if (attrName in dcmjs.data.DicomMetaDictionary.dictionary) {
|
|
31
40
|
// if in hex like "(0008,0100)", convert to text key
|
|
@@ -92,6 +101,7 @@ export default function getParser(inputPathPattern, inputFilePath, naturalData,
|
|
|
92
101
|
getMapping,
|
|
93
102
|
getDicom,
|
|
94
103
|
missingDicom,
|
|
104
|
+
protectUid,
|
|
95
105
|
// TODO: Phase this out in favor of ISO8601 duration handling.
|
|
96
106
|
// Example of this logic:
|
|
97
107
|
// ContentDate:
|
package/dist/esm/index.js
CHANGED
|
@@ -51,7 +51,8 @@ function initializeFileListWorker() {
|
|
|
51
51
|
fileListWorker.addEventListener('message', (event) => {
|
|
52
52
|
switch (event.data.response) {
|
|
53
53
|
case 'file':
|
|
54
|
-
|
|
54
|
+
const { fileIndex, fileInfo } = event.data;
|
|
55
|
+
filesToProcess.push({ fileIndex, fileInfo });
|
|
55
56
|
// Could do some throttling:
|
|
56
57
|
// if (filesToProcess.length > 10) {
|
|
57
58
|
// fileListWorker.postMessage({ request: 'stop' })
|
|
@@ -63,6 +64,7 @@ function initializeFileListWorker() {
|
|
|
63
64
|
directoryScanFinished = true;
|
|
64
65
|
break;
|
|
65
66
|
default:
|
|
67
|
+
// @ts-expect-error: response is string here, not never
|
|
66
68
|
console.error(`Unknown response from worker ${event.data.response}`);
|
|
67
69
|
}
|
|
68
70
|
dispatchMappingJobs();
|
|
@@ -96,14 +98,12 @@ function initializeMappingWorkers() {
|
|
|
96
98
|
mapResultsList.push(event.data.mapResults);
|
|
97
99
|
workersActive -= 1;
|
|
98
100
|
// Report progress
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
});
|
|
106
|
-
}
|
|
101
|
+
progressCallback({
|
|
102
|
+
response: 'progress',
|
|
103
|
+
mapResults: event.data.mapResults,
|
|
104
|
+
processedFiles: mapResultsList.length,
|
|
105
|
+
totalFiles: filesToProcess.length + mapResultsList.length + workersActive,
|
|
106
|
+
});
|
|
107
107
|
dispatchMappingJobs();
|
|
108
108
|
if (mapResultsList.length % 100 === 0) {
|
|
109
109
|
console.log(`Finished mapping ${mapResultsList.length} files`);
|
|
@@ -119,7 +119,7 @@ function initializeMappingWorkers() {
|
|
|
119
119
|
}
|
|
120
120
|
function dispatchMappingJobs() {
|
|
121
121
|
while (filesToProcess.length > 0 && availableMappingWorkers.length > 0) {
|
|
122
|
-
const fileInfo = filesToProcess.pop();
|
|
122
|
+
const { fileInfo, fileIndex } = filesToProcess.pop();
|
|
123
123
|
const mappingWorker = availableMappingWorkers.pop();
|
|
124
124
|
const _a =
|
|
125
125
|
// Not partial anymore.
|
|
@@ -127,6 +127,7 @@ function dispatchMappingJobs() {
|
|
|
127
127
|
mappingWorker.postMessage({
|
|
128
128
|
request: 'apply',
|
|
129
129
|
fileInfo,
|
|
130
|
+
fileIndex,
|
|
130
131
|
outputDirectory,
|
|
131
132
|
serializedMappingOptions: serializeMappingOptions(mappingOptions),
|
|
132
133
|
});
|
|
@@ -142,6 +143,12 @@ function dispatchMappingJobs() {
|
|
|
142
143
|
clearCaches();
|
|
143
144
|
console.log(`Finished mapping ${mapResultsList.length} files`);
|
|
144
145
|
console.log('job is finished');
|
|
146
|
+
progressCallback({
|
|
147
|
+
response: 'done',
|
|
148
|
+
mapResultsList: mapResultsList,
|
|
149
|
+
processedFiles: mapResultsList.length,
|
|
150
|
+
totalFiles: mapResultsList.length,
|
|
151
|
+
});
|
|
145
152
|
}
|
|
146
153
|
}
|
|
147
154
|
function collectMappingOptions(organizeOptions) {
|
|
@@ -182,7 +189,7 @@ function collectMappingOptions(organizeOptions) {
|
|
|
182
189
|
});
|
|
183
190
|
}
|
|
184
191
|
function queueFilesForMapping(organizeOptions) {
|
|
185
|
-
organizeOptions.inputFiles.forEach((inputFile) => {
|
|
192
|
+
organizeOptions.inputFiles.forEach((inputFile, fileIndex) => {
|
|
186
193
|
const fileInfo = {
|
|
187
194
|
path: '',
|
|
188
195
|
name: inputFile.name,
|
|
@@ -190,38 +197,51 @@ function queueFilesForMapping(organizeOptions) {
|
|
|
190
197
|
kind: 'blob',
|
|
191
198
|
blob: inputFile,
|
|
192
199
|
};
|
|
193
|
-
filesToProcess.push(fileInfo);
|
|
200
|
+
filesToProcess.push({ fileInfo, fileIndex });
|
|
194
201
|
dispatchMappingJobs();
|
|
195
202
|
});
|
|
196
203
|
}
|
|
197
204
|
let progressCallback;
|
|
198
205
|
function curateMany(organizeOptions, onProgress) {
|
|
199
206
|
return __awaiter(this, void 0, void 0, function* () {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
request
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
207
|
+
return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
|
|
208
|
+
// Resolve promise if progressCallback gets called with 'done'
|
|
209
|
+
progressCallback = (msg) => {
|
|
210
|
+
onProgress === null || onProgress === void 0 ? void 0 : onProgress(msg);
|
|
211
|
+
if (msg.response === 'done') {
|
|
212
|
+
resolve(msg);
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
try {
|
|
216
|
+
// create the mapping workers
|
|
217
|
+
initializeMappingWorkers();
|
|
218
|
+
// Set global mappingWorkerOptions
|
|
219
|
+
mappingWorkerOptions = (yield collectMappingOptions(organizeOptions));
|
|
220
|
+
//
|
|
221
|
+
// If the request provides a directory, then use the worker
|
|
222
|
+
// to recursively convert to fileSystemHandles.
|
|
223
|
+
// If the request provides a list of File objects,
|
|
224
|
+
// send them to the mapping workers directly.
|
|
225
|
+
//
|
|
226
|
+
if (organizeOptions.inputType === 'directory') {
|
|
227
|
+
const fileListWorker = initializeFileListWorker();
|
|
228
|
+
fileListWorker.postMessage({
|
|
229
|
+
request: 'scan',
|
|
230
|
+
directoryHandle: organizeOptions.inputDirectory,
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
else if (organizeOptions.inputType === 'files') {
|
|
234
|
+
queueFilesForMapping(organizeOptions);
|
|
235
|
+
}
|
|
236
|
+
else {
|
|
237
|
+
console.error('`inputType` should be "directory" or "files"');
|
|
238
|
+
}
|
|
239
|
+
dispatchMappingJobs();
|
|
240
|
+
}
|
|
241
|
+
catch (error) {
|
|
242
|
+
reject(error);
|
|
243
|
+
}
|
|
244
|
+
}));
|
|
225
245
|
});
|
|
226
246
|
}
|
|
227
247
|
export { curateMany, curateOne, extractColumnMappings, clearCaches };
|
|
@@ -34,27 +34,14 @@ function scanDirectory(dir) {
|
|
|
34
34
|
function traverse(dir, prefix) {
|
|
35
35
|
return __awaiter(this, void 0, void 0, function* () {
|
|
36
36
|
var _a, e_1, _b, _c;
|
|
37
|
+
// First, collect sorted dir entries
|
|
38
|
+
const entries = [];
|
|
37
39
|
try {
|
|
38
40
|
for (var _d = true, _e = __asyncValues(dir.values()), _f; _f = yield _e.next(), _a = _f.done, !_a; _d = true) {
|
|
39
41
|
_c = _f.value;
|
|
40
42
|
_d = false;
|
|
41
43
|
const entry = _c;
|
|
42
|
-
|
|
43
|
-
const file = yield entry.getFile();
|
|
44
|
-
self.postMessage({
|
|
45
|
-
response: 'file',
|
|
46
|
-
fileInfo: {
|
|
47
|
-
path: prefix,
|
|
48
|
-
name: entry.name,
|
|
49
|
-
size: file.size,
|
|
50
|
-
kind: 'handle',
|
|
51
|
-
fileHandle: entry,
|
|
52
|
-
},
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
else if (entry.kind === 'directory' && keepScanning) {
|
|
56
|
-
yield traverse(entry, prefix + '/' + entry.name);
|
|
57
|
-
}
|
|
44
|
+
entries.push(entry);
|
|
58
45
|
}
|
|
59
46
|
}
|
|
60
47
|
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
@@ -64,6 +51,28 @@ function scanDirectory(dir) {
|
|
|
64
51
|
}
|
|
65
52
|
finally { if (e_1) throw e_1.error; }
|
|
66
53
|
}
|
|
54
|
+
entries.sort((a, b) => a.name.localeCompare(b.name));
|
|
55
|
+
// Assign sorted index to files
|
|
56
|
+
let fileIndex = 0;
|
|
57
|
+
for (const entry of entries) {
|
|
58
|
+
if (entry.kind === 'file' && keepScanning) {
|
|
59
|
+
const file = yield entry.getFile();
|
|
60
|
+
self.postMessage({
|
|
61
|
+
response: 'file',
|
|
62
|
+
fileIndex: fileIndex++,
|
|
63
|
+
fileInfo: {
|
|
64
|
+
path: prefix,
|
|
65
|
+
name: entry.name,
|
|
66
|
+
size: file.size,
|
|
67
|
+
kind: 'handle',
|
|
68
|
+
fileHandle: entry,
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
else if (entry.kind === 'directory' && keepScanning) {
|
|
73
|
+
yield traverse(entry, prefix + '/' + entry.name);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
67
76
|
});
|
|
68
77
|
}
|
|
69
78
|
yield traverse(dir, dir.name);
|
|
@@ -1 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
import type { TFileInfo, TSerializedMappingOptions } from './types';
|
|
2
|
+
export type MappingRequest = {
|
|
3
|
+
request: 'apply';
|
|
4
|
+
fileInfo: TFileInfo;
|
|
5
|
+
fileIndex: number;
|
|
6
|
+
outputDirectory?: FileSystemDirectoryHandle;
|
|
7
|
+
serializedMappingOptions: TSerializedMappingOptions;
|
|
8
|
+
};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import type { TMappingOptions, TMapResults } from './types';
|
|
2
2
|
import type { TDicomData, TNaturalData } from 'dcmjs';
|
|
3
|
-
export default function collectMappings(inputFilePath: string, dicomData: TDicomData, mappingOptions: TMappingOptions): [TNaturalData, TMapResults];
|
|
3
|
+
export default function collectMappings(inputFilePath: string, inputFileIndex: number, dicomData: TDicomData, mappingOptions: TMappingOptions): [TNaturalData, TMapResults];
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as dcmjs from 'dcmjs';
|
|
2
2
|
import type { TDicomData } from 'dcmjs';
|
|
3
3
|
import type { TMappingOptions } from './types';
|
|
4
|
-
export default function curateDict(inputFilePath: string, dicomData: TDicomData, mappingOptions: TMappingOptions): {
|
|
4
|
+
export default function curateDict(inputFilePath: string, inputFileIndex: number, dicomData: TDicomData, mappingOptions: TMappingOptions): {
|
|
5
5
|
dicomData: dcmjs.data.DicomDict;
|
|
6
6
|
mapResults: import("./types").TMapResults;
|
|
7
7
|
};
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import type { TFileInfo, TMappingOptions, TMapResults } from './types';
|
|
2
|
-
export
|
|
2
|
+
export type TCurateOneArgs = {
|
|
3
|
+
fileInfo: TFileInfo;
|
|
4
|
+
fileIndex?: number;
|
|
5
|
+
outputDirectory: FileSystemDirectoryHandle | undefined;
|
|
6
|
+
mappingOptions: TMappingOptions;
|
|
7
|
+
};
|
|
8
|
+
export declare function curateOne({ fileInfo, fileIndex, outputDirectory, mappingOptions, }: TCurateOneArgs): Promise<Omit<Partial<TMapResults>, 'anomalies'> & {
|
|
3
9
|
anomalies: TMapResults['anomalies'];
|
|
4
10
|
}>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { TNaturalData } from 'dcmjs';
|
|
2
2
|
import type { Iso8601Duration, TPs315Options, TMapResults } from './types';
|
|
3
|
+
export declare function protectUid(uid: string, retainUIDsOption: string): string;
|
|
3
4
|
export default function deidentifyPS315E({ naturalData, dicomPS315EOptions, dateOffset, mapResults, }: {
|
|
4
5
|
naturalData: TNaturalData;
|
|
5
6
|
dicomPS315EOptions: TPs315Options;
|
|
@@ -6,4 +6,4 @@ export declare const FILENAME: symbol;
|
|
|
6
6
|
declare const clearUniqueNumberCache: () => void;
|
|
7
7
|
declare const clearUniqueInGroupCache: () => void;
|
|
8
8
|
export { clearUniqueNumberCache, clearUniqueInGroupCache };
|
|
9
|
-
export default function getParser(inputPathPattern: string, inputFilePath: string, naturalData: TNaturalData, columnMappings?: TColumnMappings, additionalData?: TCurationSpecification['additionalData']): TParser;
|
|
9
|
+
export default function getParser(inputPathPattern: string, inputFilePath: string, naturalData: TNaturalData, dicomPS315EOptions: TCurationSpecification['dicomPS315EOptions'], columnMappings?: TColumnMappings, additionalData?: TCurationSpecification['additionalData']): TParser;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { extractColumnMappings } from './csvMapping';
|
|
2
2
|
import { clearCaches } from './clearCaches';
|
|
3
3
|
import { curateOne } from './curateOne';
|
|
4
|
-
import type { OrganizeOptions, TProgressMessage } from './types';
|
|
4
|
+
import type { OrganizeOptions, TProgressMessage, TProgressMessageDone } from './types';
|
|
5
5
|
export type ProgressCallback = (message: TProgressMessage) => void;
|
|
6
6
|
export type { TPs315Options, TMapResults, TProgressMessage, OrganizeOptions, TCurationSpecification, } from './types';
|
|
7
|
+
export { TCurateOneArgs } from './curateOne';
|
|
7
8
|
export { specVersion } from './config/specVersion';
|
|
8
9
|
export { sample2PassCurationSpecification as sampleSpecification } from './config/sample2PassCurationSpecification';
|
|
9
10
|
export { csvTextToRows } from './csvMapping';
|
|
10
11
|
export type { Row } from './csvMapping';
|
|
11
|
-
declare function curateMany(organizeOptions: OrganizeOptions, onProgress?: ProgressCallback): Promise<
|
|
12
|
+
declare function curateMany(organizeOptions: OrganizeOptions, onProgress?: ProgressCallback): Promise<TProgressMessageDone>;
|
|
12
13
|
export { curateMany, curateOne, extractColumnMappings, clearCaches };
|
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
import { TMappingOptions } from './types';
|
|
2
|
-
type TSerializedMappingOptions = Omit<TMappingOptions, 'curationSpec'> & {
|
|
3
|
-
curationSpecStr: string;
|
|
4
|
-
};
|
|
1
|
+
import { TMappingOptions, TSerializedMappingOptions } from './types';
|
|
5
2
|
export declare function serializeMappingOptions(mappingOptions: TMappingOptions): TSerializedMappingOptions;
|
|
6
3
|
export declare function deserializeMappingOptions(serializedMappingOptions: TSerializedMappingOptions): TMappingOptions;
|
|
7
|
-
export {};
|
package/dist/types/types.d.ts
CHANGED
|
@@ -34,6 +34,9 @@ export type TMappingOptions = {
|
|
|
34
34
|
skipValidation?: boolean;
|
|
35
35
|
dateOffset?: Iso8601Duration;
|
|
36
36
|
};
|
|
37
|
+
export type TSerializedMappingOptions = Omit<TMappingOptions, 'curationSpec'> & {
|
|
38
|
+
curationSpecStr: string;
|
|
39
|
+
};
|
|
37
40
|
export type TFileInfo = {
|
|
38
41
|
path: string;
|
|
39
42
|
name: string;
|
|
@@ -92,6 +95,7 @@ export type TParser = {
|
|
|
92
95
|
getMapping: ((value: string) => string | number) | undefined;
|
|
93
96
|
getDicom: (attrName: string) => any;
|
|
94
97
|
missingDicom: (attrName: string) => boolean;
|
|
98
|
+
protectUid: (uid: string) => string;
|
|
95
99
|
addDays: (dicomDateString: string, offsetDays: number) => string;
|
|
96
100
|
FILENAME: symbol;
|
|
97
101
|
FILEBASENAME: symbol;
|
|
@@ -134,11 +138,18 @@ export type TCurationSpecification = {
|
|
|
134
138
|
mapping: TMappedValues;
|
|
135
139
|
} & (TMappingInputDirect | TMappingInputTwoPass);
|
|
136
140
|
};
|
|
137
|
-
|
|
138
|
-
response: 'start' | 'progress' | 'finished' | 'error';
|
|
141
|
+
type TProgressMessageBase = {
|
|
139
142
|
totalFiles?: number;
|
|
140
143
|
processedFiles?: number;
|
|
144
|
+
};
|
|
145
|
+
type TProgressMessageProgress = TProgressMessageBase & {
|
|
146
|
+
response: 'progress';
|
|
141
147
|
mapResults?: TMapResults;
|
|
142
148
|
error?: Error;
|
|
143
149
|
};
|
|
150
|
+
export type TProgressMessageDone = TProgressMessageBase & {
|
|
151
|
+
response: 'done';
|
|
152
|
+
mapResultsList: TMapResults[];
|
|
153
|
+
};
|
|
154
|
+
export type TProgressMessage = TProgressMessageProgress | TProgressMessageDone;
|
|
144
155
|
export {};
|