5#include "tpcclibConfig.h"
34 if(verbose>0) {printf(
"%s(dcmfile, *isotope, *decaycorrection)\n", __func__); fflush(stdout);}
37 if(d==NULL || d->
item==NULL)
return(1);
44 if(verbose>1) {printf(
"trying to find 'Decay Correction' tag\n"); fflush(stdout);}
48 if(verbose>12) printf(
"Decay Correction := '%s'\n", buf);
54 if(verbose>1) {printf(
" not found\ntrying to find 'Decay Corrected' tag\n"); fflush(stdout);}
58 if(verbose>12) printf(
"Decay Correction := '%s'\n", buf);
62 }
else if(verbose>1) {printf(
" not found.\n"); fflush(stdout);}
65 fprintf(stderr,
"Warning: status of decay correction not found.\n");
68 if(verbose>11) printf(
"decayCorrection := %s\n",
decayDescr(*dc));
71 if(isot==NULL)
return(0);
74 if(verbose>1) {printf(
"trying to find Radiopharmaceutical Information Sequence\n"); fflush(stdout);}
77 if(verbose>1) {printf(
" found.\n"); fflush(stdout);}
80 if(verbose>1) {printf(
" not found.\n"); fflush(stdout);}
83 if(verbose>1) {printf(
"trying to find Radionuclide Code Sequence\n"); fflush(stdout);}
86 if(verbose>1) {printf(
" found.\n"); fflush(stdout);}
87 if(verbose>1) {printf(
"trying to find Code Meaning\n"); fflush(stdout);}
91 if(verbose>12) {printf(
"Code Meaning := '%s'\n", buf); fflush(stdout);}
94 if(verbose>11) {printf(
"isotope := %s\n",
isotopeName(*isot)); fflush(stdout);}
95 }
else if(verbose>1) {printf(
" not found.\n"); fflush(stdout);}
97 if(verbose>1) {printf(
" not found.\n"); fflush(stdout);}
100 if(verbose>1) {printf(
"trying to find Radionuclide Half Life\n"); fflush(stdout);}
104 if(verbose>12) {printf(
"Radionuclide Half Life := '%s'\n", buf); fflush(stdout);}
108 if(verbose>11) {printf(
"isotope := %s\n",
isotopeName(*isot)); fflush(stdout);}
109 }
else if(verbose>1) {printf(
" not found.\n"); fflush(stdout);}
130 if(verbose>0) {printf(
"%s(dcmfile, imgpos)\n", __func__); fflush(stdout);}
131 if(d==NULL || d->
item==NULL || imgpos==NULL)
return(1);
132 for(
int i=0; i<3; i++) imgpos[i]=nan(
"");
136 if(verbose>1) {printf(
"trying to find Per Frame Functional Groups Sequence\n"); fflush(stdout);}
140 if(verbose>1) {printf(
" found.\n"); fflush(stdout);}
143 int posnr=0;
dcmTagSet(&tag, 0x0020, 0x9111);
150 posnr=
dcmitemGetInt(kptr);
if(verbose>3) printf(
" posnr=%d\n", posnr);
156 if(posnr==1 && jptr!=NULL) {
165 if(verbose>4) printf(
" image_position := '%s'\n", buf);
166 int n=sscanf(buf,
"%lf\\%lf\\%lf", &imgpos[0], &imgpos[1], &imgpos[2]);
169 if(verbose>0) fprintf(stderr,
"Error: invalid Image Position (Patient)\n");
173 if(verbose>0) fprintf(stderr,
"Error: no Image Position (Patient)\n");
177 if(verbose>0) fprintf(stderr,
"Error: no Plane Position Sequence\n");
181 if(verbose>0) {fprintf(stderr,
"Error: stack position 1 not found.\n"); fflush(stderr);}
186 if(verbose>1) {printf(
" not found.\n"); fflush(stdout);}
188 if(verbose>1) {printf(
"find the smallest Instance (image) Number\n"); fflush(stdout);}
192 if(verbose>0) {fprintf(stderr,
"Error: Instance (image) Number not found.\n"); fflush(stderr);}
195 int mininr=
dcmitemGetInt(iptr);
if(verbose>5) printf(
" inr=%d\n", mininr);
199 if(jptr==NULL)
break;
200 int inr=
dcmitemGetInt(jptr);
if(verbose>5) printf(
" inr=%d\n", inr);
201 if(inr<mininr) {mininr=inr; iptr=jptr;}
203 if(verbose>2) {printf(
" smallest Instance (image) Number: %d\n", mininr); fflush(stdout);}
209 if(verbose>0) fprintf(stderr,
"Error: no Image Position (Patient)\n");
213 if(verbose>2) printf(
" image_position := '%s'\n", buf);
214 int n=sscanf(buf,
"%lf\\%lf\\%lf", &imgpos[0], &imgpos[1], &imgpos[2]);
217 if(verbose>0) fprintf(stderr,
"Error: invalid Image Position (Patient)\n");
236 unsigned short int *imgdim,
240 if(verbose>0) {printf(
"%s(dcmfile, imgdim)\n", __func__); fflush(stdout);}
241 if(d==NULL || d->
item==NULL || imgdim==NULL)
return(1);
242 for(
int i=0; i<4; i++) imgdim[i]=0;
250 if(verbose>0) {fprintf(stderr,
"Error: cannot find matrix row number.\n"); fflush(stderr);}
259 if(verbose>0) {fprintf(stderr,
"Error: cannot find matrix column number.\n"); fflush(stderr);}
266 if(verbose>1) {printf(
"trying to read plane number as 'Number of Slices'\n"); fflush(stdout);}
271 if(verbose>2) printf(
"planeNr := %u\n", imgdim[2]);
273 if(verbose>1) {printf(
"trying to read plane number from 'In Stack Position Number'\n"); fflush(stdout);}
276 imgdim[2]=(
unsigned short int)b;
277 if(verbose>2) printf(
"planeNr := %u\n", imgdim[2]);
279 if(verbose>1) {printf(
"trying to read plane number from 'Dimension Index Values'\n"); fflush(stdout);}
282 imgdim[2]=(
unsigned short int)b;
283 if(verbose>2) printf(
"planeNr := %u\n", imgdim[2]);
285 if(verbose>0) {fprintf(stderr,
"Warning: cannot find plane number.\n"); fflush(stderr);}
293 if(verbose>1) {printf(
"trying to get frame number from 'Temporal position index'\n"); fflush(stdout);}
296 imgdim[3]=(
unsigned short int)b;
297 if(verbose>2) printf(
"frameNr := %u\n", imgdim[3]);
299 if(verbose>1) {printf(
"trying to get frame number from 'Number of Time Slices'\n"); fflush(stdout);}
304 if(verbose>2) printf(
"frameNr := %u\n", imgdim[3]);
306 if(verbose>0) {fprintf(stderr,
"Warning: cannot find frame number.\n"); fflush(stderr);}
330 if(verbose>0) {printf(
"%s(dcmfile, pxlsize)\n", __func__); fflush(stdout);}
331 if(d==NULL || d->
item==NULL || pxlsize==NULL)
return(1);
332 for(
int i=0; i<3; i++) pxlsize[i]=nan(
"");
336 if(verbose>1) {printf(
"trying to find Pixel Measures Sequence\n"); fflush(stdout);}
341 if(verbose>3) {fprintf(stdout,
"Note: missing Pixel Measures Sequence.\n"); fflush(stdout);}
348 if(verbose>0) {fprintf(stderr,
"Error: missing Slice Thickness.\n"); fflush(stderr);}
353 if(verbose>1) {printf(
"trying to find Spacing Between Slices\n"); fflush(stdout);}
357 if(verbose>1) {fprintf(stderr,
"Warning: missing Spacing Between Slices.\n"); fflush(stderr);}
360 if(v>pxlsize[2]) pxlsize[2]=v;
363 if(verbose>1) {printf(
"trying to find Pixel Spacing/Size\n"); fflush(stdout);}
367 if(verbose>0) {fprintf(stderr,
"Error: missing Pixel Spacing/Size.\n"); fflush(stderr);}
371 int n=sscanf(buf,
"%lf\\%lf", &pxlsize[1], &pxlsize[0]);
374 if(verbose>0) {fprintf(stderr,
"Error: invalid Pixel Spacing/Size\n"); fflush(stderr);}
395 if(verbose>0) {printf(
"%s(dcmfile, iop)\n", __func__); fflush(stdout);}
396 if(d==NULL || d->
item==NULL || iop==NULL)
return(1);
397 for(
int i=0; i<6; i++) iop[i]=nan(
"");
401 if(verbose>1) {printf(
"reading Image Orientation (Patient)\n"); fflush(stdout);}
405 if(verbose>0) {fprintf(stderr,
"Error: no Image Orientation (Patient)\n"); fflush(stderr);}
409 if(verbose>2) printf(
" image_orientation := '%s'\n", buf);
410 int n=sscanf(buf,
"%lf\\%lf\\%lf\\%lf\\%lf\\%lf", &iop[0], &iop[1], &iop[2],
411 &iop[3], &iop[4], &iop[5]);
414 if(verbose>0) {fprintf(stderr,
"Error: invalid Image Orientation (Patient)\n"); fflush(stderr);}
443 if(verbose>0) {printf(
"%s(iop[], xyzMM[], imgPos[], xform)\n", __func__); fflush(stdout);}
444 if(iop==NULL || xyzMM==NULL || imgPos==NULL || xform==NULL)
return(1);
445 for(
int i=0; i<16; i++) xform[i]=nan(
"");
448 double readV[3], phaseV[3];
449 readV[0]=iop[0]; readV[1]=iop[1]; readV[2]=iop[2];
450 phaseV[0]=iop[3]; phaseV[1]=iop[4]; phaseV[2]=iop[5];
452 printf(
"readV := %g", readV[0]);
for(
int i=1; i<3; i++) printf(
", %g", readV[i]);
454 printf(
"phaseV := %g", phaseV[0]);
for(
int i=1; i<3; i++) printf(
", %g", phaseV[i]);
460 sliceV[0]= readV[1]*phaseV[2] - phaseV[1]*readV[2];
461 sliceV[1]=-readV[0]*phaseV[2] + phaseV[0]*readV[2];
462 sliceV[2]= readV[0]*phaseV[1] - phaseV[0]*readV[1];
464 printf(
"sliceV := %g", sliceV[0]);
for(
int i=1; i<3; i++) printf(
", %g", sliceV[i]);
470 for(
int i=0; i<3; i++) rM[0][i]=readV[i];
471 for(
int i=0; i<3; i++) rM[1][i]=phaseV[i];
472 for(
int i=0; i<3; i++) rM[2][i]=sliceV[i];
476 for(
int i=0; i<3; i++)
for(
int j=0; j<3; j++) tM[i][j]=rM[i][j];
477 for(
int i=0; i<3; i++)
for(
int j=0; j<3; j++) rM[i][j]=tM[j][i];
480 printf(
"rM :=\t%g", rM[0][0]);
481 for(
int i=1; i<3; i++) printf(
"\t%g", rM[0][i]);
483 for(
int i=0; i<3; i++) printf(
"\t%g", rM[1][i]);
485 for(
int i=0; i<3; i++) printf(
"\t%g", rM[2][i]);
489 unsigned short int xyz[3];
491 if(fabs(rM[1][0])>fabs(rM[0][0]) && fabs(rM[1][0])>fabs(rM[2][0])) xyz[0]=1;
492 else if(fabs(rM[2][0])>fabs(rM[0][0]) && fabs(rM[1][0])>fabs(rM[1][0])) xyz[0]=2;
493 if(xyz[0]==0) {
if(fabs(rM[2][1])>fabs(rM[1][1])) xyz[1]=2;
else xyz[1]=1;}
494 else if(xyz[0]==1) {
if(fabs(rM[2][1])>fabs(rM[0][1])) xyz[1]=2;
else xyz[1]=0;}
495 else {
if(fabs(rM[1][1])>fabs(rM[0][1])) xyz[1]=1;
else xyz[1]=0;}
496 xyz[2]=3-xyz[0]-xyz[1];
498 printf(
"xyz := %u", xyz[0]);
for(
int i=1; i<3; i++) printf(
", %u", xyz[i]);
499 printf(
"\n(0, 1, 2 for Sag/Cor/Tra slice)\n");
501 double cosSL=rM[xyz[2]][2];
502 if(verbose>3) {printf(
"cosSL := %g\n", cosSL); fflush(stdout);}
506 printf(
"xyzMM := %g", xyzMM[0]);
for(
int i=1; i<3; i++) printf(
", %g", xyzMM[i]);
510 double tM[3][3], sM[3][3];
511 for(
int i=0; i<3; i++)
for(
int j=0; j<3; j++) tM[i][j]=rM[i][j];
512 for(
int i=0; i<3; i++)
for(
int j=0; j<3; j++) sM[i][j]=0.0;
513 sM[0][0]=xyzMM[0]; sM[1][1]=xyzMM[1]; sM[2][2]=xyzMM[2];
514 for(
int i=0; i<3; i++)
515 for(
int j=0; j<3; j++)
516 rM[i][j]= tM[i][0]*sM[0][j] + tM[i][1]*sM[1][j] + tM[i][2]*sM[2][j];
520 for(
int i=0; i<3; i++)
521 for(
int j=0; j<3; j++)
522 xform[j+4*i]=rM[i][j];
523 for(
int i=0; i<3; i++)
524 xform[3+4*i]=imgPos[i];
552 if(verbose>0) {printf(
"%s(xform[16], quatern[3], qoffset[3])\n", __func__); fflush(stdout);}
553 if(xform==NULL)
return(1);
554 if(quatern!=NULL)
for(
int i=0; i<3; i++) quatern[i]=nan(
"");
555 if(qoffset!=NULL)
for(
int i=0; i<3; i++) qoffset[i]=nan(
"");
559 for(
int i=0; i<4; i++)
560 for(
int j=0; j<4; j++)
561 xformM[i][j]=xform[j+4*i];
563 for(
int i=0; i<2; i++)
564 for(
int j=0; j<4; j++)
565 xformM[i][j]=-xformM[i][j];
568 if(qoffset!=NULL)
for(
int i=0; i<3; i++) qoffset[i]=xformM[i][3];
571 if(quatern==NULL)
return(0);
575 for(
int i=0; i<3; i++)
576 for(
int j=0; j<3; j++)
577 mt[i][j]=xformM[i][j];
579 xd=sqrt(mt[0][0]*mt[0][0] + mt[1][0]*mt[1][0] + mt[2][0]*mt[2][0]);
580 yd=sqrt(mt[0][1]*mt[0][1] + mt[1][1]*mt[1][1] + mt[2][1]*mt[2][1]);
581 zd=sqrt(mt[0][2]*mt[0][2] + mt[1][2]*mt[1][2] + mt[2][2]*mt[2][2]);
582 if(!(xd>0.0)) {mt[0][0]=1.0; mt[1][0]=mt[2][0]=0.0; xd=1.0;}
583 if(!(yd>0.0)) {mt[1][1]=1.0; mt[0][1]=mt[2][1]=0.0; yd=1.0;}
584 if(!(zd>0.0)) {mt[2][2]=1.0; mt[0][2]=mt[1][2]=0.0; zd=1.0;}
586 for(
int i=0; i<3; i++) mt[i][0]/=xd;
587 for(
int i=0; i<3; i++) mt[i][1]/=yd;
588 for(
int i=0; i<3; i++) mt[i][2]/=zd;
593 dt= mt[0][0]*mt[1][1]*mt[2][2] - mt[0][0]*mt[2][1]*mt[1][2] - mt[1][0]*mt[0][1]*mt[2][2]
594 +mt[1][0]*mt[2][1]*mt[0][2] + mt[2][0]*mt[0][1]*mt[1][2] - mt[2][0]*mt[1][1]*mt[0][2];
595 if(verbose>3) printf(
"determinant=%g\n", dt);
596 if(dt<0.0)
for(
int i=0; i<3; i++) mt[i][2]=-mt[i][2];
600 a=1.0+mt[0][0]+mt[1][1]+mt[2][2];
603 b=0.25*(mt[2][1]-mt[1][2])/a;
604 c=0.25*(mt[0][2]-mt[2][0])/a;
605 d=0.25*(mt[1][0]-mt[0][1])/a;
607 xd=1.0+mt[0][0]-(mt[1][1]+mt[2][2]);
608 yd=1.0+mt[1][1]-(mt[0][0]+mt[2][2]);
609 zd=1.0+mt[2][2]-(mt[0][0]+mt[1][1]);
612 c=0.25*(mt[0][1]+mt[1][0])/b;
613 d=0.25*(mt[0][2]+mt[2][0])/b;
614 a=0.25*(mt[2][1]-mt[1][2])/b;
617 b=0.25*(mt[0][1]+mt[1][0])/c;
618 d=0.25*(mt[1][2]+mt[2][0])/c;
619 a=0.25*(mt[0][2]-mt[2][0])/c;
622 b=0.25*(mt[0][2]+mt[2][0])/d;
623 c=0.25*(mt[1][2]+mt[2][1])/d;
624 a=0.25*(mt[1][0]-mt[0][1])/d;
627 if(a<0.0) {b=-b; c=-c; d=-d;}
long int dcmitemGetInt(DCMITEM *d)
void dcmTagSet(DCMTAG *tag, unsigned short int group, unsigned short int element)
DCMITEM * dcmFindTag(DCMITEM *d, const short int omit, DCMTAG *tag, const int verbose)
DCMITEM * dcmFindDownTag(DCMITEM *d, const short int omit, DCMTAG *tag, const int verbose)
int dcmTagIntRange(DCMITEM *d, DCMTAG *tag, int *mi, int *ma, const int verbose)
double dcmitemGetReal(DCMITEM *d)
char * dcmValueString(DCMITEM *d)
int dcmImgPxlsize(DCMFILE *d, double *pxlsize, const int verbose)
int dcmImgDim(DCMFILE *d, unsigned short int *imgdim, const int verbose)
int dcmImgOrient(DCMFILE *d, double *iop, const int verbose)
int dcmImgIsotope(DCMFILE *d, isotope *isot, decaycorrection *dc, const int verbose)
int dcmImgPos(DCMFILE *d, double *imgpos, const int verbose)
int dcmXformToQuatern(double *xform, double *quatern, double *qoffset, const int verbose)
int dcmImgXform(double *iop, double *xyzMM, double *imgPos, double *xform, const int verbose)
char * decayDescr(decaycorrection d)
double atofVerified(const char *s)
char * isotopeName(int isotope_code)
int isotopeIdentifyHalflife(double halflife)
int isotopeIdentify(const char *isotope)
int strCleanSpaces(char *s)
char * strcasestr(const char *haystack, const char *needle)
struct DCMITEM * child_item
struct DCMITEM * next_item
Header file for libtpcdcm.
Header file for library libtpcextensions.
@ DECAY_UNKNOWN
Not known; usually assumed that data is corrected.
@ DECAY_CORRECTED_ADMIN
Data is corrected for physical decay to radioligand administration time.
@ DECAY_NOTCORRECTED
Data is not corrected for physical decay.
@ DECAY_CORRECTED
Data is corrected for physical decay.
@ DECAY_CORRECTED_START
Data is corrected for physical decay to scan start time.
@ ISOTOPE_UNKNOWN
Unknown.