Skip to content

Commit

Permalink
Experimental start for reproin support
Browse files Browse the repository at this point in the history
  • Loading branch information
neurolabusc committed Mar 21, 2024
1 parent d635970 commit 1b4505e
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 5 deletions.
1 change: 1 addition & 0 deletions BIDS/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ These fields are present regardless of modality (e.g. MR, CT, PET).
| PatientPosition | | DICOM tag 0020,0032 | D |
| ProcedureStepDescription | | DICOM tag 0040,0254 | D |
| SoftwareVersions | | DICOM tag 0020,1020 | B |
| StudyDescription | | DICOM tag 0008,1030 | D |
| SeriesDescription | | DICOM tag 0008,103E | D |
| ProtocolName | | DICOM tag 0018,1030 | D |
| ScanningSequence | | DICOM tag 0018,0020 | B |
Expand Down
5 changes: 5 additions & 0 deletions console/nii_dicom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,7 @@ struct TDICOMdata clear_dicom_data() {
strcpy(d.deviceSerialNumber, "");
strcpy(d.softwareVersions, "");
strcpy(d.stationName, "");
strcpy(d.studyDescription, "");
strcpy(d.scanOptions, "");
//strcpy(d.mrAcquisitionType, "");
strcpy(d.seriesInstanceUID, "");
Expand Down Expand Up @@ -4368,6 +4369,7 @@ struct TDICOMdata readDICOMx(char *fname, struct TDCMprefs *prefs, struct TDTI4D
#define kTracerRadionuclide1 0x0008 + (0x0100 << 16) //SH
#define kTracerRadionuclide2 0x0008 + (0x0104 << 16) //LO
#define kStationName 0x0008 + (0x1010 << 16)
#define kStudyDescription 0x0008 + (0x1030 << 16) //LO
#define kSeriesDescription 0x0008 + (0x103E << 16) // '0008' '103E' 'LO' 'SeriesDescription'
#define kInstitutionalDepartmentName 0x0008 + (0x1040 << 16)
#define kManufacturersModelName 0x0008 + (0x1090 << 16)
Expand Down Expand Up @@ -5695,6 +5697,9 @@ const uint32_t kEffectiveTE = 0x0018 + uint32_t(0x9082 << 16); //FD
case kStationName:
dcmStr(lLength, &buffer[lPos], d.stationName);
break;
case kStudyDescription:
dcmStr(lLength, &buffer[lPos], d.studyDescription);
break;
case kSeriesDescription:
dcmStr(lLength, &buffer[lPos], d.seriesDescription);
#ifdef USING_DCM2NIIXFSWRAPPER
Expand Down
2 changes: 1 addition & 1 deletion console/nii_dicom.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ static const uint8_t MAX_NUMBER_OF_DIMENSIONS = 8;
float pixelPaddingValue; // used for both FloatPixelPaddingValue (0028, 0122) and PixelPaddingValue (0028, 0120); NaN if not present.
double imagingFrequency, acquisitionDuration, triggerDelayTime, RWVScale, RWVIntercept, dateTime, acquisitionTime, acquisitionDate, bandwidthPerPixelPhaseEncode;
char parallelAcquisitionTechnique[kDICOMStr], radiopharmaceutical[kDICOMStr], convolutionKernel[kDICOMStr], unitsPT[kDICOMStr], tracerRadionuclide[kDICOMStr], decayCorrection[kDICOMStr], attenuationCorrectionMethod[kDICOMStr],reconstructionMethod[kDICOMStr], transferSyntax[kDICOMStr];
char prescanReuseString[kDICOMStr], imageOrientationText[kDICOMStr], pulseSequenceName[kDICOMStr], coilElements[kDICOMStr], coilName[kDICOMStr], phaseEncodingDirectionDisplayedUIH[kDICOMStr], imageBaseName[kDICOMStr], stationName[kDICOMStr], softwareVersions[kDICOMStr], deviceSerialNumber[kDICOMStr], institutionName[kDICOMStr], referringPhysicianName[kDICOMStr], instanceUID[kDICOMStr], seriesInstanceUID[kDICOMStr], studyInstanceUID[kDICOMStr], bodyPartExamined[kDICOMStr], procedureStepDescription[kDICOMStr], imageTypeText[kDICOMStr], imageType[kDICOMStr], institutionalDepartmentName[kDICOMStr], manufacturersModelName[kDICOMStr], patientID[kDICOMStr], patientOrient[kDICOMStr], patientName[kDICOMStr], accessionNumber[kDICOMStr], seriesDescription[kDICOMStr], studyID[kDICOMStr], sequenceName[kDICOMStr], protocolName[kDICOMStr],sequenceVariant[kDICOMStr],scanningSequence[kDICOMStr], patientBirthDate[kDICOMStr], patientAge[kDICOMStr], studyDate[kDICOMStr],studyTime[kDICOMStr];
char prescanReuseString[kDICOMStr], imageOrientationText[kDICOMStr], pulseSequenceName[kDICOMStr], coilElements[kDICOMStr], coilName[kDICOMStr], phaseEncodingDirectionDisplayedUIH[kDICOMStr], imageBaseName[kDICOMStr], stationName[kDICOMStr], studyDescription[kDICOMStr], softwareVersions[kDICOMStr], deviceSerialNumber[kDICOMStr], institutionName[kDICOMStr], referringPhysicianName[kDICOMStr], instanceUID[kDICOMStr], seriesInstanceUID[kDICOMStr], studyInstanceUID[kDICOMStr], bodyPartExamined[kDICOMStr], procedureStepDescription[kDICOMStr], imageTypeText[kDICOMStr], imageType[kDICOMStr], institutionalDepartmentName[kDICOMStr], manufacturersModelName[kDICOMStr], patientID[kDICOMStr], patientOrient[kDICOMStr], patientName[kDICOMStr], accessionNumber[kDICOMStr], seriesDescription[kDICOMStr], studyID[kDICOMStr], sequenceName[kDICOMStr], protocolName[kDICOMStr],sequenceVariant[kDICOMStr],scanningSequence[kDICOMStr], patientBirthDate[kDICOMStr], patientAge[kDICOMStr], studyDate[kDICOMStr],studyTime[kDICOMStr];
char deepLearningText[kDICOMStrLarge], scanOptions[kDICOMStrLarge], institutionAddress[kDICOMStrLarge], imageComments[kDICOMStrLarge];
uint32_t dimensionIndexValues[MAX_NUMBER_OF_DIMENSIONS];
struct TCSAdata CSA;
Expand Down
86 changes: 82 additions & 4 deletions console/nii_dicom_batch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1395,6 +1395,7 @@ tse3d: T2*/
fprintf(fp, "\t\"MRAcquisitionType\": \"2D\",\n");
if (d.is3DAcq)
fprintf(fp, "\t\"MRAcquisitionType\": \"3D\",\n");
json_Str(fp, "\t\"StudyDescription\": \"%s\",\n", d.studyDescription);
json_Str(fp, "\t\"SeriesDescription\": \"%s\",\n", d.seriesDescription);
json_Str(fp, "\t\"ProtocolName\": \"%s\",\n", d.protocolName);
json_Str(fp, "\t\"ScanningSequence\": \"%s\",\n", d.scanningSequence);
Expand Down Expand Up @@ -3416,6 +3417,66 @@ void cleanISO8859(char *cString) {
}
}

void heudiconvStrPth(char *cString) {
int len = strlen(cString);
int j = 0;
int i = 0;
bool hasCaret = false;
while (i < len) {
if (cString[i] == '^') {
cString[j++] = kPathSeparator;
hasCaret = true;
} else if ((!hasCaret) && (cString[i] == '_') ) {
cString[j++] = kPathSeparator;
} else if (cString[i] != '-') {
cString[j] = cString[i];
j ++;
}
i++;
}
cString[j] = '\0';
}

void heudiconvStr(char *cString) {
int len = strlen(cString);
int j = 0;
int i = 0;
const char kTempPathSeparator = '\a';
bool hasCaret = false;
while (i < len) {
if (cString[i] != '-') {
cString[j] = cString[i];
j ++;
}
i++;
}
cString[j] = '\0';
}

void mkDirs(char *pth) {
if (strlen(pth) < 1) return;
char newdir[2048] = {""};
for (size_t pos = 0; pos < strlen(pth); pos++) {
if (pth[pos] == kPathSeparator) {
if (!is_dir(newdir, true))
#if defined(_WIN64) || defined(_WIN32)
mkdir(newdir);
#else
mkdir(newdir, 0700);
#endif
}
char ch[128] = {""};
snprintf(ch, 128, "%c", pth[pos]);
strcat(newdir, ch);
}
if (!is_dir(newdir, true))
#if defined(_WIN64) || defined(_WIN32)
mkdir(newdir);
#else
mkdir(newdir, 0700);
#endif
} //mkDirs()

void createDummyBidsBoilerplate(char *pth, bool isFunc) {
//https://remi-gau.github.io/bids_cookbook/#starters
char pathSep[2] = {"a"};
Expand Down Expand Up @@ -3539,13 +3600,30 @@ int nii_createFilename(struct TDICOMdata dcm, char *niiFilename, struct TDCMopts
strcat(outname, opts.indirParent);
if (f == 'G')
strcat(outname, dcm.accessionNumber);
if (f == 'H') {
printWarning("hazardous (%%h) bids naming experimental\n");
if ((f == 'H') || (f == 'V')) {
printWarning("hazardous (%%h) or volatile (%%v) bids naming experimental\n");
bool isReproin = (f == 'V');
if (isReproin) {
//https://dbic-handbook.readthedocs.io/en/latest/mri/reproin.html
//reproin convention is hard for one-pass, as `ses` may only be reported in one series in the session (e.g. localizer)
//printf("study %s\n", dcm.studyDescription);
//printf("series %s\n", dcm.seriesDescription);
//printf("id %s\n", dcm.patientID);
snprintf(newstr, PATH_MAX, "%s", dcm.studyDescription);
heudiconvStrPth(newstr);
if ((strlen(pth) > 0) && (pth[strlen(pth)-1] != kPathSeparator))
strcat(pth, kFileSep);//kPathSeparator);
strcat(pth, newstr);
mkDirs(pth);
strcpy(opts.bidsSubject, dcm.patientID);
heudiconvStr(opts.bidsSubject);
}
char bidsSubject[kOptsStr] = "sub-";
if (strlen(opts.bidsSubject) <= 0)
strcat(bidsSubject, "1");
else
strcat(bidsSubject, opts.bidsSubject);
printf("%s<<<:::\n", bidsSubject);
char bidsSession[kOptsStr] = "ses-";
if (strlen(opts.bidsSession) <= 0)
strcat(bidsSession, "1");
Expand Down Expand Up @@ -3626,13 +3704,13 @@ int nii_createFilename(struct TDICOMdata dcm, char *niiFilename, struct TDCMopts
if (strlen(dcm.protocolName) < 1)
printWarning("Unable to append protocol name (0018,1030) to filename (it is empty).\n");
}
if (f == 'Q')
strcat(outname, dcm.scanningSequence);
if (f == 'R') {
snprintf(newstr, PATH_MAX, "%d", dcm.imageNum);
strcat(outname, newstr);
isImageNumReported = true;
}
if (f == 'Q')
strcat(outname, dcm.scanningSequence);
if (f == 'S') {
snprintf(newstr, PATH_MAX, "%ld", dcm.seriesNum);
strcat(outname, newstr);
Expand Down

0 comments on commit 1b4505e

Please sign in to comment.