Skip to content
Commits on Source (5)
......@@ -18,7 +18,7 @@ The following sub-sections list how you can modify this basic recipe for your ne
## Trouble Shooting
Some [Centos/Redhat](https://github.com/rordenlab/dcm2niix/issues/137) may report "/usr/bin/ld: cannot find -lstdc++". This can be resolved by installing static versions of libstd: `yum install libstdc++-static`.
Some [Centos/Redhat](https://github.com/rordenlab/dcm2niix/issues/137) may report "/usr/bin/ld: cannot find -lstdc++". This can be resolved by installing static versions of libstdc++: `yum install libstdc++-static`.
##### ZLIB BUILD
If we have zlib, we can use it (-lz) and disable [miniz](https://code.google.com/p/miniz/) (-myDisableMiniZ)
......
## About
dcm2niix attempts to convert GE DICOM format images to NIfTI.
## dcm2niix Notes
In addition to reading the
In addition to the public DICOM tags, dcm2niix attempts to decode the proprietary GE Protocol Data Block (0025,101B). This is essentially a [GZip format](http://www.onicos.com/staff/iz/formats/gzip.html) file embedded inside the DICOM header. Here are comments regarding the usage of this data block:
- The VIEWORDER tag is used to set the polarity of the BIDS tag PhaseEncodingDirection, with VIEWORDER of 1 suggesting bottom up phase encoding.
- The SLICEORDER tag is used to set the SliceTiming for the BIDS tag PhaseEncodingDirection, with a SLICEORDER of 1 suggesting interleaved acquisition. Note that current versions of dcm2niix do not detect multiband for GE datasets. Therefore, the slice timing reported in the BIDS header will be incorrect for multiband acquisitions.
- There are reports that newer versions of GE equipement (e.g. DISCOVERY MR750 / 24\MX\MR Software release:DV24.0_R01_1344.a) are now storing an [XML](https://groups.google.com/forum/#!msg/comp.protocols.dicom/mxnCkv8A-i4/W_uc6SxLwHQJ) file within the Protocolo Data Block (compressed). Since the developers of dcm2niix have not had access to any of these files, dcm2niix should generate a warning when it encounters any of these images.
```
POSITION "Supine"
ENTRY "Head First"
CLINICALCOIL "C-GE_32Ch Head"
COIL "32Ch Head"
COILCOMPONENT "32 Ch Head Coil"
PLANE "AXIAL"
SEDESC "Axial rsfMRI (Eyes Open)"
HOS "0"
IMODE "2D"
PSEQ "Gradient Echo"
IOPT "MPh, EPI"
PLUG "9"
IEC_ACCEPT "ON"
FILTCHOICE "None"
BWRT "-1"
TRICKSIMG "1"
TAG_SPACE "7"
TAG_TYPE "None"
USERCV0 "1.00"
USERCV_MASK "1"
USERCV_MASK2 "0"
NUMBVALUE "1"
REOPT "1"
FLIPANG "90"
TE "30.0"
NECHO "1"
TR "3000.0"
NUMSHOTS "1"
BPMMODE "0"
AUTOTRGTYPE "0"
INITSTATE "0"
PSDTRIG "0"
SLICEORDER "1"
VIEWORDER "1"
TRREST "0"
TRACTIVE "0"
SLPERLOC "200"
ACQORDER "0"
DELACQ "Minimum"
DELACQNOAV "2"
SEPSERIES "0"
AUTOTRIGWIN "0"
FOV "22.0"
SLTHICK "3.4"
SPC "0.0"
GRXOPT "0"
SLOC1 "R0.5"
SLOC2 "A27.0"
SLOC3 "I63.3"
ELOC1 "R0.5"
ELOC2 "A27.0"
ELOC3 "S96.5"
FOVCNT1 "R0.5"
FOVCNT2 "A27.0"
NOSLC "48"
SL3PLANE "0"
SL3PLANE1 "0"
SL3PLANE2 "0"
SL3PLANE3 "0"
SPCPERPLANE1 "0.0"
SPCPERPLANE2 "0.0"
SPCPERPLANE3 "0.0"
MATRIXX "64"
MATRIXY "64"
SWAPPF "R/L"
NEX "1.00"
CONTRAST "No"
CONTAM "Yes "
TBLDELTA "0.00"
PHASEFOV "1.00"
AUTOSHIM "Off"
PHASECORR "Yes"
PAUSEDELMASKACQ "1"
GRIP_SLGROUP1 "0.500000 26.985256 16.641255 0.000000 0.000000 1.000000 0.000000 1.000000 0.000000 1.000000 0.000000 0.000000 48 0.000000 1 0.000000 0"
GRIP_NUMSLGROUPS "1"
GRIP_TRACKER "0"
GRIP_SPECTRO "0"
GRIP_NUMPSCVOL "0"
GRIP_PSCVOL1 "0"
GRIP_PSCVOL2 "0"
GRIP_PSCVOLFOV "0.000000"
GRIP_PSCVOLTHICK "0.000000"
GRIP_IRBAND_A "0"
GRIP_IRBAND_B "0"
AUTOSUBOPTIONS "0"
AUTOSCIC "0"
AUTOVOICE "0"
PRESETDELAY "0.0"
MASKPHASE "0"
MASKPAUSE "0"
GRXLOCSAVE "0"
AUTOCOIL "0"
ONETOUCHREG "0"
TEMPORALPHASES "4"
MEGFREQ "60"
DRIVERAMP "50"
MEGDIR "4"
DRIVERFREQ "60"
RFDRIVEMODE "Quadrature"
INRANGETR "0"
NAVPSCPAUSE "0"
EXCITATIONMODE "Selective"
ANATOMY "SRT%5CNone%5CT-A0100"
```
\ No newline at end of file
## About
dcm2niix attempts to convert Philips PAR/REC format images to NIfTI. While this format remains popular with users, it is slowly being superceded by Philips enhanced DICOM format as well as the direct NIfTI export that Philips provides for users.
## dcm2niix Limitations
None of the major contributors to the dcm2niix source code have access to Philips hardware. Therefore, one should be cautious when converting Philips PAR/REC data. Two situations will generate error reports from the current version of dcm2niix. If you encounter any of these situations you may want to consider filing a GitHub issue or trying an alternative such as [dicm2nii](https://www.mathworks.com/matlabcentral/fileexchange/42997-dicom-to-nifti-converter--nifti-tool-and-viewer) or [r2agui](http://r2agui.sourceforge.net/).
- dcm2niix assumes that the data is stored in complete 3D volumes. It will not convert datasets where the scan is interrupted mid-volume (e.g. where the number of 2D slices is not divisible by the number of slices in a volume).
- dcm2niix is aware of phase maps and magnitude maps. In theory (though we have never seen any examples), the format can also store real, imaginary and subsequent calculations such as B1. These may or may not be converted correctly.
## About
dcm2niix attempts to convert all DICOM images to NIfTI. The Philips enhanced DICOM images are elegantly able to save all images from a series as a single file. However, this format is necessarily complex. The usage of this format has evolved over time, and can become further complicated when DICOM are handled by DICOM tools (for example, anonymization, transfer which converts explicit VRs to implicit VRs, etc.).
This web page describes some of the strategies handle these images. However, users should be vigilant when handling these datasets. If you encounter problems using dcm2niix you can explore [https://github.com/rordenlab/dcm2niix competing DICOM to NIfTI converters] or [ [https://github.com/rordenlab/dcm2niix report an issue].
## Image Patient Position
The Image Patient Position (0020,0032) tag is required to determine the position of the slices with respect to each other (and with respect to the scanner bore). Philips scans often report two conflicting IPPs for each single slice: with one stored in the private sequence (SQ) 2005,140F while the other is in the public sequence. This is unusual, but is [ftp://medical.nema.org/medical/dicom/final/cp758_ft.pdf legal].
In practice, this complication has several major implications. First, not all software translate private SQs well. One potential problem is when the implicit VRs are saved as implicit VRs. This can obscure the fact that 2005,140F is an SQ. Indeed, some tools will convert the private SQ type as a "UN" unknown type and add another public sequence. This can confuse reading software.
Furthermore, in the real world there are many Philips DICOM images that ONLY contain IPP inside SQ 2005,140F. These situations appear to reflect modifications applied by a PACS to the DICOM data or attempts to anonymize the DICOM images (e.g. using simple Matlab scripts). Note that the private IPP differs from the public one by half a voxel. Therefore, in theory if one only has the private IPP, one can infer the public IPP location. Current versions of dcm2niix do not do this: the error is assumed small enough that it will not impact image processing steps such as coregistration.
In general it is recommended that you archive and convert DICOM images as they are created from the scanner. If one does use an export tool such as the excellent dcmtk, it is recommended that you preserve the explicit VR, as implicit VR has the potential of obscuring private sequence (SQ) tags. Be aware that subsequent processing of DICOM data can disrupt data conversion.
Therefore, dcm2niix will ignore the IPP enclosed in 2005,140F unless no alternative exists.
## 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").
```
(0018,9075) CS [DIRECTIONAL]
(0018,9089) FD 1\0\0
(0018,9087) FD 1000
(0020,9157) UL 1\1\2\32
...
(0018,9075) CS [ISOTROPIC]
(0018,9087) FD 1000
(0020,9157) UL 1\2\1\33
...
(0018,9075) CS [NONE]
(0018,9087) FD 0
(0020,9157) UL 1\1\2\33
```
## Diffusion Direction
Proper Philips enhanced scans use tag 0018,9089 to report the 3 gradient directions. However, in the wild, other files from Philips (presumably using older versions of Philips software) use the tags 2005,10b0, 2005,10b1, 2005,10b2. In general, dcm2niix will use the values that most closely precede the Dimension Index Values (0020,9157).
The current version of dcm2niix uses Dimension Index Values (0020,9157) to determine gradient number, which can also be found in (2005,1413). However, while 2005,1413 is always indexed from one, this is not necessarily the case for 0020,9157. For example, the ADNI DWI dataset for participant 018_S_4868 has values of 2005,1413 that range from 1..36 for the 36 directions, while 0020,9157 ranges from 2..37. The current version of dcm2niix compensates for this by re-indexing the values of 0020,9157 after all the volumes have been read.
## General variations
Prior versions of dcm2niix used different methods to sort images. However, these have proved unreliable The undocumented tags SliceNumberMrPhilips (2001,100A), NumberOfSlicesMrPhilips (2001,1018) are not always present. In theory, InStackPositionNumber (0020,9057) should be present in all enhanced files, but has not proved reliable (perhaps not in older Philips images or DICOM images that were modified after leaving the scanner). MRImageGradientOrientationNumber (2005,1413) is complicated by the inclusion of derived images.Therefore, current versions of dcm2niix do not depend on any of these.
......@@ -59,19 +59,33 @@ The batch processing binary `dcm2niibatch` is optional. To build `dcm2niibatch`
If you have any problems with the cmake build script described above or want to customize the software see the [COMPILE.md file for details on manual compilation](./COMPILE.md).
## Alternatives
- [Valerio Luccio's dinifti](http://cbi.nyu.edu/software/dinifti.php) is focused on conversion of Siemens data
- [dcm2nii](http://www.mccauslandcenter.sc.edu/mricro/mricron/dcm2nii.htm) is the predecessor of dcm2niix. It is deprecated for modern images, but does handle image formats that predate DICOM (proprietary Elscint, GE and Siemens formats).
- [Xiangrui Li's dicm2nii](http://www.mathworks.com/matlabcentral/fileexchange/42997-dicom-to-nifti-converter) is written in Matlab. The Matlab language makes this very scriptable.
- [dicom2nifti](https://github.com/icometrix/dicom2nifti) uses the scriptable Python wrapper utilizes the [high performance GDCMCONV](http://gdcm.sourceforge.net/wiki/index.php/Gdcmconv) executables.
- [MRtrix mrconvert](http://mrtrix.readthedocs.io/en/latest/reference/commands/mrconvert.html) is a useful general purpose image converter and handles DTI data well. It is an outstanding tool for modern Philips enhanced images.
- [Jolinda Smith's mcverter](http://lcni.uoregon.edu/%7Ejolinda/MRIConvert/) has great support for various vendors.
- [mri_convert](https://surfer.nmr.mgh.harvard.edu/pub/docs/html/mri_convert.help.xml.html) is part of the popular FreeSurfer package. In my limited experience this tool works well for GE and Siemens data, but fails with Philips 4D datasets.
- [SPM12](http://www.fil.ion.ucl.ac.uk/spm/software/spm12/) is one of the most popular tools in the field. It includes DICOM to NIfTI conversion. Being based on Matlab it is easy to script.
- [R2A_GUI](http://r2agui.sourceforge.net/) is a Matlab script that converts Philips PAR/REC images to NIfTI.
## Links
- [Dcm2Bids](https://github.com/cbedetti/Dcm2Bids) uses dcm2niix to create [BIDS](http://bids.neuroimaging.io/) datasets.
- [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.
- [boutiques-dcm2niix](https://github.com/lalet/boutiques-dcm2niix) is a dockerfile for installing and validating dcm2niix.
- [DAC2BIDS](https://github.com/dangom/dac2bids) uses dcm2niibatch to create [BIDS](http://bids.neuroimaging.io/) datasets.
- [heudiconv](https://github.com/nipy/heudiconv) can use dcm2niix to create [BIDS](http://bids.neuroimaging.io/) datasets.
- [nipype](https://github.com/nipy/nipype) can use dcm2niix to convert images.
- [pydcm2niix is a Python module for working with dcm2niix](https://github.com/jstutters/pydcm2niix).
- [Dcm2Bids](https://github.com/cbedetti/Dcm2Bids) uses dcm2niix to create [BIDS](http://bids.neuroimaging.io/) datasets.
- [dcm2niir](https://github.com/muschellij2/dcm2niir) R wrapper for dcm2niix/dcm2nii.
- [dcm2niix_afni](https://afni.nimh.nih.gov/pub/dist/doc/program_help/dcm2niix_afni.html) is a version of dcm2niix included with the [AFNI](https://afni.nimh.nih.gov/) distribution.
- [divest](https://github.com/jonclayden/divest) R interface to dcm2niix.
- [sci-tran dcm2niix](https://github.com/scitran-apps/dcm2niix) docker.
- [heudiconv](https://github.com/nipy/heudiconv) can use dcm2niix to create [BIDS](http://bids.neuroimaging.io/) datasets.
- [MRIcroGL](https://github.com/neurolabusc/MRIcroGL) is available for MacOS, Linux and Windows and provides a graphical interface for dcm2niix. You can get compiled copies from the [MRIcroGL NITRC web site](https://www.nitrc.org/projects/mricrogl/).
- [neuro_docker](https://github.com/Neurita/neuro_docker) includes dcm2niix as part of a single, static Dockerfile.
- [https://github.com/lalet/boutiques-dcm2niix boutiques-dcm2niix] is a dockerfile for installing and validating dcm2niix.
- [NeuroDebian](http://neuro.debian.net/pkgs/dcm2niix.html) provides up-to-date version of dcm2niix for Debian-based systems.
- [neurodocker](https://github.com/kaczmarj/neurodocker) generates [custom](https://github.com/rordenlab/dcm2niix/issues/138) Dockerfiles given specific versions of neuroimaging software.
- [dcm2niix_afni](https://afni.nimh.nih.gov/pub/dist/doc/program_help/dcm2niix_afni.html) is a version of dcm2niix included with the [AFNI](https://afni.nimh.nih.gov/) distribution.
- [MRIcroGL](https://github.com/neurolabusc/MRIcroGL) is available for MacOS, Linux and Windows and provides a graphical interface for dcm2niix. You can get compiled copies from the [MRIcroGL NITRC web site](https://www.nitrc.org/projects/mricrogl/).
\ No newline at end of file
- [nipype](https://github.com/nipy/nipype) can use dcm2niix to convert images.
- [pydcm2niix is a Python module for working with dcm2niix](https://github.com/jstutters/pydcm2niix).
- [sci-tran dcm2niix](https://github.com/scitran-apps/dcm2niix) Flywheel Gear (docker).
\ No newline at end of file
# Check if git exists
find_package(Git)
if(NOT GIT_FOUND)
message(ERROR "Cannot find git. git is required for Superbuild")
message(FATAL_ERROR "Cannot find Git. Git is required for Superbuild")
endif()
# Use git protocol or not
......@@ -20,6 +20,19 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
option(USE_STATIC_RUNTIME "Use static runtime" ON)
if(USE_STATIC_RUNTIME)
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
find_file(STATIC_LIBCXX "libstdc++.a" ${CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES})
if(NOT STATIC_LIBCXX)
unset(STATIC_LIBCXX CACHE)
# only on some Centos/Redhat systems
message(FATAL_ERROR
"\"USE_STATIC_RUNTIME\" set to ON but \"libstdcxx.a\" not found! \
\"yum install libstdc++-static\" to resolve the error.")
endif()
endif()
endif()
option(USE_SYSTEM_ZLIB "Use the system zlib" OFF)
option(USE_TURBOJPEG "Use TurboJPEG to decode classic JPEG" OFF)
option(USE_JASPER "Build with JPEG2000 support using Jasper" OFF)
......
......@@ -20,16 +20,15 @@ set(PROGRAMS dcm2niix)
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
# using Clang
add_definitions(-Wno-deprecated-register)
add_definitions(-fno-caret-diagnostics)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-dead_strip")
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
# using GCC
if (${CMAKE_CXX_COMPILER_VERSION} VERSION_GREATER 4.4.7)
add_definitions(-Wno-unused-result) # available since GCC 4.5
if(NOT (${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 4.5.0))
add_definitions(-Wno-unused-result) # available since GCC 4.5.0
endif()
if (${CMAKE_CXX_COMPILER_VERSION} VERSION_GREATER 4.7.4)
add_definitions(-fno-diagnostics-show-caret) # available since GCC 4.8
if(NOT (${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 4.8.0))
add_definitions(-fno-diagnostics-show-caret) # available since GCC 4.8.0
endif()
elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
# using Intel C++
......@@ -47,6 +46,7 @@ elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4800") # 'uint32_t' : forcing value to bool 'true' or 'false'
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4819") # The file contains a character that cannot be represented in the current code page
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4996") # 'access': The POSIX name for this item is deprecated
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /STACK:8388608") # set "Stack Reserve Size" to 8MB (default value is 1MB)
endif()
add_executable(dcm2niix
......
......@@ -74,18 +74,19 @@ void showHelp(const char * argv[], struct TDCMopts opts) {
printf(" -1..-9 : gz compression level (1=fastest..9=smallest, default %d)\n", opts.gzLevel);
char bidsCh = 'n';
if (opts.isCreateBIDS) bidsCh = 'y';
printf(" -b : BIDS sidecar (y/n/o(o=only: no NIfTI), default %c)\n", bidsCh);
printf(" -b : BIDS sidecar (y/n/o [o=only: no NIfTI], default %c)\n", bidsCh);
if (opts.isAnonymizeBIDS) bidsCh = 'y'; else bidsCh = 'n';
printf(" -ba : anonymize BIDS (y/n, default %c)\n", bidsCh);
printf(" -c : comment stored as NIfTI aux_file (up to 24 characters)\n");
if (opts.isSortDTIbyBVal) bidsCh = 'y'; else bidsCh = 'n';
printf(" -d : diffusion volumes sorted by b-value (y/n, default %c)\n", bidsCh);
//printf(" -d : diffusion volumes sorted by b-value (y/n, default %c)\n", bidsCh);
#ifdef mySegmentByAcq
#define kQstr " %%q=sequence number,"
#else
#define kQstr ""
#endif
printf(" -f : filename (%%a=antenna (coil) number, %%c=comments, %%d=description, %%e echo number, %%f=folder name, %%i ID of patient, %%j seriesInstanceUID, %%k studyInstanceUID, %%m=manufacturer, %%n=name of patient, %%p=protocol,%s %%s=series number, %%t=time, %%u=acquisition number, %%v=vendor, %%x=study ID; %%z sequence name; default '%s')\n", kQstr, opts.filename);
printf(" -f : filename (%%a=antenna (coil) number, %%c=comments, %%d=description, %%e=echo number, %%f=folder name, %%i=ID of patient, %%j=seriesInstanceUID, %%k=studyInstanceUID, %%m=manufacturer, %%n=name of patient, %%p=protocol,%s %%s=series number, %%t=time, %%u=acquisition number, %%v=vendor, %%x=study ID; %%z=sequence name; default '%s')\n", kQstr, opts.filename);
printf(" -g : generate defaults file (y/n/o [o=only: reset and write defaults], default n)\n");
printf(" -h : show help\n");
printf(" -i : ignore derived, localizer and 2D images (y/n, default n)\n");
printf(" -m : merge 2D slices from same series regardless of study time, echo, coil, orientation, etc. (y/n, default n)\n");
......@@ -200,6 +201,8 @@ int checkUpToDate() {
int main(int argc, const char * argv[])
{
struct TDCMopts opts;
bool isSaveIni = false;
bool isResetDefaults = false;
readIniFile(&opts, argv); //set default preferences
#ifdef mydebugtest
//strcpy(opts.indir, "/Users/rorden/desktop/sliceOrder/dicom2/Philips_PARREC_Rotation/NoRotation/DBIEX_4_1.PAR");
......@@ -257,8 +260,25 @@ int main(int argc, const char * argv[])
if (invalidParam(i, argv)) return 0;
if ((argv[i][0] == 'n') || (argv[i][0] == 'N') || (argv[i][0] == '0'))
opts.isSortDTIbyBVal = false;
else
else {
opts.isSortDTIbyBVal = true;
printf("Warning: sorting by b-value is deprecated: do not do this before undistortion.");
printf(" https://www.nitrc.org/forum/message.php?msg_id=22867");
}
} else if ((argv[i][1] == 'g') && ((i+1) < argc)) {
i++;
if (invalidParam(i, argv)) return 0;
if ((argv[i][0] == 'y') || (argv[i][0] == 'Y'))
isSaveIni = true;
if (((argv[i][0] == 'o') || (argv[i][0] == 'O')) && (!isResetDefaults)) {
//reset defaults - do not read, but do write defaults
isSaveIni = true;
isResetDefaults = true;
printf("Defaults reset\n");
setDefaultOpts(&opts, argv);
//this next line is optional, otherwise "dcm2niix -f %p_%s -d o" and "dcm2niix -d o -f %p_%s" will create different results
i = 0; //re-read all settings for this pass, e.g. "dcm2niix -f %p_%s -d o" should save filename as "%p_%s"
}
} else if ((argv[i][1] == 'i') && ((i+1) < argc)) {
i++;
if (invalidParam(i, argv)) return 0;
......@@ -304,7 +324,11 @@ int main(int argc, const char * argv[])
if (invalidParam(i, argv)) return 0;
if ((argv[i][0] == 'n') || (argv[i][0] == 'N') || (argv[i][0] == '0')) //0: verbose OFF
opts.isVerbose = 0;
else if ((argv[i][0] == 'h') || (argv[i][0] == 'H') || (argv[i][0] == '2')) //2: verbose HYPER
else if ((argv[i][0] == 'o') || (argv[i][0] == 'O')) {//-1: experimental SQ skipping: 'O'ptimized!? faster, does not get confused with Philips tags
opts.isVerbose = -1;
printf(">> Experimental SQ skipping enabled\n");
} else if ((argv[i][0] == 'h') || (argv[i][0] == 'H') || (argv[i][0] == '2')) //2: verbose HYPER
opts.isVerbose = 2;
else
opts.isVerbose = 1; //1: verbose ON
......@@ -336,7 +360,7 @@ int main(int argc, const char * argv[])
strcpy(opts.outdir,argv[i]);
} else if ((argv[i][1] == 'n') && ((i+1) < argc)) {
i++;
int seriesNumber = atoi(argv[i]);
float seriesNumber = atof(argv[i]);
if (seriesNumber < 0)
opts.numSeries = -1; //report series: convert none
else if ((opts.numSeries >= 0) && (opts.numSeries < MAX_NUM_SERIES)) {
......@@ -352,6 +376,8 @@ int main(int argc, const char * argv[])
} //if parameter is a command
i ++; //read next parameter
} //while parameters to read
if (isSaveIni)
saveIniFile(opts);
//printf("%d %d",argc,lastCommandArg);
if (argc == (lastCommandArg+1)) { //+1 as array indexed from 0
//the user did not provide an input filename, report filename structure
......@@ -383,6 +409,7 @@ int main(int argc, const char * argv[])
#else
printf ("Conversion required %f seconds.\n",((float)(clock()-start))/CLOCKS_PER_SEC);
#endif
saveIniFile(opts);
//if (isSaveIni) //we now save defaults earlier, in case of early termination.
// saveIniFile(opts);
return EXIT_SUCCESS;
}
This diff is collapsed.
......@@ -38,10 +38,12 @@ extern "C" {
#define kCCsuf " CompilerNA" //unknown compiler!
#endif
#define kDCMvers "v1.0.20171215" kDCMsuf kCCsuf
#define kDCMvers "v1.0.20180328" kDCMsuf kCCsuf
static const int kMaxEPI3D = 1024; //maximum number of EPI images in Siemens Mosaic
static const int kMaxDTI4D = 4096; //maximum number of DTI directions for 4D (Philips) images, also maximum number of 3D slices for Philips 3D and 4D images
static const int kMaxSlice2D = 64000; //maximum number of 2D slices in 4D (Philips) images
#define kDICOMStr 64
#define kDICOMStrLarge 256
#define kMANUFACTURER_UNKNOWN 0
......@@ -76,10 +78,14 @@ static const uint8_t MAX_NUMBER_OF_DIMENSIONS = 8;
struct TDTI {
float V[4];
int sliceNumberMrPhilips;
//int totalSlicesIn4DOrder;
};
struct TDTI4D {
struct TDTI S[kMaxDTI4D];
int sliceOrder[kMaxSlice2D]; // [7,3,2] means the first slice on disk should be moved to 7th position
int gradDynVol[kMaxDTI4D]; //used to parse dimensions of Philips data, e.g. file with multiple dynamics, echoes, phase+magnitude
float TE[kMaxDTI4D], intenScale[kMaxDTI4D], intenIntercept[kMaxDTI4D], intenScalePhilips[kMaxDTI4D];
bool isPhase[kMaxDTI4D];
};
#ifdef _MSC_VER //Microsoft nomenclature for packed structures is different...
......@@ -110,14 +116,18 @@ static const uint8_t MAX_NUMBER_OF_DIMENSIONS = 8;
} TCSAitem; //Siemens csa item structure
#endif
struct TCSAdata {
bool isPhaseMap;
float sliceTiming[kMaxEPI3D], dtiV[4], sliceNormV[4], bandwidthPerPixelPhaseEncode, sliceMeasurementDuration;
int numDti, SeriesHeader_offset, SeriesHeader_length, multiBandFactor, sliceOrder, slice_start, slice_end, mosaicSlices,protocolSliceNumber1,phaseEncodingDirectionPositive;
bool isPhaseMap;
};
struct TDICOMdata {
long seriesNum;
int xyzDim[5];
int modality, dwellTime, effectiveEchoSpacingGE, phaseEncodingLines, phaseEncodingSteps, echoTrainLength, patientPositionNumPhilips, coilNum, echoNum, sliceOrient,numberOfDynamicScans, manufacturer, converted2NII, acquNum, imageNum, imageStart, imageBytes, bitsStored, bitsAllocated, samplesPerPixel,patientPositionSequentialRepeats,locationsInAcquisition, compressionScheme;
//numberOfDynamicScans, patientPositionNumPhilips
//patientPositionSequentialRepeats,patientPositionRepeats,
//maxGradDynVol, gradDynVol,
int protocolBlockStartGE, protocolBlockLengthGE, modality, dwellTime, effectiveEchoSpacingGE, phaseEncodingLines, phaseEncodingSteps, echoTrainLength, coilNum, echoNum, sliceOrient, manufacturer, converted2NII, acquNum, imageNum, imageStart, imageBytes, bitsStored, bitsAllocated, samplesPerPixel,locationsInAcquisition, compressionScheme;
float patientWeight, zSpacing, zThick, pixelBandwidth, SAR, phaseFieldofView, accelFactPE, flipAngle, fieldStrength, TE, TI, TR, intenScale, intenIntercept, intenScalePhilips, gantryTilt, lastScanLoc, angulation[4];
float orient[7], patientPosition[4], patientPositionLast[4], xyzMM[4], stackOffcentre[4];
float radionuclidePositronFraction, radionuclideTotalDose, radionuclideHalfLife, doseCalibrationFactor; //PET ISOTOPE MODULE ATTRIBUTES (C.8-57)
......@@ -128,25 +138,28 @@ static const uint8_t MAX_NUMBER_OF_DIMENSIONS = 8;
char imageComments[kDICOMStrLarge];
uint32_t dimensionIndexValues[MAX_NUMBER_OF_DIMENSIONS];
struct TCSAdata CSA;
bool isSegamiOasis, isDerived, isXRay, isMultiEcho, isSlicesSpatiallySequentialPhilips, isValid, is3DAcq, is2DAcq, isExplicitVR, isLittleEndian, isPlanarRGB, isSigned, isHasPhase,isHasMagnitude,isHasMixed, isFloat, isResampled;
//isSlicesSpatiallySequentialPhilips
bool isSegamiOasis, isScaleOrTEVaries, isDerived, isXRay, isMultiEcho, isValid, is3DAcq, is2DAcq, isExplicitVR, isLittleEndian, isPlanarRGB, isSigned, isHasPhase,isHasMagnitude,isHasMixed, isFloat, isResampled, isLocalizer;
char phaseEncodingRC, patientSex;
//uint32_t *totalSlicesIn4DOrder; //Reordering array for Philips slices
};
size_t nii_ImgBytes(struct nifti_1_header hdr);
int isSameFloatGE (float a, float b);
struct TDICOMdata readDICOMv(char * fname, int isVerbose, int compressFlag, struct TDTI4D *dti4D);
struct TDICOMdata readDICOM(char * fname);
struct TDICOMdata clear_dicom_data();
struct TDICOMdata nii_readParRec (char * parname, int isVerbose, struct TDTI4D *dti4D);
struct TDICOMdata nii_readParRec (char * parname, int isVerbose, struct TDTI4D *dti4D, bool isReadPhase);
unsigned char * nii_flipY(unsigned char* bImg, struct nifti_1_header *h);
unsigned char * nii_flipZ(unsigned char* bImg, struct nifti_1_header *h);
unsigned char * nii_reorderSlices(unsigned char* bImg, struct nifti_1_header *h, struct TDTI4D *dti4D);
//*unsigned char * nii_reorderSlices(unsigned char* bImg, struct nifti_1_header *h, struct TDTI4D *dti4D);
void changeExt (char *file_name, const char* ext);
unsigned char * nii_planar2rgb(unsigned char* bImg, struct nifti_1_header *hdr, int isPlanar);
int isDICOMfile(const char * fname); //0=not DICOM, 1=DICOM, 2=NOTSURE(not part 10 compliant)
void setQSForm(struct nifti_1_header *h, mat44 Q44i, bool isVerbose);
int headerDcm2Nii2(struct TDICOMdata d, struct TDICOMdata d2, struct nifti_1_header *h, int isVerbose);
int headerDcm2Nii(struct TDICOMdata d, struct nifti_1_header *h, bool isComputeSForm) ;
unsigned char * nii_loadImgXL(char* imgname, struct nifti_1_header *hdr, struct TDICOMdata dcm, bool iVaries, int compressFlag, int isVerbose);
unsigned char * nii_loadImgXL(char* imgname, struct nifti_1_header *hdr, struct TDICOMdata dcm, bool iVaries, int compressFlag, int isVerbose, struct TDTI4D *dti4D);
#ifdef __cplusplus
}
#endif
......
This diff is collapsed.
......@@ -28,7 +28,8 @@ extern "C" {
bool isSave3D,isGz, isFlipY, isCreateBIDS, isSortDTIbyBVal, isAnonymizeBIDS, isOnlyBIDS, isCreateText, isIgnoreDerivedAnd2D, isPhilipsFloatNotDisplayScaling, isTiltCorrect, isRGBplanar, isOnlySingleFile, isForceStackSameSeries, isCrop;
int isVerbose, compressFlag, gzLevel; //support for compressed data 0=none,
char filename[512], outdir[512], indir[512], pigzname[512], optsname[512], indirParent[512], imageComments[24];
long seriesNumber[MAX_NUM_SERIES], numSeries;
float seriesNumber[MAX_NUM_SERIES];
long numSeries;
#ifdef HAVE_R
bool isScanOnly;
void *imageList;
......
......@@ -598,7 +598,7 @@ NJ_INLINE void njDecodeDHT(void) {
remain -= currcnt << (16 - codelen);
if (remain < 0) njThrow(NJ_SYNTAX_ERROR);
for (i = 0; i < currcnt; ++i) {
register unsigned char code = nj.pos[i];
unsigned char code = nj.pos[i];
for (j = spread; j; --j) {
vlc->bits = (unsigned char) codelen;
vlc->code = code;
......@@ -840,9 +840,9 @@ NJ_INLINE void njConvert(void) {
const unsigned char *pcr = nj.comp[2].pixels;
for (yy = nj.height; yy; --yy) {
for (x = 0; x < nj.width; ++x) {
register int y = py[x] << 8;
register int cb = pcb[x] - 128;
register int cr = pcr[x] - 128;
int y = py[x] << 8;
int cb = pcb[x] - 128;
int cr = pcr[x] - 128;
*prgb++ = njClip((y + 359 * cr + 128) >> 8);
*prgb++ = njClip((y - 88 * cb - 183 * cr + 128) >> 8);
*prgb++ = njClip((y + 454 * cb + 128) >> 8);
......
dcm2niix (1.0.20180328-1) UNRELEASED; urgency=medium
* Team upload.
* New upstream version
* Point Vcs fields to salsa.debian.org
* Standards-Version: 4.1.4
-- Andreas Tille <tille@debian.org> Mon, 28 May 2018 22:29:21 +0200
dcm2niix (1.0.20171215-1) unstable; urgency=medium
* Ensure tags are signed
......
......@@ -11,9 +11,9 @@ Build-Depends: cmake,
pkg-config,
python3-sphinx,
zlib1g-dev
Standards-Version: 4.1.3
Vcs-Browser: https://anonscm.debian.org/cgit/debian-med/dcm2niix.git
Vcs-Git: https://anonscm.debian.org/git/debian-med/dcm2niix.git
Standards-Version: 4.1.4
Vcs-Browser: https://salsa.debian.org/med-team/dcm2niix
Vcs-Git: https://salsa.debian.org/med-team/dcm2niix.git
Homepage: https://github.com/rordenlab/dcm2niix
Package: dcm2niix
......