Skip to content

Commit

Permalink
checks Source Application Entity Title for “oasis” to detect bogus Se…
Browse files Browse the repository at this point in the history
…gami spatial transforms.
  • Loading branch information
neurolabusc committed Aug 23, 2017
1 parent 6b9c921 commit d54cf68
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 19 deletions.
23 changes: 10 additions & 13 deletions console/nii_dicom.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -345,16 +345,6 @@ int verify_slice_dir (struct TDICOMdata d, struct TDICOMdata d2, struct nifti_1_
for (int i = 0; i < 4; i++)
R->m[i][2] = -R->m[i][2];
}
/*if (d.manufacturer == kMANUFACTURER_SEGAMI) { //set origin as center of volume
for (int i = 0; i < 3; i++)
R->m[i][3] = 0; //remove old offset
vec4 originVx = setVec4( (h->dim[1]+1.0f)/2.0f, (h->dim[2]+1.0f)/2.0f, (h->dim[3]+1.0f)/2.0f);
printMessage("origin (vx) %g %g %g\n",originVx.v[0],originVx.v[1],originVx.v[2]);
vec4 originMm = nifti_vect44mat44_mul(originVx, *R);
printMessage("origin (mm) %g %g %g\n",originMm.v[0],originMm.v[1],originMm.v[2]);
for (int i = 0; i < 3; i++)
R->m[i][3] = originMm.v[i]; //remove old offset
}*/
if (flip)
iSL = -iSL;
#ifdef MY_DEBUG
Expand Down Expand Up @@ -539,7 +529,7 @@ mat44 set_nii_header(struct TDICOMdata d) {
mat44 set_nii_header_x(struct TDICOMdata d, struct TDICOMdata d2, struct nifti_1_header *h, int* sliceDir, int isVerbose) {
*sliceDir = 0;
mat44 Q44 = nifti_dicom2mat(d.orient, d.patientPosition, d.xyzMM);
if (d.manufacturer == kMANUFACTURER_SEGAMI) {
if (d.isSegamiOasis == true) {
//Segami reconstructions appear to disregard DICOM spatial parameters: assume center of volume is isocenter and no table tilt
// Consider sample image with d.orient (0020,0037) = -1 0 0; 0 1 0: this suggests image RAI (L->R, P->A, S->I) but the vendors viewing software suggests LPS
//Perhaps we should ignore 0020,0037 and 0020,0032 as they are hidden in sequence 0054,0022, but in this case no positioning is provided
Expand Down Expand Up @@ -742,6 +732,7 @@ struct TDICOMdata clear_dicom_data() {
d.is3DAcq = false; //e.g. MP-RAGE, SPACE, TFE
d.isSlicesSpatiallySequentialPhilips = true; //Philips can save slices in random order, e.g. 4,5,6,1,2,3
d.isDerived = false; //0008,0008 = DERIVED,CSAPARALLEL,POSDISP
d.isSegamiOasis = false; //these images do not store spatial coordinates
d.bitsAllocated = 16;//bits
d.bitsStored = 0;
d.samplesPerPixel = 1;
Expand Down Expand Up @@ -938,8 +929,6 @@ int dcmStrManufacturer (int lByteLength, unsigned char lBuffer[]) {//read float
ret = kMANUFACTURER_PHILIPS;
if ((toupper(cString[0])== 'T') && (toupper(cString[1])== 'O'))
ret = kMANUFACTURER_TOSHIBA;
if ((toupper(cString[0])== 'S') && (toupper(cString[1])== 'E'))
ret = kMANUFACTURER_SEGAMI;
//#ifdef _MSC_VER
free(cString);
//#endif
Expand Down Expand Up @@ -2689,6 +2678,7 @@ struct TDICOMdata readDICOMv(char * fname, int isVerbose, int compressFlag, stru
#define kUnused 0x0001+(0x0001 << 16 )
#define kStart 0x0002+(0x0000 << 16 )
#define kTransferSyntax 0x0002+(0x0010 << 16)
#define kSourceApplicationEntityTitle 0x0002+(0x0016 << 16 )
//#define kSpecificCharacterSet 0x0008+(0x0005 << 16 ) //someday we should handle foreign characters...
#define kImageTypeTag 0x0008+(0x0008 << 16 )
#define kStudyDate 0x0008+(0x0020 << 16 )
Expand Down Expand Up @@ -2988,6 +2978,13 @@ struct TDICOMdata readDICOMv(char * fname, int isVerbose, int compressFlag, stru
d.imageStart = 1;//abort as invalid (imageStart MUST be >128)
}
break;} //{} provide scope for variable 'transferSyntax
case kSourceApplicationEntityTitle: {
char saeTxt[kDICOMStr];
dcmStr (lLength, &buffer[lPos], saeTxt);
int slen = (int) strlen(saeTxt);
if((slen < 5) || (strstr(saeTxt, "oasis") == NULL) ) break;
d.isSegamiOasis = true;
break; }
case kImageTypeTag:
dcmStr (lLength, &buffer[lPos], d.imageType);
int slen;
Expand Down
3 changes: 1 addition & 2 deletions console/nii_dicom.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ static const int kMaxDTI4D = 4096; //maximum number of DTI directions for 4D (Ph
#define kMANUFACTURER_GE 2
#define kMANUFACTURER_PHILIPS 3
#define kMANUFACTURER_TOSHIBA 4
#define kMANUFACTURER_SEGAMI 5

//note: note a complete modality list, e.g. XA,PX, etc
#define kMODALITY_UNKNOWN 0
Expand Down Expand Up @@ -118,7 +117,7 @@ static const int kCompressRLE = 4; //run length encoding
float radionuclidePositronFraction, radionuclideTotalDose, radionuclideHalfLife, doseCalibrationFactor; //PET ISOTOPE MODULE ATTRIBUTES (C.8-57)
float ecat_isotope_halflife, ecat_dosage;
double dateTime, acquisitionTime, acquisitionDate, bandwidthPerPixelPhaseEncode;
bool isDerived, isXRay, isMultiEcho, isSlicesSpatiallySequentialPhilips, isValid, is3DAcq, isExplicitVR, isLittleEndian, isPlanarRGB, isSigned, isHasPhase,isHasMagnitude,isHasMixed, isFloat, isResampled;
bool isSegamiOasis, isDerived, isXRay, isMultiEcho, isSlicesSpatiallySequentialPhilips, isValid, is3DAcq, isExplicitVR, isLittleEndian, isPlanarRGB, isSigned, isHasPhase,isHasMagnitude,isHasMixed, isFloat, isResampled;
char phaseEncodingRC;
char softwareVersions[kDICOMStr], deviceSerialNumber[kDICOMStr], institutionAddress[kDICOMStr], institutionName[kDICOMStr], referringPhysicianName[kDICOMStr], seriesInstanceUID[kDICOMStr], studyInstanceUID[kDICOMStr], bodyPartExamined[kDICOMStr], procedureStepDescription[kDICOMStr], imageType[kDICOMStr], manufacturersModelName[kDICOMStr], patientID[kDICOMStr], patientOrient[kDICOMStr], patientName[kDICOMStr],seriesDescription[kDICOMStr], studyID[kDICOMStr], sequenceName[kDICOMStr], protocolName[kDICOMStr],sequenceVariant[kDICOMStr],scanningSequence[kDICOMStr], birthDate[kDICOMStr], gender[kDICOMStr], age[kDICOMStr], studyDate[kDICOMStr],studyTime[kDICOMStr], imageComments[kDICOMStr];
struct TCSAdata CSA;
Expand Down
4 changes: 0 additions & 4 deletions console/nii_dicom_batch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -517,9 +517,6 @@ void nii_SaveBIDS(char pathoutname[], struct TDICOMdata d, struct TDCMopts opts,
case kMANUFACTURER_TOSHIBA:
fprintf(fp, "\t\"Manufacturer\": \"Toshiba\",\n" );
break;
case kMANUFACTURER_SEGAMI:
fprintf(fp, "\t\"Manufacturer\": \"Segami\",\n" );
break;
};
fprintf(fp, "\t\"ManufacturersModelName\": \"%s\",\n", d.manufacturersModelName );
if (!opts.isAnonymizeBIDS) {
Expand Down Expand Up @@ -2833,7 +2830,6 @@ void setDefaultOpts (struct TDCMopts *opts, const char * argv[]) { //either "set
opts->isGz = false;
opts->isSave3D = false;
opts->gzLevel = MZ_DEFAULT_LEVEL; //-1;
printMessage(">>>>> %d\n",Z_DEFAULT_COMPRESSION);
opts->isFlipY = true; //false: images in raw DICOM orientation, true: image rows flipped to cartesian coordinates
opts->isRGBplanar = false; //false for NIfTI (RGBRGB...), true for Analyze (RRR..RGGG..GBBB..B)
opts->isCreateBIDS = true;
Expand Down

0 comments on commit d54cf68

Please sign in to comment.