diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000..a69ea02e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,47 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** + +A clear and concise description of what the bug is. + +**To reproduce** + +Steps to reproduce the behavior: +1. Run the command 'dcm2niix ...' +2. See error ... + +**Expected behavior** + +A clear and concise description of what you expected to happen. + +**Output log** + +If applicable, output generated converting data. + +**Version** + +Please report the complete version string: + + - dcm2niix version string, e.g. `dcm2niiX version v1.0.20201207 Clang12.0.0 ARM (64-bit MacOS)` The version string is always the first line generated when dcm2niix is run. + +**Troubleshooting** + +Please try the following steps to resolve your issue: + + - Is this the [latest stable release](https://github.com/rordenlab/dcm2niix/releases)? If not, does the latest stable release resolve your issue? + - If the latest stable version fails, and you are using Windows. Does the latest commit on the development branch resolve your issue? You can get a pre-compiled version from [AppVeyor](https://ci.appveyor.com/project/neurolabusc/dcm2niix) (click on the Artifacts button). + - If the latest stable version fails, and you are using macOS or Linux. Does the latest commit on the development branch resolve your issue? You can build this using the recipe below: + +``` +git clone --branch development https://github.com/rordenlab/dcm2niix.git +cd dcm2niix/console +g++ -I. main_console.cpp nii_foreign.cpp nii_dicom.cpp jpg_0XC3.cpp ujpeg.cpp nifti1_io_core.cpp nii_ortho.cpp nii_dicom_batch.cpp -o dcm2niix -DmyDisableOpenJPEG +./dcm2niix .... +``` diff --git a/README.md b/README.md index 9da60861..d60443de 100644 --- a/README.md +++ b/README.md @@ -145,6 +145,8 @@ The following tools exploit dcm2niix - [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. - [boutiques-dcm2niix](https://github.com/lalet/boutiques-dcm2niix) is a dockerfile for installing and validating dcm2niix. + - [clinica](https://github.com/aramis-lab/clinica) is a software platform for clinical neuroimaging studies that uses dcm2niix to convert DICOM images. + - [clpipe](https://github.com/cohenlabUNC/clpipe) uses dcm2bids for DICOM import. - [conversion](https://github.com/pnlbwh/conversion) is a Python library 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. - [DAC2BIDS](https://github.com/dangom/dac2bids) uses dcm2niibatch to create [BIDS](http://bids.neuroimaging.io/) datasets. - [Dcm2Bids](https://github.com/cbedetti/Dcm2Bids) uses dcm2niix to create [BIDS](http://bids.neuroimaging.io/) datasets. Here is a [tutorial](https://andysbrainbook.readthedocs.io/en/latest/OpenScience/OS/BIDS_Overview.html) describing usage. @@ -152,10 +154,12 @@ The following tools exploit dcm2niix - [dcm2niixpy](https://github.com/Svdvoort/dcm2niixpy) Python package of dcm2niix. - [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. - [dcm2niiXL](https://github.com/neurolabusc/dcm2niiXL) is a shell script and tuned compilation of dcm2niix designed for accelerated conversion of extra large datasets. + - [dcmwrangle](https://github.com/jbteves/dcmwrangle) a Python interactive and static tool for organizing dicoms. + - [DeepDicomSort](https://github.com/Svdvoort/DeepDicomSort) can recognize different scan types. - [DICOM2BIDS](https://github.com/klsea/DICOM2BIDS) is a Python 2 script for creating BIDS files. - [dicom2bids](https://github.com/Jolinda/lcnimodules) includes python modules for converting dicom files to nifti in a bids-compatible file structure that use dcm2niix. - - [dcmwrangle](https://github.com/jbteves/dcmwrangle) a Python interactive and static tool for organizing dicoms. - [dicom2nifti_batch](https://github.com/scanUCLA/dicom2nifti_batch) is a Matlab script for automating dcm2niix. + - [DICOM-to-NIfTI-GUI](https://github.com/Zunairviqar/DICOM-to-NIfTI-GUI) is a Python script that provides a graphical wrapper for dcm2niix. - [divest](https://github.com/jonclayden/divest) R interface to dcm2niix. - [ExploreASL](https://sites.google.com/view/exploreasl/exploreasl) uses dcm2niix to import images. - [ezBIDS](https://github.com/brainlife/ezbids) is a [web service](https://brainlife.io/ezbids/) for converting directory full of DICOM images into BIDS without users having to learn python nor custom configuration file. @@ -183,6 +187,7 @@ The following tools exploit dcm2niix - [pydra-dcm2niix](https://github.com/nipype/pydra-dcm2niix) is a contains Pydra task interface for dcm2niix. - [qsm](https://github.com/CAIsr/qsm) Quantitative Susceptibility Mapping software. - [reproin](https://github.com/ReproNim/reproin) is a setup for automatic generation of shareable, version-controlled BIDS datasets from MR scanners. + - [Retina_OCT_dcm2nii](https://github.com/Choupan/Retina_OCT_dcm2nii) converts optical coherence tomography (OCT) data to NIfTI. - [sci-tran dcm2niix](https://github.com/scitran-apps/dcm2niix) Flywheel Gear (docker). - [shimming-toolbox](https://github.com/shimming-toolbox/shimming-toolbox) enabled static and real-time shimming, using dcm2niix to import DICOM data. - The [SlicerDcm2nii extension](https://github.com/Slicer/ExtensionsIndex/blob/master/SlicerDcm2nii.s4ext) is one method to import DICOM data into Slicer. diff --git a/console/nii_dicom.cpp b/console/nii_dicom.cpp index 75c1d472..04ba942b 100644 --- a/console/nii_dicom.cpp +++ b/console/nii_dicom.cpp @@ -781,7 +781,7 @@ struct TDICOMdata clear_dicom_data() { d.zSpacing = 0.0; d.zThick = 0.0; //~ d.numberOfDynamicScans = 0; - d.echoNum = 1; + d.echoNum = 0; d.echoTrainLength = 0; d.waterFatShift = 0.0; d.groupDelay = 0.0; @@ -2938,7 +2938,7 @@ unsigned char *nii_iVaries(unsigned char *img, struct nifti_1_header *hdr, struc free(img); //release previous image if ((dti4D != NULL) && (dti4D->intenScale[0] != 0.0)) { //enhanced dataset, intensity varies across slices of a single file if (dti4D->RWVScale[0] != 0.0) - printWarning("Intensity scale/slope using 0028,1053 and 0028,1052"); //to do: real-world values and precise values + printWarning("Intensity scale/slope using 0028,1053 and 0028,1052\n"); //to do: real-world values and precise values int dim1to2 = hdr->dim[1] * hdr->dim[2]; int slice = -1; //(0028,1052) SS = scale slope (2005,100E) RealWorldIntercept = (0040,9224) Real World Slope = (0040,9225) @@ -6259,6 +6259,7 @@ const uint32_t kEffectiveTE = 0x0018 + (0x9082 << 16); case kMRfMRIStatusIndicationPhilips: {//fmri volume number if (d.manufacturer != kMANUFACTURER_PHILIPS) break; + if (volumeNumber > 0) break; //issue567 int i = dcmInt(lLength, &buffer[lPos], d.isLittleEndian); if (i > 0) //only if positive value, see Magdeburg_2014 sample data from dcm_qa_philips Philips MR 51.0 volumeNumber = i; diff --git a/console/nii_dicom_batch.cpp b/console/nii_dicom_batch.cpp index 7b6a6958..fd4a6667 100644 --- a/console/nii_dicom_batch.cpp +++ b/console/nii_dicom_batch.cpp @@ -1441,7 +1441,7 @@ tse3d: T2*/ json_Float(fp, "\t\"SAR\": %g,\n", d.SAR); if (d.numberOfAverages > 1.0) json_Float(fp, "\t\"NumberOfAverages\": %g,\n", d.numberOfAverages); - if ((d.echoNum > 1) || (d.isMultiEcho)) + if ((d.echoNum > 1) || ((d.isMultiEcho) && (d.echoNum > 0))) fprintf(fp, "\t\"EchoNumber\": %d,\n", d.echoNum); if ((d.TE > 0.0) && (!d.isXRay)) fprintf(fp, "\t\"EchoTime\": %g,\n", d.TE / 1000.0); @@ -1871,7 +1871,7 @@ tse3d: T2*/ json_Float(fp, "\t\"EstimatedEffectiveEchoSpacing\": %g,\n", effectiveEchoSpacingPhil); fprintf(fp, "\t\"EstimatedTotalReadoutTime\": %g,\n", totalReadoutTime); } - if (d.effectiveEchoSpacingGE > 0.0) { + if ((d.effectiveEchoSpacingGE > 0.0) && (reconMatrixPE > 1) && (d.accelFactPE > 0.0)) { //TotalReadoutTime = [ ceil (PE_AcquisitionMatrix / Asset_R_factor) - 1] * ESP float roundFactor = 2.0; if (d.isPartialFourier) @@ -3168,11 +3168,14 @@ int nii_createFilename(struct TDICOMdata dcm, char *niiFilename, struct TDCMopts } // myMultiEchoFilenameSkipEcho1 https://github.com/rordenlab/dcm2niix/issues/237 #ifdef myMultiEchoFilenameSkipEcho1 - if ((isAddNamePostFixes) && (!isEchoReported) && (dcm.isMultiEcho) && (dcm.echoNum >= 1)) { //multiple echoes saved as same series + if ((isAddNamePostFixes) && (!isEchoReported) && (dcm.isMultiEcho)) { //multiple echoes saved as same series #else if ((isAddNamePostFixes) && (!isEchoReported) && ((dcm.isMultiEcho) || (dcm.echoNum > 1))) { //multiple echoes saved as same series #endif - sprintf(newstr, "_e%d", dcm.echoNum); + if ((dcm.echoNum < 1) && (dcm.TE > 0)) + sprintf(newstr, "_e%g", dcm.TE); //issue568: Siemens XA20 might omit echo number + else + sprintf(newstr, "_e%d", dcm.echoNum); strcat(outname, newstr); isEchoReported = true; } @@ -7522,8 +7525,12 @@ bool isSameSet(struct TDICOMdata d1, struct TDICOMdata d2, struct TDCMopts *opts if ((!(isSameFloat(d1.TE, d2.TE))) || (d1.echoNum != d2.echoNum)) { if ((!warnings->echoVaries) && (d1.isXRay)) //for CT/XRay we check DICOM tag 0018,1152 (XRayExposure) printMessage("Slices not stacked: X-Ray Exposure varies (exposure %g, %g; number %d, %d). Use 'merge 2D slices' option to force stacking\n", d1.TE, d2.TE, d1.echoNum, d2.echoNum); - if ((!warnings->echoVaries) && (!d1.isXRay)) //for MRI - printMessage("Slices not stacked: echo varies (TE %g, %g; echo %d, %d). Use 'merge 2D slices' option to force stacking\n", d1.TE, d2.TE, d1.echoNum, d2.echoNum); + if ((!warnings->echoVaries) && (!d1.isXRay)) {//for MRI + if (d1.echoNum == d2.echoNum) + printMessage("Slices not stacked: echo varies (TE %g, %g). No echo number (0018,0086; issue 568). Use 'merge 2D slices' option to force stacking\n", d1.TE, d2.TE); + else + printMessage("Slices not stacked: echo varies (TE %g, %g; echo %d, %d). Use 'merge 2D slices' option to force stacking\n", d1.TE, d2.TE, d1.echoNum, d2.echoNum); + } warnings->echoVaries = true; *isMultiEcho = true; return false;