Skip to content

Commit

Permalink
Siemens series instance UID issues (#394)
Browse files Browse the repository at this point in the history
  • Loading branch information
neurolabusc committed Nov 6, 2024
1 parent b3605c4 commit 29c224b
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 10 deletions.
17 changes: 13 additions & 4 deletions console/nii_dicom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4838,6 +4838,7 @@ struct TDICOMdata readDICOMx(char *fname, struct TDCMprefs *prefs, struct TDTI4D
// philDTI[i].V[0] = -1;
// array for storing DimensionIndexValues
int numDimensionIndexValues = 0;
bool isSiemensXA = false;
//don't use stack! TDCMdim dcmDim[kMaxSlice2D];
TDCMdim *dcmDim = (TDCMdim *)malloc(kMaxSlice2D * sizeof(TDCMdim));
for (int i = 0; i < kMaxSlice2D; i++) {
Expand Down Expand Up @@ -5818,6 +5819,8 @@ struct TDICOMdata readDICOMx(char *fname, struct TDCMprefs *prefs, struct TDTI4D
case kSoftwareVersions: {
dcmStr(lLength, &buffer[lPos], d.softwareVersions);
int slen = (int)strlen(d.softwareVersions);
if ((slen > 4) && (strstr(d.softwareVersions, "XA10") != NULL))
d.isXA10A = true;
if ((slen > 4) && (strstr(d.softwareVersions, "XA11") != NULL))
d.isXA10A = true;
if ((slen > 4) && (strstr(d.softwareVersions, "XA20") != NULL))
Expand All @@ -5826,9 +5829,15 @@ struct TDICOMdata readDICOMx(char *fname, struct TDCMprefs *prefs, struct TDTI4D
d.isXA10A = true;
if ((slen > 4) && (strstr(d.softwareVersions, "XA31") != NULL))
d.isXA10A = true;
if ((slen < 5) || (strstr(d.softwareVersions, "XA10") == NULL))
break;
d.isXA10A = true;
//isXA10A is designed to catch early Siemens bugs, while isSiemensXA also detect modern XA
if (d.isXA10A)
isSiemensXA = true;
if ((slen > 4) && (strstr(d.softwareVersions, "XA5") != NULL))
isSiemensXA = true; //XA50/XA51
if ((slen > 4) && (strstr(d.softwareVersions, "XA6") != NULL))
isSiemensXA = true; //XA60
if ((slen > 4) && (strstr(d.softwareVersions, "XA7") != NULL))
isSiemensXA = true; //XA70
break;
}
case kProtocolName: {
Expand Down Expand Up @@ -8265,7 +8274,7 @@ struct TDICOMdata readDICOMx(char *fname, struct TDCMprefs *prefs, struct TDTI4D
if (d.phaseNumber > 0) // Philips TurboQUASAR set this uniquely for each slice
d.triggerDelayTime = 0.0;
// printf("%d\t%g\t%g\t%g\n", d.imageNum, d.acquisitionTime, d.triggerDelayTime, MRImageDynamicScanBeginTime);
if ((d.manufacturer == kMANUFACTURER_SIEMENS) && (strlen(seriesTimeTxt) > 1) && (d.isXA10A) && (d.xyzDim[3] == 1) && (d.xyzDim[4] < 2)) {
if ((d.manufacturer == kMANUFACTURER_SIEMENS) && (strlen(seriesTimeTxt) > 1) && (isSiemensXA) && (d.xyzDim[3] == 1) && (d.xyzDim[4] < 2)) {
// printWarning(">>Ignoring series number of XA data saved as classic DICOM (issue 394)\n");
d.isStackableSeries = true;
d.imageNum += (d.seriesNum * 1000);
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.20241025"
#define kDCMdate "v1.0.20241106"
#define kDCMvers kDCMdate " " kJP2suf kLSsuf kCCsuf kCPUsuf

static const int kMaxEPI3D = 1024; // maximum number of EPI images in Siemens Mosaic
Expand Down
17 changes: 12 additions & 5 deletions console/nii_dicom_batch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2611,6 +2611,10 @@ int *nii_saveDTI(char pathoutname[], int nConvert, struct TDCMsort dcmSort[], st
if (isnan(dcmList[indx0].patientPosition[1]))
return NULL; // issue606 do not save bvec for non-spatial data (e.g. physio)
int numDti = dcmList[indx0].CSA.numDti;
if ((numDti > nConvert) && (numDti > kMaxSlice2D)) {
printError("nii_saveDTI unable to save vectors.\n");
return NULL;
}
#ifdef USING_R
ImageList *images = (ImageList *)opts.imageList;
#endif
Expand Down Expand Up @@ -2674,15 +2678,16 @@ int *nii_saveDTI(char pathoutname[], int nConvert, struct TDCMsort dcmSort[], st
TDTI *vx = NULL;
if (numDti > 1) {
vx = (TDTI *)malloc(numDti * sizeof(TDTI));
for (int i = 0; i < numDti; i++) // for each direction
for (int v = 0; v < 4; v++) // for each vector+B-value
for (int i = 0; i < numDti; i++) {// for each direction
for (int v = 0; v < 4; v++) // for each vector+B-value
vx[i].V[v] = dti4D->S[i].V[v];
}
} else { // if (numDti == 1) {//extract DTI from different slices
vx = (TDTI *)malloc(nConvert * sizeof(TDTI));
numDti = 0;
for (int i = 0; i < nConvert; i++) { // for each image
if ((dcmList[indx0].CSA.mosaicSlices > 1) || (isSamePosition(dcmList[indx0], dcmList[dcmSort[i].indx]))) {
// if (numDti < kMaxDTIv)
int idx = dcmSort[i].indx;
for (int v = 0; v < 4; v++) // for each vector+B-value
vx[numDti].V[v] = dcmList[dcmSort[i].indx].CSA.dtiV[v]; // dcmList[indx0].CSA.dtiV[numDti][v] = dcmList[dcmSort[i].indx].CSA.dtiV[0][v];
numDti++;
Expand Down Expand Up @@ -6696,6 +6701,10 @@ void sliceTimingXA(struct TDCMsort *dcmSort, struct TDICOMdata *dcmList, struct
uint64_t indx0 = dcmSort[0].indx; // first volume
if ((!dcmList[indx0].isXA10A) || (hdr->dim[3] < 1) || (hdr->dim[4] < 1))
return;
if (hdr->dim[3] > kMaxEPI3D) {
printWarning("Unable to set Siemens XA sliceTiming due to excessive slices per volume (%d).\n", hdr->dim[3]);
return;
}
if ((nConvert == (hdr->dim[3] * hdr->dim[4])) && (hdr->dim[3] < (kMaxEPI3D - 1)) && (hdr->dim[3] > 1)) {
// issue875 use 2nd volume
int offset = 0;
Expand Down Expand Up @@ -8081,7 +8090,6 @@ int saveDcm2NiiCore(int nConvert, struct TDCMsort dcmSort[], struct TDICOMdata d
#ifdef USING_DCM2NIIXFSWRAPPER
printMessage("load Image %s\n", nameList->str[indx]);
#endif

// printMessage(" %d %d %d %d %lu\n", hdr0.dim[1], hdr0.dim[2], hdr0.dim[3], hdr0.dim[4], (unsigned long)[imgM length]);
bool isHasOverlay = dcmList[indx0].isHasOverlay;
bool isDerived = dcmList[indx0].isDerived;
Expand Down Expand Up @@ -8465,7 +8473,6 @@ int saveDcm2NiiCore(int nConvert, struct TDCMsort dcmSort[], struct TDICOMdata d
checkDateTimeOrder(&dcmList[dcmSort[0].indx], &dcmList[dcmSort[nConvert - 1].indx]);
}
bool ok = setBids(&dcmList[indx0], nameList->str[dcmSort[0].indx], nConvert, opts.isVerbose);

if (opts.isIgnoreDerivedAnd2D && !ok) {
printMessage("Ignoring derived image(s) of series %ld %s\n", dcmList[indx].seriesNum, nameList->str[indx]);
return EXIT_SUCCESS;
Expand Down

0 comments on commit 29c224b

Please sign in to comment.