All Projects → PantelisGeorgiadis → dcmjs-dimse

PantelisGeorgiadis / dcmjs-dimse

Licence: MIT license
DICOM DIMSE implementation for Node.js using the dcmjs library

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to dcmjs-dimse

dicom-dimse-native
node js native addon for dimse services
Stars: ✭ 33 (+17.86%)
Mutual labels:  dicom, dimse
dicomweb-pacs
Easy to use DICOMWEB enabled PACS with DIMSE services based on sqlite database
Stars: ✭ 42 (+50%)
Mutual labels:  dicom, dimse
contrib-pydicom
contributions to the core pydicom base, including tutorials, extra plugins, etc.
Stars: ✭ 46 (+64.29%)
Mutual labels:  dicom
weasis-chcapi-extension
Weasis plugin adding support for the Google Cloud Healthcare API
Stars: ✭ 12 (-57.14%)
Mutual labels:  dicom
dicomifier
A medical image converter
Stars: ✭ 22 (-21.43%)
Mutual labels:  dicom
go-dicom
DICOM parser for golang
Stars: ✭ 51 (+82.14%)
Mutual labels:  dicom
lightdicom python
Light DICOM package
Stars: ✭ 16 (-42.86%)
Mutual labels:  dicom
slicebox
Microservice for safe sharing and easy access to medical images
Stars: ✭ 18 (-35.71%)
Mutual labels:  dicom
pylidc
An object relational mapping for the LIDC dataset using sqlalchemy.
Stars: ✭ 88 (+214.29%)
Mutual labels:  dicom
dicom-standard-chinese
Chinese translation of DICOM standard, DICOM协议中文版
Stars: ✭ 26 (-7.14%)
Mutual labels:  dicom
clara-dicom-adapter
DICOM Adapter is a component of the Clara Deploy SDK which facilitates integration with DICOM compliant systems, enables ingestion of imaging data, helps triggering of jobs with configurable rules and offers pushing the output of jobs to PACS systems.
Stars: ✭ 31 (+10.71%)
Mutual labels:  dicom
Emory-BMI-GSoC
Emory BMI GSoC Project Ideas
Stars: ✭ 27 (-3.57%)
Mutual labels:  dicom
dicomweb-server
Lightweight DICOMweb Server with CouchDB
Stars: ✭ 74 (+164.29%)
Mutual labels:  dicom
dicom parser
Facilitates DICOM data access.
Stars: ✭ 19 (-32.14%)
Mutual labels:  dicom
bidskit
Utility functions for working with DICOM and BIDS neuroimaging data
Stars: ✭ 52 (+85.71%)
Mutual labels:  dicom
dicom-containers
singularity and Docker containers to easily get started with common dicom tools
Stars: ✭ 18 (-35.71%)
Mutual labels:  dicom
dicognito
A library and command line tool for anonymizing DICOM files
Stars: ✭ 17 (-39.29%)
Mutual labels:  dicom
MRIcro
macOS Xcode GLSL Volume Render for NIfTI, Bio-Rad Pic, NRRD, Philips, ITK MetaImage, AFNI, Freesurfer, DICOM images.
Stars: ✭ 17 (-39.29%)
Mutual labels:  dicom
u-dicom-viewer
A simple web browser DICOM viewer for any device.
Stars: ✭ 91 (+225%)
Mutual labels:  dicom
dcm
A lightweight C++ DICOM library (for study purpose only!)
Stars: ✭ 25 (-10.71%)
Mutual labels:  dicom

NPM version build MIT License

dcmjs-dimse

DICOM DIMSE implementation for Node.js using Steve Pieper's dcmjs library. This library was inspired by fo-dicom and mdcm. Part of the networking code was taken from dicom-dimse.

Note

This effort is a work-in-progress and should not be used for production or clinical purposes.

Install

npm install dcmjs-dimse

Build

npm install
npm run build

Features

  • Implements C-ECHO, C-FIND, C-STORE, C-MOVE, C-GET, N-CREATE, N-ACTION, N-DELETE, N-EVENT-REPORT, N-GET and N-SET services as SCU and SCP.
  • Supports secure DICOM TLS connections.
  • Allows custom DICOM implementations (Implementation Class UID and Implementation Version).
  • Provides asynchronous event handlers for incoming SCP requests.

Examples

C-Echo SCU

const dcmjsDimse = require('dcmjs-dimse');
const { Client } = dcmjsDimse;
const { CEchoRequest } = dcmjsDimse.requests;
const { Status } = dcmjsDimse.constants;

const client = new Client();
const request = new CEchoRequest();
request.on('response', (response) => {
  if (response.getStatus() === Status.Success) {
    console.log('Happy!');
  }
});
client.addRequest(request);
client.on('networkError', (e) => {
  console.log('Network error: ', e);
});
client.send('127.0.0.1', 12345, 'SCU', 'ANY-SCP');

C-Find SCU (Studies)

const dcmjsDimse = require('dcmjs-dimse');
const { Client } = dcmjsDimse;
const { CFindRequest } = dcmjsDimse.requests;
const { Status } = dcmjsDimse.constants;

const client = new Client();
const request = CFindRequest.createStudyFindRequest({ PatientID: '12345', PatientName: '*' });
request.on('response', (response) => {
  if (response.getStatus() === Status.Pending && response.hasDataset()) {
    console.log(response.getDataset());
  }
});
client.addRequest(request);
client.on('networkError', (e) => {
  console.log('Network error: ', e);
});
client.send('127.0.0.1', 12345, 'SCU', 'ANY-SCP');

C-Store SCU

const dcmjsDimse = require('dcmjs-dimse');
const { Client } = dcmjsDimse;
const { CStoreRequest } = dcmjsDimse.requests;

const client = new Client();
const request = new CStoreRequest('test.dcm');
client.addRequest(request);
client.on('networkError', (e) => {
  console.log('Network error: ', e);
});
client.send('127.0.0.1', 12345, 'SCU', 'ANY-SCP');

C-Move SCU

const dcmjsDimse = require('dcmjs-dimse');
const { Client } = dcmjsDimse;
const { CMoveRequest } = dcmjsDimse.requests;
const { Status } = dcmjsDimse.constants;

const client = new Client();
const request = CMoveRequest.createStudyMoveRequest('DEST-AE', studyInstanceUid);
request.on('response', (response) => {
  if (response.getStatus() === Status.Pending) {
    console.log('Remaining: ' + response.getRemaining());
    console.log('Completed: ' + response.getCompleted());
    console.log('Warning: ' + response.getWarnings());
    console.log('Failed: ' + response.getFailures());
  }
});
client.addRequest(request);
client.on('networkError', (e) => {
  console.log('Network error: ', e);
});
client.send('127.0.0.1', 12345, 'SCU', 'ANY-SCP');

C-Get SCU

const dcmjsDimse = require('dcmjs-dimse');
const { Client } = dcmjsDimse;
const { CGetRequest } = dcmjsDimse.requests;
const { CStoreResponse } = dcmjsDimse.responses;
const { Status } = dcmjsDimse.constants;

const client = new Client();
const request = CGetRequest.createStudyGetRequest(studyInstanceUid);
request.on('response', (response) => {
  if (response.getStatus() === Status.Pending) {
    console.log('Remaining: ' + response.getRemaining());
    console.log('Completed: ' + response.getCompleted());
    console.log('Warning: ' + response.getWarnings());
    console.log('Failed: ' + response.getFailures());
  }
});
client.on('cStoreRequest', (request, callback) => {
  console.log(request.getDataset());

  const response = CStoreResponse.fromRequest(request);
  response.setStatus(Status.Success);
  callback(response);
});
client.addRequest(request);
client.on('networkError', (e) => {
  console.log('Network error: ', e);
});
client.send('127.0.0.1', 12345, 'SCU', 'ANY-SCP');

SCP

const dcmjsDimse = require('dcmjs-dimse');
const { Dataset, Server, Scp } = dcmjsDimse;
const { CEchoResponse, CFindResponse, CStoreResponse } = dcmjsDimse.responses;
const {
  Status,
  PresentationContextResult,
  RejectResult,
  RejectSource,
  RejectReason,
  TransferSyntax,
  SopClass,
  StorageClass,
} = dcmjsDimse.constants;

class DcmjsDimseScp extends Scp {
  constructor(socket, opts) {
    super(socket, opts);
    this.association = undefined;
  }

  // Handle incoming association requests
  associationRequested(association) {
    this.association = association;

    // Evaluate calling/called AET and reject association, if needed
    if (this.association.getCallingAeTitle() !== 'SCU') {
      this.sendAssociationReject(
        RejectResult.Permanent,
        RejectSource.ServiceUser,
        RejectReason.CallingAeNotRecognized
      );
      return;
    }

    // Optionally set the preferred max PDU length
    this.association.setMaxPduLength(65536);

    const contexts = association.getPresentationContexts();
    contexts.forEach((c) => {
      const context = association.getPresentationContext(c.id);
      if (
        context.getAbstractSyntaxUid() === SopClass.Verification ||
        context.getAbstractSyntaxUid() === SopClass.StudyRootQueryRetrieveInformationModelFind ||
        context.getAbstractSyntaxUid() === StorageClass.MrImageStorage
        // Accept other presentation contexts, as needed
      ) {
        const transferSyntaxes = context.getTransferSyntaxUids();
        transferSyntaxes.forEach((transferSyntax) => {
          if (transferSyntax === TransferSyntax.ImplicitVRLittleEndian) {
            context.setResult(
              PresentationContextResult.Accept,
              TransferSyntax.ImplicitVRLittleEndian
            );
          } else {
            context.setResult(PresentationContextResult.RejectTransferSyntaxesNotSupported);
          }
        });
      } else {
        context.setResult(PresentationContextResult.RejectAbstractSyntaxNotSupported);
      }
    });
    this.sendAssociationAccept();
  }

  // Handle incoming C-ECHO requests
  cEchoRequest(request, callback) {
    const response = CEchoResponse.fromRequest(request);
    response.setStatus(Status.Success);
    
    callback(response);
  }

  // Handle incoming C-FIND requests
  cFindRequest(request, callback) {
    console.log(request.getDataset());

    const pendingResponse = CFindResponse.fromRequest(request);
    pendingResponse.setDataset(new Dataset({ PatientID: '12345', PatientName: 'JOHN^DOE' }));
    pendingResponse.setStatus(Status.Pending);

    const finalResponse = CFindResponse.fromRequest(request);
    finalResponse.setStatus(Status.Success);

    callback([pendingResponse, finalResponse]);
  }

  // Handle incoming C-STORE requests
  cStoreRequest(request, callback) {
    console.log(request.getDataset());

    const response = CStoreResponse.fromRequest(request);
    response.setStatus(Status.Success);

    callback(response);
  }

  // Handle incoming association release requests
  associationReleaseRequested() {
    this.sendAssociationReleaseResponse();
  }
}

const server = new Server(DcmjsDimseScp);
server.on('networkError', (e) => {
  console.log('Network error: ', e);
});
server.listen(port);

// When done
server.close();

Please check the respecting Wiki section for more examples.

License

dcmjs-dimse is released under the MIT License.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].