@radicalimaging/static-wado-creator 0.6.5 → 1.2.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/CHANGELOG.md ADDED
@@ -0,0 +1,67 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
+
6
+ ## [0.6.4](https://github.com/OHIF/static-wado/compare/@radicalimaging/static-wado-creator@0.6.3...@radicalimaging/static-wado-creator@0.6.4) (2022-04-04)
7
+
8
+ **Note:** Version bump only for package @radicalimaging/static-wado-creator
9
+
10
+
11
+
12
+
13
+
14
+ ## [0.6.3](https://github.com/OHIF/static-wado/compare/@radicalimaging/static-wado-creator@0.6.2...@radicalimaging/static-wado-creator@0.6.3) (2022-03-14)
15
+
16
+ **Note:** Version bump only for package @radicalimaging/static-wado-creator
17
+
18
+
19
+
20
+
21
+
22
+ ## [0.6.2](https://github.com/OHIF/static-wado/compare/@radicalimaging/static-wado-creator@0.6.1...@radicalimaging/static-wado-creator@0.6.2) (2022-03-04)
23
+
24
+ **Note:** Version bump only for package @radicalimaging/static-wado-creator
25
+
26
+
27
+
28
+
29
+
30
+ ## [0.6.1](https://github.com/OHIF/static-wado/compare/@radicalimaging/static-wado-creator@0.6.0...@radicalimaging/static-wado-creator@0.6.1) (2022-03-04)
31
+
32
+ **Note:** Version bump only for package @radicalimaging/static-wado-creator
33
+
34
+
35
+
36
+
37
+
38
+ # [0.6.0](https://github.com/OHIF/static-wado/compare/@radicalimaging/static-wado-creator@0.5.1...@radicalimaging/static-wado-creator@0.6.0) (2022-03-03)
39
+
40
+
41
+ ### Bug Fixes
42
+
43
+ * **static-wado:** make the various constructors use a straight configuration without using the program data ([1997d9f](https://github.com/OHIF/static-wado/commit/1997d9f0fe2e0a084d31edeb475494bcec78fd77))
44
+
45
+
46
+ ### Features
47
+
48
+ * **static-wado:** qido series fallback to retrieve from proxyAe ([#8](https://github.com/OHIF/static-wado/issues/8)) ([47b5550](https://github.com/OHIF/static-wado/commit/47b55503732e25be08b215bdc201593f64de52e6))
49
+
50
+
51
+
52
+
53
+
54
+ ## 0.5.1 (2022-02-16)
55
+
56
+
57
+ ### Bug Fixes
58
+
59
+ * **pencil:** add more files to lint, increase test config and README ([89b667c](https://github.com/OHIF/static-wado/commit/89b667c83d324ab9fa540cda0c037af8fe088f72))
60
+ * **pencil:** adding must package and minor test changes ([9194f3f](https://github.com/OHIF/static-wado/commit/9194f3f1bb52da57e20bb8bb9f07262bcebdffbf))
61
+ * **pencil:** code review.lint ([fa1a58a](https://github.com/OHIF/static-wado/commit/fa1a58a0c62015503575fbeb172b71810c6833de))
62
+ * **pencil:** fix format ([68fbc9b](https://github.com/OHIF/static-wado/commit/68fbc9bf5a3e9bf85e3fbcddfb3e0759e79b769d))
63
+ * **pencil:** fix lint and add pre-commit restr ([deec345](https://github.com/OHIF/static-wado/commit/deec34524531d5a8595a775bac414f63f60e9f23))
64
+ * **pencil:** lint/prettier ([d6ecbc6](https://github.com/OHIF/static-wado/commit/d6ecbc6b5961e03e8a557f4fcc78af53549132cd))
65
+ * **pencil:** moving from wado-js to wado repo ([5916aec](https://github.com/OHIF/static-wado/commit/5916aecd7c77dbc4882681877e2b51210976427f))
66
+ * **pencil:** readme link name ([40408ab](https://github.com/OHIF/static-wado/commit/40408ab6b4e97c8656e30b1dd2c30b92440b9f90))
67
+ * **pencil:** unit tests migration ([d9d56dd](https://github.com/OHIF/static-wado/commit/d9d56dd619fb1f41ed1d5ad85f7f804e013c6527))
package/README.md CHANGED
@@ -158,11 +158,13 @@ There is currently no notification of what studies have been updated between sta
158
158
  ### To Serve Instances As a Web Server
159
159
  ```
160
160
  cd ~/dicomweb
161
- npx http-server -p 5000 -g --cors
161
+ npx http-server -p 5000 -g --cors -e json
162
162
  ```
163
163
 
164
164
  The -g option serves up compressed files ending in .gz as compressed http streams.
165
165
 
166
+ The -e option will mark json files as the default extension, so when requesting `GET dicomweb/studies/` the `./studies/index.json.gz` file will be served.
167
+
166
168
  ### To Create DICOM part 10 from DICOMweb files
167
169
  TODO
168
170
 
package/bin/mkdicomweb.js CHANGED
@@ -5,5 +5,5 @@ const { configureProgram } = require("../lib/program");
5
5
 
6
6
  // Configure program commander
7
7
  configureProgram(mkdicomwebConfig).then(() => {
8
- console.log("done");
8
+ console.verbose("done");
9
9
  });
@@ -1,6 +1,6 @@
1
1
  const { JSONReader } = require("@radicalimaging/static-wado-util");
2
- const JSONWriter = require("./writer/JSONWriter");
3
- const Tags = require("./dictionary/Tags");
2
+ const { JSONWriter } = require("@radicalimaging/static-wado-util");
3
+ const { Tags } = require("@radicalimaging/static-wado-util");
4
4
 
5
5
  module.exports = (options) =>
6
6
  async function (studyInstanceUid) {
@@ -1,16 +1,23 @@
1
- const dataExtractor = /^(.*studies)?[\\/]?([^/\\]+)[\\/](series[\\/])?([^/\\]+)([\\/]instances[\\/]([^/\\]*))?$/;
1
+ const dataExtractor = /^(.*studies)?[\\/]?([0-9.a-zA-Z]+)[\\/](series[\\/])?([0-9.a-zA-Z]+)([\\/]instances[\\/]([0-9.a-zA-Z]*))?$/;
2
2
 
3
- module.exports = (options) =>
4
- async function (rejectPath, reason) {
5
- console.log("Reject instance", rejectPath, reason);
6
- const extracted = rejectPath.match(dataExtractor);
7
- if (!extracted) {
8
- console.log("Unable to reject", rejectPath, "because it isn't in the format studies/<studyUID>/series/<seriesUID>");
9
- return;
3
+ module.exports = () =>
4
+ async function rejectInstanceWithOptions(args) {
5
+ let studyInstanceUid = args[0];
6
+ let seriesInstanceUid;
7
+ let sopInstanceUid;
8
+ const reason = args[2] || "REJECT";
9
+ const extracted = args[0].match(dataExtractor);
10
+ if (extracted) {
11
+ studyInstanceUid = extracted[2];
12
+ seriesInstanceUid = extracted[4];
13
+ sopInstanceUid = extracted[6];
14
+ console.log("Extracted", studyInstanceUid, seriesInstanceUid, sopInstanceUid, reason);
15
+ } else {
16
+ console.log("Not extracting from URL", studyInstanceUid, seriesInstanceUid, reason);
17
+ seriesInstanceUid = args[1];
10
18
  }
11
- const [, , studyInstanceUid, , seriesInstanceUid, , sopInstanceUid] = extracted;
12
- const studyData = await this.scanStudy("studies", studyInstanceUid);
13
- if (options.verbose) console.log("Trying to reject", seriesInstanceUid, "because", reason);
19
+ const studyData = await this.scanStudy(studyInstanceUid);
20
+ console.verbose("Trying to reject", seriesInstanceUid, "because", reason);
14
21
  await studyData.reject(seriesInstanceUid, sopInstanceUid, reason);
15
22
  await studyData.writeDeduplicatedGroup();
16
23
  return studyData.writeMetadata();
package/lib/StaticWado.js CHANGED
@@ -1,11 +1,10 @@
1
1
  const dicomCodec = require("@cornerstonejs/dicom-codec");
2
- const { Stats, handleHomeRelative } = require("@radicalimaging/static-wado-util");
2
+ const staticCS = require("@radicalimaging/static-cs-lite");
3
+ const { Stats, handleHomeRelative, dirScanner, JSONReader, JSONWriter, asyncIterableToBuffer, Tags } = require("@radicalimaging/static-wado-util");
3
4
  const dicomParser = require("dicom-parser");
4
5
  const fs = require("fs");
5
6
  const path = require("path");
6
- const { dirScanner } = require("@radicalimaging/static-wado-util");
7
- const { JSONReader } = require("@radicalimaging/static-wado-util");
8
- const asyncIterableToBuffer = require("@radicalimaging/static-wado-util/lib/asyncIterableToBuffer");
7
+ const { NotificationService } = require("@radicalimaging/static-wado-util");
9
8
  const getDataSet = require("./operation/getDataSet");
10
9
  const InstanceDeduplicate = require("./operation/InstanceDeduplicate");
11
10
  const DeduplicateWriter = require("./writer/DeduplicateWriter");
@@ -17,15 +16,33 @@ const HashDataWriter = require("./writer/HashDataWriter");
17
16
  const VideoWriter = require("./writer/VideoWriter");
18
17
  const { transcodeImageFrame, transcodeId, transcodeMetadata } = require("./operation/adapter/transcodeImage");
19
18
  const ThumbnailWriter = require("./writer/ThumbnailWriter");
19
+ const decodeImage = require("./operation/adapter/decodeImage");
20
20
  const ThumbnailService = require("./operation/ThumbnailService");
21
21
  const DeleteStudy = require("./DeleteStudy");
22
22
  const RejectInstance = require("./RejectInstance");
23
- const JSONWriter = require("./writer/JSONWriter");
23
+ const RawDicomWriter = require("./writer/RawDicomWriter");
24
+ const { isVideo } = require("./writer/VideoWriter");
24
25
 
25
26
  function setStudyData(studyData) {
26
27
  this.studyData = studyData;
27
28
  }
28
29
 
30
+ function internalGenerateImage(originalImageFrame, dataset, metadata, transferSyntaxUid, doneCallback) {
31
+ decodeImage(originalImageFrame, dataset, transferSyntaxUid)
32
+ .then((decodeResult = {}) => {
33
+ if (isVideo(transferSyntaxUid)) {
34
+ console.log("Video data - no thumbnail generator yet");
35
+ } else {
36
+ const { imageFrame, imageInfo } = decodeResult;
37
+ const pixelData = dicomCodec.getPixelData(imageFrame, imageInfo, transferSyntaxUid);
38
+ staticCS.getRenderedBuffer(transferSyntaxUid, pixelData, metadata, doneCallback);
39
+ }
40
+ })
41
+ .catch((error) => {
42
+ console.log(`Error while generating thumbnail:: ${error}`);
43
+ });
44
+ }
45
+
29
46
  class StaticWado {
30
47
  constructor(configuration) {
31
48
  const { rootDir = "~/dicomweb", pathDeduplicated = "deduplicated", pathInstances = "instances", verbose } = configuration;
@@ -38,7 +55,8 @@ class StaticWado {
38
55
  directoryName,
39
56
  deduplicatedRoot: path.join(directoryName, pathDeduplicated),
40
57
  deduplicatedInstancesRoot: path.join(directoryName, pathInstances),
41
- TransferSyntaxUID: "1.2.840.10008.1.2",
58
+ // TODO - make this configurable and auto-detect by updating the parseDicom library
59
+ TransferSyntaxUID: "1.2.840.10008.1.2.1",
42
60
  };
43
61
  this.callback = {
44
62
  uids: IdCreator(this.options),
@@ -53,6 +71,9 @@ class StaticWado {
53
71
  reject: RejectInstance(this.options),
54
72
  delete: DeleteStudy(this.options),
55
73
  setStudyData,
74
+ rawDicomWriter: RawDicomWriter(this.options),
75
+ notificationService: new NotificationService(this.options.notificationDir),
76
+ internalGenerateImage
56
77
  };
57
78
  }
58
79
 
@@ -62,10 +83,8 @@ class StaticWado {
62
83
  *
63
84
  * @param {string} args listing the instances to remove (may remove entire series)
64
85
  */
65
- async reject(args) {
66
- args.forEach((removal) => {
67
- this.callback.reject(removal);
68
- });
86
+ async reject(studyUID, seriesUID, reason) {
87
+ this.callback.reject(studyUID, seriesUID, reason);
69
88
  }
70
89
 
71
90
  /**
@@ -95,7 +114,7 @@ class StaticWado {
95
114
  await this.importBinaryDicom(dicomp10stream, { ...params, file });
96
115
  Stats.StudyStats.add("DICOM P10", "Parse DICOM P10 file");
97
116
  } catch (e) {
98
- console.error("Couldn't process", file, e);
117
+ console.error("Couldn't process", file);
99
118
  }
100
119
  },
101
120
  });
@@ -104,14 +123,13 @@ class StaticWado {
104
123
  /**
105
124
  * Processes a study directory, matching up study instance UIDs. Either processes the
106
125
  * deduplicated group directory or the instances directory, or the notifications directory.
107
- * @param {*} params
126
+ * @param {*} options
108
127
  */
109
- async processStudyDir(studyUids, params) {
110
- return dirScanner(params[params.scanStudies], {
111
- ...params,
112
- recursive: false,
113
- callback: (dir, name) => this.callback.scanStudy(dir, name),
114
- });
128
+ async processStudyDir(studyUids /* , options */) {
129
+ for (const studyUid of studyUids) {
130
+ const study = await this.callback.scanStudy(studyUid);
131
+ console.log("Processed study", study.studyInstanceUid);
132
+ }
115
133
  }
116
134
 
117
135
  async importBinaryDicom(dicomp10stream, params) {
@@ -124,7 +142,7 @@ class StaticWado {
124
142
  const studyInstanceUid = dataSet.string("x0020000d");
125
143
 
126
144
  if (!studyInstanceUid) {
127
- console.log(`Can't import file ${params.file}`);
145
+ console.log("No study UID, can't import file", params.file, dataSet.elements);
128
146
  return undefined;
129
147
  }
130
148
 
@@ -139,7 +157,7 @@ class StaticWado {
139
157
  params.file
140
158
  );
141
159
 
142
- const targetId = transcodeId(id, this.options);
160
+ const targetId = transcodeId(id, this.options, dataSet.uint16(Tags.RawSamplesPerPixel));
143
161
 
144
162
  let bulkDataIndex = 0;
145
163
  let imageFrameIndex = 0;
@@ -176,8 +194,10 @@ class StaticWado {
176
194
  // convert to DICOMweb MetaData and BulkData
177
195
  const result = await getDataSet(dataSet, generator, this.options);
178
196
 
197
+ await this.callback.rawDicomWriter?.(id, result, buffer);
198
+
179
199
  const transcodedMeta = transcodeMetadata(result.metadata, id, this.options);
180
- thumbnailService.generateThumbnails(id, dataSet, transcodedMeta, this.callback);
200
+ await thumbnailService.generateThumbnails(id, dataSet, transcodedMeta, this.callback);
181
201
 
182
202
  await this.callback.metadata(targetId, transcodedMeta);
183
203
 
@@ -185,6 +205,14 @@ class StaticWado {
185
205
  return {};
186
206
  }
187
207
 
208
+ static async getDataSet(dataSet, generator, params) {
209
+ return await getDataSet(dataSet, generator, params);
210
+ }
211
+
212
+ static internalGenerateImage(originalImageFrame, dataSet, metadata, transferSyntaxUid, doneCallback) {
213
+ return internalGenerateImage(originalImageFrame, dataSet, metadata, transferSyntaxUid, doneCallback)
214
+ }
215
+
188
216
  /**
189
217
  * The mkdicomweb command first runs mkdicomwebinstances, writing out the deduplicated data, and then runs the
190
218
  * mkdicomwebstudy command, creating the deduplicated data set. This version, however, keeps the deduplicated
@@ -192,16 +220,18 @@ class StaticWado {
192
220
  */
193
221
  async executeCommand(input) {
194
222
  if (this.options.scanStudies) {
223
+ console.log("Scanning study dir", input);
195
224
  // Scan one of the study directories - in this case, files is a set of study directories
196
225
  await this.processStudyDir(input, this.options);
197
226
  } else {
227
+ console.log("Scanning files", input);
198
228
  await this.processFiles(input, this.options);
199
229
  }
200
230
  await this.close();
201
231
  }
202
232
 
203
233
  async close() {
204
- await this.callback.completeStudy();
234
+ await this.callback.completeStudy(this.callback);
205
235
  Stats.OverallStats.summarize("Completed Study Processing");
206
236
  }
207
237
 
package/lib/createMain.js CHANGED
@@ -4,10 +4,14 @@ const adaptProgramOpts = require("./util/adaptProgramOpts");
4
4
  module.exports = function createMain(options, program) {
5
5
  const finalOptions = adaptProgramOpts(options, {
6
6
  ...this,
7
- isInstance: false,
7
+ // Instance metadata is the instances/<sopUID>/metadata.gz files
8
+ isInstance: true,
9
+ // Deduplicated data is single instance deduplicated data
10
+ isDeduplicate: false,
11
+ // Group data is the group file directories
8
12
  isGroup: true,
9
- isDeduplicate: true,
10
13
  isStudyData: true,
14
+ isDeleteInstances: true,
11
15
  });
12
16
  const importer = new StaticWado(finalOptions);
13
17
  return importer.executeCommand(program.args);
package/lib/groupMain.js CHANGED
@@ -5,8 +5,11 @@ module.exports = function createMain(options, program) {
5
5
  const finalOptions = adaptProgramOpts(options, {
6
6
  ...this,
7
7
  isInstance: false,
8
+ isDeduplicate: true,
8
9
  isGroup: true,
9
10
  isStudyData: false,
11
+ scanStudies: true,
12
+ isDeleteInstances: true,
10
13
  });
11
14
  const importer = new StaticWado(finalOptions);
12
15
  // Either do a scan or on specified studies
package/lib/index.js CHANGED
@@ -4,5 +4,6 @@ const StaticWado = require("./StaticWado");
4
4
  StaticWado.mkdicomwebConfig = mkdicomwebConfig;
5
5
  StaticWado.createMain = require("./createMain");
6
6
  StaticWado.deleteMain = require("./deleteMain");
7
+ StaticWado.adaptProgramOpts = require("./util/adaptProgramOpts");
7
8
 
8
9
  module.exports = StaticWado;
@@ -5,6 +5,8 @@ module.exports = function createMain(options, program) {
5
5
  const finalOptions = adaptProgramOpts(options, {
6
6
  ...this,
7
7
  isInstance: true,
8
+ // Deduplicated data is single instance deduplicated data
9
+ isDeduplicate: true,
8
10
  isGroup: false,
9
11
  isStudyData: false,
10
12
  });
@@ -5,8 +5,9 @@ module.exports = function createMain(options, program) {
5
5
  const finalOptions = adaptProgramOpts(options, {
6
6
  ...this,
7
7
  isInstance: false,
8
- isGroup: false,
9
- isStudyData: false,
8
+ isGroup: true,
9
+ isStudyData: true,
10
+ scanStudies: true,
10
11
  });
11
12
  const importer = new StaticWado(finalOptions);
12
13
  // Either do a scan or on specified studies
@@ -25,6 +25,20 @@ const { mkdicomwebConfig } = ConfigPoint.register({
25
25
  description: "Clean the outputs before generating/starting to write new values.",
26
26
  defaultValue: false,
27
27
  },
28
+ {
29
+ key: "-d, --deployments <listvalue...>",
30
+ description: "List of deployments from configuration to deploy to. Separated by space.",
31
+ defaultValue: undefined,
32
+ },
33
+ {
34
+ key: "--no-notifications",
35
+ description: "Turns off notifications",
36
+ },
37
+ {
38
+ key: "--delete",
39
+ description: "Delete the imported instances",
40
+ defaultValue: false,
41
+ },
28
42
  {
29
43
  key: "-v, --verbose",
30
44
  description: "Write verbose output",
@@ -32,10 +46,26 @@ const { mkdicomwebConfig } = ConfigPoint.register({
32
46
  },
33
47
  {
34
48
  key: "-t, --content-type <type>",
35
- description: 'Destination type to compress to (choices: "jls", "lei", "jls-lossy" or DICOM Transfer Syntax UID - default: "jls")',
49
+ description: 'Destination type to compress to (choices: "jpeg", "jls", "lei", "jls-lossy", "jhc", "jxl" or DICOM Transfer Syntax UID - default: "jls")',
36
50
  defaultValue: "jls",
37
51
  customParser: compressionOptionParser,
38
52
  },
53
+ {
54
+ key: "--encapsulated-image",
55
+ description: "Avoid encapsulating the image frame. Writes with the extension and without multipart",
56
+ },
57
+ {
58
+ key: "-e, --no-encapsulated-image",
59
+ description: "Avoid encapsulating the image frame. Writes with the extension and without multipart",
60
+ },
61
+ {
62
+ key: "--single-part-image",
63
+ description: "Writes single part image data",
64
+ },
65
+ {
66
+ key: "--no-single-part-image",
67
+ description: "Writes single part image data",
68
+ },
39
69
  {
40
70
  key: "-m, --maximum-inline-public-length <value>",
41
71
  description: "Maximum length of public binary data",
@@ -49,8 +79,14 @@ const { mkdicomwebConfig } = ConfigPoint.register({
49
79
  {
50
80
  key: "-r, --recompress <listvalue...>",
51
81
  description: "List of types to recompress separated by space",
52
- defaultValue: ["uncompressed", "jp2"],
53
- choices: ["uncompressed", "jp2", "jpeglossless", "rle", "none"],
82
+ defaultValue: ["uncompressed", "jp2", "jls", "jll"],
83
+ choices: ["uncompressed", "jp2", "jpeg", "jpeglossless", "rle", "jph", "jls", "true", "none"],
84
+ },
85
+ {
86
+ key: "--recompress-color <listvalue...>",
87
+ description: "List of types to recompress for color images, separated by space",
88
+ defaultValue: ["uncompressed"],
89
+ choices: ["uncompressed", "jpeg", "jp2", "jpeglossless", "rle", "jph", "jls", "true", "none"],
54
90
  },
55
91
  {
56
92
  key: "--recompress-thumb <listvalue...>",
@@ -69,9 +105,9 @@ const { mkdicomwebConfig } = ConfigPoint.register({
69
105
  defaultValue: false,
70
106
  },
71
107
  {
72
- key: "-T, --colour-content-type <value>",
108
+ key: "-T, --color-content-type <value>",
73
109
  description: "Colour content type",
74
- defaultValue: null,
110
+ defaultValue: "jpeg",
75
111
  },
76
112
  {
77
113
  key: "--path-deduplicated <path>",
@@ -136,7 +172,7 @@ const { mkdicomwebConfig } = ConfigPoint.register({
136
172
  command: "metadata",
137
173
  arguments: ["input"],
138
174
  main: metadataMain,
139
- helpDescription: "Write the metadata object (series and study details) from the deduplicated data.",
175
+ helpDescription: "Write the metadata object (series and study details) from the grouped deduplicated data.",
140
176
  },
141
177
  {
142
178
  command: "delete",
@@ -144,9 +180,9 @@ const { mkdicomwebConfig } = ConfigPoint.register({
144
180
  helpDescription: "Delete the given study, series or instance (not yet implemented)",
145
181
  },
146
182
  {
147
- command: "reject",
183
+ command: "reject <studyUID...>",
148
184
  main: rejectMain,
149
- helpDescription: "Reject the specified series, specified as studies/<studyUID>/series/<seriesUID>",
185
+ helpDescription: "Reject the specified series",
150
186
  },
151
187
  ],
152
188
  },
@@ -1,5 +1,5 @@
1
1
  const hashFactory = require("node-object-hash");
2
- const Tags = require("../dictionary/Tags");
2
+ const { Tags } = require("@radicalimaging/static-wado-util");
3
3
 
4
4
  /* eslint "no-param-reassign": "off" */
5
5
 
package/lib/model/uids.js CHANGED
@@ -12,7 +12,7 @@ const jpeg = "image/jpeg";
12
12
  const jls = "image/jls";
13
13
  const jll = "image/jll";
14
14
  const jxl = "image/x-jxl";
15
- const htj2k = "image/x-htj2k";
15
+ const htj2k = "image/jphc";
16
16
  const jp2 = "image/jp2";
17
17
  const rle = "image/dicom-rle";
18
18
 
@@ -21,20 +21,19 @@ const uids = {
21
21
  "1.2.840.10008.1.2.1": uncompressed,
22
22
  "1.2.840.10008.1.2.1.99": uncompressed,
23
23
  "1.2.840.10008.1.2.2": uncompressed,
24
- "1.2.840.10008.1.2.4.50": { contentType: jpeg, lossy: true },
24
+ "1.2.840.10008.1.2.4.50": { contentType: jpeg, lossy: true, extension: ".jpeg" },
25
25
  "1.2.840.10008.1.2.4.51": { contentType: jpeg, lossy: true },
26
26
  "1.2.840.10008.1.2.4.57": { contentType: jpeg },
27
- "1.2.840.10008.1.2.4.70": { contentType: jll },
28
- "1.2.840.10008.1.2.4.140": { contentType: jxl },
27
+ "1.2.840.10008.1.2.4.70": { contentType: jll, extension: ".jll" },
28
+ "1.2.840.10008.1.2.4.140": { contentType: jxl, extension: ".jxl" },
29
+ // Lossy, original JPEG reconstruction mode
29
30
  "1.2.840.10008.1.2.4.141": { contentType: jxl, lossy: true },
30
- "1.2.840.10008.1.2.4.80": { contentType: jls },
31
+ "1.2.840.10008.1.2.4.142": { contentType: jxl, lossy: true },
32
+ "1.2.840.10008.1.2.4.80": { contentType: jls, extension: ".jls" },
31
33
  "1.2.840.10008.1.2.4.81": { contentType: jls, lossy: true },
32
- "1.2.840.10008.1.2.4.90": { contentType: jp2 },
34
+ "1.2.840.10008.1.2.4.90": { contentType: jp2, extension: ".jp2" },
33
35
  "1.2.840.10008.1.2.4.91": { contentType: jp2 },
34
- // From JPEG original data, lossless to JXL
35
- "1.2.840.10008.1.2.4.142": { contentType: jxl, lossy: true },
36
- "1.2.840.10008.1.2.4.150": { contentType: htj2k },
37
- // **
36
+ "3.2.840.10008.1.2.4.96": { contentType: htj2k, extension: ".jhc" },
38
37
  "1.2.840.10008.1.2.5": { contentType: rle },
39
38
  default: {},
40
39
  };
@@ -1,7 +1,7 @@
1
1
  // TODO review returning type of some methods
2
- const JSONWriter = require("../writer/JSONWriter");
2
+ const { JSONWriter } = require("@radicalimaging/static-wado-util");
3
+ const { Tags } = require("@radicalimaging/static-wado-util");
3
4
  const TagLists = require("../model/TagLists");
4
- const Tags = require("../dictionary/Tags");
5
5
 
6
6
  const { getValue, setValue } = Tags;
7
7
 
@@ -77,8 +77,8 @@ const InstanceDeduplicate = (options) =>
77
77
  async function run(id, sourceImageFrame) {
78
78
  // Notify the existing listeners, if any
79
79
  const imageFrame = canonicalize(sourceImageFrame);
80
- if (options.isInstanceMetadata) {
81
- // console.log("Writing instance metadata");
80
+ if (options.isInstance) {
81
+ if (options.verbose) console.log("Writing instance metadata");
82
82
  await JSONWriter(id.sopInstanceRootPath, "metadata", imageFrame);
83
83
  }
84
84
  if (!options.isDeduplicate && !options.isGroup) {
@@ -3,11 +3,12 @@ const path = require("path");
3
3
  function ScanStudy(options) {
4
4
  const { directoryName, deduplicatedRoot, deduplicatedInstancesRoot } = options;
5
5
 
6
- return function run(dir, studyInstanceUid) {
6
+ return function scanStudy(studyInstanceUid) {
7
+ console.verbose("scanStudy", studyInstanceUid);
7
8
  const studyPath = path.join(directoryName, "studies", studyInstanceUid);
8
- const deduplicatedPath = path.join(deduplicatedRoot, studyInstanceUid);
9
9
  const deduplicatedInstancesPath = path.join(deduplicatedInstancesRoot, studyInstanceUid);
10
- console.log("Scanning", dir, studyInstanceUid);
10
+ const deduplicatedPath = path.join(deduplicatedRoot, studyInstanceUid);
11
+ console.verbose("Importing", studyInstanceUid, studyPath, deduplicatedInstancesPath, deduplicatedPath);
11
12
  return this.completeStudy.getCurrentStudyData(this, {
12
13
  studyPath,
13
14
  deduplicatedPath,