Skip to content

Commit

Permalink
Update dcm_qa_nih submodule.
Browse files Browse the repository at this point in the history
  • Loading branch information
neurolabusc committed Oct 27, 2018
1 parent da860f1 commit c014f25
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 13 deletions.
7 changes: 3 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,16 +74,15 @@ If you have any problems with the cmake build script described above or want to

## Alternatives

- [Valerio Luccio's dinifti](http://cbi.nyu.edu/software/dinifti.php) is focused on conversion of Siemens data.
- [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).
- [DWIConvert](https://github.com/BRAINSia/BRAINSTools/tree/master/DWIConvert) converts DICOM images to NRRD and NIfTI 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.
- [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.
- [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

Expand Down
29 changes: 29 additions & 0 deletions console/nii_dicom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -819,6 +819,26 @@ struct TDICOMdata clear_dicom_data() {
return d;
} //clear_dicom_data()

int isdigitdot(int c) { //returns true if digit or '.'
if (c == '.') return 1;
return isdigit(c);
}

void dcmStrDigitsDotOnlyKey(char key, char* lStr) {
//e.g. string "F:2.50" returns 2.50 if key==":"
size_t len = strlen(lStr);
if (len < 1) return;
bool isKey = false;
for (int i = 0; i < (int) len; i++) {
if (!isdigitdot(lStr[i]) ) {
isKey = (lStr[i] == key);
lStr[i] = ' ';

} else if (!isKey)
lStr[i] = ' ';
}
} //dcmStrDigitsOnlyKey()

void dcmStrDigitsOnlyKey(char key, char* lStr) {
//e.g. string "p2s3" returns 2 if key=="p" and 3 if key=="s"
size_t len = strlen(lStr);
Expand Down Expand Up @@ -3966,6 +3986,7 @@ const uint32_t kEffectiveTE = 0x0018+ (0x9082 << 16);
#define kPETImageIndex 0x0054+(0x1330<< 16 )
#define kPEDirectionDisplayedUIH 0x0065+(0x1005<< 16 )//SH
#define kDiffusion_bValueUIH 0x0065+(0x1009<< 16 ) //FD
#define kParallelInformationUIH 0x0065+(0x100D<< 16 ) //SH
#define kNumberOfImagesInGridUIH 0x0065+(0x1050<< 16 ) //DS
#define kMRVFrameSequenceUIH 0x0065+(0x1050<< 16 ) //SQ
#define kDiffusionGradientDirectionUIH 0x0065+(0x1037<< 16 ) //FD
Expand Down Expand Up @@ -4889,6 +4910,14 @@ double TE = 0.0; //most recent echo time recorded
d.CSA.numDti = 1;
//printf("%d>>>%g\n", lPos, v[0]);
break; }
case kParallelInformationUIH: {//SENSE factor (0065,100d) SH [F:2S]
if (d.manufacturer != kMANUFACTURER_UIH) break;
char accelStr[kDICOMStr];
dcmStr (lLength, &buffer[lPos], accelStr);
char *ptr;
dcmStrDigitsDotOnlyKey(':', accelStr); //e.g. if "p2s4" return "2", if "s4" return ""
d.accelFactPE = atof(accelStr);
break; }
case kNumberOfImagesInGridUIH :
if (d.manufacturer != kMANUFACTURER_UIH) break;
d.numberOfImagesInGridUIH = dcmStrFloat(lLength, &buffer[lPos]);
Expand Down
19 changes: 10 additions & 9 deletions console/nii_dicom_batch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -980,15 +980,16 @@ void nii_SaveBIDS(char pathoutname[], struct TDICOMdata d, struct TDCMopts opts,
json_Str(fp, "\t\"ReceiveCoilActiveElements\": \"%s\",\n", d.coilElements);
if (strcmp(d.coilElements,d.coilName) != 0)
json_Str(fp, "\t\"CoilString\": \"%s\",\n", d.coilName);
if ((d.phaseEncodingLines > d.echoTrainLength) && (d.echoTrainLength > 1)) {
//ETL is > 1, as some GE files list 1, as an example see series mr_0005 in dcm_qa_nih
float pf = (float)d.phaseEncodingLines;
if (d.accelFactPE > 1)
pf = (float)pf / (float)d.accelFactPE; //estimate: not sure if we round up or down
pf = (float)d.echoTrainLength / (float)pf;
if (pf < 1.0) //e.g. if difference between lines and echo length not all explained by iPAT (SENSE/GRAPPA)
fprintf(fp, "\t\"PartialFourier\": %g,\n", pf);
if ((!d.is3DAcq) && (d.phaseEncodingLines > d.echoTrainLength) && (d.echoTrainLength > 1)) {
//ETL is > 1, as some GE files list 1, as an example see series mr_0005 in dcm_qa_nih
float pf = (float)d.phaseEncodingLines;
if (d.accelFactPE > 1)
pf = (float)pf / (float)d.accelFactPE; //estimate: not sure if we round up or down
pf = (float)d.echoTrainLength / (float)pf;
if (pf < 1.0) //e.g. if difference between lines and echo length not all explained by iPAT (SENSE/GRAPPA)
fprintf(fp, "\t\"PartialFourier\": %g,\n", pf);
} //compute partial Fourier: not reported in XA10, so infer
//printf("PhaseLines=%d EchoTrainLength=%d SENSE=%g\n", d.phaseEncodingLines, d.echoTrainLength, d.accelFactPE); //n.b. we can not distinguish pF from SENSE/GRAPPA for UIH
}
#endif
if (d.CSA.multiBandFactor > 1) //AccelFactorSlice
Expand Down Expand Up @@ -1018,7 +1019,7 @@ void nii_SaveBIDS(char pathoutname[], struct TDICOMdata d, struct TDCMopts opts,
if (bandwidthPerPixelPhaseEncode == 0.0)
bandwidthPerPixelPhaseEncode = d.CSA.bandwidthPerPixelPhaseEncode;
json_Float(fp, "\t\"BandwidthPerPixelPhaseEncode\": %g,\n", bandwidthPerPixelPhaseEncode );
if (d.accelFactPE > 1.0) fprintf(fp, "\t\"ParallelReductionFactorInPlane\": %g,\n", d.accelFactPE);
if ((!d.is3DAcq) && (d.accelFactPE > 1.0)) fprintf(fp, "\t\"ParallelReductionFactorInPlane\": %g,\n", d.accelFactPE);
//EffectiveEchoSpacing
// Siemens bandwidthPerPixelPhaseEncode already accounts for the effects of parallel imaging,
// interpolation, phaseOversampling, and phaseResolution, in the context of the size of the
Expand Down

0 comments on commit c014f25

Please sign in to comment.