Skip to content

Commit

Permalink
added coilName (#235)
Browse files Browse the repository at this point in the history
  • Loading branch information
neurolabusc committed Oct 4, 2018
1 parent b494d11 commit 17ae881
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 25 deletions.
2 changes: 1 addition & 1 deletion console/main_console.cpp
Expand Up @@ -85,7 +85,7 @@ void showHelp(const char * argv[], struct TDCMopts opts) {
#else
#define kQstr ""
#endif
printf(" -f : filename (%%a=antenna (coil) number, %%b=basename, %%c=comments, %%d=description, %%e=echo number, %%f=folder name, %%i=ID of patient, %%j=seriesInstanceUID, %%k=studyInstanceUID, %%m=manufacturer, %%n=name of patient, %%p=protocol,%s %%r=instance number, %%s=series number, %%t=time, %%u=acquisition number, %%v=vendor, %%x=study ID; %%z=sequence name; default '%s')\n", kQstr, opts.filename);
printf(" -f : filename (%%a=antenna (coil) name, %%b=basename, %%c=comments, %%d=description, %%e=echo number, %%f=folder name, %%i=ID of patient, %%j=seriesInstanceUID, %%k=studyInstanceUID, %%m=manufacturer, %%n=name of patient, %%p=protocol,%s %%r=instance number, %%s=series number, %%t=time, %%u=acquisition number, %%v=vendor, %%x=study ID; %%z=sequence name; default '%s')\n", kQstr, opts.filename);
printf(" -g : generate defaults file (y/n/o/i [o=only: reset and write defaults; i=ignore: reset defaults], default n)\n");
printf(" -h : show help\n");
printf(" -i : ignore derived, localizer and 2D images (y/n, default n)\n");
Expand Down
29 changes: 18 additions & 11 deletions console/nii_dicom.cpp
Expand Up @@ -714,6 +714,7 @@ struct TDICOMdata clear_dicom_data() {
strcpy(d.studyID, "");
strcpy(d.studyInstanceUID, "");
strcpy(d.bodyPartExamined,"");
strcpy(d.coilName, "");
d.phaseEncodingLines = 0;
//~ d.patientPositionSequentialRepeats = 0;
//~ d.patientPositionRepeats = 0;
Expand Down Expand Up @@ -749,7 +750,7 @@ struct TDICOMdata clear_dicom_data() {
d.protocolBlockStartGE = 0;
d.protocolBlockLengthGE = 0;
d.phaseEncodingSteps = 0;
d.coilNum = 0;
d.coilCrc = 0;
d.accelFactPE = 0.0;
//d.patientPositionNumPhilips = 0;
d.imageBytes = 0;
Expand Down Expand Up @@ -4929,15 +4930,21 @@ double TE = 0.0; //most recent echo time recorded
case kCoilSiemens : {
if (d.manufacturer == kMANUFACTURER_SIEMENS) {
//see if image from single coil "H12" or an array "HEA;HEP"
char coilStr[kDICOMStr];
dcmStr (lLength, &buffer[lPos], coilStr);
if (strlen(coilStr) < 1) break;
if (coilStr[0] == 'C') break; //kludge as Nova 32-channel defaults to "C:A32" https://github.com/rordenlab/dcm2niix/issues/187
char *ptr;
dcmStrDigitsOnly(coilStr);
d.coilNum = (int)strtol(coilStr, &ptr, 10);
if (*ptr != '\0')
d.coilNum = 0;
//char coilStr[kDICOMStr];
//int coilNum;
dcmStr (lLength, &buffer[lPos], d.coilName);
if (strlen(d.coilName) < 1) break;
//printf("-->%s\n", coilStr);
//d.coilName = coilStr;
//if (coilStr[0] == 'C') break; //kludge as Nova 32-channel defaults to "C:A32" https://github.com/rordenlab/dcm2niix/issues/187
//char *ptr;
//dcmStrDigitsOnly(coilStr);
//coilNum = (int)strtol(coilStr, &ptr, 10);
d.coilCrc =(long)abs( (long)mz_crc32((unsigned char*) &d.coilName, strlen(d.coilName)));

//printf("%d:%s\n", d.coilNum, coilStr);
//if (*ptr != '\0')
// d.coilNum = 0;
}
break; }
case kImaPATModeText : { //e.g. Siemens iPAT x2 listed as "p2"
Expand Down Expand Up @@ -5600,7 +5607,7 @@ if (d.isHasPhase)
if (!isnan(patientPositionEndPhilips[1]))
printMessage(" patient position end (0020,0032)\t%g\t%g\t%g\n", patientPositionEndPhilips[1],patientPositionEndPhilips[2],patientPositionEndPhilips[3]);
printMessage(" orient (0020,0037)\t%g\t%g\t%g\t%g\t%g\t%g\n", d.orient[1],d.orient[2],d.orient[3], d.orient[4],d.orient[5],d.orient[6]);
printMessage(" acq %d img %d ser %ld dim %dx%dx%dx%d mm %gx%gx%g offset %d loc %d valid %d ph %d mag %d nDTI %d 3d %d bits %d littleEndian %d echo %d coil %d TE %g TR %g\n",d.acquNum,d.imageNum,d.seriesNum,d.xyzDim[1],d.xyzDim[2],d.xyzDim[3], d.xyzDim[4],d.xyzMM[1],d.xyzMM[2],d.xyzMM[3],d.imageStart, d.locationsInAcquisition, d.isValid, d.isHasPhase, d.isHasMagnitude, d.CSA.numDti, d.is3DAcq, d.bitsAllocated, d.isLittleEndian, d.echoNum, d.coilNum, d.TE, d.TR);
printMessage(" acq %d img %d ser %ld dim %dx%dx%dx%d mm %gx%gx%g offset %d loc %d valid %d ph %d mag %d nDTI %d 3d %d bits %d littleEndian %d echo %d coil %d TE %g TR %g\n",d.acquNum,d.imageNum,d.seriesNum,d.xyzDim[1],d.xyzDim[2],d.xyzDim[3], d.xyzDim[4],d.xyzMM[1],d.xyzMM[2],d.xyzMM[3],d.imageStart, d.locationsInAcquisition, d.isValid, d.isHasPhase, d.isHasMagnitude, d.CSA.numDti, d.is3DAcq, d.bitsAllocated, d.isLittleEndian, d.echoNum, d.coilCrc, d.TE, d.TR);
//if (d.CSA.dtiV[0] > 0)
// printMessage(" DWI bxyz %g %g %g %g\n", d.CSA.dtiV[0], d.CSA.dtiV[1], d.CSA.dtiV[2], d.CSA.dtiV[3]);
}
Expand Down
8 changes: 4 additions & 4 deletions console/nii_dicom.h
Expand Up @@ -43,7 +43,7 @@ extern "C" {
#define kCCsuf " CompilerNA" //unknown compiler!
#endif

#define kDCMvers "v1.0.20180931 " kJP2suf kLSsuf kCCsuf
#define kDCMvers "v1.0.20181004 " kJP2suf kLSsuf kCCsuf

static const int kMaxEPI3D = 1024; //maximum number of EPI images in Siemens Mosaic
static const int kMaxDTI4D = 18000; //maximum number of DTI directions for 4D (Philips) images, also maximum number of 3D slices for Philips 3D and 4D images
Expand Down Expand Up @@ -154,17 +154,17 @@ static const uint8_t MAX_NUMBER_OF_DIMENSIONS = 8;
struct TDICOMdata {
long seriesNum;
int xyzDim[5];
int numberOfImagesInGridUIH, phaseEncodingGE, protocolBlockStartGE, protocolBlockLengthGE, modality, dwellTime, effectiveEchoSpacingGE, phaseEncodingLines, phaseEncodingSteps, echoTrainLength, coilNum, echoNum, sliceOrient, manufacturer, converted2NII, acquNum, imageNum, imageStart, imageBytes, bitsStored, bitsAllocated, samplesPerPixel,locationsInAcquisition, compressionScheme;
int numberOfImagesInGridUIH, phaseEncodingGE, protocolBlockStartGE, protocolBlockLengthGE, modality, dwellTime, effectiveEchoSpacingGE, phaseEncodingLines, phaseEncodingSteps, echoTrainLength, coilCrc, echoNum, sliceOrient, manufacturer, converted2NII, acquNum, imageNum, imageStart, imageBytes, bitsStored, bitsAllocated, samplesPerPixel,locationsInAcquisition, compressionScheme;
float imagingFrequency, patientWeight, zSpacing, zThick, pixelBandwidth, SAR, phaseFieldofView, accelFactPE, flipAngle, fieldStrength, TE, TI, TR, intenScale, intenIntercept, intenScalePhilips, gantryTilt, lastScanLoc, angulation[4];
float orient[7], patientPosition[4], patientPositionLast[4], xyzMM[4], stackOffcentre[4];
float rtia_timerGE, radionuclidePositronFraction, radionuclideTotalDose, radionuclideHalfLife, doseCalibrationFactor; //PET ISOTOPE MODULE ATTRIBUTES (C.8-57)
float ecat_isotope_halflife, ecat_dosage;
double acquisitionDuration, triggerDelayTime, RWVScale, RWVIntercept, dateTime, acquisitionTime, acquisitionDate, bandwidthPerPixelPhaseEncode;
char phaseEncodingDirectionDisplayedUIH[kDICOMStr], imageBaseName[kDICOMStr], scanOptions[kDICOMStr], stationName[kDICOMStr], softwareVersions[kDICOMStr], deviceSerialNumber[kDICOMStr], institutionAddress[kDICOMStr], institutionName[kDICOMStr], referringPhysicianName[kDICOMStr], seriesInstanceUID[kDICOMStr], studyInstanceUID[kDICOMStr], bodyPartExamined[kDICOMStr], procedureStepDescription[kDICOMStr], imageType[kDICOMStr], institutionalDepartmentName[kDICOMStr], manufacturersModelName[kDICOMStr], patientID[kDICOMStr], patientOrient[kDICOMStr], patientName[kDICOMStr],seriesDescription[kDICOMStr], studyID[kDICOMStr], sequenceName[kDICOMStr], protocolName[kDICOMStr],sequenceVariant[kDICOMStr],scanningSequence[kDICOMStr], patientBirthDate[kDICOMStr], patientAge[kDICOMStr], studyDate[kDICOMStr],studyTime[kDICOMStr];
char coilName[kDICOMStr], phaseEncodingDirectionDisplayedUIH[kDICOMStr], imageBaseName[kDICOMStr], scanOptions[kDICOMStr], stationName[kDICOMStr], softwareVersions[kDICOMStr], deviceSerialNumber[kDICOMStr], institutionAddress[kDICOMStr], institutionName[kDICOMStr], referringPhysicianName[kDICOMStr], seriesInstanceUID[kDICOMStr], studyInstanceUID[kDICOMStr], bodyPartExamined[kDICOMStr], procedureStepDescription[kDICOMStr], imageType[kDICOMStr], institutionalDepartmentName[kDICOMStr], manufacturersModelName[kDICOMStr], patientID[kDICOMStr], patientOrient[kDICOMStr], patientName[kDICOMStr],seriesDescription[kDICOMStr], studyID[kDICOMStr], sequenceName[kDICOMStr], protocolName[kDICOMStr],sequenceVariant[kDICOMStr],scanningSequence[kDICOMStr], patientBirthDate[kDICOMStr], patientAge[kDICOMStr], studyDate[kDICOMStr],studyTime[kDICOMStr];
char imageComments[kDICOMStrLarge];
uint32_t dimensionIndexValues[MAX_NUMBER_OF_DIMENSIONS];
struct TCSAdata CSA;
bool isNonParallelSlices, isSegamiOasis, isScaleOrTEVaries, isDerived, isXRay, isMultiEcho, isValid, is3DAcq, is2DAcq, isExplicitVR, isLittleEndian, isPlanarRGB, isSigned, isHasPhase, isHasImaginary, isHasReal, isHasMagnitude,isHasMixed, isFloat, isResampled, isLocalizer;
bool isCoilVaries, isNonParallelSlices, isSegamiOasis, isScaleOrTEVaries, isDerived, isXRay, isMultiEcho, isValid, is3DAcq, is2DAcq, isExplicitVR, isLittleEndian, isPlanarRGB, isSigned, isHasPhase, isHasImaginary, isHasReal, isHasMagnitude,isHasMixed, isFloat, isResampled, isLocalizer;
char phaseEncodingRC, patientSex;
};

Expand Down
25 changes: 17 additions & 8 deletions console/nii_dicom_batch.cpp
Expand Up @@ -333,7 +333,7 @@ void nii_SaveText(char pathoutname[], struct TDICOMdata d, struct TDCMopts opts,
fprintf(fp, "%s\tField Strength:\t%g\tProtocolName:\t%s\tScanningSequence00180020:\t%s\tTE:\t%g\tTR:\t%g\tSeriesNum:\t%ld\tAcquNum:\t%d\tImageNum:\t%d\tImageComments:\t%s\tDateTime:\t%f\tName:\t%s\tConvVers:\t%s\tDoB:\t%s\tGender:\t%c\tAge:\t%s\tDimXYZT:\t%d\t%d\t%d\t%d\tCoil:\t%d\tEchoNum:\t%d\tOrient(6)\t%g\t%g\t%g\t%g\t%g\t%g\tbitsAllocated\t%d\tInputName\t%s\n",
pathoutname, d.fieldStrength, d.protocolName, d.scanningSequence, d.TE, d.TR, d.seriesNum, d.acquNum, d.imageNum, d.imageComments,
d.dateTime, d.patientName, kDCMvers, d.patientBirthDate, d.patientSex, d.patientAge, h->dim[1], h->dim[2], h->dim[3], h->dim[4],
d.coilNum,d.echoNum, d.orient[1], d.orient[2], d.orient[3], d.orient[4], d.orient[5], d.orient[6],
d.coilCrc,d.echoNum, d.orient[1], d.orient[2], d.orient[3], d.orient[4], d.orient[5], d.orient[6],
d.bitsAllocated, dcmname);
fclose(fp);
}// nii_SaveText()
Expand Down Expand Up @@ -950,6 +950,8 @@ void nii_SaveBIDS(char pathoutname[], struct TDICOMdata d, struct TDCMopts opts,
//if (epiFactor > 0) fprintf(fp, "\t\"EPIFactor\": %d,\n", epiFactor);
json_Str(fp, "\t\"ReceiveCoilName\": \"%s\",\n", coilID);
json_Str(fp, "\t\"ReceiveCoilActiveElements\": \"%s\",\n", coilElements);
json_Str(fp, "\t\"CoilString\": \"%s\",\n", d.coilName);
strcpy(d.coilName, "");
json_Str(fp, "\t\"PulseSequenceDetails\": \"%s\",\n", pulseSequenceDetails);
json_Str(fp, "\t\"FmriExternalInfo\": \"%s\",\n", fmriExternalInfo);
json_Str(fp, "\t\"WipMemBlock\": \"%s\",\n", wipMemBlock);
Expand Down Expand Up @@ -1596,10 +1598,9 @@ int nii_createFilename(struct TDICOMdata dcm, char * niiFilename, struct TDCMopt
pos++; //extra increment: skip both % and following character
char f = 'P';
if (pos < strlen(inname)) f = toupper(inname[pos]);
if ((f == 'A') && (dcm.coilNum > 0)) {
if (f == 'A') {
isCoilReported = true;
sprintf(newstr, "%02d", dcm.coilNum);
strcat (outname,newstr);
strcat (outname,dcm.coilName);
}
if (f == 'B') strcat (outname,dcm.imageBaseName);
if (f == 'C') strcat (outname,dcm.imageComments);
Expand Down Expand Up @@ -1705,9 +1706,11 @@ int nii_createFilename(struct TDICOMdata dcm, char * niiFilename, struct TDCMopt
newstr[pos - start] = '\0';
strcat (outname,newstr);
}
if (!isCoilReported && (dcm.coilNum > 1)) {
sprintf(newstr, "_c%d", dcm.coilNum);
strcat (outname,newstr);
if ((!isCoilReported) && (dcm.isCoilVaries)) {
//sprintf(newstr, "_c%d", dcm.coilNum);
//strcat (outname,newstr);
strcat (outname, "_c");
strcat (outname,dcm.coilName);
}
if ((!isEchoReported) && (dcm.isMultiEcho) && (dcm.echoNum >= 1)) { //multiple echoes saved as same series
sprintf(newstr, "_e%d", dcm.echoNum);
Expand Down Expand Up @@ -2931,6 +2934,10 @@ int saveDcm2NiiCore(int nConvert, struct TDCMsort dcmSort[],struct TDICOMdata dc
printMessage("Slice positions repeated, but number of slices (%d) not divisible by number of repeats (%d): missing images?\n", nConvert, nAcq);
}
}
//next: detect if ANY file flagged as coil varies
for (int i = 0; i < nConvert; i++)
if (dcmList[dcmSort[i].indx].isCoilVaries)
dcmList[indx0].isCoilVaries = true;
//next: detect if ANY file flagged as echo varies
for (int i = 0; i < nConvert; i++)
if (dcmList[dcmSort[i].indx].isMultiEcho)
Expand Down Expand Up @@ -3550,7 +3557,7 @@ bool isSameSet (struct TDICOMdata d1, struct TDICOMdata d2, struct TDCMopts* opt
*isMultiEcho = true;
return false;
}
if (d1.coilNum != d2.coilNum) {
if (d1.coilCrc != d2.coilCrc) {
if (!warnings->coilVaries)
printMessage("slices not stacked: coil varies\n");
warnings->coilVaries = true;
Expand Down Expand Up @@ -3955,6 +3962,8 @@ int nii_loadDir(struct TDCMopts* opts) {
dcmList[j].isMultiEcho = isMultiEcho;
dcmList[i].isNonParallelSlices = isNonParallelSlices;
dcmList[j].isNonParallelSlices = isNonParallelSlices;
dcmList[i].isCoilVaries = warnings.coilVaries;
dcmList[j].isCoilVaries = warnings.coilVaries;
}
qsort(dcmSort, nConvert, sizeof(struct TDCMsort), compareTDCMsort); //sort based on series and image numbers....
//dcmList[dcmSort[0].indx].isMultiEcho = isMultiEcho;
Expand Down
2 changes: 1 addition & 1 deletion docs/source/dcm2niix.rst
Expand Up @@ -34,7 +34,7 @@ Options
-f <format> Format string for the output filename(s). The following
specifiers are supported:

- %a, antenna (coil) number
- %a, antenna (coil) name
- %b, basename (filename of 1st DICOM file)
- %c, comments
- %d, description
Expand Down

0 comments on commit 17ae881

Please sign in to comment.