dicom-curate 0.38.1 → 0.39.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/dist/esm/applyMappingsWorker.js +11 -9
- package/dist/esm/collectMappings.js +11 -9
- package/dist/esm/config/sampleSummaryCurationSpecification.js +40 -0
- package/dist/esm/curateDict.js +11 -9
- package/dist/esm/curateOne.js +11 -9
- package/dist/esm/getParser.js +9 -7
- package/dist/esm/index.js +17 -10
- package/dist/esm/mappingWorkerPool.js +11 -9
- package/dist/types/config/sampleSummaryCurationSpecification.d.ts +2 -0
- package/dist/types/types.d.ts +18 -5
- package/dist/umd/dicom-curate.umd.js +40 -21
- 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
|
@@ -86083,14 +86083,16 @@ function getParser(inputPathPattern, inputFilePath, naturalData, dicomPS315EOpti
|
|
|
86083
86083
|
function getFrom(source, identifier) {
|
|
86084
86084
|
return source === "dicom" ? getDicom(identifier) : getFilePathComp(identifier);
|
|
86085
86085
|
}
|
|
86086
|
-
const getMapping = !additionalData || !columnMappings ? void 0 : (
|
|
86086
|
+
const getMapping = !additionalData || !additionalData.mapping || !columnMappings ? void 0 : (
|
|
86087
86087
|
// key: one of the keys defined in the `mapping` object
|
|
86088
|
-
|
|
86089
|
-
const
|
|
86090
|
-
|
|
86091
|
-
|
|
86092
|
-
|
|
86093
|
-
|
|
86088
|
+
(() => {
|
|
86089
|
+
const mapping = additionalData.mapping;
|
|
86090
|
+
return function getMapping2(key) {
|
|
86091
|
+
const { value: valueFn } = mapping[key];
|
|
86092
|
+
const value = valueFn({ getDicom, getFilePathComp, getFrom });
|
|
86093
|
+
return getCsvMapping(columnMappings, mapping, key, value);
|
|
86094
|
+
};
|
|
86095
|
+
})()
|
|
86094
86096
|
);
|
|
86095
86097
|
function missingDicom(attrName) {
|
|
86096
86098
|
const value = getDicom(attrName);
|
|
@@ -86183,12 +86185,12 @@ function collectMappings(inputFilePath, dicomData, mappingOptions) {
|
|
|
86183
86185
|
});
|
|
86184
86186
|
const cleanedInfo = info.map((item) => {
|
|
86185
86187
|
if (Array.isArray(item[1]) && item[1].length === 1 && typeof item[1][0] === "object" && "Alphabetic" in item[1][0] && /^\d+$/.test(item[1][0].Alphabetic)) {
|
|
86186
|
-
return [item[0], item[1][0].Alphabetic];
|
|
86188
|
+
return item.length > 2 ? [item[0], item[1][0].Alphabetic, item[2]] : [item[0], item[1][0].Alphabetic];
|
|
86187
86189
|
} else {
|
|
86188
86190
|
return item;
|
|
86189
86191
|
}
|
|
86190
86192
|
});
|
|
86191
|
-
mapResults.listing = { info: cleanedInfo, collectByValue };
|
|
86193
|
+
mapResults.listing = { info: cleanedInfo, collectByValue, lookups };
|
|
86192
86194
|
}
|
|
86193
86195
|
if (!mappingOptions.skipModifications) {
|
|
86194
86196
|
mapResults.outputFilePath = finalSpec.outputFilePathComponents(parser).join("/");
|
|
@@ -34147,14 +34147,16 @@ function getParser(inputPathPattern, inputFilePath, naturalData, dicomPS315EOpti
|
|
|
34147
34147
|
function getFrom(source, identifier) {
|
|
34148
34148
|
return source === "dicom" ? getDicom(identifier) : getFilePathComp(identifier);
|
|
34149
34149
|
}
|
|
34150
|
-
const getMapping = !additionalData || !columnMappings ? void 0 : (
|
|
34150
|
+
const getMapping = !additionalData || !additionalData.mapping || !columnMappings ? void 0 : (
|
|
34151
34151
|
// key: one of the keys defined in the `mapping` object
|
|
34152
|
-
|
|
34153
|
-
const
|
|
34154
|
-
|
|
34155
|
-
|
|
34156
|
-
|
|
34157
|
-
|
|
34152
|
+
(() => {
|
|
34153
|
+
const mapping = additionalData.mapping;
|
|
34154
|
+
return function getMapping2(key) {
|
|
34155
|
+
const { value: valueFn } = mapping[key];
|
|
34156
|
+
const value = valueFn({ getDicom, getFilePathComp, getFrom });
|
|
34157
|
+
return getCsvMapping(columnMappings, mapping, key, value);
|
|
34158
|
+
};
|
|
34159
|
+
})()
|
|
34158
34160
|
);
|
|
34159
34161
|
function missingDicom(attrName) {
|
|
34160
34162
|
const value = getDicom(attrName);
|
|
@@ -34247,12 +34249,12 @@ function collectMappings(inputFilePath, dicomData, mappingOptions) {
|
|
|
34247
34249
|
});
|
|
34248
34250
|
const cleanedInfo = info.map((item) => {
|
|
34249
34251
|
if (Array.isArray(item[1]) && item[1].length === 1 && typeof item[1][0] === "object" && "Alphabetic" in item[1][0] && /^\d+$/.test(item[1][0].Alphabetic)) {
|
|
34250
|
-
return [item[0], item[1][0].Alphabetic];
|
|
34252
|
+
return item.length > 2 ? [item[0], item[1][0].Alphabetic, item[2]] : [item[0], item[1][0].Alphabetic];
|
|
34251
34253
|
} else {
|
|
34252
34254
|
return item;
|
|
34253
34255
|
}
|
|
34254
34256
|
});
|
|
34255
|
-
mapResults.listing = { info: cleanedInfo, collectByValue };
|
|
34257
|
+
mapResults.listing = { info: cleanedInfo, collectByValue, lookups };
|
|
34256
34258
|
}
|
|
34257
34259
|
if (!mappingOptions.skipModifications) {
|
|
34258
34260
|
mapResults.outputFilePath = finalSpec.outputFilePathComponents(parser).join("/");
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// src/config/sampleSummaryCurationSpecification.ts
|
|
2
|
+
function sampleSummaryCurationSpecification() {
|
|
3
|
+
const hostProps = { protocolNumber: "Demo" };
|
|
4
|
+
return {
|
|
5
|
+
inputPathPattern: "any",
|
|
6
|
+
additionalData: {
|
|
7
|
+
type: "listing",
|
|
8
|
+
collect: (parser) => ({
|
|
9
|
+
lookups: {
|
|
10
|
+
PerSeries: parser.getDicom("SeriesInstanceUID")
|
|
11
|
+
},
|
|
12
|
+
info: [
|
|
13
|
+
["StudyInstanceUID", parser.getDicom("StudyInstanceUID")],
|
|
14
|
+
["SeriesInstanceUID", parser.getDicom("SeriesInstanceUID")],
|
|
15
|
+
["SeriesDescription", parser.getDicom("SeriesDescription")],
|
|
16
|
+
["FolderX", parser.getFilePathComp(0)],
|
|
17
|
+
["FolderY", parser.getFilePathComp(1)],
|
|
18
|
+
["SOPInstanceUIDs", parser.getDicom("SOPInstanceUID"), "list"]
|
|
19
|
+
],
|
|
20
|
+
collect: []
|
|
21
|
+
}),
|
|
22
|
+
output: {
|
|
23
|
+
path: "reports/series_summary.csv",
|
|
24
|
+
rowKey: "PerSeries"
|
|
25
|
+
}
|
|
26
|
+
// No `mapping` => single pass, write CSV summary instead of DICOMs.
|
|
27
|
+
},
|
|
28
|
+
version: "3.0",
|
|
29
|
+
hostProps,
|
|
30
|
+
// No de-identification or header modification in summary mode.
|
|
31
|
+
dicomPS315EOptions: "Off",
|
|
32
|
+
modifyDicomHeader: () => ({}),
|
|
33
|
+
// Unused when consumers run with skipModifications.
|
|
34
|
+
outputFilePathComponents: () => [],
|
|
35
|
+
errors: () => []
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export {
|
|
39
|
+
sampleSummaryCurationSpecification
|
|
40
|
+
};
|
package/dist/esm/curateDict.js
CHANGED
|
@@ -34164,14 +34164,16 @@ function getParser(inputPathPattern, inputFilePath, naturalData, dicomPS315EOpti
|
|
|
34164
34164
|
function getFrom(source, identifier) {
|
|
34165
34165
|
return source === "dicom" ? getDicom(identifier) : getFilePathComp(identifier);
|
|
34166
34166
|
}
|
|
34167
|
-
const getMapping = !additionalData || !columnMappings ? void 0 : (
|
|
34167
|
+
const getMapping = !additionalData || !additionalData.mapping || !columnMappings ? void 0 : (
|
|
34168
34168
|
// key: one of the keys defined in the `mapping` object
|
|
34169
|
-
|
|
34170
|
-
const
|
|
34171
|
-
|
|
34172
|
-
|
|
34173
|
-
|
|
34174
|
-
|
|
34169
|
+
(() => {
|
|
34170
|
+
const mapping = additionalData.mapping;
|
|
34171
|
+
return function getMapping2(key) {
|
|
34172
|
+
const { value: valueFn } = mapping[key];
|
|
34173
|
+
const value = valueFn({ getDicom, getFilePathComp, getFrom });
|
|
34174
|
+
return getCsvMapping(columnMappings, mapping, key, value);
|
|
34175
|
+
};
|
|
34176
|
+
})()
|
|
34175
34177
|
);
|
|
34176
34178
|
function missingDicom(attrName) {
|
|
34177
34179
|
const value = getDicom(attrName);
|
|
@@ -34264,12 +34266,12 @@ function collectMappings(inputFilePath, dicomData, mappingOptions) {
|
|
|
34264
34266
|
});
|
|
34265
34267
|
const cleanedInfo = info.map((item) => {
|
|
34266
34268
|
if (Array.isArray(item[1]) && item[1].length === 1 && typeof item[1][0] === "object" && "Alphabetic" in item[1][0] && /^\d+$/.test(item[1][0].Alphabetic)) {
|
|
34267
|
-
return [item[0], item[1][0].Alphabetic];
|
|
34269
|
+
return item.length > 2 ? [item[0], item[1][0].Alphabetic, item[2]] : [item[0], item[1][0].Alphabetic];
|
|
34268
34270
|
} else {
|
|
34269
34271
|
return item;
|
|
34270
34272
|
}
|
|
34271
34273
|
});
|
|
34272
|
-
mapResults.listing = { info: cleanedInfo, collectByValue };
|
|
34274
|
+
mapResults.listing = { info: cleanedInfo, collectByValue, lookups };
|
|
34273
34275
|
}
|
|
34274
34276
|
if (!mappingOptions.skipModifications) {
|
|
34275
34277
|
mapResults.outputFilePath = finalSpec.outputFilePathComponents(parser).join("/");
|
package/dist/esm/curateOne.js
CHANGED
|
@@ -79792,14 +79792,16 @@ function getParser(inputPathPattern, inputFilePath, naturalData, dicomPS315EOpti
|
|
|
79792
79792
|
function getFrom(source, identifier) {
|
|
79793
79793
|
return source === "dicom" ? getDicom(identifier) : getFilePathComp(identifier);
|
|
79794
79794
|
}
|
|
79795
|
-
const getMapping = !additionalData || !columnMappings ? void 0 : (
|
|
79795
|
+
const getMapping = !additionalData || !additionalData.mapping || !columnMappings ? void 0 : (
|
|
79796
79796
|
// key: one of the keys defined in the `mapping` object
|
|
79797
|
-
|
|
79798
|
-
const
|
|
79799
|
-
|
|
79800
|
-
|
|
79801
|
-
|
|
79802
|
-
|
|
79797
|
+
(() => {
|
|
79798
|
+
const mapping = additionalData.mapping;
|
|
79799
|
+
return function getMapping2(key) {
|
|
79800
|
+
const { value: valueFn } = mapping[key];
|
|
79801
|
+
const value = valueFn({ getDicom, getFilePathComp, getFrom });
|
|
79802
|
+
return getCsvMapping(columnMappings, mapping, key, value);
|
|
79803
|
+
};
|
|
79804
|
+
})()
|
|
79803
79805
|
);
|
|
79804
79806
|
function missingDicom(attrName) {
|
|
79805
79807
|
const value = getDicom(attrName);
|
|
@@ -79892,12 +79894,12 @@ function collectMappings(inputFilePath, dicomData, mappingOptions) {
|
|
|
79892
79894
|
});
|
|
79893
79895
|
const cleanedInfo = info.map((item) => {
|
|
79894
79896
|
if (Array.isArray(item[1]) && item[1].length === 1 && typeof item[1][0] === "object" && "Alphabetic" in item[1][0] && /^\d+$/.test(item[1][0].Alphabetic)) {
|
|
79895
|
-
return [item[0], item[1][0].Alphabetic];
|
|
79897
|
+
return item.length > 2 ? [item[0], item[1][0].Alphabetic, item[2]] : [item[0], item[1][0].Alphabetic];
|
|
79896
79898
|
} else {
|
|
79897
79899
|
return item;
|
|
79898
79900
|
}
|
|
79899
79901
|
});
|
|
79900
|
-
mapResults.listing = { info: cleanedInfo, collectByValue };
|
|
79902
|
+
mapResults.listing = { info: cleanedInfo, collectByValue, lookups };
|
|
79901
79903
|
}
|
|
79902
79904
|
if (!mappingOptions.skipModifications) {
|
|
79903
79905
|
mapResults.outputFilePath = finalSpec.outputFilePathComponents(parser).join("/");
|
package/dist/esm/getParser.js
CHANGED
|
@@ -32798,14 +32798,16 @@ function getParser(inputPathPattern, inputFilePath, naturalData, dicomPS315EOpti
|
|
|
32798
32798
|
function getFrom(source, identifier) {
|
|
32799
32799
|
return source === "dicom" ? getDicom(identifier) : getFilePathComp(identifier);
|
|
32800
32800
|
}
|
|
32801
|
-
const getMapping = !additionalData || !columnMappings ? void 0 : (
|
|
32801
|
+
const getMapping = !additionalData || !additionalData.mapping || !columnMappings ? void 0 : (
|
|
32802
32802
|
// key: one of the keys defined in the `mapping` object
|
|
32803
|
-
|
|
32804
|
-
const
|
|
32805
|
-
|
|
32806
|
-
|
|
32807
|
-
|
|
32808
|
-
|
|
32803
|
+
(() => {
|
|
32804
|
+
const mapping = additionalData.mapping;
|
|
32805
|
+
return function getMapping2(key) {
|
|
32806
|
+
const { value: valueFn } = mapping[key];
|
|
32807
|
+
const value = valueFn({ getDicom, getFilePathComp, getFrom });
|
|
32808
|
+
return getCsvMapping(columnMappings, mapping, key, value);
|
|
32809
|
+
};
|
|
32810
|
+
})()
|
|
32809
32811
|
);
|
|
32810
32812
|
function missingDicom(attrName) {
|
|
32811
32813
|
const value = getDicom(attrName);
|
package/dist/esm/index.js
CHANGED
|
@@ -87646,14 +87646,16 @@ function getParser(inputPathPattern, inputFilePath, naturalData, dicomPS315EOpti
|
|
|
87646
87646
|
function getFrom(source, identifier) {
|
|
87647
87647
|
return source === "dicom" ? getDicom(identifier) : getFilePathComp(identifier);
|
|
87648
87648
|
}
|
|
87649
|
-
const getMapping = !additionalData || !columnMappings ? void 0 : (
|
|
87649
|
+
const getMapping = !additionalData || !additionalData.mapping || !columnMappings ? void 0 : (
|
|
87650
87650
|
// key: one of the keys defined in the `mapping` object
|
|
87651
|
-
|
|
87652
|
-
const
|
|
87653
|
-
|
|
87654
|
-
|
|
87655
|
-
|
|
87656
|
-
|
|
87651
|
+
(() => {
|
|
87652
|
+
const mapping = additionalData.mapping;
|
|
87653
|
+
return function getMapping2(key) {
|
|
87654
|
+
const { value: valueFn } = mapping[key];
|
|
87655
|
+
const value = valueFn({ getDicom, getFilePathComp, getFrom });
|
|
87656
|
+
return getCsvMapping(columnMappings, mapping, key, value);
|
|
87657
|
+
};
|
|
87658
|
+
})()
|
|
87657
87659
|
);
|
|
87658
87660
|
function missingDicom(attrName) {
|
|
87659
87661
|
const value = getDicom(attrName);
|
|
@@ -87746,12 +87748,12 @@ function collectMappings(inputFilePath, dicomData, mappingOptions) {
|
|
|
87746
87748
|
});
|
|
87747
87749
|
const cleanedInfo = info.map((item) => {
|
|
87748
87750
|
if (Array.isArray(item[1]) && item[1].length === 1 && typeof item[1][0] === "object" && "Alphabetic" in item[1][0] && /^\d+$/.test(item[1][0].Alphabetic)) {
|
|
87749
|
-
return [item[0], item[1][0].Alphabetic];
|
|
87751
|
+
return item.length > 2 ? [item[0], item[1][0].Alphabetic, item[2]] : [item[0], item[1][0].Alphabetic];
|
|
87750
87752
|
} else {
|
|
87751
87753
|
return item;
|
|
87752
87754
|
}
|
|
87753
87755
|
});
|
|
87754
|
-
mapResults.listing = { info: cleanedInfo, collectByValue };
|
|
87756
|
+
mapResults.listing = { info: cleanedInfo, collectByValue, lookups };
|
|
87755
87757
|
}
|
|
87756
87758
|
if (!mappingOptions.skipModifications) {
|
|
87757
87759
|
mapResults.outputFilePath = finalSpec.outputFilePathComponents(parser).join("/");
|
|
@@ -95006,7 +95008,7 @@ async function collectMappingOptions(organizeOptions) {
|
|
|
95006
95008
|
));
|
|
95007
95009
|
}
|
|
95008
95010
|
let columnMappings;
|
|
95009
|
-
if (organizeOptions.table && additionalData) {
|
|
95011
|
+
if (organizeOptions.table && additionalData?.mapping) {
|
|
95010
95012
|
columnMappings = extractColumnMappings(
|
|
95011
95013
|
organizeOptions.table,
|
|
95012
95014
|
additionalData.mapping
|
|
@@ -95017,6 +95019,11 @@ async function collectMappingOptions(organizeOptions) {
|
|
|
95017
95019
|
const skipValidation = organizeOptions.skipValidation ?? false;
|
|
95018
95020
|
const hashMethod = organizeOptions.hashMethod;
|
|
95019
95021
|
const hashPartSize = organizeOptions.hashPartSize;
|
|
95022
|
+
if (additionalData?.type === "listing" && additionalData.output && !skipWrite) {
|
|
95023
|
+
throw new Error(
|
|
95024
|
+
"additionalData.output (summary-table mode) requires skipWrite: true \u2014 summary specs produce a CSV summary and no curated output."
|
|
95025
|
+
);
|
|
95026
|
+
}
|
|
95020
95027
|
const dateOffset = organizeOptions.dateOffset;
|
|
95021
95028
|
if (requiresDateOffset(deIdOpts) && !dateOffset?.match(iso8601)) {
|
|
95022
95029
|
throw new Error(
|
|
@@ -86083,14 +86083,16 @@ function getParser(inputPathPattern, inputFilePath, naturalData, dicomPS315EOpti
|
|
|
86083
86083
|
function getFrom(source, identifier) {
|
|
86084
86084
|
return source === "dicom" ? getDicom(identifier) : getFilePathComp(identifier);
|
|
86085
86085
|
}
|
|
86086
|
-
const getMapping = !additionalData || !columnMappings ? void 0 : (
|
|
86086
|
+
const getMapping = !additionalData || !additionalData.mapping || !columnMappings ? void 0 : (
|
|
86087
86087
|
// key: one of the keys defined in the `mapping` object
|
|
86088
|
-
|
|
86089
|
-
const
|
|
86090
|
-
|
|
86091
|
-
|
|
86092
|
-
|
|
86093
|
-
|
|
86088
|
+
(() => {
|
|
86089
|
+
const mapping = additionalData.mapping;
|
|
86090
|
+
return function getMapping2(key) {
|
|
86091
|
+
const { value: valueFn } = mapping[key];
|
|
86092
|
+
const value = valueFn({ getDicom, getFilePathComp, getFrom });
|
|
86093
|
+
return getCsvMapping(columnMappings, mapping, key, value);
|
|
86094
|
+
};
|
|
86095
|
+
})()
|
|
86094
86096
|
);
|
|
86095
86097
|
function missingDicom(attrName) {
|
|
86096
86098
|
const value = getDicom(attrName);
|
|
@@ -86183,12 +86185,12 @@ function collectMappings(inputFilePath, dicomData, mappingOptions) {
|
|
|
86183
86185
|
});
|
|
86184
86186
|
const cleanedInfo = info.map((item) => {
|
|
86185
86187
|
if (Array.isArray(item[1]) && item[1].length === 1 && typeof item[1][0] === "object" && "Alphabetic" in item[1][0] && /^\d+$/.test(item[1][0].Alphabetic)) {
|
|
86186
|
-
return [item[0], item[1][0].Alphabetic];
|
|
86188
|
+
return item.length > 2 ? [item[0], item[1][0].Alphabetic, item[2]] : [item[0], item[1][0].Alphabetic];
|
|
86187
86189
|
} else {
|
|
86188
86190
|
return item;
|
|
86189
86191
|
}
|
|
86190
86192
|
});
|
|
86191
|
-
mapResults.listing = { info: cleanedInfo, collectByValue };
|
|
86193
|
+
mapResults.listing = { info: cleanedInfo, collectByValue, lookups };
|
|
86192
86194
|
}
|
|
86193
86195
|
if (!mappingOptions.skipModifications) {
|
|
86194
86196
|
mapResults.outputFilePath = finalSpec.outputFilePathComponents(parser).join("/");
|
package/dist/types/types.d.ts
CHANGED
|
@@ -189,6 +189,9 @@ export type TMapResults = {
|
|
|
189
189
|
listing?: {
|
|
190
190
|
info: TMappingTwoPassInfo[];
|
|
191
191
|
collectByValue: [...TMappingTwoPassCollect, string | number][];
|
|
192
|
+
lookups: {
|
|
193
|
+
[lookupField: string]: string;
|
|
194
|
+
};
|
|
192
195
|
};
|
|
193
196
|
mappedBlob?: Blob;
|
|
194
197
|
outputUpload?: {
|
|
@@ -236,13 +239,19 @@ export type TPostExcludeParser = TParser & {
|
|
|
236
239
|
type TMappingInputDirect = {
|
|
237
240
|
type: 'load';
|
|
238
241
|
collect: Record<string, RegExp | string[]>;
|
|
242
|
+
mapping: TMappedValues;
|
|
239
243
|
};
|
|
240
|
-
type
|
|
244
|
+
type TMappingTwoPassInfoMode = 'list';
|
|
245
|
+
type TMappingTwoPassInfo = [name: string, value: string] | [name: string, value: string, mode: TMappingTwoPassInfoMode];
|
|
241
246
|
type TMappingTwoPassCollect = [
|
|
242
247
|
value: string,
|
|
243
248
|
format: RegExp | string[],
|
|
244
249
|
lookupField: string
|
|
245
250
|
];
|
|
251
|
+
type TSummaryOutput = {
|
|
252
|
+
path: string;
|
|
253
|
+
rowKey: string;
|
|
254
|
+
};
|
|
246
255
|
type TMappingInputTwoPass = {
|
|
247
256
|
type: 'listing';
|
|
248
257
|
collect: (parser: Pick<TParser, 'getDicom' | 'getFilePathComp' | 'getFrom'>) => {
|
|
@@ -252,7 +261,13 @@ type TMappingInputTwoPass = {
|
|
|
252
261
|
info: TMappingTwoPassInfo[];
|
|
253
262
|
collect: TMappingTwoPassCollect[];
|
|
254
263
|
};
|
|
255
|
-
}
|
|
264
|
+
} & ({
|
|
265
|
+
mapping: TMappedValues;
|
|
266
|
+
output?: never;
|
|
267
|
+
} | {
|
|
268
|
+
output: TSummaryOutput;
|
|
269
|
+
mapping?: never;
|
|
270
|
+
});
|
|
256
271
|
type HPPrimitive = string | number | boolean | null | RegExp | ((...args: any[]) => any);
|
|
257
272
|
export type HPValue = HPPrimitive | {
|
|
258
273
|
[k: string]: HPValue;
|
|
@@ -269,9 +284,7 @@ export type TCurationSpecification<THost extends HostProps = HostProps> = {
|
|
|
269
284
|
dicomPS315EOptions: TPs315Options | 'Off';
|
|
270
285
|
inputPathPattern: string;
|
|
271
286
|
hostProps: THost;
|
|
272
|
-
additionalData?:
|
|
273
|
-
mapping: TMappedValues;
|
|
274
|
-
} & (TMappingInputDirect | TMappingInputTwoPass);
|
|
287
|
+
additionalData?: TMappingInputDirect | TMappingInputTwoPass;
|
|
275
288
|
excludedFiletypes?: string[];
|
|
276
289
|
preExclude?: (parser: TParser) => boolean;
|
|
277
290
|
postExclude?: (parser: TPostExcludeParser) => boolean;
|
|
@@ -53836,15 +53836,17 @@
|
|
|
53836
53836
|
? getDicom(identifier)
|
|
53837
53837
|
: getFilePathComp(identifier);
|
|
53838
53838
|
}
|
|
53839
|
-
const getMapping = !additionalData || !columnMappings
|
|
53839
|
+
const getMapping = !additionalData || !additionalData.mapping || !columnMappings
|
|
53840
53840
|
? undefined
|
|
53841
53841
|
: // key: one of the keys defined in the `mapping` object
|
|
53842
|
-
|
|
53843
|
-
const
|
|
53844
|
-
|
|
53845
|
-
|
|
53846
|
-
|
|
53847
|
-
|
|
53842
|
+
(() => {
|
|
53843
|
+
const mapping = additionalData.mapping;
|
|
53844
|
+
return function getMapping(key) {
|
|
53845
|
+
const { value: valueFn } = mapping[key];
|
|
53846
|
+
const value = valueFn({ getDicom, getFilePathComp, getFrom });
|
|
53847
|
+
return getCsvMapping(columnMappings, mapping, key, value);
|
|
53848
|
+
};
|
|
53849
|
+
})();
|
|
53848
53850
|
function missingDicom(attrName) {
|
|
53849
53851
|
const value = getDicom(attrName);
|
|
53850
53852
|
return typeof value === 'undefined' || value === '';
|
|
@@ -53933,20 +53935,23 @@
|
|
|
53933
53935
|
const lookupValue = lookups[lookupField];
|
|
53934
53936
|
return [...item, lookupValue];
|
|
53935
53937
|
});
|
|
53936
|
-
// FIXME: Bug in dcmjs
|
|
53938
|
+
// FIXME: Bug in dcmjs. Flatten single-element PN arrays, preserving any
|
|
53939
|
+
// optional aggregation mode marker (3rd tuple element) untouched.
|
|
53937
53940
|
const cleanedInfo = info.map((item) => {
|
|
53938
53941
|
if (Array.isArray(item[1]) &&
|
|
53939
53942
|
item[1].length === 1 &&
|
|
53940
53943
|
typeof item[1][0] === 'object' &&
|
|
53941
53944
|
'Alphabetic' in item[1][0] &&
|
|
53942
53945
|
/^\d+$/.test(item[1][0].Alphabetic)) {
|
|
53943
|
-
return
|
|
53946
|
+
return (item.length > 2
|
|
53947
|
+
? [item[0], item[1][0].Alphabetic, item[2]]
|
|
53948
|
+
: [item[0], item[1][0].Alphabetic]);
|
|
53944
53949
|
}
|
|
53945
53950
|
else {
|
|
53946
53951
|
return item;
|
|
53947
53952
|
}
|
|
53948
53953
|
});
|
|
53949
|
-
mapResults.listing = { info: cleanedInfo, collectByValue };
|
|
53954
|
+
mapResults.listing = { info: cleanedInfo, collectByValue, lookups };
|
|
53950
53955
|
}
|
|
53951
53956
|
if (!mappingOptions.skipModifications) {
|
|
53952
53957
|
mapResults.outputFilePath = finalSpec
|
|
@@ -125428,15 +125433,17 @@
|
|
|
125428
125433
|
? getDicom(identifier)
|
|
125429
125434
|
: getFilePathComp(identifier);
|
|
125430
125435
|
}
|
|
125431
|
-
const getMapping = !additionalData || !columnMappings
|
|
125436
|
+
const getMapping = !additionalData || !additionalData.mapping || !columnMappings
|
|
125432
125437
|
? undefined
|
|
125433
125438
|
: // key: one of the keys defined in the `mapping` object
|
|
125434
|
-
|
|
125435
|
-
const
|
|
125436
|
-
|
|
125437
|
-
|
|
125438
|
-
|
|
125439
|
-
|
|
125439
|
+
(() => {
|
|
125440
|
+
const mapping = additionalData.mapping;
|
|
125441
|
+
return function getMapping(key) {
|
|
125442
|
+
const { value: valueFn } = mapping[key];
|
|
125443
|
+
const value = valueFn({ getDicom, getFilePathComp, getFrom });
|
|
125444
|
+
return getCsvMapping(columnMappings, mapping, key, value);
|
|
125445
|
+
};
|
|
125446
|
+
})();
|
|
125440
125447
|
function missingDicom(attrName) {
|
|
125441
125448
|
const value = getDicom(attrName);
|
|
125442
125449
|
return typeof value === 'undefined' || value === '';
|
|
@@ -125525,20 +125532,23 @@
|
|
|
125525
125532
|
const lookupValue = lookups[lookupField];
|
|
125526
125533
|
return [...item, lookupValue];
|
|
125527
125534
|
});
|
|
125528
|
-
// FIXME: Bug in dcmjs
|
|
125535
|
+
// FIXME: Bug in dcmjs. Flatten single-element PN arrays, preserving any
|
|
125536
|
+
// optional aggregation mode marker (3rd tuple element) untouched.
|
|
125529
125537
|
const cleanedInfo = info.map((item) => {
|
|
125530
125538
|
if (Array.isArray(item[1]) &&
|
|
125531
125539
|
item[1].length === 1 &&
|
|
125532
125540
|
typeof item[1][0] === 'object' &&
|
|
125533
125541
|
'Alphabetic' in item[1][0] &&
|
|
125534
125542
|
/^\d+$/.test(item[1][0].Alphabetic)) {
|
|
125535
|
-
return
|
|
125543
|
+
return (item.length > 2
|
|
125544
|
+
? [item[0], item[1][0].Alphabetic, item[2]]
|
|
125545
|
+
: [item[0], item[1][0].Alphabetic]);
|
|
125536
125546
|
}
|
|
125537
125547
|
else {
|
|
125538
125548
|
return item;
|
|
125539
125549
|
}
|
|
125540
125550
|
});
|
|
125541
|
-
mapResults.listing = { info: cleanedInfo, collectByValue };
|
|
125551
|
+
mapResults.listing = { info: cleanedInfo, collectByValue, lookups };
|
|
125542
125552
|
}
|
|
125543
125553
|
if (!mappingOptions.skipModifications) {
|
|
125544
125554
|
mapResults.outputFilePath = finalSpec
|
|
@@ -141144,7 +141154,7 @@
|
|
|
141144
141154
|
// The need for mapping can come from additionalData or from the
|
|
141145
141155
|
// retainLongitudinalTemporalInformationOptions option
|
|
141146
141156
|
let columnMappings;
|
|
141147
|
-
if (organizeOptions.table && additionalData) {
|
|
141157
|
+
if (organizeOptions.table && additionalData?.mapping) {
|
|
141148
141158
|
columnMappings = extractColumnMappings(organizeOptions.table, additionalData.mapping);
|
|
141149
141159
|
}
|
|
141150
141160
|
const skipWrite = organizeOptions.skipWrite ?? false;
|
|
@@ -141152,6 +141162,15 @@
|
|
|
141152
141162
|
const skipValidation = organizeOptions.skipValidation ?? false;
|
|
141153
141163
|
const hashMethod = organizeOptions.hashMethod;
|
|
141154
141164
|
const hashPartSize = organizeOptions.hashPartSize;
|
|
141165
|
+
// Summary-table mode (additionalData.output set) produces a CSV summary and
|
|
141166
|
+
// no curated DICOMs, so it must run read-only. skipWrite is the option that
|
|
141167
|
+
// actually prevents any file from being written/transferred (skipModifications
|
|
141168
|
+
// only governs whether content is changed). Fail fast on misuse.
|
|
141169
|
+
if (additionalData?.type === 'listing' &&
|
|
141170
|
+
additionalData.output &&
|
|
141171
|
+
!skipWrite) {
|
|
141172
|
+
throw new Error('additionalData.output (summary-table mode) requires skipWrite: true — summary specs produce a CSV summary and no curated output.');
|
|
141173
|
+
}
|
|
141155
141174
|
const dateOffset = organizeOptions.dateOffset;
|
|
141156
141175
|
if (requiresDateOffset(deIdOpts) && !dateOffset?.match(iso8601)) {
|
|
141157
141176
|
throw new Error('When using "Offset" for retainLongitudinalTemporalInformationOptions, an iso8601 compatible dateOffset must be provided.');
|