itk-wasm icon indicating copy to clipboard operation
itk-wasm copied to clipboard

readImage[Local]DICOMFileSeries not working

Open obermillerk opened this issue 2 years ago • 8 comments

I've tried using both readImageDICOMFileSeries and readLocalImageDICOMFileSeries and both fail for different reasons. I've been at this for hours on end trying to fix one of them, but with no luck.

I have a bit of a complex situation since I'm using electron with node support in the renderer, so I have a complicated environment that allows for both node and browser features, I'm not sure if that might be confusing itk or not.

readLocalImageDICOMFileSeries

This one just fails to read the dicom files. It fails at the canReadTestFile call that is made on the first file of the series, which I can't debug what exactly is failing because it goes to the compiled web assembly. I've looked at the ITK source code to find that method, and as far as I can tell my DICOMs do have the demarcation at 128 in the file, and every other DICOM parsing tool I've used has no issue reading them. I can even use the itk-vtk-viewer in my browser to load the same file that is failing with this call, and it reads it and renders, so why is the different function it's using able to read it but not this one?

readImageDICOMFileSeries

For this, I have the ImageIOs and WebWorkers directories being copied over as per the Webpack instructions, and the web worker seems to start, but then the web worker has an error while trying to load the wasm. The ...BindingWasm.js file is loaded via a webpack dev server on localhost and then when that file runs, it tries to retrieve the binary .wasm file via node fs for some reason? This wouldn't be a problem since as I said I have node support in my electron renderer environment, but the file it tries to read is the path that should be appended to my dev server host, not any actual file path. I could understand how this might be a result of there being both node and browser elements in my environment and reusing the DICOM Series Reader stuff.

Any assistance you could offer would be great, feels like I've been hitting my head against a wall for the past couple days.

obermillerk avatar Jul 16 '21 19:07 obermillerk

@obermillerk I can understand your frustration.

Yes, it sounds like there is some sort of environment issue. One approach that make it easier to reveal what is happening is to build itk.js yourself in debug mode. This will build the Emscripten modules with additional debugging information and not minified.

git clone https://github.com/InsightSoftwareConsortium/itk-js
cd itk-js
npm ci
npm run build:debug

thewtex avatar Jul 20 '21 22:07 thewtex

I will also make a follow-up suggestion: either a repo containing a minimal reproduction scenario or any console errors (or both) would be very helpful for us in debugging this issue. :)

floryst avatar Jul 21 '21 16:07 floryst

Thank you for the suggestions, I've had some other things on my plate since then so apologies for the delay. I will be back to working on this next week, so I'll try building itk-js myself and maybe see if I can get you a min repro on Monday.

obermillerk avatar Jul 23 '21 20:07 obermillerk

Hey, sorry again for the delay, just managed to get back to this. Managed to get a minimal repro working here: https://github.com/obermillerk/itk-min-repro

yarn start or npm equivalent to launch the electron app once dependencies are installed. Press the button to select the folder containing DICOM images and it will trigger an attempt to load them via ITK and convert to VTK image. This repro is presently attempting to use the web version, not the local version.

The electron renderer window has nodeIntegrationInWorker set to true, as I use this in my actual project. Setting this to false (or removing) in index.ts (line 16) makes it work, but since I use node integration in my own workers in my other project, ideally I'd be able to leave this as true.

I have yet to build ITK myself to try more debugging, but I'm about to try that now.

obermillerk avatar Aug 04 '21 18:08 obermillerk

I've attempted to build the module in debug mode as you suggested, unfortunately your build process is not working for me.

To start, the pipelines fail to build the first time it tries each one. Then on subsequent runs that pipeline doesn't fail, so it gets to the next pipeline which does fail, until all of them are not failing. This is the error I got for each pipeline:

docker: error during connect: Post "http://%2F%2F.%2Fpipe%2FdockerDesktopLinuxEngine/v1.24/containers/create": open //./pipe/dockerDesktopLinuxEngine: The system cannot find the file specified.
See 'docker run --help'.

Then, after all the pipeline steps fail once and then no longer fail, I get the following error every time I try to run the build:

Error: Can't walk dependency graph: Cannot find module '../MeshIOIndex' from 'C:\Workspace\itk-js\src\WebWorkers\MeshIO.worker.js'
    required by C:\Workspace\itk-js\src\WebWorkers\MeshIO.worker.js
    at C:\Workspace\itk-js\node_modules\browser-resolve\node_modules\resolve\lib\async.js:137:35
    at load (C:\Workspace\itk-js\node_modules\browser-resolve\node_modules\resolve\lib\async.js:156:43)
    at onex (C:\Workspace\itk-js\node_modules\browser-resolve\node_modules\resolve\lib\async.js:181:17)
    at C:\Workspace\itk-js\node_modules\browser-resolve\node_modules\resolve\lib\async.js:15:69
    at FSReqCallback.oncomplete (fs.js:192:21)
Emitted 'error' event on Readable instance at:
    at Labeled.<anonymous> (C:\Workspace\itk-js\node_modules\read-only-stream\index.js:28:44)
    at Labeled.emit (events.js:376:20)
    at Labeled.<anonymous> (C:\Workspace\itk-js\node_modules\stream-splicer\index.js:130:18)
    at Labeled.emit (events.js:376:20)
    at Deps.<anonymous> (C:\Workspace\itk-js\node_modules\stream-splicer\index.js:130:18)
    at Deps.emit (events.js:376:20)
    at C:\Workspace\itk-js\node_modules\module-deps\index.js:387:25
    at onresolve (C:\Workspace\itk-js\node_modules\module-deps\index.js:185:25)
    at C:\Workspace\itk-js\node_modules\browserify\index.js:528:22
    at C:\Workspace\itk-js\node_modules\browser-resolve\index.js:265:24

Followed by a very long JSON object that I think might be the error with some config or something

Click to expand JSON object
{
  code: 'MODULE_NOT_FOUND',
  stream: Labeled {
    _readableState: ReadableState {
      objectMode: true,
      highWaterMark: 16,
      buffer: BufferList { head: null, tail: null, length: 0 },
      length: 0,
      pipes: Labeled {
        _readableState: ReadableState {
          objectMode: true,
          highWaterMark: 16,
          buffer: BufferList { head: null, tail: null, length: 0 },
          length: 0,
          pipes: Labeled {
            _readableState: [ReadableState],
            readable: true,
            _events: [Object: null prototype],
            _eventsCount: 8,
            _maxListeners: undefined,
            _writableState: [WritableState],
            writable: true,
            allowHalfOpen: true,
            _options: [Object],
            _wrapOptions: [Object],
            _streams: [Array],
            length: 1,
            label: 'unbom',
            [Symbol(kCapture)]: false
          },
          pipesCount: 1,
          flowing: true,
          ended: false,
          endEmitted: false,
          reading: true,
          sync: false,
          needReadable: true,
          emittedReadable: false,
          readableListening: false,
          resumeScheduled: false,
          destroyed: false,
          defaultEncoding: 'utf8',
          awaitDrain: 0,
          readingMore: false,
          decoder: null,
          encoding: null
        },
        readable: true,
        _events: [Object: null prototype] {
          end: [ [Function], [Function], [Function] ],
          finish: [ [Function], [Function] ],
          error: [ [Function: onerror], [Function (anonymous)] ],
          unpipe: [Function: onunpipe],
          drain: [Function (anonymous)],
          close: [Function: bound onceWrapper] {
            listener: [Function: onclose]
          },
          data: [Function: ondata],
          _mutate: [Function: bound onceWrapper] {
            listener: [Function: onreadable]
          }
        },
        _eventsCount: 8,
        _maxListeners: undefined,
        _writableState: WritableState {
          objectMode: true,
          highWaterMark: 16,
          finalCalled: false,
          needDrain: false,
          ending: false,
          ended: false,
          finished: false,
          destroyed: false,
          decodeStrings: true,
          defaultEncoding: 'utf8',
          length: 0,
          writing: false,
          corked: 0,
          sync: true,
          bufferProcessing: false,
          onwrite: [Function (anonymous)],
          writecb: null,
          writelen: 0,
          bufferedRequest: null,
          lastBufferedRequest: null,
          pendingcb: 0,
          prefinished: false,
          errorEmitted: false,
          bufferedRequestCount: 0,
          corkedRequestsFree: CorkedRequest {
            next: null,
            entry: null,
            finish: [Function (anonymous)]
          }
        },
        writable: true,
        allowHalfOpen: true,
        _options: { objectMode: true },
        _wrapOptions: { objectMode: true },
        _streams: [
          DestroyableTransform {
            _readableState: [ReadableState],
            readable: true,
            _events: [Object: null prototype],
            _eventsCount: 4,
            _maxListeners: undefined,
            _writableState: [WritableState],
            writable: true,
            allowHalfOpen: true,
            _transformState: [Object],
            _destroyed: false,
            _transform: [Function (anonymous)],
            [Symbol(kCapture)]: false
          }
        ],
        length: 1,
        label: 'json',
        [Symbol(kCapture)]: false
      },
      pipesCount: 1,
      flowing: true,
      ended: false,
      endEmitted: false,
      reading: true,
      sync: false,
      needReadable: true,
      emittedReadable: false,
      readableListening: false,
      resumeScheduled: false,
      destroyed: false,
      defaultEncoding: 'utf8',
      awaitDrain: 0,
      readingMore: false,
      decoder: null,
      encoding: null
    },
    readable: true,
    _events: [Object: null prototype] {
      end: [
        [Function: bound onceWrapper] { listener: [Function: onend] },
        [Function: bound onceWrapper] {
          listener: [Function (anonymous)]
        },
        [Function: bound onceWrapper] { listener: [Function: onend] }
      ],
      error: [Function (anonymous)],
      data: [Function: ondata],
      _mutate: [Function: bound onceWrapper] { listener: [Function: onreadable] }
    },
    _eventsCount: 4,
    _maxListeners: undefined,
    _writableState: WritableState {
      objectMode: true,
      highWaterMark: 16,
      finalCalled: false,
      needDrain: false,
      ending: true,
      ended: true,
      finished: true,
      destroyed: false,
      decodeStrings: true,
      defaultEncoding: 'utf8',
      length: 0,
      writing: false,
      corked: 0,
      sync: false,
      bufferProcessing: false,
      onwrite: [Function (anonymous)],
      writecb: null,
      writelen: 0,
      bufferedRequest: null,
      lastBufferedRequest: null,
      pendingcb: 0,
      prefinished: true,
      errorEmitted: false,
      bufferedRequestCount: 0,
      corkedRequestsFree: CorkedRequest {
        next: null,
        entry: null,
        finish: [Function (anonymous)]
      }
    },
    writable: false,
    allowHalfOpen: true,
    _options: { objectMode: true },
    _wrapOptions: { objectMode: true },
    _streams: [
      Deps {
        _readableState: ReadableState {
          objectMode: true,
          highWaterMark: 16,
          buffer: BufferList { head: null, tail: null, length: 0 },
          length: 0,
          pipes: null,
          pipesCount: 0,
          flowing: null,
          ended: false,
          endEmitted: false,
          reading: false,
          sync: false,
          needReadable: true,
          emittedReadable: false,
          readableListening: true,
          resumeScheduled: false,
          destroyed: false,
          defaultEncoding: 'utf8',
          awaitDrain: 0,
          readingMore: false,
          decoder: null,
          encoding: null
        },
        readable: true,
        _events: [Object: null prototype] {
          end: [ [Function], [Function] ],
          prefinish: [Function: prefinish],
          file: [Function (anonymous)],
          package: [Function (anonymous)],
          transform: [Function (anonymous)],
          error: [Function (anonymous)],
          readable: [Function: bound onceWrapper] {
            listener: [Function: onreadable]
          }
        },
        _eventsCount: 7,
        _maxListeners: undefined,
        _writableState: WritableState {
          objectMode: true,
          highWaterMark: 16,
          finalCalled: false,
          needDrain: false,
          ending: true,
          ended: true,
          finished: true,
          destroyed: false,
          decodeStrings: true,
          defaultEncoding: 'utf8',
          length: 0,
          writing: false,
          corked: 0,
          sync: true,
          bufferProcessing: false,
          onwrite: [Function (anonymous)],
          writecb: null,
          writelen: 0,
          bufferedRequest: null,
          lastBufferedRequest: null,
          pendingcb: 0,
          prefinished: true,
          errorEmitted: false,
          bufferedRequestCount: 0,
          corkedRequestsFree: CorkedRequest {
            next: null,
            entry: null,
            finish: [Function (anonymous)]
          }
        },
        writable: false,
        allowHalfOpen: true,
        _transformState: {
          afterTransform: [Function: bound afterTransform],
          needTransform: true,
          transforming: false,
          writecb: null,
          writechunk: null,
          writeencoding: 'utf8'
        },
        basedir: 'C:\\Workspace\\itk-js',
        persistentCache: [Function (anonymous)],
        cache: undefined,
        fileCache: undefined,
        pkgCache: {
          'C:\\Workspace\\itk-js\\src\\WebWorkers\\package.json': false,
          'C:\\Workspace\\itk-js\\src\\package.json': false,
          'C:\\Workspace\\itk-js\\package.json': {
            name: 'itk',
            version: '14.1.1',
            description: 'High performance spatial analysis in a JavaScript runtime environment.',
            main: './dist/itk.js',
            directories: [Object],
            scripts: [Object],
            config: [Object],
            repository: [Object],
            keywords: [Array],
            author: 'Insight Software Consortium',
            license: 'Apache-2.0',
            bugs: [Object],
            homepage: 'https://insightsoftwareconsortium.github.io/itk-js/',
            devDependencies: [Object],
            dependencies: [Object],
            bin: [Object],
            standard: [Object],
            __dirname: 'C:\\Workspace\\itk-js'
          },
          'C:\\Workspace\\itk-js\\src\\WebWorkers\\MeshIO.worker.js': {
            name: 'itk',
            version: '14.1.1',
            description: 'High performance spatial analysis in a JavaScript runtime environment.',
            main: './dist/itk.js',
            directories: [Object],
            scripts: [Object],
            config: [Object],
            repository: [Object],
            keywords: [Array],
            author: 'Insight Software Consortium',
            license: 'Apache-2.0',
            bugs: [Object],
            homepage: 'https://insightsoftwareconsortium.github.io/itk-js/',
            devDependencies: [Object],
            dependencies: [Object],
            bin: [Object],
            standard: [Object],
            __dirname: 'C:\\Workspace\\itk-js'
          }
        },
        pkgFileCache: {},
        pkgFileCachePending: {},
        _emittedPkg: {
          'C:\\Workspace\\itk-js': true,
          'C:\\Workspace\\itk-js\\node_modules\\webworker-promise': true
        },
        _transformDeps: {},
        visited: {
          'C:\\Workspace\\itk-js\\src\\WebWorkers\\MeshIO.worker.js': true,
          'C:\\Workspace\\itk-js\\src\\getFileExtension.js': true,
          'C:\\Workspace\\itk-js\\src\\MimeToMeshIO.js': true,
          'C:\\Workspace\\itk-js\\src\\extensionToMeshIO.js': true,
          'C:\\Workspace\\itk-js\\src\\writeMeshEmscriptenFSFile.js': true,
          'C:\\Workspace\\itk-js\\src\\loadEmscriptenModuleBrowser.js': true,
          'C:\\Workspace\\itk-js\\src\\readMeshEmscriptenFSFile.js': true,
          'C:\\Workspace\\itk-js\\node_modules\\webworker-promise\\lib\\register.js': true
        },
        walking: {},
        entries: [
          'C:\\Workspace\\itk-js\\src\\WebWorkers\\MeshIO.worker.js'
        ],
        _input: [ { row: [Object], pkg: [Object] } ],
        paths: [],
        transforms: [
          [
            'C:\\Workspace\\itk-js\\node_modules\\babelify\\index.js',
            [Object]
          ]
        ],
        globalTransforms: [ [ [Function: globalTr], [Object] ] ],
        resolver: [Function (anonymous)],
        detective: [Function (anonymous)] { find: [Function (anonymous)] },
        options: {
          entries: [ 'src/WebWorkers/MeshIO.worker.js' ],
          dedupe: true,
          expose: {},
          extensions: [ '.js', '.json' ],
          transform: [],
          transformKey: [ 'browserify', 'transform' ],
          postFilter: [Function (anonymous)],
          filter: [Function (anonymous)],
          resolve: [Function (anonymous)],
          modules: {
            assert: 'C:\\Workspace\\itk-js\\node_modules\\assert\\assert.js',
            buffer: 'C:\\Workspace\\itk-js\\node_modules\\buffer\\index.js',
            child_process: 'C:\\Workspace\\itk-js\\node_modules\\browserify\\lib\\_empty.js',
            cluster: 'C:\\Workspace\\itk-js\\node_modules\\browserify\\lib\\_empty.js',
            console: 'C:\\Workspace\\itk-js\\node_modules\\console-browserify\\index.js',
            constants: 'C:\\Workspace\\itk-js\\node_modules\\constants-browserify\\constants.json',
            crypto: 'C:\\Workspace\\itk-js\\node_modules\\crypto-browserify\\index.js',
            dgram: 'C:\\Workspace\\itk-js\\node_modules\\browserify\\lib\\_empty.js',
            dns: 'C:\\Workspace\\itk-js\\node_modules\\browserify\\lib\\_empty.js',
            domain: 'C:\\Workspace\\itk-js\\node_modules\\domain-browser\\source\\index.js',
            events: 'C:\\Workspace\\itk-js\\node_modules\\events\\events.js',
            fs: 'C:\\Workspace\\itk-js\\node_modules\\browserify\\lib\\_empty.js',
            http: 'C:\\Workspace\\itk-js\\node_modules\\stream-http\\index.js',
            https: 'C:\\Workspace\\itk-js\\node_modules\\https-browserify\\index.js',
            http2: 'C:\\Workspace\\itk-js\\node_modules\\browserify\\lib\\_empty.js',
            inspector: 'C:\\Workspace\\itk-js\\node_modules\\browserify\\lib\\_empty.js',
            module: 'C:\\Workspace\\itk-js\\node_modules\\browserify\\lib\\_empty.js',
            net: 'C:\\Workspace\\itk-js\\node_modules\\browserify\\lib\\_empty.js',
            os: 'C:\\Workspace\\itk-js\\node_modules\\os-browserify\\browser.js',
            path: 'C:\\Workspace\\itk-js\\node_modules\\path-browserify\\index.js',
            perf_hooks: 'C:\\Workspace\\itk-js\\node_modules\\browserify\\lib\\_empty.js',
            punycode: 'C:\\Workspace\\itk-js\\node_modules\\browserify\\node_modules\\punycode\\punycode.js',
            querystring: 'C:\\Workspace\\itk-js\\node_modules\\querystring-es3\\index.js',
            readline: 'C:\\Workspace\\itk-js\\node_modules\\browserify\\lib\\_empty.js',
            repl: 'C:\\Workspace\\itk-js\\node_modules\\browserify\\lib\\_empty.js',
            stream: 'C:\\Workspace\\itk-js\\node_modules\\browserify\\node_modules\\stream-browserify\\index.js',
            _stream_duplex: 'C:\\Workspace\\itk-js\\node_modules\\browserify\\node_modules\\readable-stream\\duplex.js',
            _stream_passthrough: 'C:\\Workspace\\itk-js\\node_modules\\browserify\\node_modules\\readable-stream\\passthrough.js',
            _stream_readable: 'C:\\Workspace\\itk-js\\node_modules\\browserify\\node_modules\\readable-stream\\readable.js',
            _stream_transform: 'C:\\Workspace\\itk-js\\node_modules\\browserify\\node_modules\\readable-stream\\transform.js',
            _stream_writable: 'C:\\Workspace\\itk-js\\node_modules\\browserify\\node_modules\\readable-stream\\writable.js',
            string_decoder: 'C:\\Workspace\\itk-js\\node_modules\\string_decoder\\lib\\string_decoder.js',
            sys: 'C:\\Workspace\\itk-js\\node_modules\\util\\util.js',
            timers: 'C:\\Workspace\\itk-js\\node_modules\\timers-browserify\\main.js',
            tls: 'C:\\Workspace\\itk-js\\node_modules\\browserify\\lib\\_empty.js',
            tty: 'C:\\Workspace\\itk-js\\node_modules\\tty-browserify\\index.js',
            url: 'C:\\Workspace\\itk-js\\node_modules\\url\\url.js',
            util: 'C:\\Workspace\\itk-js\\node_modules\\util\\util.js',
            vm: 'C:\\Workspace\\itk-js\\node_modules\\vm-browserify\\index.js',
            zlib: 'C:\\Workspace\\itk-js\\node_modules\\browserify-zlib\\lib\\index.js',
            _process: 'C:\\Workspace\\itk-js\\node_modules\\process\\browser.js'
          },
          globalTransform: []
        },
        pending: 12,
        inputPending: 0,
        top: {
          id: 'C:\\Workspace\\itk-js\\__fake.js',
          filename: 'C:\\Workspace\\itk-js\\__fake.js',
          paths: [],
          basedir: 'C:\\Workspace\\itk-js'
        },
        _ended: true,
        [Symbol(kCapture)]: false
      }
    ],
    length: 1,
    label: 'deps',
    [Symbol(kCapture)]: false
  }
}

Would greatly appreciate further assistance.

EDIT: I notice that the file the last error is looking for (../MeshIOIndex) doesn't exist as a normal .js file, but there is a .js.in file by that name in the expected location. I'm not familiar with that format, is there something I needed to do to compile that or anything before running the build?

obermillerk avatar Aug 18 '21 14:08 obermillerk

I'd be interest to learn how to build this project as well, I get the following errors when I npm run build:

src/io/readImageLocalFile.ts:7:26 - error TS2307: Cannot find module './internal/ImageIOIndex.js' or its corresponding type declarations.

7 import ImageIOIndex from './internal/ImageIOIndex.js'
                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

src/io/readMeshLocalFile.ts:7:25 - error TS2307: Cannot find module './internal/MeshIOIndex.js' or its corresponding type declarations.

7 import MeshIOIndex from './internal/MeshIOIndex.js'
                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~

src/io/writeImageLocalFile.ts:7:26 - error TS2307: Cannot find module './internal/ImageIOIndex.js' or its corresponding type declarations.

7 import ImageIOIndex from './internal/ImageIOIndex.js'
                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

src/io/writeMeshLocalFile.ts:7:25 - error TS2307: Cannot find module './internal/MeshIOIndex.js' or its corresponding type declarations.

7 import MeshIOIndex from './internal/MeshIOIndex.js'
                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~


Found 4 errors.

I'm on an ARM Mac, I'm not sure if it matters.

FezVrasta avatar Feb 15 '22 12:02 FezVrasta

I wonder if anyone managed to find a solution to this issue. Currently trying to create a debug build and getting the same error with the missing ./internal/*IOIndex.js files.

ZooLeeCoding avatar Jan 25 '23 12:01 ZooLeeCoding

@ZooLeeCoding do you get these errors when following the development documentation?

thewtex avatar Feb 16 '23 01:02 thewtex