From 1bde92bf35fbeca2d6b7a0902eebc877f1f9e1b2 Mon Sep 17 00:00:00 2001 From: Chris Rorden Date: Fri, 17 May 2019 09:14:27 +0200 Subject: [PATCH] Update tinydir call (https://github.com/rordenlab/dcm2niix/pull/298) --- README.md | 4 +++- console/nii_dicom_batch.cpp | 44 +++++++++++++++++++++++-------------- 2 files changed, 30 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 314e814c..378d048c 100644 --- a/README.md +++ b/README.md @@ -100,6 +100,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. @@ -126,4 +127,5 @@ The following tools exploit dcm2niix - [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. \ No newline at end of file + - 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). diff --git a/console/nii_dicom_batch.cpp b/console/nii_dicom_batch.cpp index 2b312f62..41cbd690 100644 --- a/console/nii_dicom_batch.cpp +++ b/console/nii_dicom_batch.cpp @@ -2542,7 +2542,7 @@ void writeNiiGz (char * baseName, struct nifti_1_header hdr, unsigned char* src int nii_saveNII (char *niiFilename, struct nifti_1_header hdr, unsigned char *im, struct TDCMopts opts, struct TDICOMdata d) { hdr.vox_offset = 352; - + // Extract the basename from the full file path char *start = niiFilename + strlen(niiFilename); while (start >= niiFilename && *start != '/' && *start != kPathSeparator) @@ -2633,7 +2633,7 @@ void nii_saveAttributes (struct TDICOMdata &data, struct nifti_1_header &header, images->addAttribute("phaseEncodingSteps", data.phaseEncodingSteps); if (data.phaseEncodingLines > 0) images->addAttribute("phaseEncodingLines", data.phaseEncodingLines); - + // Calculations relating to the reconstruction in the phase encode direction, // which are needed to derive effective echo spacing and readout time below. // See the nii_SaveBIDS() function for details @@ -2646,7 +2646,7 @@ void nii_saveAttributes (struct TDICOMdata &data, struct nifti_1_header &header, else if (data.phaseEncodingRC =='C') reconMatrixPE = header.dim[1]; } - + double bandwidthPerPixelPhaseEncode = data.bandwidthPerPixelPhaseEncode; if (bandwidthPerPixelPhaseEncode == 0.0) bandwidthPerPixelPhaseEncode = data.CSA.bandwidthPerPixelPhaseEncode; @@ -2655,7 +2655,7 @@ void nii_saveAttributes (struct TDICOMdata &data, struct nifti_1_header &header, effectiveEchoSpacing = 1.0 / (bandwidthPerPixelPhaseEncode * reconMatrixPE); if (data.effectiveEchoSpacingGE > 0.0) effectiveEchoSpacing = data.effectiveEchoSpacingGE / 1000000.0; - + if (effectiveEchoSpacing > 0.0) images->addAttribute("effectiveEchoSpacing", effectiveEchoSpacing); if ((reconMatrixPE > 0) && (effectiveEchoSpacing > 0.0)) @@ -2664,7 +2664,7 @@ void nii_saveAttributes (struct TDICOMdata &data, struct nifti_1_header &header, images->addAttribute("pixelBandwidth", data.pixelBandwidth); if ((data.manufacturer == kMANUFACTURER_SIEMENS) && (data.dwellTime > 0)) images->addAttribute("dwellTime", data.dwellTime * 1e-9); - + // Phase encoding polarity // We only save these attributes if both direction and polarity are known if (((data.phaseEncodingRC == 'R') || (data.phaseEncodingRC == 'C')) && (!data.is3DAcq) && ((data.CSA.phaseEncodingDirectionPositive == 1) || (data.CSA.phaseEncodingDirectionPositive == 0))) { @@ -2679,7 +2679,7 @@ void nii_saveAttributes (struct TDICOMdata &data, struct nifti_1_header &header, images->addAttribute("phaseEncodingSign", data.CSA.phaseEncodingDirectionPositive == 0 ? -1 : 1); } } - + // Slice timing if (data.CSA.sliceTiming[0] >= 0.0 && (data.manufacturer == kMANUFACTURER_UIH || data.manufacturer == kMANUFACTURER_GE || (data.manufacturer == kMANUFACTURER_SIEMENS && !data.isXA10A))) { std::vector sliceTimes; @@ -2699,7 +2699,7 @@ void nii_saveAttributes (struct TDICOMdata &data, struct nifti_1_header &header, } images->addAttribute("sliceTiming", sliceTimes); } - + if (strlen(data.patientID) > 0) images->addAttribute("patientIdentifier", data.patientID); if (strlen(data.patientName) > 0) @@ -5334,7 +5334,7 @@ int searchDirRenameDICOM(char *path, int maxDepth, int depth, struct TDCMopts* o int count = 0; if (tinydir_open_sorted(&dir, path) != 0) return -1; - + for (size_t i=0; i 1) dcm.isMultiEcho = true; nii_createFilename(dcm, outname, *opts); - + // If the file name part of the target path has no extension, add ".dcm" std::string targetPath(outname); std::string targetStem, targetExtension; @@ -5377,7 +5377,7 @@ int searchDirRenameDICOM(char *path, int maxDepth, int depth, struct TDCMopts* o targetStem = targetPath.substr(0, periodLoc); targetExtension = targetPath.substr(periodLoc); } - + // Deduplicate the target path to avoid overwriting existing files targetPath = targetStem + targetExtension; GetRNGstate(); @@ -5388,7 +5388,7 @@ int searchDirRenameDICOM(char *path, int maxDepth, int depth, struct TDCMopts* o targetPath = targetStem + "_" + suffix.str() + targetExtension; } PutRNGstate(); - + // Copy the file, unless the source and target paths are the same if (targetPath.compare(sourcePath) == 0) { if (opts->isVerbose > 1) @@ -5413,13 +5413,23 @@ int searchDirRenameDICOM(char *path, int maxDepth, int depth, struct TDCMopts* o int searchDirRenameDICOM(char *path, int maxDepth, int depth, struct TDCMopts* opts ) { int retAll = 0; - //bool isDcmExt = isExt(opts->filename, ".dcm"); // "%r.dcm" with multi-echo should generate "1.dcm", "1e2.dcm" tinydir_dir dir; - tinydir_open(&dir, path); - while (dir.has_next) { - tinydir_file file; - file.is_dir = 0; //avoids compiler warning: this is set by tinydir_readfile - tinydir_readfile(&dir, &file); + int count = 0; + if (tinydir_open_sorted(&dir, path) != 0) { + if (opts->isVerbose > 0) + printMessage("Unable to open %s\n", path); + return -1; + } + if (dir.n_files < 1) { + if (opts->isVerbose > 0) + printMessage("No files in %s\n", path); + return 0; + } + if (opts->isVerbose > 0) + printMessage("Found %lu items in %s\n", dir.n_files, path); + for (size_t i=0; i