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

Misc arithmetical routines for processing 4D IMG data. More...

#include "libtpcimgp.h"

Go to the source code of this file.

Functions

int imgArithm (IMG *img1, IMG *img2, char operation, float ulimit, int verbose)
 
int imgArithmConst (IMG *img, float operand, char operation, float ulimit, int verbose)
 
int imgArithmFrame (IMG *img1, IMG *img2, char operation, float ulimit, int verbose)
 
int imgLn (IMG *img)
 
int imgLog10 (IMG *img)
 
int imgAbs (IMG *img)
 
int imgInv (IMG *img)
 
int imgFrameIntegral (IMG *img, int first, int last, IMG *iimg, int verbose)
 
int imgRawCountsPerTime (IMG *img, int operation)
 
int imgConvertUnit (IMG *img, char *unit)
 
int imgAUMC (IMG *img, IMG *oimg, int verbose)
 
int imgMRT (IMG *img, IMG *oimg, int verbose)
 

Detailed Description

Misc arithmetical routines for processing 4D IMG data.

Author
Vesa Oikonen

Definition in file imgarithm.c.

Function Documentation

◆ imgAbs()

int imgAbs ( IMG * img)

Replace IMG data values by their absolute values.

See also
imgLog10, imgLn, imgArithm, imgMatch
Returns
Returns 0, if ok.
Parameters
imgPointer to IMG data.

Definition at line 292 of file imgarithm.c.

295 {
296 if(img->status<IMG_STATUS_OCCUPIED) return(1);
297 if(img->dimt<1 || img->dimz<1 || img->dimy<1 || img->dimx<1) return(2);
298 for(int pi=0; pi<img->dimz; pi++)
299 for(int yi=0; yi<img->dimy; yi++)
300 for(int xi=0; xi<img->dimx; xi++)
301 for(int fi=0; fi<img->dimt; fi++)
302 img->m[pi][yi][xi][fi]=fabsf(img->m[pi][yi][xi][fi]);
303 return(0);
304}
#define IMG_STATUS_OCCUPIED
unsigned short int dimx
float **** m
char status
unsigned short int dimt
unsigned short int dimz
unsigned short int dimy

◆ imgArithm()

int imgArithm ( IMG * img1,
IMG * img2,
char operation,
float ulimit,
int verbose )

Simple arithmetics between matching IMG planes and frames. Specify the operation as one of characters +, -, /, :, *, ., x. Results that are higher than ulimit are set to ulimit.

See also
imgArithmConst, imgArithmFrame, imgRawCountsPerTime, imgConvertUnit, imgSS
Returns
Returns 0, if ok.
Parameters
img1The first IMG data.
img2The second IMG data.
operationOperation, one of the characters +, -, /, :, *, ., x.
ulimitResults that are higher than ulimit are set to ulimit; set to <=0 if not needed.
verboseVerbose level; if <=0, then nothing is printed into stderr.

Definition at line 16 of file imgarithm.c.

27 {
28 if(verbose>0) printf("%s(img1, img2, '%c', %g, %d)\n", __func__, operation, ulimit, verbose);
29
30 /* Check the arguments */
32 if(verbose>0) fprintf(stderr, "Invalid image status.\n");
33 return(1);
34 }
35 int ret=0;
36 if(img1->dimx!=img2->dimx || img1->dimy!=img2->dimy) ret=1;
37 /* Check the plane numbers */
38 if(img1->dimz!=img2->dimz) ret=2;
39 if(ret==0) for(int pi=0; pi<img1->dimz; pi++)
40 if(img1->planeNumber[pi]!=img2->planeNumber[pi]) ret=2;
41 /* Check the frame numbers */
42 if(img1->dimt!=img2->dimt) ret=3;
43 if(ret>0) {
44 if(verbose>0) fprintf(stderr, "Image dimensions do not match.\n");
45 return(ret);
46 }
47
48 /* Operate */
49 switch(operation) {
50 case '+':
51 for(int pi=0; pi<img1->dimz; pi++) for(int yi=0; yi<img1->dimy; yi++)
52 for(int xi=0; xi<img1->dimx; xi++) for(int fi=0; fi<img1->dimt; fi++)
53 img1->m[pi][yi][xi][fi]+=img2->m[pi][yi][xi][fi];
54 break;
55 case '-':
56 for(int pi=0; pi<img1->dimz; pi++) for(int yi=0; yi<img1->dimy; yi++)
57 for(int xi=0; xi<img1->dimx; xi++) for(int fi=0; fi<img1->dimt; fi++)
58 img1->m[pi][yi][xi][fi]-=img2->m[pi][yi][xi][fi];
59 break;
60 case '/':
61 case ':':
62 for(int pi=0; pi<img1->dimz; pi++) for(int yi=0; yi<img1->dimy; yi++)
63 for(int xi=0; xi<img1->dimx; xi++) for(int fi=0; fi<img1->dimt; fi++) {
64 if(fabs(img2->m[pi][yi][xi][fi])>1.0E-5)
65 img1->m[pi][yi][xi][fi]/=img2->m[pi][yi][xi][fi];
66 else img1->m[pi][yi][xi][fi]=0.0;
67 }
68 break;
69 case '*':
70 case 'x':
71 case '.':
72 for(int pi=0; pi<img1->dimz; pi++) for(int yi=0; yi<img1->dimy; yi++)
73 for(int xi=0; xi<img1->dimx; xi++) for(int fi=0; fi<img1->dimt; fi++)
74 img1->m[pi][yi][xi][fi]*=img2->m[pi][yi][xi][fi];
75 break;
76 default:
77 if(verbose>0) fprintf(stderr, "Invalid operation.\n");
78 return(10);
79 }
80
81 /* Check for limits */
82 if(ulimit>0.0) {
83 for(int pi=0; pi<img1->dimz; pi++) for(int yi=0; yi<img1->dimy; yi++)
84 for(int xi=0; xi<img1->dimx; xi++) for(int fi=0; fi<img1->dimt; fi++)
85 if(img1->m[pi][yi][xi][fi]>ulimit) img1->m[pi][yi][xi][fi]=ulimit;
86 }
87
88 return(0);
89}
int * planeNumber

◆ imgArithmConst()

int imgArithmConst ( IMG * img,
float operand,
char operation,
float ulimit,
int verbose )

Simple arithmetic between IMG and specified constant.

Specify the operation as one of characters +, -, /, :, *, ., x. Results that are higher than ulimit are set to ulimit.

See also
imgArithm, imgScale, imgInv, imgArithmFrame, imgRawCountsPerTime, imgConvertUnit
Returns
Returns 0, if ok.
Parameters
imgIMG data which is modified.
operandConstant value which is used to modify the data.
operationOperation, one of the characters +, -, /, :, *, ., x.
ulimitResults that are higher than ulimit are set to ulimit; set to <=0 if not needed.
verboseVerbose level; if <=0, then nothing is printed into stderr.

Definition at line 100 of file imgarithm.c.

111 {
112 if(verbose>0) printf("%s(img, %g, '%c', %g, %d)\n", __func__, operand, operation, ulimit, verbose);
113
114 /* Check the arguments */
115 if(img->status!=IMG_STATUS_OCCUPIED) {
116 if(verbose>0) fprintf(stderr, "Invalid image status.\n");
117 return(1);
118 }
119 switch(operation) {
120 case '+':
121 for(int pi=0; pi<img->dimz; pi++) for(int yi=0; yi<img->dimy; yi++)
122 for(int xi=0; xi<img->dimx; xi++) for(int fi=0; fi<img->dimt; fi++)
123 img->m[pi][yi][xi][fi]+=operand;
124 break;
125 case '-':
126 for(int pi=0; pi<img->dimz; pi++) for(int yi=0; yi<img->dimy; yi++)
127 for(int xi=0; xi<img->dimx; xi++) for(int fi=0; fi<img->dimt; fi++)
128 img->m[pi][yi][xi][fi]-=operand;
129 break;
130 case '/':
131 case ':':
132 if(fabs(operand)<1.0e-100) return(2);
133 for(int pi=0; pi<img->dimz; pi++) for(int yi=0; yi<img->dimy; yi++)
134 for(int xi=0; xi<img->dimx; xi++) for(int fi=0; fi<img->dimt; fi++)
135 img->m[pi][yi][xi][fi]/=operand;
136 break;
137 case '*':
138 case 'x':
139 case '.':
140 for(int pi=0; pi<img->dimz; pi++) for(int yi=0; yi<img->dimy; yi++)
141 for(int xi=0; xi<img->dimx; xi++) for(int fi=0; fi<img->dimt; fi++)
142 img->m[pi][yi][xi][fi]*=operand;
143 break;
144 default:
145 if(verbose>0) fprintf(stderr, "Invalid operation.\n");
146 return(10);
147 }
148
149 /* Check for limits */
150 if(ulimit>0.0) {
151 for(int pi=0; pi<img->dimz; pi++) for(int yi=0; yi<img->dimy; yi++)
152 for(int xi=0; xi<img->dimx; xi++) for(int fi=0; fi<img->dimt; fi++)
153 if(img->m[pi][yi][xi][fi]>ulimit) img->m[pi][yi][xi][fi]=ulimit;
154 }
155
156 return(0);
157}

Referenced by imgConvertUnit(), and imgTimeIntegral().

◆ imgArithmFrame()

int imgArithmFrame ( IMG * img1,
IMG * img2,
char operation,
float ulimit,
int verbose )

Simple arithmetic between matching IMG planes and the first frame of img2.

Specify the operation as one of characters +, -, /, :, *, ., x. Results that are higher than ulimit are set to ulimit.

See also
imgArithmConst, imgArithm, imgFrameIntegral
Returns
Returns 0, if ok.
Parameters
img1IMG data which is modified.
img2Operand IMG data, only the first frame is used.
operationOperation, one of the characters +, -, /, :, *, ., x.
ulimitResults that are higher than ulimit are set to ulimit; set to <=0 if not needed.
verboseVerbose level; if <=0, then nothing is printed into stderr.

Definition at line 168 of file imgarithm.c.

179 {
180 if(verbose>0) printf("%s(img1, img2, '%c', %g, %d)\n", __func__, operation, ulimit, verbose);
181
182 /* Check the arguments */
184 if(verbose>0) fprintf(stderr, "Invalid image status.\n");
185 return(1);
186 }
187 int ret=0;
188 if(img1->dimx!=img2->dimx || img1->dimy!=img2->dimy) ret=1;
189 /* Check the plane numbers */
190 if(img1->dimz!=img2->dimz) ret=2;
191 if(ret==0) for(int pi=0; pi<img1->dimz; pi++)
192 if(img1->planeNumber[pi]!=img2->planeNumber[pi]) ret=2;
193 if(ret>0) {
194 if(verbose>0) fprintf(stderr, "Image dimensions do not match.\n");
195 return(ret);
196 }
197
198 /* Operate */
199 switch(operation) {
200 case '+':
201 for(int pi=0; pi<img1->dimz; pi++) for(int yi=0; yi<img1->dimy; yi++)
202 for(int xi=0; xi<img1->dimx; xi++) for(int fi=0; fi<img1->dimt; fi++)
203 img1->m[pi][yi][xi][fi]+=img2->m[pi][yi][xi][0];
204 break;
205 case '-':
206 for(int pi=0; pi<img1->dimz; pi++) for(int yi=0; yi<img1->dimy; yi++)
207 for(int xi=0; xi<img1->dimx; xi++) for(int fi=0; fi<img1->dimt; fi++)
208 img1->m[pi][yi][xi][fi]-=img2->m[pi][yi][xi][0];
209 break;
210 case '/':
211 case ':':
212 for(int pi=0; pi<img1->dimz; pi++) for(int yi=0; yi<img1->dimy; yi++)
213 for(int xi=0; xi<img1->dimx; xi++) {
214 if(fabs(img2->m[pi][yi][xi][0])>1.0E-8)
215 for(int fi=0; fi<img1->dimt; fi++)
216 img1->m[pi][yi][xi][fi]/=img2->m[pi][yi][xi][0];
217 else for(int fi=0; fi<img1->dimt; fi++) img1->m[pi][yi][xi][fi]=0.0;
218 }
219 break;
220 case '*':
221 case 'x':
222 case '.':
223 for(int pi=0; pi<img1->dimz; pi++) for(int yi=0; yi<img1->dimy; yi++)
224 for(int xi=0; xi<img1->dimx; xi++) for(int fi=0; fi<img1->dimt; fi++)
225 img1->m[pi][yi][xi][fi]*=img2->m[pi][yi][xi][0];
226 break;
227 default:
228 if(verbose>0) fprintf(stderr, "Invalid operation.\n");
229 return(10);
230 }
231
232 /* Check for limits */
233 if(ulimit>0.0) {
234 for(int pi=0; pi<img1->dimz; pi++) for(int yi=0; yi<img1->dimy; yi++)
235 for(int xi=0; xi<img1->dimx; xi++) for(int fi=0; fi<img1->dimt; fi++)
236 if(img1->m[pi][yi][xi][fi]>ulimit) img1->m[pi][yi][xi][fi]=ulimit;
237 }
238
239 return(0);
240}

◆ imgAUMC()

int imgAUMC ( IMG * img,
IMG * oimg,
int verbose )

Calculate (incomplete) area under moment curve (AUMC) for every pixel in a dynamic image.

Data is not extrapolated. Frame gaps or overlaps are not accepted.

See also
imgMRT, imgGetMaxTime, imgGetPeak, imgGetMaxFrame, imgFramesCheck, imgMaxDifference, imgSS
Returns
Returns 0, if ok.
Parameters
imgPointer to dynamic image; not modified. Frame times are obligatory.
oimgPointer to empty IMG struct in which the AUMC will be written; any old contents are deleted.
verboseVerbose level; if zero, then nothing is printed to stderr or stdout.

Definition at line 540 of file imgarithm.c.

548 {
549 if(verbose>0) printf("%s(*img, *oimg)\n", __func__);
550
551 if(img==NULL || img->status!=IMG_STATUS_OCCUPIED) return(1);
552 if(img->dimt<2) {
553 if(verbose>1) fprintf(stderr, "Error: dynamic image required.\n");
554 return(2);
555 }
556 if(!imgExistentTimes(img)) {
557 if(verbose>1) fprintf(stderr, "Error: unknown frame times.\n");
558 return(2);
559 }
560 if(oimg==NULL) return(3);
561 if(oimg->status==IMG_STATUS_OCCUPIED) imgEmpty(oimg);
562
563 if(imgFramesCheck(img, verbose-1)>0) {
564 if(verbose>1) fprintf(stderr, "Error: gaps or overlap between time frames.\n");
565 return(4);
566 }
567
568 /* Allocate memory for one frame */
569 int ret;
570 if(verbose>1) printf("allocating memory for %dx%dx%d pixels\n", img->dimz, img->dimy, img->dimx);
571 ret=imgAllocate(oimg, img->dimz, img->dimy, img->dimx, 1);
572 if(ret) return(ret);
573 /* set image header information */
574 imgCopyhdr(img, oimg);
575 oimg->start[0]=img->start[0]; oimg->end[0]=img->end[img->dimt-1];
576 oimg->mid[0]=(oimg->start[0]+oimg->end[0])/2.0;
577 oimg->unit=CUNIT_UNKNOWN;
578
579 /* Calculate sum of (frame time * pixel value) */
580 for(int zi=0; zi<img->dimz; zi++) {
581 for(int yi=0; yi<img->dimy; yi++) {
582 for(int xi=0; xi<img->dimx; xi++) {
583 oimg->m[zi][yi][xi][0]=0.0;
584 for(int ti=0; ti<img->dimt; ti++) {
585 if(isnan(img->m[zi][yi][xi][ti])) continue;
586 float fdur=img->end[ti]-img->start[ti]; if(!(fdur>0.0)) fdur=0.0;
587 oimg->m[zi][yi][xi][0]+=img->m[zi][yi][xi][ti]*img->mid[ti]*fdur;
588 }
589 }
590 }
591 }
592
593 return(0);
594}
int imgExistentTimes(IMG *img)
Definition img.c:613
int imgAllocate(IMG *image, int planes, int rows, int columns, int frames)
Definition img.c:194
int imgCopyhdr(IMG *image1, IMG *image2)
Definition img.c:471
void imgEmpty(IMG *image)
Definition img.c:121
int imgFramesCheck(IMG *img, int verbose)
Definition imgframe.c:15
char unit
float * start
float * end
float * mid

◆ imgConvertUnit()

int imgConvertUnit ( IMG * img,
char * unit )

Converts the unit of pixel values in IMG based to specified unit string.

See also
imgArithmConst, imgArithm, imgFrameIntegral
Returns
Returns 0 if successful.
Parameters
imgPointer to IMG struct.
unitString containing the new unit.

Definition at line 480 of file imgarithm.c.

485 {
486 int ret, new_unit=0;
487 float conversion_factor=1.0;
488
489 if(img==NULL || unit==NULL) return(1);
490 if(img->unit==CUNIT_UNKNOWN) return(1);
491 /* Try to identify requested unit */
492 new_unit=imgUnitId(unit); if(new_unit<0) return(1-new_unit);
493 /* Check if unit needs no conversion */
494 if(img->unit==new_unit) return(0);
495 /* Get conversion factor */
496 if(img->unit==CUNIT_KBQ_PER_ML && new_unit==CUNIT_BQ_PER_ML)
497 conversion_factor=1000.0;
498 else if(img->unit==CUNIT_BQ_PER_ML && new_unit==CUNIT_KBQ_PER_ML)
499 conversion_factor=0.001;
500 else if(img->unit==CUNIT_KBQ_PER_ML && new_unit==CUNIT_NCI_PER_ML)
501 conversion_factor=27.027;
502 else if(img->unit==CUNIT_NCI_PER_ML && new_unit==CUNIT_KBQ_PER_ML)
503 conversion_factor=0.037;
504 else if(img->unit==CUNIT_NCI_PER_ML && new_unit==CUNIT_BQ_PER_ML)
505 conversion_factor=37.0;
506 else if(img->unit==CUNIT_KBQ_PER_ML && new_unit==CUNIT_MBQ_PER_ML)
507 conversion_factor=0.001;
508 else if(img->unit==CUNIT_MBQ_PER_ML && new_unit==CUNIT_KBQ_PER_ML)
509 conversion_factor=1000.0;
510 else if(img->unit==CUNIT_PER_SEC && new_unit==CUNIT_PER_MIN)
511 conversion_factor=60.0;
512 else if(img->unit==CUNIT_PER_MIN && new_unit==CUNIT_PER_SEC)
513 conversion_factor=1.0/60.0;
514 else if(img->unit==CUNIT_ML_PER_ML && new_unit==CUNIT_ML_PER_DL)
515 conversion_factor=0.01;
516 else if(img->unit==CUNIT_ML_PER_DL && new_unit==CUNIT_ML_PER_ML)
517 conversion_factor=100.0;
518 else
519 return(10);
520
521 /* Convert pixel values */
522 ret=imgArithmConst(img, conversion_factor, '*', FLT_MAX, 0);
523 if(ret) return(10+ret);
524
525 /* Set the unit id */
526 img->unit=new_unit;
527
528 return(0);
529}
int imgArithmConst(IMG *img, float operand, char operation, float ulimit, int verbose)
Definition imgarithm.c:100
int imgUnitId(char *unit)
Definition imgunits.c:14

◆ imgFrameIntegral()

int imgFrameIntegral ( IMG * img,
int first,
int last,
IMG * iimg,
int verbose )

Integration from first frame (0..last) to last frame (first..dimt) to iimg, which is allocated here.

Frames do not have to be continuous in time. Time unit in integral is sec. Raw data (sinogram) must be divided by frame durations before calling this. If dynamic image data does not contain frame times (e.g. Analyze image) then just the sum is calculated.

See also
imgArithm, imgRawCountsPerTime, imgTimeIntegral, imgAUMC
Returns
Returns 0 if ok, otherwise >0.
Parameters
img(Dynamic) IMG data.
firstFirst frame to include in AUC; 0..dimt-1.
lastLast frame to include in AUC; 0..dimt-1.
iimgPointer to initiated and empty AUC IMG data.
verboseVerbose level; if <=0, then nothing is printed into stderr.

Definition at line 346 of file imgarithm.c.

357 {
358 if(verbose>0) printf("%s(img, %d, %d, iimg, %d)\n", __func__, first, last, verbose);
359
360 int zi, yi, xi, fi, ret, times_exist;
361 float fstart, fend, dur, x, y, k;
362
363 /* Check the arguments */
364 if(img==NULL || iimg==NULL || first<0 || first>last) return(1);
365 if(img->status!=IMG_STATUS_OCCUPIED) return(2);
366 times_exist=imgExistentTimes(img);
367 fstart=img->start[first]; fend=img->end[last];
368 if(verbose>1) printf(" time_range := %g - %g\n", fstart, fend);
369
370 /* Allocate memory for the integral */
371 imgEmpty(iimg);
372 ret=imgAllocateWithHeader(iimg, img->dimz, img->dimy, img->dimx, 1, img);
373 if(ret) {
374 if(verbose>0) fprintf(stderr, "Error %d in allocating memory for sum image.\n", ret);
375 imgEmpty(iimg); return(3);
376 }
377
378 /* Set header information */
379 iimg->start[0]=fstart; iimg->end[0]=fend;
380 iimg->mid[0]=0.5*(iimg->start[0]+iimg->end[0]);
383 iimg->decayCorrFactor[0]=0.0;
384 /* Change also the unit, if possible */
385 if(img->type==IMG_TYPE_IMAGE) {
386 if(img->unit==CUNIT_KBQ_PER_ML) iimg->unit=CUNIT_SEC_KBQ_PER_ML;
387 }
388
389 /* Integrate the first frame */
390 fi=first;
391 if(times_exist) {
392 dur=img->end[fi]-img->start[fi]; if(dur<0.0) {imgEmpty(iimg); return(4);}
393 } else dur=1.0;
394 for(zi=0; zi<img->dimz; zi++)
395 for(yi=0; yi<img->dimy; yi++)
396 for(xi=0; xi<img->dimx; xi++)
397 iimg->m[zi][yi][xi][0]=dur*img->m[zi][yi][xi][fi];
398 /* Add integrals of the following frames */
399 for(fi=first+1; fi<=last; fi++) {
400 if(times_exist) {
401 dur=img->end[fi]-img->start[fi]; if(dur<0.0) {imgEmpty(iimg); return(4);}
402 } else dur=1.0;
403 /* Add the integral of this frame to the previous integral */
404 for(zi=0; zi<img->dimz; zi++)
405 for(yi=0; yi<img->dimy; yi++)
406 for(xi=0; xi<img->dimx; xi++)
407 iimg->m[zi][yi][xi][0]+=dur*img->m[zi][yi][xi][fi];
408 if(times_exist) {
409 /* Check whether frames are contiguous */
410 dur=img->start[fi]-img->end[fi-1]; if(dur<=1.0E-10) continue;
411 /* When not, calculate the integral between frames */
412 x=0.5*(img->start[fi]+img->end[fi-1]);
413 for(zi=0; zi<img->dimz; zi++)
414 for(yi=0; yi<img->dimy; yi++)
415 for(xi=0; xi<img->dimx; xi++) {
416 k=(img->m[zi][yi][xi][fi]-img->m[zi][yi][xi][fi-1])
417 /(img->mid[fi]-img->mid[fi-1]);
418 y=img->m[zi][yi][xi][fi-1]+k*(x-img->mid[fi-1]);
419 iimg->m[zi][yi][xi][0]+=dur*y;
420 }
421 }
422 } /* next frame */
423
424 /* Set frame times */
425 iimg->start[0]=img->start[first];
426 iimg->end[0]=img->end[last];
427 iimg->mid[0]=0.5*(iimg->start[0]+iimg->end[0]);
428
429 return(0);
430}
int imgAllocateWithHeader(IMG *image, int planes, int rows, int columns, int frames, IMG *image_from)
Definition img.c:279
#define IMG_TYPE_RAW
#define IMG_DC_CORRECTED
#define IMG_DC_NONCORRECTED
#define IMG_TYPE_IMAGE
char type
char decayCorrection
float * decayCorrFactor

Referenced by imgsegmSimilar(), imgThresholding(), imgThresholdingLowHigh(), and imgTimeIntegral().

◆ imgInv()

int imgInv ( IMG * img)

Replace IMG data values by their inverse value (1/activity).

Pixels with <=0 are set to zero.

See also
imgLn, imgLog10, imgAbs, imgArithm
Returns
Returns 0, if ok.
Parameters
imgPointer to IMG data.

Definition at line 314 of file imgarithm.c.

317 {
318 if(img->status<IMG_STATUS_OCCUPIED) return(1);
319 if(img->dimt<1 || img->dimz<1 || img->dimy<1 || img->dimx<1) return(2);
320 for(int pi=0; pi<img->dimz; pi++)
321 for(int yi=0; yi<img->dimy; yi++)
322 for(int xi=0; xi<img->dimx; xi++)
323 for(int fi=0; fi<img->dimt; fi++) {
324 if(img->m[pi][yi][xi][fi]<=0.0) img->m[pi][yi][xi][fi]=0.0;
325 else {
326 img->m[pi][yi][xi][fi]=1.0/img->m[pi][yi][xi][fi];
327 if(!isfinite(img->m[pi][yi][xi][fi])) img->m[pi][yi][xi][fi]=0.0;
328 }
329 }
330 return(0);
331}

◆ imgLn()

int imgLn ( IMG * img)

Replace IMG data values by their natural logarithms.

See also
imgLog10, imgAbs, imgArithm, imgInv, imgSS
Returns
Returns 0, if ok.
Parameters
imgPointer to IMG data.

Definition at line 248 of file imgarithm.c.

251 {
252 if(img->status<IMG_STATUS_OCCUPIED) return(1);
253 if(img->dimt<1 || img->dimz<1 || img->dimy<1 || img->dimx<1) return(2);
254 for(int pi=0; pi<img->dimz; pi++)
255 for(int yi=0; yi<img->dimy; yi++)
256 for(int xi=0; xi<img->dimx; xi++)
257 for(int fi=0; fi<img->dimt; fi++) {
258 if(img->m[pi][yi][xi][fi]<=0.0) img->m[pi][yi][xi][fi]=0.0;
259 else img->m[pi][yi][xi][fi]=log(img->m[pi][yi][xi][fi]);
260 }
261 return(0);
262}

◆ imgLog10()

int imgLog10 ( IMG * img)

Replace IMG data values by their log10 values.

See also
imgLn, imgAbs, imgArithm
Returns
Returns 0, if ok.
Parameters
imgPointer to IMG data.

Definition at line 270 of file imgarithm.c.

273 {
274 if(img->status<IMG_STATUS_OCCUPIED) return(1);
275 if(img->dimt<1 || img->dimz<1 || img->dimy<1 || img->dimx<1) return(2);
276 for(int pi=0; pi<img->dimz; pi++)
277 for(int yi=0; yi<img->dimy; yi++)
278 for(int xi=0; xi<img->dimx; xi++)
279 for(int fi=0; fi<img->dimt; fi++) {
280 if(img->m[pi][yi][xi][fi]<=0.0) img->m[pi][yi][xi][fi]=0.0;
281 else img->m[pi][yi][xi][fi]=log10(img->m[pi][yi][xi][fi]);
282 }
283 return(0);
284}

◆ imgMRT()

int imgMRT ( IMG * img,
IMG * oimg,
int verbose )

Calculate (incomplete) mean residence time (MRT) for every pixel in dynamic image.

MRT = area under moment curve (AUMC) / area under curve (AUC). Data is not extrapolated. Frame gaps or overlaps are not accepted.

See also
imgAUMC, imgGetMaxTime, imgGetPeak, imgGetMaxFrame, imgFramesCheck
Returns
Returns 0, if ok.
Parameters
imgPointer to dynamic image; not modified. Frame times are obligatory.
oimgPointer to empty IMG struct in which the AUMC will be written; any old contents are deleted.
verboseVerbose level; if zero, then nothing is printed to stderr or stdout.

Definition at line 606 of file imgarithm.c.

614 {
615 if(verbose>0) printf("%s(*img, *oimg)\n", __func__);
616
617 if(img==NULL || img->status!=IMG_STATUS_OCCUPIED) return(1);
618 if(img->dimt<2) {
619 if(verbose>1) fprintf(stderr, "Error: dynamic image required.\n");
620 return(2);
621 }
622 if(!imgExistentTimes(img)) {
623 if(verbose>1) fprintf(stderr, "Error: unknown frame times.\n");
624 return(2);
625 }
626 if(oimg==NULL) return(3);
627 if(oimg->status==IMG_STATUS_OCCUPIED) imgEmpty(oimg);
628
629 if(imgFramesCheck(img, verbose-1)>0) {
630 if(verbose>1) fprintf(stderr, "Error: gaps or overlap between time frames.\n");
631 return(4);
632 }
633
634 /* Allocate memory for one frame */
635 int ret;
636 if(verbose>1) printf("allocating memory for %dx%dx%d pixels\n", img->dimz, img->dimy, img->dimx);
637 ret=imgAllocate(oimg, img->dimz, img->dimy, img->dimx, 1);
638 if(ret) return(ret);
639 /* set image header information */
640 imgCopyhdr(img, oimg);
641 oimg->start[0]=img->start[0]; oimg->end[0]=img->end[img->dimt-1];
642 oimg->mid[0]=(oimg->start[0]+oimg->end[0])/2.0;
643 oimg->unit=CUNIT_UNKNOWN;
644
645 /* Calculate AUMC, AUC, and MRT */
646 for(int zi=0; zi<img->dimz; zi++) {
647 for(int yi=0; yi<img->dimy; yi++) {
648 for(int xi=0; xi<img->dimx; xi++) {
649 float aumc=0.0, auc=0.0;
650 for(int ti=0; ti<img->dimt; ti++) {
651 if(isnan(img->m[zi][yi][xi][ti])) continue;
652 float fdur=img->end[ti]-img->start[ti]; if(!(fdur>0.0)) fdur=0.0;
653 aumc+=img->m[zi][yi][xi][ti]*img->mid[ti]*fdur;
654 auc+=img->m[zi][yi][xi][ti]*fdur;
655 }
656 float mrt=aumc/auc;
657 if(isfinite(mrt)) oimg->m[zi][yi][xi][0]=mrt; else oimg->m[zi][yi][xi][0]=0.0;
658 }
659 }
660 }
661
662 return(0);
663}

◆ imgRawCountsPerTime()

int imgRawCountsPerTime ( IMG * img,
int operation )

Divide or multiply raw data (sinogram) counts by frame duration.

If IMG is not raw data, division is quietly not done. Error is returned if sinogram does not contain frame times, except if sinogram contains only one time frame, also then division is not done.

See also
imgArithmConst, imgArithm, imgFrameIntegral
Returns
Returns 0 if ok.
Parameters
imgIMG containing raw data.
operation1=division, 0=multiply.

Definition at line 442 of file imgarithm.c.

447 {
448 int fi, zi, xi, yi, notime=0;
449 float f;
450
451 /* Check the input data */
452 if(operation!=0 && operation!=1) return(1);
453 if(img==NULL) return(2);
454 if(img->status!=IMG_STATUS_OCCUPIED) return(3);
455 if(img->type!=IMG_TYPE_RAW) return(0);
456 for(fi=0; fi<img->dimt; fi++) {
457 f=img->end[fi]-img->start[fi]; if(f<=1.0E-12) notime++;
458 }
459 if(notime>0) {
460 if(img->dimt>1) return(4);
461 else return(0); /* just one frame; might be parametric or transmission sinogram,
462 therefore no error. */
463 }
464 for(fi=0; fi<img->dimt; fi++) {
465 f=img->end[fi]-img->start[fi]; if(operation==1) f=1.0/f;
466 for(zi=0; zi<img->dimz; zi++)
467 for(yi=0; yi<img->dimy; yi++)
468 for(xi=0; xi<img->dimx; xi++)
469 img->m[zi][yi][xi][fi]*=f;
470 }
471 return(0);
472}