Giter Site home page Giter Site logo

project-eutopia / vega Goto Github PK

View Code? Open in Web Editor NEW
26.0 6.0 7.0 16.9 MB

C++ library for reading/writing/editing DICOM files

License: MIT License

CMake 0.05% Ruby 0.26% C++ 99.62% Python 0.03% Dockerfile 0.03%
dicom dicom-files cpp medical shared-library

vega's Introduction

Build Status

vega

C++ library for reading/writing/editing DICOM files. Detailed documentation can be found here. Note that while this library is fully functional, it is still in an early alpha stage of development so changes to the library can be expected.

Getting started

To get started, clone the repository:

git clone https://github.com/project-eutopia/vega.git

To compile and install the shared library to your system, take the following steps:

mkdir build
cd build
cmake ..
sudo make -j8 install

To compile code that uses this library, you should link the library, the zlib library, and have to use at least C++11 standard:

clang++ --std=c++11 -lvega -lz my_code.cpp -o my_code

Installing vega binary

This library comes packaged with a runtime executable vega that can is installed by make install to /usr/local/bin/vega. It reads from the dictionary file installed to /usr/local/share/vega/dictionary.txt, and can be used to process DICOM files in the terminal. A DICOM file can either be piped in as STDIN from a DICOM file,

cat my_dicom_file.dcm | vega

or it can be specified in an input flag

vega --input=my_dicom_file.dcm

The input can also be a comma separated list of filenames, with the condition that there must be and equal number of filenames separated by commas in the output field,

vega --input=file1.dcm,file2.dcm --output=file1b.dcm,file2b.dcm

If the suffix option is passed in, then instead that will be appended to the filename for each output file. For instance, the following will anonymize each input file, and write them to file1.anon.dcm and file2.anon.dcm,

vega --input=file1.dcm,file2.dcm --suffix=anon --anonymize

Lastly, input files can be piped in to the executable as follows:

ls *.dcm | vega --anonymize --suffix=anon --folder=/my/data/directory

Here the --folder option is being used to specify the output directory to write the files to.

For output, vega supports 3 file formats: ".dcm" for DICOM format, ".json" for JSON file format, and ".txt" for human-readable plain text files. If --output is just equal to the extension (e.g. --output=json), then the DICOM file will be printed to STDOUT in that format. If --output is a full filename with the relevant extension, then it will be wrote to that file.

The vega binary also supports options to modify the DICOM file before outputting. The supported file options are:

  • --remove_undefined_lengths: forces the output file(s) to have no data elements with udnefined lengths
  • --anonymize or --anonymize=my_new_patient_id: anonymizes the input file(s)

Reading/writing files

Here is a simple example of using the library to read a file in and print a string representation of the content to standard out.

#include <string>

#include "vega/dictionary/dictionary.h"
#include "vega/dicom/file.h"

int main() {
  // Set the dictionary file
  vega::dictionary::Dictionary::set_dictionary("/path/to/dictionary/dictionary.txt");
  
  // Read the DICOM file in
  const std::string file_name = "/path/to/dicom/file/dicom.dcm";
  vega::dicom::File file(file_name);
  
  // Print a human-friendly representation of the file to std::cout
  vega::Formatter formatter(std::cout);
  file.data_set()->log(formatter);
}

To write a DICOM file, you call the vega::dicom::File::write method, either passing in a string that represents the file name, or a std::shared_ptr<std::ostream> pointer to an output stream.

Creating new DICOM file

To create a new DICOM file, use the File constructor with either const SOPClass& reference, or a const SOPClass& reference and const UID& reference to a SOP instance UID.

vega::dicom::File file(vega::dicom::SOPClass("RT Plan Storage"), vega::UID("1.2.3.4.5"));

Editing a DICOM file

The rough structure of a DICOM file is that at the root of a DICOM file is a single data set, where each data set contains a set of data elements. A data element is identified by a unique tag, which is a pair of 2 byte unsigned integers, often represented in hexadecimal, for instance (300A,00C2) is the tag corresponding to "Beam Name". A data set contains at most one data element for each tag, so it is effectively a map from tags to data elements. Each data element contains some data whose interpretation is determined by the tag, for instance (0010,0010) which corresponds to the patient's name. The storage format of the data is determined by the value representation (or VR).

Each File object has a data_set() method which returns a shared_ptr to the root vega::dicom::DataSet object. DataSet has iterators for going through each DataElement, and also offers many useful methods for selecting a specific DataElement. You can search for a DataElement using a dictionary element string name, e.g. "PatientName" or a tag like Tag{0x0010,0x0010}.

The data stored inside each DataElement is accessed through what is called a manipulator. Each manipulator, for instance vega::manipulators::DateManipulator is used for data elements with VR DA (corresponding to "date"). This manipulator acts very much like a std::vector of vega::Date objects which makes reading, adding, and modifying data very easy. The translation to the behind-the-scenes DICOM formats is hidden from the user.

In addition to DataElement, there is also an easier to use class vega::dicom::Element<T>, where T is a dictionary element type (e.g. vega::dictionary::PatientName, see include/vega/dictionary_data.h for all possibilities). The benefit of using this class is that you do not need to make explicit the manipulator class, as it is implied by the type (e.g. vega::dictionary::PatientName::manipulator_type is the expected PersonNameManipulator). As an example of adding patient name to a new data set:

auto element = data_set->new_element<vega::dictionary::PatientName>();
element->manipulator()->push_back("Smith^Alice");

vega's People

Contributors

project-eutopia avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

vega's Issues

Serving native DICOM image tiles from a certain level

When working with Whole Slide Images and developing applications using this library, it might be handy to be able to serve the native image tiles in parallel, efficiently, for display purposes.
Scenario: I provide a list of coordinates and resolutions and I get back a list of tiles.

Does this library facilitate such functionality/use cases?

Getting error while using vega library (DICOM_2_egsinp)

Hi Chris,
We're using an old version of vega library to convert dicom files to egsinp files (DICOM_2_egsinp). Recently, we updated the cluster and got following error while running DICOM_2_egsinp script,
/usr/bin/ld: Vega_DICOM_Library//libvega.a(VEGA_Classes.o): relocation R_X86_64_32 against `.rodata' can not be used when making a PIE object; recompile with -fPIE
/usr/bin/ld: failed to set dynamic section sizes: bad value
collect2: error: ld returned 1 exit status

To resolve this error we installed the new version of vega library from github and included the PIE flag in CMakeLists.txt file. Now, when we run DICOM_2_egsinp script we get following error,
undefined reference to ‘CPP_Sequence::item(unsigned int) const’ etc
In DICOM_2_egsinp.cpp file, we're using #include line for VEGA_Classes.h for the old version, but we can’t find such file for the new Vega. Could you please let us know how to get rid of this error. Thanks.

Compiling on Mac

Hi, I am trying to compile your project on a Mac, I get:
Scanning dependencies of target vega_dev
Scanning dependencies of target vega
[ 1%] Building CXX object CMakeFiles/vega.dir/src/vega/anonymizer.cpp.o
[ 1%] Building CXX object CMakeFiles/vega_dev.dir/src/vega/anonymizer.cpp.o
[ 4%] Building CXX object CMakeFiles/vega_dev.dir/src/vega/controller.cpp.o
[ 4%] Building CXX object CMakeFiles/vega_dev.dir/src/vega/dicom/data_set.cpp.o
[ 4%] Building CXX object CMakeFiles/vega_dev.dir/src/vega/dicom/data_element.cpp.o
[ 4%] Building CXX object CMakeFiles/vega.dir/src/vega/controller.cpp.o
[ 4%] Building CXX object CMakeFiles/vega_dev.dir/src/vega/dicom/file_meta.cpp.o
[ 4%] Building CXX object CMakeFiles/vega_dev.dir/src/vega/dicom/file.cpp.o
[ 6%] Building CXX object CMakeFiles/vega.dir/src/vega/dicom/file.cpp.o
[ 6%] Building CXX object CMakeFiles/vega.dir/src/vega/dicom/data_element.cpp.o
[ 6%] Building CXX object CMakeFiles/vega.dir/src/vega/dicom/data_set.cpp.o
(cv) iMac:build andrew$ more log
In file included from /Volumes/andrew/projects/radiology/vega/src/vega/dicom/data_element.cpp:1:
In file included from /Volumes/andrew/projects/radiology/vega/include/vega/dicom/data_element.h:11:
In file included from /Volumes/andrew/projects/radiology/vega/include/vega/dictionary/dictionary.h:9:
In file included from /Volumes/andrew/projects/radiology/vega/include/vega/dictionary/page.h:7:
/Volumes/andrew/projects/radiology/vega/include/vega/vm.h:23:17: error: constexpr constructor never produces a constant expression [-Winvalid-constexpr]
constexpr VM() : m_limits(std::make_pair(1,1)), m_multiple(false) {}
^
/Volumes/andrew/projects/radiology/vega/include/vega/vm.h:23:24: note: non-constexpr constructor 'pair<int, int, false>' cannot be used in a constant expression
constexpr VM() : m_limits(std::make_pair(1,1)), m_multiple(false) {}
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/utility:464:5: note: declared here
pair(pair<_U1, _U2>&& __p)
^

Would appreciate a fix, many thanks

Andrew

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.