diff --git a/console/nii_dicom.cpp b/console/nii_dicom.cpp index 76cf1940..ce470f84 100644 --- a/console/nii_dicom.cpp +++ b/console/nii_dicom.cpp @@ -1376,8 +1376,9 @@ struct TDICOMdata nii_readParRec (char * parname, int isVerbose, struct TDTI4D #define kYmm 29 #define kTEcho 30 #define kDynTime 31 -#define kGradientNumber 42 #define kbval 33 +#define kInversionDelayMs 40 +#define kGradientNumber 42 #define kv1 47 #define kv2 45 #define kv3 46 @@ -1387,6 +1388,8 @@ struct TDICOMdata nii_readParRec (char * parname, int isVerbose, struct TDTI4D float maxBValue = 0.0f; float maxDynTime = 0.0f; float minDynTime = 999999.0f; + int minDyn = 32767; + int maxDyn = 0; bool ADCwarning = false; int parVers = 0; int maxEcho = 1; @@ -1429,7 +1432,6 @@ struct TDICOMdata nii_readParRec (char * parname, int isVerbose, struct TDTI4D if (buff[0] == '.') { //tag char Comment[8][50]; sscanf(buff, ". %s %s %s %s %s %s %s %s\n", Comment[0], Comment[1],Comment[2], Comment[3], Comment[4], Comment[5], Comment[6], Comment[7]); - if ((strcmp(Comment[0], "Acquisition") == 0) && (strcmp(Comment[1], "nr") == 0)) { d.acquNum = atoi( Comment[3]); d.seriesNum = d.acquNum; @@ -1493,6 +1495,8 @@ struct TDICOMdata nii_readParRec (char * parname, int isVerbose, struct TDTI4D if (slice == 1) { //for (int i = 0; i < nCols; i++) // cols1[i] = cols[i]; //store first slice to see if dimensions or intensity scale varies between slices + //for (int i = 0; i < nCols; i++) + // printMessage("%d %g\n",i, cols[i]); //store first slice to see if dimensions or intensity scale varies between slices d.xyzDim[1] = (int) cols[kXdim]; d.xyzDim[2] = (int) cols[kYdim]; d.xyzMM[1] = cols[kXmm]; @@ -1506,6 +1510,7 @@ struct TDICOMdata nii_readParRec (char * parname, int isVerbose, struct TDTI4D d.angulation[3] = cols[kAngulationFHs]; d.sliceOrient = (int) cols[kSliceOrients]; d.TE = cols[kTEcho]; + d.TI = cols[kInversionDelayMs]; d.bitsAllocated = (int) cols[kBitsPerVoxel]; d.bitsStored = (int) cols[kBitsPerVoxel]; d.intenIntercept = cols[kRI]; @@ -1526,6 +1531,8 @@ struct TDICOMdata nii_readParRec (char * parname, int isVerbose, struct TDTI4D } if (cols[kImageType] == 0) d.isHasMagnitude = true; if (cols[kImageType] != 0) d.isHasPhase = true; + if (cols[kDyn] > maxDyn) maxDyn = (int) cols[kDyn]; + if (cols[kDyn] < minDyn) minDyn = (int) cols[kDyn]; if (cols[kDynTime] > maxDynTime) maxDynTime = cols[kDynTime]; if (cols[kDynTime] < minDynTime) minDynTime = cols[kDynTime]; if (cols[kEcho] > maxEcho) maxEcho = cols[kEcho]; @@ -1554,7 +1561,8 @@ struct TDICOMdata nii_readParRec (char * parname, int isVerbose, struct TDTI4D ADCwarning = true; }*/ //666: test (cols[kDyn] == 1) - if ((cols[kDyn] == 1) && (cols[kEcho] == 1) && (cols[kCardiac] == 1) && (cols[kSlice] == 1)) { //only first slice + //(cols[kImageType] == 0) means magnitude scan + if ((cols[kImageType] == 0) && (cols[kDyn] == 1) && (cols[kEcho] == 1) && (cols[kCardiac] == 1) && (cols[kSlice] == 1)) { //only first slice d.CSA.numDti++; int dir = d.CSA.numDti; if (dir <= kMaxDTI4D) { @@ -1671,8 +1679,10 @@ struct TDICOMdata nii_readParRec (char * parname, int isVerbose, struct TDTI4D printError("Unable to convert DTI [increase kMaxDTI4D]\n"); d.CSA.numDti = 0; }; - if ((maxBValue <= 0.0f) && (maxDynTime > minDynTime) && (d.CSA.numDti > 1)) { - float TRms = 1000.0f * (maxDynTime - minDynTime) / (float)(d.CSA.numDti-1); + if ((maxBValue <= 0.0f) && (maxDyn > minDyn) && (maxDynTime > minDynTime)) { //use max vs min Dyn instead of && (d.CSA.numDti > 1) + int numDyn = maxDyn - minDyn; + float TRms = 1000.0f * (maxDynTime - minDynTime) / (float)numDyn; + //float TRms = 1000.0f * (maxDynTime - minDynTime) / (float)(d.CSA.numDti-1); if (fabs(TRms - d.TR) > 0.005f) printWarning("Reported TR=%gms, measured TR=%gms (prospect. motion corr.?)\n", d.TR, TRms); d.TR = TRms; diff --git a/console/nii_dicom_batch.cpp b/console/nii_dicom_batch.cpp index 6d91f66b..9b2a7d38 100644 --- a/console/nii_dicom_batch.cpp +++ b/console/nii_dicom_batch.cpp @@ -535,6 +535,7 @@ void siemensCsaAscii(const char * filename, int csaOffset, int csaLength, float char keyStr[] = "### ASCCONV BEGIN"; //skip to start of ASCII often "### ASCCONV BEGIN ###" but also "### ASCCONV BEGIN object=MrProtDataImpl@MrProtocolData" char *keyPos = (char *)memmem(bufferTrim, csaLengthTrim, keyStr, strlen(keyStr)); if (keyPos) { + //We could detect multi-echo MPRAGE here, e.g. "lContrasts = 4"- but ideally we want an earlier detection csaLengthTrim -= (keyPos-bufferTrim); char keyStrEnd[] = "### ASCCONV END"; char *keyPosEnd = (char *)memmem(keyPos, csaLengthTrim, keyStrEnd, strlen(keyStrEnd)); @@ -2602,7 +2603,6 @@ TWarnings setWarnings() { bool isSameSet (struct TDICOMdata d1, struct TDICOMdata d2, struct TDCMopts* opts, struct TWarnings* warnings, bool *isMultiEcho) { //returns true if d1 and d2 should be stacked together as a single output - *isMultiEcho = false; if (!d1.isValid) return false; if (!d2.isValid) return false; if (d1.modality != d2.modality) return false; //do not stack MR and CT data! @@ -2965,13 +2965,14 @@ int nii_loadDir(struct TDCMopts* opts) { if ((dcmList[i].converted2NII == 0) && (dcmList[i].isValid)) { int nConvert = 0; struct TWarnings warnings = setWarnings(); - bool isMultiEcho; + bool isMultiEcho = false; for (int j = i; j < (int)nDcm; j++) if (isSameSet(dcmList[i], dcmList[j], opts, &warnings, &isMultiEcho ) ) nConvert++; if (nConvert < 1) nConvert = 1; //prevents compiler warning for next line: never executed since j=i always causes nConvert ++ TDCMsort * dcmSort = (TDCMsort *)malloc(nConvert * sizeof(TDCMsort)); nConvert = 0; + isMultiEcho = false; for (int j = i; j < (int)nDcm; j++) if (isSameSet(dcmList[i], dcmList[j], opts, &warnings, &isMultiEcho)) { dcmSort[nConvert].indx = j; @@ -2983,6 +2984,7 @@ int nii_loadDir(struct TDCMopts* opts) { dcmList[j].isMultiEcho = isMultiEcho; } qsort(dcmSort, nConvert, sizeof(struct TDCMsort), compareTDCMsort); //sort based on series and image numbers.... + //dcmList[dcmSort[0].indx].isMultiEcho = isMultiEcho; if (opts->isVerbose) nConvert = removeDuplicatesVerbose(nConvert, dcmSort, &nameList); else