TPCCLIB
Loading...
Searching...
No Matches
heart.c File Reference

Functions for simple simulation of image of heart. More...

#include "libtpcidi.h"

Go to the source code of this file.

Functions

int imgSimulateRing (IMG *img, int fi, int zi, double cx, double cy, double r1, double r2, double vr, double vi, double vo, int verbose)
int simMyocDiameterCurve (DFT *dft, double t1, double t2, double hbr, double maxdiam, double mindiam)
int imgSimulateSphere (IMG *img, int fi, double cx, double cy, double cz, double r1, double r2, double vr, double vi, double vo, int verbose)

Detailed Description

Functions for simple simulation of image of heart.

Author
Vesa Oikonen

Definition in file heart.c.

Function Documentation

◆ imgSimulateRing()

int imgSimulateRing ( IMG * img,
int fi,
int zi,
double cx,
double cy,
double r1,
double r2,
double vr,
double vi,
double vo,
int verbose )

Simulate an image of ring with specified inner and outer radius and activity in the ring and inside and outside of it. The applied method is only approximate at pixel borders (pixel is divided into 5x5 subpixels). PET resolution effects are not simulated.

See also
imgRingMask, imgSimulateSphere, imgGaussianFIRFilter, idiSimulateTubeVol
Returns
Returns 0 if successful.
Parameters
imgPointer to allocated static or dynamic image; image must contain pixel sizes and dimensions; values are added to any existing pixel values, thus you may need to set pixel values to zero before calling this function.
fiFrame index [0..dimt-1].
ziPlane index [0..dimz-1].
cxX distance of circle centre (mm) from the upper left corner of the image.
cyY distance of circle centre (mm) from the upper left corner of the image.
r1Inner radius of circle (mm).
r2Outer radius of circle (mm).
vrRing value; this value is added to each pixel value that fits inside the radius's; the pixels that are partially inside the ring will get fraction of the value.
viInside value; this value is added to each pixel value that fits inside the inner radius; the pixels that are partially inside the radius will get fraction of the value.
voOutside value; this value is added to each pixel value that fits outside the outer radius; the pixels that are partially outside the radius will get fraction of the value.
verboseVerbose level; set to <=0 to prevent all prints to stdout.

Definition at line 17 of file heart.c.

45 {
46 int nr, ni, no, xi, yi, i, j;
47 double dx[5], dy[5], v, d;
48 double ri2, ro2;
49
50 if(verbose>0)
51 printf("%s(img, %d, %d, %g, %g, %g, %g, %g, %g, %g, %d)\n",
52 __func__, fi, zi, cx, cy, r1, r2, vr, vi, vo, verbose);
53 if(r1>=r2 || r1<0.0) {
54 if(verbose>0) fprintf(stderr, "Error: invalid radius.\n");
55 return(1);
56 }
57
58 if(img->status<IMG_STATUS_OCCUPIED) return(1);
59 if(zi<0 || zi>=img->dimz) return(2);
60 if(img->sizey<=0.0 || img->sizex<=0.0) return(3);
61 if(img->sizey!=img->sizex) return(4);
62 if(img->dimt<1 || fi>=img->dimt) return(5);
63 if(r1<0.0 || r2<r1) return(6);
64
65 /* Compare radius ^2 to sum of squared distances instead of square roots */
66 ri2=r1*r1; ro2=r2*r2;
67 for(yi=0; yi<img->dimy; yi++) {
68 dy[0]=(0.1+(double)yi)*img->sizey - cy;
69 for(j=1; j<5; j++) dy[j]=dy[j-1]+0.2*img->sizey;
70 for(xi=0; xi<img->dimx; xi++) {
71 dx[0]=(0.1+(double)xi)*img->sizex - cx;
72 for(i=1; i<5; i++) dx[i]=dx[i-1]+0.2*img->sizex;
73 nr=ni=no=0;
74 for(i=0; i<5; i++) for(j=0; j<5; j++) {
75 d=dx[i]*dx[i]+dy[j]*dy[j];
76 if(d<ri2) ni++; else if(d<ro2) nr++; else no++;
77 }
78 v=(double)nr*vr/25.0;
79 v+=(double)ni*vi/25.0;
80 v+=(double)no*vo/25.0;
81 img->m[zi][yi][xi][fi]+=v;
82 }
83 }
84 return(0);
85}
#define IMG_STATUS_OCCUPIED
float sizex
unsigned short int dimx
float **** m
char status
unsigned short int dimt
float sizey
unsigned short int dimz
unsigned short int dimy

◆ imgSimulateSphere()

int imgSimulateSphere ( IMG * img,
int fi,
double cx,
double cy,
double cz,
double r1,
double r2,
double vr,
double vi,
double vo,
int verbose )

Simulate a 3D image of circle with specified inner and outer radius and activity in the circle and inside and outside of it.

The applied method is only approximate at pixel borders (pixel is divided into 5x5 subpixels). PET resolution effects are not simulated.

See also
imgRingMask, imgCircleMask, imgGaussianFIRFilter, idiSimulateTubeVol
Returns
Returns 0 if successful.
Parameters
imgPointer to allocated static or dynamic image; image must contain pixel sizes and dimensions; values are added to any existing pixel values, thus you may need to set pixel values to zero before calling this function.
fiFrame index [0..dimt-1].
cxX distance of circle centre (mm) from the upper left corner of the image.
cyY distance of circle centre (mm) from the upper left corner of the image.
czZ distance of circle centre (mm) from the upper left corner of the image.
r1Inner radius of circle (mm).
r2Outer radius of circle (mm).
vrSphere wall value; this value is added to each pixel value that fits inside the radius's; the pixels that are partially inside the wall will get fraction of the value.
viInside value; this value is added to each pixel value that fits inside the inner radius; the pixels that are partially inside the radius will get fraction of the value.
voOutside value; this value is added to each pixel value that fits outside the outer radius; the pixels that are partially outside the radius will get fraction of the value.
verboseVerbose level; set to <=0 to prevent all prints to stdout.

Definition at line 154 of file heart.c.

182 {
183 int nr, ni, no, xi, yi, zi, i, j, k;
184 double dx[5], dy[5], dz[5], v, d;
185 double ri2, ro2;
186
187 if(verbose>0)
188 printf("%s(img, %d, %g, %g, %g, %g, %g, %g, %g, %g, %d)\n",
189 __func__, fi, cx, cy, cz, r1, r2, vr, vi, vo, verbose);
190 if(r1>=r2 || r1<0.0) {
191 if(verbose>0) fprintf(stderr, "Error: invalid radius.\n");
192 return(1);
193 }
194
195 if(img->status<IMG_STATUS_OCCUPIED) return(1);
196 if(img->sizez<=0.0 || img->sizey<=0.0 || img->sizex<=0.0) return(2);
197 if(img->sizey!=img->sizex || img->sizez!=img->sizex) return(3);
198 if(img->dimt<1 || fi>=img->dimt) return(4);
199 if(r1<0.0 || r2<r1) return(5);
200
201 /* Compare radius ^2 to sum of squared distances instead of square roots */
202 ri2=r1*r1; ro2=r2*r2;
203 for(zi=0; zi<img->dimz; zi++) {
204 dz[0]=(0.1+(double)zi)*img->sizez - cz;
205 for(k=1; k<5; k++) dz[k]=dz[k-1]+0.2*img->sizez;
206 for(yi=0; yi<img->dimy; yi++) {
207 dy[0]=(0.1+(double)yi)*img->sizey - cy;
208 for(j=1; j<5; j++) dy[j]=dy[j-1]+0.2*img->sizey;
209 for(xi=0; xi<img->dimx; xi++) {
210 dx[0]=(0.1+(double)xi)*img->sizex - cx;
211 for(i=1; i<5; i++) dx[i]=dx[i-1]+0.2*img->sizex;
212 nr=ni=no=0;
213 for(i=0; i<5; i++) for(j=0; j<5; j++) for(k=0; k<5; k++) {
214 d=dx[i]*dx[i]+dy[j]*dy[j]+dz[k]*dz[k];
215 if(d<ri2) ni++; else if(d<ro2) nr++; else no++;
216 }
217 v=(double)nr*vr/125.0;
218 v+=(double)ni*vi/125.0;
219 v+=(double)no*vo/125.0;
220 img->m[zi][yi][xi][fi]+=v;
221 }
222 }
223 }
224 return(0);
225}
float sizez

◆ simMyocDiameterCurve()

int simMyocDiameterCurve ( DFT * dft,
double t1,
double t2,
double hbr,
double maxdiam,
double mindiam )

Calculate the inner LV cavity diameter as a function of time for simulations.

10 samples per heart beat will be calculated. Fractional increase/decrease rate is fixed and coded in here.

See also
imgSimulateRing, imgRingMask, idiSimulateTubeVol
Returns
Returns 0 if successful.
Parameters
dftPointer to initiated DFT struct where diameter curve will be written.
t1Start time (s).
t2Stop time (s).
hbrHeart rate (beats/min).
maxdiamMaximum inner diameter (mm).
mindiamMinimum inner diameter (mm).

Definition at line 96 of file heart.c.

109 {
110 int n, i, ret;
111 double s;
112 double rfract[10]={1.0, 0.6, 0.25, 0.0, 0.1, 0.25, 0.6, 0.8, 0.9, 0.95};
113
114 /* check input */
115 if(dft==NULL) return(1);
116 if(t2<t1) return(1);
117 if(maxdiam<mindiam) return(1);
118
119 /* delete any previous curve contents */
120 dftEmpty(dft);
121
122 /* convert heart rate to per sec */
123 if(hbr>0.0) hbr/=60.0; else hbr=0.0;
124
125 /* calculate the nr of samples */
126 if(hbr>0.0 && (t2-t1)>0.0) n=10.0*(t2-t1)/hbr; else n=1;
127
128 /* Set up curve struct */
129 ret=dftSetmem(dft, n, 1); if(ret!=0) return(3);
130 dft->frameNr=n; dft->voiNr=1; dft->timetype=DFT_TIME_STARTEND;
131 dft->timeunit=TUNIT_SEC;
132
133 /* Fill curve */
134 dft->x1[0]=t1; if(hbr>0.0) s=0.1*hbr; else s=t2-t1;
135 for(i=n=0; i<dft->frameNr; i++) {
136 if(i>0) dft->x1[i]=dft->x2[i-1];
137 dft->x2[i]=dft->x1[i]+s; dft->x[i]=0.5*(dft->x1[i]+dft->x2[i]);
138 dft->voi[0].y[i]=mindiam+rfract[n]*(maxdiam-mindiam); n++; if(n==10) n=0;
139 }
140
141 return 0;
142}
int dftSetmem(DFT *data, int frameNr, int voiNr)
Definition dft.c:57
void dftEmpty(DFT *data)
Definition dft.c:20
#define DFT_TIME_STARTEND
int timetype
Voi * voi
int timeunit
double * x1
int voiNr
double * x2
int frameNr
double * x
double * y