Skip to content

Commit

Permalink
Merge pull request #319 from rordenlab/development
Browse files Browse the repository at this point in the history
New Stable release (v1.0.20190720)?
  • Loading branch information
neurolabusc authored Aug 1, 2019
2 parents 54cfd51 + 5f36457 commit 65c558e
Show file tree
Hide file tree
Showing 13 changed files with 1,424 additions and 657 deletions.
6 changes: 4 additions & 2 deletions GE/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ The [NA-MIC Wiki](https://www.na-mic.org/wiki/NAMIC_Wiki:DTI:DICOM_for_DWI_and_D

Knowing the relative timing of the acquisition for each 2D slice in a 3D volume is useful for [slice time correction](https://www.mccauslandcenter.sc.edu/crnl/tools/stc) of both fMRI and DTI data. Unfortunately, current GE software does not provide a consistent way to record this.

[Some sequences](https://afni.nimh.nih.gov/afni/community/board/read.php?1,154006) encode the RTIA Timer (0021,105E) element. For example, [this DV24 dataset](https://github.com/nikadon/cc-dcm2bids-wrapper/tree/master/dicom-qa-examples/ge-mr750-slice-timing) includes timing data, while [this DV26 dataset does not](https://github.com/neurolabusc/dcm_qa_nih). Be aware that different versions of GE software appear to use different units for 0021,105E. The DV24 example is reported in seconds, while [14.0 uses 1/10000 seconds](https://github.com/rordenlab/dcm2niix/issues/286).Even with the sequences that do encode the RTIA Timer, there is some debate regarding the accuracy of this element. In the example listed, the slice times are clearly wrong in the first volume. Therefore, dcm2niix always estimates slice times based on the 2nd volume in a time series.
[Some sequences](https://afni.nimh.nih.gov/afni/community/board/read.php?1,154006) encode the RTIA Timer (0021,105E) element. For example, [this DV24 dataset](https://github.com/nikadon/cc-dcm2bids-wrapper/tree/master/dicom-qa-examples/ge-mr750-slice-timing) includes timing data, while [this DV26 dataset does not](https://github.com/neurolabusc/dcm_qa_nih). Be aware that different versions of GE software appear to use different units for 0021,105E. The DV24 example is reported in seconds, while [14.0 uses 1/10000 seconds](https://github.com/rordenlab/dcm2niix/issues/286). An example of the latter format can be found [here](https://www.nitrc.org/plugins/mwiki/index.php/dcm2nii:MainPage#Archival_MRI). Even with the sequences that do encode the RTIA Timer, there is some debate regarding the accuracy of this element. In the example listed, the slice times are clearly wrong in the first volume. Therefore, dcm2niix always estimates slice times based on the 2nd volume in a time series.

In general, fMRI acquired using GE product sequence (PSD) “epi” with the multiphase option will store slice timing in the Trigger Time (DICOM 0018,1060) element. The current version of dcm2niix ignores this field, as no examples are available. In contrast, the popular PSD “epiRT” (BrainWave RT, fMRI/DTI package provided by Medical Numerics) does not save this tag (though in some cases it saves the RTIA Timer). Examples are [available](https://www.nitrc.org/plugins/mwiki/index.php/dcm2nii:MainPage#Slice_timing_correction) for both the “epiRT” and “epi” sequences.
In general, fMRI acquired using GE product sequence (PSD) “epi” with the multiphase option will store slice timing in the Trigger Time (DICOM 0018,1060) element. In contrast, the popular PSD “epiRT” (BrainWave RT, fMRI/DTI package provided by Medical Numerics) does not save this tag (though in some cases it saves the RTIA Timer). Examples are [available](https://www.nitrc.org/plugins/mwiki/index.php/dcm2nii:MainPage#Slice_timing_correction) for both the “epiRT” and “epi” sequences.

If neither Trigger Time (DICOM 0018,1060) or RTIA Timer (0021,105E) store slice timing information, a final option is to decode the GE Protocol Data Block as described below. At best, this block only reports whether the acquisition was interleaved or sequential. As long as one assumes the acquisition was continuous (with no temporal gap between volumes, e.g. sparse images) on can use this value, the number of slices in the volume and the repetition time to infer slice times.

## User Define Data GE (0043,102A)

Expand Down
4 changes: 2 additions & 2 deletions Philips/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Therefore, dcm2niix will ignore the IPP enclosed in 2005,140F unless no alternat

## Derived parametric maps stored with raw diffusion data

Some Philips diffusion DICOM images include derived image(s) along with the images. Other manufacturers save these derived images as a separate series number, and the DICOM standard seems ambiguous on whether it is allowable to mix raw and derived data in the same series (see PS 3.3-2008, C.7.6.1.1.2-3). In practice, many Philips diffusion images append [derived parametric maps](http://www.revisemri.com/blog/2008/diffusion-tensor-imaging/) with the original data. For example, ADC, Trace and Isotropic images can all be derived from the raw scans. As scientists, we want to discard these derived images, as they will disrupt data processing and we can generate better parametric maps after we have applied undistortion methods such as [Eddy and Topup](https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/eddy/UsersGuide). The current version of dcm2niix uses the Diffusion Directionality (0018,9075) tag to detect B=0 unweighted ("NONE"), B-weighted ("DIRECTIONAL"), and derived ("ISOTROPIC") images. Note that the Dimension Index Values (0020,9157) tag provides an alternative approach to discriminate these images. Here are sample tags from a Philips enhanced image that includes and derived map (3rd dimension is "1" while the other images set this to "2").
Some Philips diffusion DICOM images include derived image(s) along with the images. Other manufacturers save these derived images as a separate series number, and the DICOM standard seems ambiguous on whether it is allowable to mix raw and derived data in the same series (see PS 3.3-2008, C.7.6.1.1.2-3). In practice, many Philips diffusion images append [derived parametric maps](http://www.revisemri.com/blog/2008/diffusion-tensor-imaging/) with the original data. With Philips, appending the derived isotropic image is optional - it is only created for the 'clinical' DTI schemes for radiography analysis and is triggered if the first three vectors in the gradient table are the unit X,Y and Z vectors. For conventional DWI, the result is the conventional mean of the ADC X,Y,Z for DTI it the conventional mean of the 3 principle Eigen vectors. As scientists, we want to discard these derived images, as they will disrupt data processing and we can generate better parametric maps after we have applied undistortion methods such as [Eddy and Topup](https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/eddy/UsersGuide). The current version of dcm2niix uses the Diffusion Directionality (0018,9075) tag to detect B=0 unweighted ("NONE"), B-weighted ("DIRECTIONAL"), and derived ("ISOTROPIC") images. Note that the Dimension Index Values (0020,9157) tag provides an alternative approach to discriminate these images. Here are sample tags from a Philips enhanced image that includes and derived map (3rd dimension is "1" while the other images set this to "2").

```
(0018,9075) CS [DIRECTIONAL]
Expand Down Expand Up @@ -59,7 +59,7 @@ For modern Philips DICOMs, the current version of dcm2niix uses Dimension Index

Philips DICOMs do not contain all the information desired by many neuroscientists. Due to this, the [BIDS](http://bids.neuroimaging.io/) files created by dcm2niix are impoverished relative to data from other vendors. This reflects a limitation in the Philips DICOMs, not dcm2niix.

[Slice timing correction](https://www.mccauslandcenter.sc.edu/crnl/tools/stc) can account for some variability in fMRI datasets. Unfortunately, Philips DICOM data [does not encode slice timing information](https://neurostars.org/t/heudiconv-no-extraction-of-slice-timing-data-based-on-philips-dicoms/2201/4). Therefore, dcm2niix is unable to populate the "SliceTiming" BIDS field.
[Slice timing correction](https://www.mccauslandcenter.sc.edu/crnl/tools/stc) can account for some variability in fMRI datasets. Unfortunately, Philips DICOM data [does not encode slice timing information](https://neurostars.org/t/heudiconv-no-extraction-of-slice-timing-data-based-on-philips-dicoms/2201/4). Therefore, dcm2niix is unable to populate the "SliceTiming" BIDS field. However, one can typically infer slice timing by recording the [mode and number of packages](https://en.wikibooks.org/w/index.php?title=SPM/Slice_Timing&stable=0#Philips_scanners) reported for the sequence on the scanner console.

Likewise, the BIDS tag "PhaseEncodingDirection" allows tools like [eddy](https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/eddy) and [TOPUP](https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/topup) to undistort images. While the Philips DICOM header distinguishes the phase encoding axis (e.g. anterior-posterior vs left-right) it does not encode the polarity (A->P vs P->A).

Expand Down
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,11 @@ In rare case if cmake fails with the message like `"Generator: execution of make
As noted in the `Image Conversion and Compression Support` section, the software provides many optional modules with enhanced features. A common choice might be to include support for JPEG2000, [JPEG-LS](https://github.com/team-charls/charls) (this option requires a c++14 compiler), as well as using the high performance Cloudflare zlib library (this option requires a CPU built after 2008). To build with these options simply request them when configuring cmake:

```bash
git clone https://github.com/rordenlab/dcm2niix.git
cd dcm2niix
mkdir build && cd build
cmake -DZLIB_IMPLEMENTATION=Cloudflare -DUSE_JPEGLS=ON -DUSE_OPENJPEG=ON ..
make
```

**optional batch processing version:**
Expand Down Expand Up @@ -100,6 +104,7 @@ If you have any problems with the cmake build script described above or want to

The following tools exploit dcm2niix

- [dcm2niix can help convert data from the Adolescent Brain Cognitive Development (ABCD) DICOM to BIDS](https://github.com/ABCD-STUDY/abcd-dicom2bids)
- [bidsify](https://github.com/spinoza-rec/bidsify) is a Python project that uses dcm2niix to convert DICOM and Philips PAR/REC images to the BIDS standard.
- [bidskit](https://github.com/jmtyszka/bidskit) uses dcm2niix to create [BIDS](http://bids.neuroimaging.io/) datasets.
- [BioImage Suite Web Project](https://github.com/bioimagesuiteweb/bisweb) is a JavaScript project that uses dcm2niix for its DICOM conversion module.
Expand All @@ -122,8 +127,9 @@ The following tools exploit dcm2niix
- [neurodocker](https://github.com/kaczmarj/neurodocker) generates [custom](https://github.com/rordenlab/dcm2niix/issues/138) Dockerfiles given specific versions of neuroimaging software.
- [NeuroElf](http://neuroelf.net) can use dcm2niix to convert DICOM images.
- [nipype](https://github.com/nipy/nipype) can use dcm2niix to convert images.
- [PNL-nipype](https://github.com/pnlbwh/Dummy-PNL-nipype) is a Python script that can convert dcm2niix created NIfTI files to the popular NRRD format (including DWI gradient tables).
- [PNL-nipype](https://github.com/pnlbwh/Dummy-PNL-nipype) is a Python script that can convert dcm2niix created NIfTI files to the popular NRRD format (including DWI gradient tables). Note, recent versions of dcm2niix can directly convert DICOM images to NRRD.
- [pydcm2niix is a Python module for working with dcm2niix](https://github.com/jstutters/pydcm2niix).
- [pyBIDSconv provides a graphical format for converting DICOM images to the BIDS format](https://github.com/DrMichaelLindner/pyBIDSconv). It includes clever default heuristics for identifying Siemens scans.
- [sci-tran dcm2niix](https://github.com/scitran-apps/dcm2niix) Flywheel Gear (docker).
- The [SlicerDcm2nii extension](https://github.com/Slicer/ExtensionsIndex/blob/master/SlicerDcm2nii.s4ext) is one method to import DICOM data into Slicer.
- The [SlicerDcm2nii extension](https://github.com/Slicer/ExtensionsIndex/blob/master/SlicerDcm2nii.s4ext) is one method to import DICOM data into Slicer.
- [TractoR (Tracto­graphy with R) uses dcm2niix for image conversion](http://www.tractor-mri.org.uk/TractoR-and-DICOM).
6 changes: 4 additions & 2 deletions Siemens/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,15 @@ Private Tags
```

In theory, the public DICOM tag 'Frame Acquisition Date Time' (0018,9074) and the private tag 'Time After Start' (0021,1104) should each allow one to infer slice timing. The tag 0018,9074 uses the DT (date time) format, for example "20190621095520.330000" providing the YYYYYMMDDHHMMSS. Unfortunately, the Siemens de-identification routines will scramble these values, as time of data could be considered an identifiable attribute. The tag 0021,1104 is saved in DS (decimal string) format, for example "4.635" reporting the number of seconds since acquisition started. Be aware that some [Siemens Vida multi-band sequences](https://github.com/rordenlab/dcm2niix/issues/303) appear to fill these tags with the single-band times rather than the actual acquisition times. Therefore, neither of these two methods is perfectly reliable in determining slice timing.

## CSA Header

Many crucial Siemens parameters are stored in the [proprietary CSA header](http://nipy.org/nibabel/dicom/siemens_csa.html). This has a binary section that allows quick reading for many useful parameters. It also includes an ASCII text portion that includes a lot of information but is slow to parse and poorly curated.
Many crucial Siemens parameters are stored in the [proprietary CSA header](http://nipy.org/nibabel/dicom/siemens_csa.html). This has a binary section that allows quick reading for many useful parameters. It also includes an ASCII text portion that includes a lot of information but is slow to parse and poorly curated. Be aware that Siemens Vida scanners do not generate a CSA header.

## Slice Timing

The CSA header provides [slice timing](https://www.mccauslandcenter.sc.edu/crnl/tools/stc), and therefore dcm2niix should provide accurate slice timing information for non-XA10 datasets. For archival studies, be aware that some sequences [incorrectly reported slice timing](https://github.com/rordenlab/dcm2niix/issues/126).
For Siemens images created with software versions B15 through E11, the proprietary [CSA Image Header (0029,1010)](https://nipy.org/nibabel/dicom/siemens_csa.html) contains the array MosaicRefAcqTimes that provides [slice timing](https://www.mccauslandcenter.sc.edu/crnl/tools/stc). Earlier Siemens Software (e.g. A25 through B13) sometimes populates the tag sSliceArray.ucMode in the [CSA Series Header (0029, 1020)](https://nipy.org/nibabel/dicom/siemens_csa.html) where the values [1, 2, and 4](https://github.com/xiangruili/dicm2nii/issues/18) correspond to Ascending, Descending and Interleaved acquisitions. Therefore dcm2niix typically is able to provide accurate slice timing information for non-Vida datasets (the prior section describes Vida slice timing issues seen with the XA software series). Some Siemens DICOMs stroe slice timings in the private tag [0019,1029](https://github.com/rordenlab/dcm2niix/issues/296). In theory, this could be used when the CSA header is missing. For archival studies, be aware that some sequences [incorrectly reported slice timing](https://github.com/rordenlab/dcm2niix/issues/126). The [SPM slice timing wiki](https://en.wikibooks.org/w/index.php?title=SPM/Slice_Timing&stable=0#Siemens_scanners) provides further information on Siemens slice timing.

## Total Readout Time

Expand Down
39 changes: 32 additions & 7 deletions console/main_console.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,14 @@ void showHelp(const char * argv[], struct TDCMopts opts) {
char max16Ch = 'n';
if (opts.isMaximize16BitRange) max16Ch = 'y';
printf(" -l : losslessly scale 16-bit integers to use dynamic range (y/n, default %c)\n", max16Ch);
printf(" -m : merge 2D slices from same series regardless of study time, echo, coil, orientation, etc. (y/n, default n)\n");
printf(" -m : merge 2D slices from same series regardless of echo, exposure, etc. (n/y or 0/1/2, default 2) [no, yes, auto]\n");
printf(" -n : only convert this series number - can be used up to %i times (default convert all)\n", MAX_NUM_SERIES);
printf(" -o : output directory (omit to save to input folder)\n");
printf(" -p : Philips precise float (not display) scaling (y/n, default y)\n");
printf(" -r : rename instead of convert DICOMs (y/n, default n)\n");
printf(" -s : single file mode, do not convert other images in folder (y/n, default n)\n");
printf(" -t : text notes includes private patient details (y/n, default n)\n");
printf(" --progress : report progress (y/n, default n)\n");
#if !defined(_WIN64) && !defined(_WIN32) //shell script for Unix only
printf(" -u : up-to-date check\n");
#endif
Expand Down Expand Up @@ -219,6 +220,18 @@ int checkUpToDate() {

#endif //shell script for UNIX only

void showXML() {
//https://www.slicer.org/wiki/Documentation/Nightly/Developers/SlicerExecutionModel#XML_Schema
printf("<?xml version=""1.0"" encoding=""utf-8""?>\n");
printf("<executable>\n");
printf("<title>dcm2niix</title>\n");
printf("<description>DICOM importer</description>\n");
printf(" <parameters>\n");
printf(" At least one parameter\n");
printf(" </parameters>\n");
printf("</executable>\n");
}

//#define mydebugtest
int main(int argc, const char * argv[])
{
Expand Down Expand Up @@ -249,9 +262,19 @@ int main(int argc, const char * argv[])
int lastCommandArg = 0;
while (i < (argc)) { //-1 as final parameter is DICOM directory
if ((strlen(argv[i]) > 1) && (argv[i][0] == '-')) { //command
if (argv[i][1] == 'h')
if (argv[i][1] == 'h') {
showHelp(argv, opts);
else if ((argv[i][1] == 'a') && ((i+1) < argc)) { //adjacent DICOMs
} else if (( ! strcmp(argv[1], "--progress")) && ((i+1) < argc)) {
i++;
if ((argv[i][0] == 'n') || (argv[i][0] == 'N') || (argv[i][0] == '0'))
opts.isProgress = 0;
else
opts.isProgress = 1;
if (argv[i][0] == '2') opts.isProgress = 2; //logorrheic
} else if ( ! strcmp(argv[1], "--xml")) {
showXML();
return EXIT_SUCCESS;
} else if ((argv[i][1] == 'a') && ((i+1) < argc)) { //adjacent DICOMs
i++;
if (invalidParam(i, argv)) return 0;
if ((argv[i][0] == 'n') || (argv[i][0] == 'N') || (argv[i][0] == '0'))
Expand Down Expand Up @@ -337,9 +360,11 @@ int main(int argc, const char * argv[])
i++;
if (invalidParam(i, argv)) return 0;
if ((argv[i][0] == 'n') || (argv[i][0] == 'N') || (argv[i][0] == '0'))
opts.isForceStackSameSeries = false;
opts.isForceStackSameSeries = 0;
if ((argv[i][0] == 'y') || (argv[i][0] == 'Y') || (argv[i][0] == '1'))
opts.isForceStackSameSeries = true;
opts.isForceStackSameSeries = 1;
if ((argv[i][0] == '2'))
opts.isForceStackSameSeries = 2;
if ((argv[i][0] == 'o') || (argv[i][0] == 'O'))
opts.isForceStackDCE = false;

Expand Down Expand Up @@ -468,9 +493,9 @@ int main(int argc, const char * argv[])
if ((opts.isRenameNotConvert) && (!isOutNameSpecified)) { //sensible naming scheme for renaming option
//strcpy(opts.filename,argv[i]);
#if defined(_WIN64) || defined(_WIN32)
strcpy(opts.filename,"%t/%s_%p/%4r.dcm"); //nrrd or nhdr
strcpy(opts.filename,"%t\\%s_%p\\%4r.dcm"); //nrrd or nhdr (windows folders)
#else
strcpy(opts.filename,"%t\\%s_%p\\%4r.dcm"); //nrrd or nhdr
strcpy(opts.filename,"%t/%s_%p/%4r.dcm"); //nrrd or nhdr (unix folders)
#endif
printf("renaming without output filename, assuming '-f %s'\n", opts.filename);
}
Expand Down
3 changes: 2 additions & 1 deletion console/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ endif
ifneq ($(OS),Windows_NT)
OS = $(shell uname)
ifeq "$(OS)" "Darwin"
CFLAGS=-dead_strip -O3
#CFLAGS=-dead_strip -O3
CFLAGS=
#CFLAGS=-O2
endif
endif
Expand Down
Loading

0 comments on commit 65c558e

Please sign in to comment.