Skip to content

Commit

Permalink
GEIIS icons and Bruker diffusion (#760; #761)
Browse files Browse the repository at this point in the history
  • Loading branch information
neurolabusc committed Oct 5, 2023
1 parent c5caaa9 commit 808985e
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 8 deletions.
22 changes: 20 additions & 2 deletions console/nii_dicom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4340,6 +4340,7 @@ struct TDICOMdata readDICOMx(char *fname, struct TDCMprefs *prefs, struct TDTI4D
#define kReferencedImageEvidenceSQ (uint32_t)0x0008 + (0x9092 << 16)
#define kComplexImageComponent (uint32_t)0x0008 + (0x9208 << 16) //'0008' '9208' 'CS' 'ComplexImageComponent'
#define kAcquisitionContrast (uint32_t)0x0008 + (0x9209 << 16) //'0008' '9209' 'CS' 'AcquisitionContrast'
#define kIconSQ 0x0009 + (0x1110 << 16)
#define kPatientName 0x0010 + (0x0010 << 16)
#define kPatientID 0x0010 + (0x0020 << 16)
#define kAccessionNumber 0x0008 + (0x0050 << 16)
Expand Down Expand Up @@ -5557,6 +5558,13 @@ const uint32_t kEffectiveTE = 0x0018 + uint32_t(0x9082 << 16); //FD
if (strlen(d.studyTime) < 2)
dcmStr(lLength, &buffer[lPos], d.studyTime);
break;
case kIconSQ: {//issue760 GEIIS icon strikes again
if ((vr[0] != 'S') || (vr[1] != 'Q') || (lLength != 8)) break; //only risk kludge for explicit VR with length
isIconImageSequence = true;
if (sqDepthIcon < 0)
sqDepthIcon = sqDepth;
break;
}
case kPatientName:
dcmStr(lLength, &buffer[lPos], d.patientName);
break;
Expand Down Expand Up @@ -7711,7 +7719,7 @@ const uint32_t kEffectiveTE = 0x0018 + uint32_t(0x9082 << 16); //FD
qsort(objects, numberOfFrames, sizeof(struct fidx), fcmp);
numDimensionIndexValues = numberOfFrames;
for (int i = 0; i < numberOfFrames; i++) {
// printf("%d > %g\n", objects[i].index, objects[i].value);
//printf("%d > %g\n", objects[i].index, objects[i].value);
dcmDim[objects[i].index].dimIdx[0] = i;
}
for (int i = 0; i < 4; i++) {
Expand Down Expand Up @@ -7830,7 +7838,10 @@ const uint32_t kEffectiveTE = 0x0018 + uint32_t(0x9082 << 16); //FD
if (dti4D->intenScalePhilips[i] != dti4D->intenScalePhilips[0])
d.isScaleVariesEnh = true;
}
if (!(d.manufacturer == kMANUFACTURER_BRUKER && d.isDiffusion) && (d.xyzDim[4] > 1) && (d.xyzDim[4] < kMaxDTI4D)) { //record variations in TE
//Revert Bruker change as new Bruker data uses DimensionIndexValues 0020,9157 for diffusion vectors
// https://github.com/rordenlab/dcm2niix/commit/8207877de984dab59e0374906c7ad212756f85a6#diff-120bb215d28dcbddeca8ea56dbb97e237501901ac2dfa1fbe4182282a8dd2b75
//if (!(d.manufacturer == kMANUFACTURER_BRUKER && d.isDiffusion) && (d.xyzDim[4] > 1) && (d.xyzDim[4] < kMaxDTI4D)) { //record variations in TE
if ((d.xyzDim[4] > 1) && (d.xyzDim[4] < kMaxDTI4D)) { //record variations in TE
d.isScaleOrTEVaries = false;
bool isTEvaries = false;
bool isScaleVaries = false;
Expand Down Expand Up @@ -8121,6 +8132,13 @@ const uint32_t kEffectiveTE = 0x0018 + uint32_t(0x9082 << 16); //FD
d.rawDataRunNumber = philMRImageDiffVolumeNumber;
d.phaseNumber = 0;
}
// Phase encoding polarity
//next conditionals updated: make GE match Siemens
// it also rescues Siemens XA20 images without CSA header but with 0021,111C
if (d.phaseEncodingGE == kGE_PHASE_ENCODING_POLARITY_UNFLIPPED)
d.CSA.phaseEncodingDirectionPositive = 1;
if (d.phaseEncodingGE == kGE_PHASE_ENCODING_POLARITY_FLIPPED)
d.CSA.phaseEncodingDirectionPositive = 0;
//issue 668: several SAR levels for different regions (IEC_HEAD, IEC_LOCAL, etc)
d.SAR = fmax(maxSAR, d.SAR);
// d.rawDataRunNumber = (d.rawDataRunNumber > d.phaseNumber) ? d.rawDataRunNumber : d.phaseNumber; //will not work: conflict for MultiPhase ASL with multiple averages
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.20230904"
#define kDCMdate "v1.0.20231005"
#define kDCMvers kDCMdate " " kJP2suf kLSsuf kCCsuf kCPUsuf

static const int kMaxEPI3D = 1024; //maximum number of EPI images in Siemens Mosaic
Expand Down
21 changes: 16 additions & 5 deletions console/nii_dicom_batch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2094,16 +2094,20 @@ tse3d: T2*/
if ((d.manufacturer == kMANUFACTURER_SIEMENS) && (d.dwellTime > 0))
fprintf(fp, "\t\"DwellTime\": %g,\n", d.dwellTime * 1E-9);
// Phase encoding polarity
/*
following logic now occurs earlier to aid bids guess
int phPos = d.CSA.phaseEncodingDirectionPositive;
//next two conditionals updated: make GE match Siemens
if (d.phaseEncodingGE == kGE_PHASE_ENCODING_POLARITY_UNFLIPPED)
phPos = 1;
if (d.phaseEncodingGE == kGE_PHASE_ENCODING_POLARITY_FLIPPED)
phPos = 0;
*/
//if ((phPos >= 0) && (d.phaseEncodingRC == 'R') && (d.manufacturer == kMANUFACTURER_UIH)) phPos = 1 - phPos; //issue410
bool isSkipPhaseEncodingAxis = d.is3DAcq;
if (d.echoTrainLength > 1)
isSkipPhaseEncodingAxis = false; //issue 371: ignore phaseEncoding for 3D MP-RAGE/SPACE, but report for 3D EPI
int phPos = d.CSA.phaseEncodingDirectionPositive;
if (((d.phaseEncodingRC == 'R') || (d.phaseEncodingRC == 'C')) && (!isSkipPhaseEncodingAxis) && (phPos < 0)) {
//when phase encoding axis is known but we do not know phase encoding polarity
// https://github.com/rordenlab/dcm2niix/issues/163
Expand Down Expand Up @@ -6661,15 +6665,16 @@ void setBidsSiemens(struct TDICOMdata *d, int nConvert, int isVerbose, const cha
}
//add dir
//nb for func dir comes before echo
int phPos = d->CSA.phaseEncodingDirectionPositive;
if (isDirLabel) {
char dirLabel[kDICOMStrLarge] = "_dir-";
if (d->phaseEncodingRC == 'C') {
if (d->CSA.phaseEncodingDirectionPositive)
if (phPos)
strcat(dirLabel, "AP");
else
strcat(dirLabel, "PA");
} else {
if (d->CSA.phaseEncodingDirectionPositive)
if (phPos)
strcat(dirLabel, "RL");
else
strcat(dirLabel, "LR");
Expand Down Expand Up @@ -6783,11 +6788,17 @@ void setBidsPhilips(struct TDICOMdata *d, int nConvert, int isVerbose) {
else
strcpy(modalityBIDS, "magnitude");
} else if ((strstr(seqName, "SP") != NULL) && (strstr(d->scanningSequence, "GR") != NULL)) {
//issue 753 need to distinguish different types of phase map see Levitas example B0_DTI_MED_RES
// https://bids-specification.readthedocs.io/en/stable/04-modality-specific-files/01-magnetic-resonance-imaging-data.html#case-3-direct-field-mapping
printWarning("Unable to distinguish Philips fieldmaps: phase difference, two phase/magnitude, direct fieldmapping.");
isReportEcho = false;
strcpy(dataTypeBIDS, "fmap");
strcpy(modalityBIDS, "phasediff");
if (d->isHasPhase)
strcpy(modalityBIDS, "phasediff");
else if (d->echoTrainLength < 2)
snprintf(modalityBIDS, kDICOMStrLarge - strlen(modalityBIDS), "magnitude%d", d->echoNum);

if (d->echoTrainLength > 1) {
isReportEcho = false;
if (d->isHasPhase)
snprintf(modalityBIDS, kDICOMStrLarge - strlen(modalityBIDS), "phase%d", d->echoNum);
else if (d->isHasImaginary)
Expand Down Expand Up @@ -6853,7 +6864,7 @@ void setBidsPhilips(struct TDICOMdata *d, int nConvert, int isVerbose) {
strcat(suffixBIDS,modalityBIDS);
}
//if ((isVerbose > 0) || (strlen(dataTypeBIDS) < 1))
if (isVerbose > 0)
//if (isVerbose > 0)
printf("::autoBids:Philips pulseSeq:'%s' scanSeq:'%s' seqVariant:'%s'\n",
d->pulseSequenceName, d->scanningSequence, d->sequenceVariant);
if (isDerived)
Expand Down

0 comments on commit 808985e

Please sign in to comment.