From 2a9fbe82aaf29bf0830c23a5e44fccea9382ee32 Mon Sep 17 00:00:00 2001 From: neurolabusc Date: Mon, 24 Oct 2022 15:13:05 -0400 Subject: [PATCH] MR Solutions (https://github.com/rordenlab/dcm2niix/issues/642) --- console/nii_dicom.cpp | 4 ++++ console/nii_dicom.h | 5 +++-- console/nii_dicom_batch.cpp | 12 ++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/console/nii_dicom.cpp b/console/nii_dicom.cpp index 7ebd283f..7876009e 100644 --- a/console/nii_dicom.cpp +++ b/console/nii_dicom.cpp @@ -885,6 +885,7 @@ struct TDICOMdata clear_dicom_data() { d.isHasOverlay = false; d.isPrivateCreatorRemap = false; d.isRealIsPhaseMapHz = false; + d.isQuadruped = false; d.numberOfImagesInGridUIH = 0; d.phaseEncodingRC = '?'; d.patientSex = '?'; @@ -1211,6 +1212,8 @@ int dcmStrManufacturer(const int lByteLength, unsigned char lBuffer[]) { //read ret = kMANUFACTURER_UIH; if ((toupper(cString[0]) == 'B') && (toupper(cString[1]) == 'R')) ret = kMANUFACTURER_BRUKER; + if ((toupper(cString[0]) == 'M') && (toupper(cString[1]) == 'R')) + ret = kMANUFACTURER_MRSOLUTIONS; //if (ret == kMANUFACTURER_UNKNOWN) //reduce verbosity: single warning for series : Unable to determine manufacturer (0008,0070) // printWarning("Unknown manufacturer %s\n", cString); //#ifdef _MSC_VER @@ -5417,6 +5420,7 @@ const uint32_t kEffectiveTE = 0x0018 + (0x9082 << 16); int slen = (int)strlen(aotTxt); if ((slen < 9) || (strstr(aotTxt, "QUADRUPED") == NULL)) break; + d.isQuadruped = true; printError("Anatomical Orientation Type (0010,2210) is QUADRUPED: rotate coordinates accordingly\n"); break; } diff --git a/console/nii_dicom.h b/console/nii_dicom.h index bd8a60c2..bd6b2d8a 100644 --- a/console/nii_dicom.h +++ b/console/nii_dicom.h @@ -50,7 +50,7 @@ extern "C" { #define kCPUsuf " " //unknown CPU #endif -#define kDCMdate "v1.0.20221021" +#define kDCMdate "v1.0.20221024" #define kDCMvers kDCMdate " " kJP2suf kLSsuf kCCsuf kCPUsuf static const int kMaxEPI3D = 1024; //maximum number of EPI images in Siemens Mosaic @@ -70,6 +70,7 @@ static const int kMaxDTI4D = kMaxSlice2D; //issue460: maximum number of DTI dire #define kMANUFACTURER_HITACHI 7 #define kMANUFACTURER_CANON 8 #define kMANUFACTURER_MEDISO 9 +#define kMANUFACTURER_MRSOLUTIONS 10 //note: note a complete modality list, e.g. XA,PX, etc #define kMODALITY_UNKNOWN 0 @@ -241,7 +242,7 @@ static const uint8_t MAX_NUMBER_OF_DIMENSIONS = 8; char scanOptions[kDICOMStrLarge], institutionAddress[kDICOMStrLarge], imageComments[kDICOMStrLarge]; uint32_t dimensionIndexValues[MAX_NUMBER_OF_DIMENSIONS]; struct TCSAdata CSA; - bool isRealIsPhaseMapHz, isPrivateCreatorRemap, isHasOverlay, isEPI, isIR, isPartialFourier, isDiffusion, isVectorFromBMatrix, isRawDataStorage, isGrayscaleSoftcopyPresentationState, isStackableSeries, isCoilVaries, isNonParallelSlices, isBVecWorldCoordinates, isSegamiOasis, isXA10A, isScaleOrTEVaries, isScaleVariesEnh, isDerived, isXRay, isMultiEcho, isValid, is3DAcq, is2DAcq, isExplicitVR, isLittleEndian, isPlanarRGB, isSigned, isHasPhase, isHasImaginary, isHasReal, isHasMagnitude,isHasMixed, isFloat, isResampled, isLocalizer; + bool isQuadruped, isRealIsPhaseMapHz, isPrivateCreatorRemap, isHasOverlay, isEPI, isIR, isPartialFourier, isDiffusion, isVectorFromBMatrix, isRawDataStorage, isGrayscaleSoftcopyPresentationState, isStackableSeries, isCoilVaries, isNonParallelSlices, isBVecWorldCoordinates, isSegamiOasis, isXA10A, isScaleOrTEVaries, isScaleVariesEnh, isDerived, isXRay, isMultiEcho, isValid, is3DAcq, is2DAcq, isExplicitVR, isLittleEndian, isPlanarRGB, isSigned, isHasPhase, isHasImaginary, isHasReal, isHasMagnitude,isHasMixed, isFloat, isResampled, isLocalizer; char phaseEncodingRC, patientSex; }; struct TDCMprefs { diff --git a/console/nii_dicom_batch.cpp b/console/nii_dicom_batch.cpp index 92e658c2..7bdc8057 100644 --- a/console/nii_dicom_batch.cpp +++ b/console/nii_dicom_batch.cpp @@ -1244,6 +1244,9 @@ tse3d: T2*/ case kMANUFACTURER_UIH: fprintf(fp, "\t\"Manufacturer\": \"UIH\",\n"); break; + case kMANUFACTURER_MRSOLUTIONS: + fprintf(fp, "\t\"Manufacturer\": \"MRSolutions\",\n"); + break; }; //if (d.epiVersionGE == 0) // fprintf(fp, "\t\"PulseSequenceName\": \"epi\",\n"); @@ -1284,6 +1287,8 @@ tse3d: T2*/ //d.patientBirthDate //convert from DICOM YYYYMMDD to JSON //d.patientAge //4-digit Age String: nnnD, nnnW, nnnM, nnnY; } + if (d.isQuadruped) + json_Bool(fp, "\t\"Quadruped\": %s,\n", true); // BIDS suggests 0018,9020 but Siemens V-series do not populate this, alternatives are CSA or (0018,0021) CS [SK\MTC\SP] json_Str(fp, "\t\"BodyPartExamined\": \"%s\",\n", d.bodyPartExamined); json_Str(fp, "\t\"PatientPosition\": \"%s\",\n", d.patientOrient); // 0018,5100 = PatientPosition in DICOM json_Str(fp, "\t\"ProcedureStepDescription\": \"%s\",\n", d.procedureStepDescription); @@ -3140,6 +3145,10 @@ int nii_createFilename(struct TDICOMdata dcm, char *niiFilename, struct TDCMopts strcat(outname, "Ph"); else if (dcm.manufacturer == kMANUFACTURER_SIEMENS) strcat(outname, "Si"); + else if (dcm.manufacturer == kMANUFACTURER_MEDISO) + strcat(outname, "Me"); + else if (dcm.manufacturer == kMANUFACTURER_MRSOLUTIONS) + strcat(outname, "MR"); else strcat(outname, "NA"); //manufacturer name not available } @@ -3636,6 +3645,9 @@ void nii_saveAttributes(struct TDICOMdata &data, struct nifti_1_header &header, case kMANUFACTURER_CANON: images->addAttribute("manufacturer", "Canon"); break; + case kMANUFACTURER_MRSOLUTIONS: + images->addAttribute("manufacturer", "MRSolutions"); + break; } images->addAttribute("scannerModelName", data.manufacturersModelName); images->addAttribute("imageType", data.imageType);