# Read different series of dicom

**URL:** <https://discourse.itk.org/t/read-different-series-of-dicom/6251>\
**Category:** Beginner Questions\
**Tags:** dicom, itk-wasm\
**Created:** [October 13, 2023, 5:03am UTC](https://discourse.itk.org/t/read-different-series-of-dicom/6251 "2023-10-13T05:03:49Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![Xoz](https://discourse.itk.org/user_avatar/discourse.itk.org/xoz/32/3715_2.png) [@Xoz](https://discourse.itk.org/u/Xoz)\
**Post date:** [October 13, 2023, 5:03am UTC](https://discourse.itk.org/t/read-different-series-of-dicom/6251/1 "2023-10-13T05:03:49Z")

</div>

Hi everyone,  
I’ve got an issue when loading some dicom files using itk-wasm, in the past I load the uploaded files through readImageDICOMFileSeries, it worked fine when there is just a single serie.  
But some of the dicoms are mixed with different series, e.g. one series is a summary of 256 \* 256 \* 1 sized image with component 3 and othes have size of 800 \* 800 \* 1 with component 1, and the 256 \* 256 one might be the first, the last or some other order to be imported. Here are some results for different imports and setups:  
1. The image of 3 components is the first file to be imported, in this situation the error `ReadImageDICOMFileSeries.umd.js:9 Only one pixel component is currently supported. Image pixel components: 3` will always show not matter singleSortedSeries param is true or false.  
2. The image of 3 components is not the first and singleSortedSeries is set to false, in this situation the correct ct data will not be read, result will be only the 3 component one.  
3. The image of 3 components is not the first and singleSortedSeries is set to true, in this situation the correct ct data can be read.

I can read the single file information with readImageFile, but since it’s not ordered, if I read it one by one, the error ` WebAssembly.instantiate(): Out of memory` will show if files are big enough.

How should I handle this correctly to get the different series info? The source files are from different scan machines so the names of the files and the order can not be changed.

regards,  
Xoz

---

<div class="post-metadata">

**Author:** ![Xoz](https://discourse.itk.org/user_avatar/discourse.itk.org/xoz/32/3715_2.png) [@Xoz](https://discourse.itk.org/u/Xoz)\
**Post date:** [October 13, 2023, 6:53am UTC](https://discourse.itk.org/t/read-different-series-of-dicom/6251/2 "2023-10-13T06:53:53Z")

</div>

I’ve made a mistake that I didn’t pass the worker to next readImageFile call, when it is passed the out of memory situation will not present, the readImageFile can work properly.

---

<div class="post-metadata">

**Author:** ![matt.mccormick](https://discourse.itk.org/user_avatar/discourse.itk.org/matt.mccormick/32/7_2.png) [@matt.mccormick](https://discourse.itk.org/u/matt.mccormick)\
**Post date:** [October 13, 2023, 1:11pm UTC](https://discourse.itk.org/t/read-different-series-of-dicom/6251/3 "2023-10-13T13:11:48Z")

</div>

Hi @Xoz ,

Welcome to the ITK community! 🌞

A note – the updated DICOM package is now at [@itk-wasm/dicom](https://www.npmjs.com/package/@itk-wasm/dicom).

The `readDicomTags` function can be used to help identify the different series.

---

<div class="post-metadata">

**Author:** ![Xoz](https://discourse.itk.org/user_avatar/discourse.itk.org/xoz/32/3715_2.png) [@Xoz](https://discourse.itk.org/u/Xoz)\
**Post date:** [February 7, 2024, 3:54am UTC](https://discourse.itk.org/t/read-different-series-of-dicom/6251/4 "2024-02-07T03:54:46Z")

</div>

Hi @matt.mccormick ,  
I’ve met a problem that when reading dicom files from some devices, the readImageFile throws an error ‘No DICOM magic number found, but the file appears to be DICOM without a preamble’, it seems that the dicom files lost some part called preamble, but it can be display in 3d sclicer correctly, should I manully add the lost part to the file?

I’ve also done update itk to the newest version to check if this could be solved but find readImageFile deprecated, the error log tolds me to use new one from @itk-wam/image-io, but that module does not have a function exported which named with that. I’ve found a readImage function, but when I run it to replace the old readImageFile(params changed) like this:

```auto
import { readImage } from '@itk-wasm/image-io'
  ...
// in an async func, file is an input File given by an input element
{
    ...
    const imageResult = await readImage(file, { webWorker: null })
    ....
}

```

The promise keeps pending at this state and will not return anything. The readDicomTags from module dicom still have the same problem.

Did I miss anything important? The document for web io api is still the older version one at [https://wasm.itk.org/en/latest/typescript/browser\_io.html](https://wasm.itk.org/en/latest/typescript/browser_io.html)

regards,  
Xoz

---

<div class="post-metadata">

**Author:** ![matt.mccormick](https://discourse.itk.org/user_avatar/discourse.itk.org/matt.mccormick/32/7_2.png) [@matt.mccormick](https://discourse.itk.org/u/matt.mccormick)\
**Post date:** [February 7, 2024, 5:02pm UTC](https://discourse.itk.org/t/read-different-series-of-dicom/6251/5 "2024-02-07T17:02:02Z")

</div>

Hi @Xoz ,

> [@Xoz](#):
>
> I’ve met a problem that when reading dicom files from some devices, the readImageFile throws an error ‘No DICOM magic number found, but the file appears to be DICOM without a preamble’, it seems that the dicom files lost some part called preamble, but it can be display in 3d sclicer correctly, should I manully add the lost part to the file?

Just a note that there are improvements in progress in handling the dicom preamble in the upcoming ITK 5.4.

Yes, a dicom preamble should be in dicom files - you may want to fix the file or how it was generated.

> Did I miss anything important? The document for web io api is still the older version one at [Web Browser Input/Output - ITK-Wasm documentation](https://wasm.itk.org/en/latest/typescript/browser_io.html)

The docs are currently [being updated](https://github.com/InsightSoftwareConsortium/itk-wasm/issues/1027).

The interface has been simplified and changed. Notes can be found in [the migration guide](https://wasm.itk.org/en/latest/development/itk_js_to_itk_wasm_migration_guide.html) and [breaking changes log](https://github.com/InsightSoftwareConsortium/itk-wasm/blob/main/BREAKING_CHANGES.md).

The `readImage` interface in `@itk-wasm/image-io` is [documented here](https://insightsoftwareconsortium.github.io/itk-wasm/image-io/ts/docs/). This link can be found on the [packages page](https://wasm.itk.org/en/latest/introduction/packages.html).

Essentially, you want:

```js
const { image } = await readImage(file)

```

And the [`@itk-wasm/dicom` docs are here](https://insightsoftwareconsortium.github.io/itk-wasm/dicom/ts/docs/).

I plan to provide a high level interface in the dicom package that works with all types of dicom object types over the next few months.

---

<div class="post-metadata">

**Author:** ![Xoz](https://discourse.itk.org/user_avatar/discourse.itk.org/xoz/32/3715_2.png) [@Xoz](https://discourse.itk.org/u/Xoz)\
**Post date:** [February 21, 2024, 1:48am UTC](https://discourse.itk.org/t/read-different-series-of-dicom/6251/6 "2024-02-21T01:48:04Z")

</div>

Thanks matt, I’ll check it again to find out the reason why async functions did not work

---

<div class="post-metadata">

**Author:** ![Xoz](https://discourse.itk.org/user_avatar/discourse.itk.org/xoz/32/3715_2.png) [@Xoz](https://discourse.itk.org/u/Xoz)\
**Post date:** [April 30, 2024, 3:37am UTC](https://discourse.itk.org/t/read-different-series-of-dicom/6251/7 "2024-04-30T03:37:14Z")

</div>

Hi matt,  
I still can not get it to work, here is a sandbox, could you please check it if you have spare time? The dicom file to test is in the public dir if you do not have.  
[ITK module demo](https://codesandbox.io/p/devbox/dicom-parser-to-vtk-x5vpt2?layout=%257B%2522sidebarPanel%2522%253A%2522EXPLORER%2522%252C%2522rootPanelGroup%2522%253A%257B%2522direction%2522%253A%2522horizontal%2522%252C%2522contentType%2522%253A%2522UNKNOWN%2522%252C%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522id%2522%253A%2522ROOT_LAYOUT%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522UNKNOWN%2522%252C%2522direction%2522%253A%2522vertical%2522%252C%2522id%2522%253A%2522cluw3vg8a0006356mwqlinpoa%2522%252C%2522sizes%2522%253A%255B70%252C30%255D%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522EDITOR%2522%252C%2522direction%2522%253A%2522horizontal%2522%252C%2522id%2522%253A%2522EDITOR%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522EDITOR%2522%252C%2522id%2522%253A%2522cluw3vg8a0002356mlw1n5pyh%2522%257D%255D%257D%252C%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522SHELLS%2522%252C%2522direction%2522%253A%2522horizontal%2522%252C%2522id%2522%253A%2522SHELLS%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522SHELLS%2522%252C%2522id%2522%253A%2522cluw3vg8a0004356m0hv0qhk9%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%255D%257D%252C%257B%2522type%2522%253A%2522PANEL_GROUP%2522%252C%2522contentType%2522%253A%2522DEVTOOLS%2522%252C%2522direction%2522%253A%2522vertical%2522%252C%2522id%2522%253A%2522DEVTOOLS%2522%252C%2522panels%2522%253A%255B%257B%2522type%2522%253A%2522PANEL%2522%252C%2522contentType%2522%253A%2522DEVTOOLS%2522%252C%2522id%2522%253A%2522cluw3vg8a0005356mok0eijsv%2522%257D%255D%252C%2522sizes%2522%253A%255B100%255D%257D%255D%252C%2522sizes%2522%253A%255B64.03436638056569%252C35.965633619434314%255D%257D%252C%2522tabbedPanels%2522%253A%257B%2522cluw3vg8a0002356mlw1n5pyh%2522%253A%257B%2522tabs%2522%253A%255B%257B%2522id%2522%253A%2522cluw3vg8a0001356m4urm7x87%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522type%2522%253A%2522FILE%2522%252C%2522filepath%2522%253A%2522%252FREADME.md%2522%252C%2522state%2522%253A%2522IDLE%2522%257D%252C%257B%2522id%2522%253A%2522cluw3y3pc0002356l399tqx13%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522type%2522%253A%2522FILE%2522%252C%2522filepath%2522%253A%2522%252Fsrc%252FApp.vue%2522%252C%2522state%2522%253A%2522IDLE%2522%257D%255D%252C%2522id%2522%253A%2522cluw3vg8a0002356mlw1n5pyh%2522%252C%2522activeTabId%2522%253A%2522cluw3y3pc0002356l399tqx13%2522%257D%252C%2522cluw3vg8a0005356mok0eijsv%2522%253A%257B%2522id%2522%253A%2522cluw3vg8a0005356mok0eijsv%2522%252C%2522tabs%2522%253A%255B%257B%2522type%2522%253A%2522UNASSIGNED_PORT%2522%252C%2522port%2522%253A5173%252C%2522id%2522%253A%2522clvltp0bg01da356myrsg7wfd%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522path%2522%253A%2522%252F%2522%257D%255D%252C%2522activeTabId%2522%253A%2522clvltp0bg01da356myrsg7wfd%2522%257D%252C%2522cluw3vg8a0004356m0hv0qhk9%2522%253A%257B%2522id%2522%253A%2522cluw3vg8a0004356m0hv0qhk9%2522%252C%2522tabs%2522%253A%255B%257B%2522id%2522%253A%2522cluw3vg8a0003356mjureod10%2522%252C%2522mode%2522%253A%2522permanent%2522%252C%2522type%2522%253A%2522TERMINAL%2522%252C%2522shellId%2522%253A%2522clvlt6x1j000fdkgz8rjv35dq%2522%257D%255D%252C%2522activeTabId%2522%253A%2522cluw3vg8a0003356mjureod10%2522%257D%257D%252C%2522showDevtools%2522%253Atrue%252C%2522showShells%2522%253Atrue%252C%2522showSidebar%2522%253Atrue%252C%2522sidebarPanelSize%2522%253A15%257D)  
I’m just using the methods like what I did in older version itk-wasm(orders of params are changed), but the promise returned by new APIs (including readImage and readDicomTags) seem to be always pending

---

<div class="post-metadata">

**Author:** ![matt.mccormick](https://discourse.itk.org/user_avatar/discourse.itk.org/matt.mccormick/32/7_2.png) [@matt.mccormick](https://discourse.itk.org/u/matt.mccormick)\
**Post date:** [May 19, 2024, 7:19pm UTC](https://discourse.itk.org/t/read-different-series-of-dicom/6251/8 "2024-05-19T19:19:11Z")

</div>

Hi @Xoz ,

With sandbox, I made the following changes. Reading the dicom tags work, I did not see about the images.

* * *

package.json: remove the itk-wasm entry, update the packages. Mixing that very old pre-release version of itk-wasm with the newer packages is likely not compatible. The newer itk-wasm packages are modular and self-sufficient.

```json
[...]
  "dependencies": {
    "@ffmpeg/ffmpeg": "^0.11.6",
    "@itk-wasm/dicom": "^7.0.0",
    "@itk-wasm/image-io": "^1.2.0",
    "@kitware/vtk.js": "^28.2.7",
    "jszip": "^3.10.1",
    "vue": "^3.2.45"
  [...]

```

* * *

vite.config.js: due to limitation / bug of vite regarding transitive dependencies, we want to exclude the itk-wasm packages from optimization. This can also be seen in the [vite.config.js examples in the itk-wasm demo apps](https://github.com/InsightSoftwareConsortium/itk-wasm/blob/8fab5ceff963e5f063719d9a3d4bdaebf43c1ed7/packages/downsample/typescript/vite.config.js#L20-L22).

```js
  optimizeDeps: {
    exclude: ['itk-wasm', '@itk-wasm/image-io', '@itk-wasm/dicom-io', '@thewtex/zstddec']
  },

```

* * *

CTManager.ts: Update and use the simplified readImageDicomFileSeries calls. There is now only one function. And the input is an object with `inputFiles` property.

```ts
import {
  readImageDicomFileSeries,
} from "@itk-wasm/dicom";
import vtkImageData from "@kitware/vtk.js/Common/DataModel/ImageData";
import vtkITKHelper from "@kitware/vtk.js/Common/DataModel/ITKHelper";

class CTManager {
  vtkImage: vtkImageData;
  constructor() {
    this.vtkImage = vtkImageData.newInstance();
  }
  // load dicom url
  public async loadDICOMsThroughURLs(urls: string[]) {
    try {
      const binaryFiles = urls.map(async (url) =>
        const response = fetch(url)
        const arrayBuffer = await response.arrayBuffer()
        const urlObj = new URL(url)
        const basename = urlObj.pathname.split('/').pop()
        return { path: basename, data: new Uint8Array(arrayBuffer) }
      );
      const seriesBinaryFiles = await Promise.all(binaryFiles);
      const { image } = await readImageDicomFileSeries(
        { inputFiles: seriesBinaryFiles }
      );
      this.vtkImage = vtkITKHelper.convertItkToVtkImage(image);
    } catch (err) {
      console.error("load dicom fail");
    }
  }
  // load dicom file
  public async loadDICOMsThroughFiles(list: FileList) {
    try {
      const { image } = await readImageDicomFileSeries({ inputImages: list });
      this.vtkImage = vtkITKHelper.convertItkToVtkImage(image);
    } catch (err) {
      console.error("load dicom fail");
    }
  }
  public getVtkImage() {
    return this.vtkImage;
  }
}

export default CTManager;

```

* * *

ITKLoad.vue: use new API

```vue
<template>
  <div>
    <div>
      <button @click="triggerLoadFile">LoadFrom@itk-wasm/dicom</button>
      <input type="file" ref="input" class="invisible" @change="onFileChange" />
    </div>
    <div>
      <button type="primary" @click="triggerLoadFile2">
        Load from itk-wasm ver.b174(work)
      </button>
    </div>
  </div>
</template>
<script lang="ts" setup>
import { readDicomTags } from "@itk-wasm/dicom";
import { readImage } from "@itk-wasm/image-io";
import { ref } from "vue";

type Nullable<T> = T | null;

const input = ref<Nullable<HTMLElement>>(null); // @itk-wasm/dicom
const input2 = ref<Nullable<HTMLElement>>(null); // itk-wasm
const triggerLoadFile = () => input.value?.click();
const triggerLoadFile2 = () => input2.value?.click();
const onFileChange = async (e: any) => {
  const files = e.target.files;
  console.log(files[0]);
  const tags = await readDicomTags(files[0], { webWorker: null });
  console.log(tags);
};
</script>

<style>
input {
  visibility: hidden;
}
</style>

```

---

<div class="post-metadata">

**Author:** ![Xoz](https://discourse.itk.org/user_avatar/discourse.itk.org/xoz/32/3715_2.png) [@Xoz](https://discourse.itk.org/u/Xoz)\
**Post date:** [May 20, 2024, 4:13am UTC](https://discourse.itk.org/t/read-different-series-of-dicom/6251/9 "2024-05-20T04:13:43Z")

</div>

Hi @matt.mccormick ,  
Thank you for your reply, the reason I use the readDicomTags instead of readImageDicomFileSeries is that sometimes user would select and upload all the files in a folder which includes multiple series in a case. In this case readImageDicomFileSeries will throw error for the unsupported series whose image pixel components is 3, so I use readDicomTags to sort them at first.

I have set the excluded packages in vite config and update to newest package, it is working.
