Skip to content

Commit

Permalink
Siemens XA20 omits echo number (018,0086) (#568)
Browse files Browse the repository at this point in the history
  • Loading branch information
neurolabusc committed Dec 20, 2021
1 parent 06951ec commit 23d0875
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 9 deletions.
11 changes: 10 additions & 1 deletion console/nii_dicom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -777,7 +777,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;
Expand Down Expand Up @@ -4266,6 +4266,7 @@ const uint32_t kEffectiveTE = 0x0018 + (0x9082 << 16);
#define kSequenceVariant21 0x0021 + (0x105B << 16) //CS
#define kPATModeText 0x0021 + (0x1009 << 16) //LO, see kImaPATModeText
#define kTimeAfterStart 0x0021 + (0x1104 << 16) //DS
//#define kICE_Dims 0x0021 + (0x1106 << 16) //LO
#define kPhaseEncodingDirectionPositiveSiemens 0x0021 + (0x111C << 16) //IS
//#define kRealDwellTime 0x0021+(0x1142<< 16 )//IS
#define kBandwidthPerPixelPhaseEncode21 0x0021 + (0x1153 << 16) //FD
Expand Down Expand Up @@ -5772,6 +5773,14 @@ const uint32_t kEffectiveTE = 0x0018 + (0x9082 << 16);
//printf("x\t%d\t%g\tkTimeAfterStart\n", acquisitionTimesGE_UIH, d.CSA.sliceTiming[acquisitionTimesGE_UIH]);
acquisitionTimesGE_UIH++;
break;
/*case kICE_Dims: { //issue568 "X_4_1_1_1_1_160_1_1_1_1_1_277"
if (d.manufacturer != kMANUFACTURER_SIEMENS)
break;
char iceStr[kDICOMStr];
dcmStr(lLength, &buffer[lPos], iceStr);
printf("do something profound with %s\n", iceStr);
break;
}*/
case kPhaseEncodingDirectionPositiveSiemens: {
if (d.manufacturer != kMANUFACTURER_SIEMENS)
break;
Expand Down
2 changes: 1 addition & 1 deletion console/nii_dicom.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ extern "C" {
#define kCPUsuf " " //unknown CPU
#endif

#define kDCMdate "v1.0.20211215"
#define kDCMdate "v1.0.20211220"
#define kDCMvers kDCMdate " " kJP2suf kLSsuf kCCsuf kCPUsuf

static const int kMaxEPI3D = 1024; //maximum number of EPI images in Siemens Mosaic
Expand Down
21 changes: 14 additions & 7 deletions console/nii_dicom_batch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1398,7 +1398,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);
Expand Down Expand Up @@ -3107,11 +3107,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;
}
Expand Down Expand Up @@ -6277,8 +6280,8 @@ int saveDcm2NiiCore(int nConvert, struct TDCMsort dcmSort[], struct TDICOMdata d
nii_scale16bitUnsigned(imgM, &hdr0, opts.isVerbose); //allow UINT16 to use full dynamic range
} else if ((opts.isMaximize16BitRange == kMaximize16BitRange_False) && (hdr0.datatype == DT_UINT16) && (!dcmList[dcmSort[0].indx].isSigned))
nii_check16bitUnsigned(imgM, &hdr0, opts.isVerbose); //save UINT16 as INT16 if we can do this losslessly
if ((dcmList[dcmSort[0].indx].isXA10A) && (nConvert < 2))
printWarning("Siemens XA DICOM inadequate for robust conversion (issue 236)\n");
//if ((dcmList[dcmSort[0].indx].isXA10A) && (nConvert < 2)) //20211220: XA30 appears robust
// printWarning("Siemens XA DICOM inadequate for robust conversion (issue 236)\n");
if ((dcmList[dcmSort[0].indx].isXA10A) && (nConvert > 1))
printWarning("Siemens XA exported as classic not enhanced DICOM (issue 236)\n");
printMessage("Convert %d DICOM as %s (%dx%dx%dx%d)\n", nConvert, pathoutname, hdr0.dim[1], hdr0.dim[2], hdr0.dim[3], hdr0.dim[4]);
Expand Down Expand Up @@ -6803,8 +6806,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;
Expand Down

0 comments on commit 23d0875

Please sign in to comment.