2008年7月31日 星期四
Cerebral Blood Flow Measurement (Unarranged)
* program: TC_CBF_std.c
*
* purpose: generate CBF standard file
*
* author: Ta-Cheng Chang
*
* modified: July 11, 2008
*
****************************************************************
/#include "cbook.h"
int TC_CBF_std(void)
{
FILE *fin;
char temp[64];
char * directory = (char*)malloc(512);
char * tempdic1 = (char*)malloc(512);
char * tempdic2 = (char*)malloc(512);
char * tempdic3 = (char*)malloc(512);
char * tempstring = (char*)malloc(512);
char * fname = (char*)malloc(512);
char * stddic = (char*)malloc(64);
int tp, i, j, k, choice, indx;
float lambda, Kvalue, m, W;
float * Flowtable = (float*)malloc(4 * 256);
m = 1; // Net effect diffusion limitation (0~1); default = 1
W = 100; // Tissue mass; default = 100 [g]
clr;
move (12,5); bold;
printf ("Instruction:\n"); move (12,6); bold; printf ("STEP1 "); norm; printf ("Enter animal file directory to import date"); move (19,7); printf ("Folder contains Time.txt, DPM.txt, Intensity.txt\n"); move (12,8); bold; printf ("STEP2 "); norm; printf ("Choose radioisotope concentration standard\n"); move (12,9); bold; printf ("STEP3 "); norm; printf ("Intensity vs. blood flow file (ff.std) is generated at the same directory\n"); move (19,10); printf("Blood flow unit: ml/min/100g"); move (12,11); printf ("\n");
move (12,12); bold; printf ("Enter animal file directory: ex: "); norm; printf ("/usr/users/IMAGES/CBF-DATA/0304164"); move (12,14);
/***************************************************** * Import Data * *****************************************************/ /************** Import Time File ********************/ INQUIRY: scanf ("%s", &directory);
strcpy (tempdic1, &directory); strcpy (tempstring, "/Time.txt"); fname = strcat (tempdic1, tempstring); fin = fopen (fname, "r"); strcpy (tempdic1, &directory);
//fin = fopen ("/usr/users/IMAGES/CBF-DATA/0304164/T0304164.txt", "r"); if ( fin == 0 ) { move (12,13); printf ("No time file! Please re-enter directory!\n"); move (12,14); goto INQUIRY; } fscanf (fin, "%s", temp); tp = atoi (temp); temp[0] = 0;
fscanf (fin, "%s", temp); lambda = atof (temp); temp[0] = 0;
float * tdatam = (float*)malloc(4 * tp); float * tdatas = (float*)malloc(4 * tp); for (i = 0; i < tp; i++) { fscanf (fin, "%s" ,temp); tdatam[i] = atof (temp); //Minute tdatas[i] = atof (temp) * 60; //Second } fclose (fin); temp[0] = 0;
/***************** Import DPM File ***********************/ strcpy (tempdic2, tempdic1); strcpy (tempstring, "/DPM.txt"); fname = strcat (tempdic1, tempstring); fin = fopen (fname, "r"); //fin = fopen ("/usr/users/IMAGES/CBF-DATA/0304164/DPM0304164.txt", "r"); if ( fin == 0 ) { move (12,13); printf ("No DPM file! Please re-enter directory!\n"); move (12,14); goto INQUIRY; }
float * dpmdata = (float*)malloc(4 * tp); float * Ca = (float*)malloc(4 * tp); for (i = 0; i < tp; i++) { fscanf (fin, "%s", temp); dpmdata[i] = atof (temp); Ca[i] = atof (temp) / 2220 / 0.02; //Measured unit:[DPM/l];wanted unit:[nCi/ml].Sample size:20ml.1[nCi]=2220[DPM]. } fclose (fin); temp[0] = 0;
/****************** Import Standard ***********************/ move (12,16); bold; printf ("Choose standard file:\n"); move (12,17); bold; printf ("1) "); norm; printf ("set1\n"); move (12,18); bold; printf ("2) "); norm; printf ("set2\n"); move (12,19); bold; printf ("3) "); norm; printf ("146A\n"); move (12,20); bold; printf ("4) "); norm; printf ("146E\n"); printf ("\n"); move (12,22); bold; printf ("Enter Choice: "); norm;
INQUIRY2: move (26,22);
scanf ("%d", &choice); switch ( choice ) { case 1: stddic = "set1.txt"; break; case 2: stddic = "set2.txt"; break; case 3: stddic = "146A.txt"; break; case 4: stddic = "146E.txt"; break; default: goto INQUIRY2; break; } strcpy(tempstring, "/usr/users/IMAGES/STD/"); fname = strcat (tempstring, stddic); fin = fopen (fname, "r"); if ( fin == 0 ) { move (12,23); printf ("No standard file! Please check!\n"); goto INQUIRY2; }
i = 0; float * tempstd = (float*)malloc(4 * 30); while(fscanf (fin, "%s", temp) != EOF ) { tempstd[i] = atof (temp); i++; } int stdpt = i; float * stdata = (float*)malloc(4 * stdpt); for (i = 0; i < stdpt; i++) { stdata[i] = tempstd[i]; } free(tempstd); fclose (fin); temp[0] = 0;
/**************** Import Standard Intenstity *****************/ strcpy (tempdic3, tempdic2); strcpy (tempstring, "/Intensity.txt"); fname = strcat (tempdic2, tempstring); fin = fopen (fname, "r");
//fin = fopen ("/usr/users/IMAGES/CBF-DATA/0304164/I0304164.txt", "r"); if ( fin == 0 ) { move (12,13); printf ("No intensity file! Please re-enter directory!\n"); move (12,14); goto INQUIRY; } int stdint[stdpt]; for (i = 0; i < stdpt; i++) { fscanf (fin, "%s", temp); stdint[i] = atoi (temp); } fclose (fin); temp[0] = 0;
/******************* Printing ************************/ move (12,24); printf ("Total number of time points is %d\n", tp); move (12,25); printf ("Lambda is %f [ml/g]\n", lambda); move (12,26); printf("\n"); move (12,27); bold; printf("Sample Time[sec] Ca[nCi/ml] Ca[DPM]\n"); norm; for (i = 0; i < tp; i++) { move (12,28 + i); printf(" %d %f %f %f\n", i + 1, tdatas[i], Ca[i], dpmdata[i]); } indx = 28 + i; move (12,indx + 1); bold; printf("Count Intensity Ci[nCi/g]\n"); norm; for (i = 0; i < stdpt; i++) { move (12,indx + 2 + i); printf(" %d %d %f\n", i + 1, stdint[i], stdata[i]); } indx = indx + 2 + i; printf("\n");
/************************************************************ * Standard Intensity vs Standard Concentration Curve Fitting * *************************************************************/ float intervall; float * cfconint = (float*)malloc(4 * 256);
/******************* 0 to the 1st Point *********************/ intervall = stdata[0] / stdint[0]; for (i = 0; i <= stdint[0] - 1; i++) { cfconint[i] = intervall * i; }
/****** From the 1st Point to Rest Points *******************/ for (i = 1; i <= stdpt - 1; i++) { cfconint[stdint[i - 1]] = stdata[i - 1]; if (stdint[i - 1] == stdint[i]) { stdint[i] = stdint[i] + 1; } intervall = (stdata[i] - stdata[i - 1]) / (stdint[i] - stdint[i - 1]); for (j = 1; j <= (stdint[i] - stdint[i - 1]); j++) { cfconint[stdint[i - 1] + j] = intervall * j + stdata[i - 1]; } }
/********** From the last Point to 255 ***********************/ for (i = 1; i <= 255-stdint[stdpt - 1]; i++) { cfconint[stdint[stdpt - 1] + i] = intervall * i + stdata[stdpt - 1]; }
/********************** Printing curve fitting result ***************************** bold; printf("Intensity Concentration[nCi/g]\n"); norm; for (i = 0; i <= 255; i++) { printf(" %d %f\n", i, cfconint[i]); } printf("\n"); printf("\n");*/
/************************************************************ * Generating Blood Flow Table * *************************************************************/ /****** Generate K table (0~0.35 in 10^-5 precision) ********/ int Ctlength, index; float tempk, temp2; float * tempCt = (float*)malloc(4 * 35100);
for (i = 0; i <= 35000; i++) { tempk = i * 0.00001; temp2 = 0; for (j = 1; j <= tp - 1; j++) { temp2 = temp2 + lambda * tempk * Ca[j] * exp(-tempk * (45 - tdatas[j])) * (tdatas[j] - tdatas[j - 1]); } tempCt[i] = temp2; if (i > 0) { if (tempCt[i] < tempCt[i - 1]) { break; } } } Ctlength = i; float * Ct = (float*)malloc(4 * (Ctlength - 1)); //Resize Ct for (j = 0; j <= Ctlength - 1; j++) { Ct[j] = tempCt[j]; } free(tempCt);
/****** Approach K value in 10^-6 precision; generate bloodflow table ********/ for (i = 0; i <= 255; i++) { for (j = 0; j <= Ctlength -1; j++) { if (cfconint[i] < index =" j;" temp2 =" 0;" j =" 0;" kvalue =" (0.00001)" k =" 1;" temp2 =" temp2">= cfconint[i]) { Flowtable[i] = Kvalue * 60 * lambda * W / m; // Bloodflow unit: ml/min/100g; default m = 1; W = 100 [g] break; } } }
/****** Generate blood flow file at the same directory **********/ strcpy (tempstring, "/ff.std"); fname = strcat (tempdic3, tempstring); fin = fopen (fname, "w"); for (i = 0; i <= 254; i++) { fprintf(fin, "%d %f\n", i, Flowtable[i]); } fprintf(fin, "0 0\n"); fclose (fin);
/*****************************************************************/ free(tempdic1); free(tempdic2); free(tempdic3); free(tempstring); free(tdatam); free(tdatas); free(dpmdata); free(Ca); free(stdata); free(Flowtable); move (12,indx + 1); printf("Type 'm' then press enter to back to main menu: "); move (61,indx + 1); scanf ("%d",&k); }
2008年4月11日 星期五
2008年4月10日 星期四
LU Decomposition
Tcl/Tk Code:
## LU Decomposition. Find X if AX=B by LU decomposition. After calculation X=B.
for {set i 0} {$i <= 1} {incr i 1} {
for {set k [expr {$i + 1}]} {$k <= 2} {incr k 1} {
set temp [expr {double($A($k,$i)) / double($A($i,$i))}]
for {set l [expr {$i + 1}]} {$l <= 2} {incr l 1} {
set A($k,$l) [expr {$A($k,$l) - ($A($i,$l) * $temp)}]
}
set B($k) [expr {$B($k) - (($B($i)) * $temp)}]
}
}
set B(2) [expr {$B(2) / $A(2,2)}]
for {set i 1} {$i >= 0} {incr i -1} {
for {set k [expr {$i + 1}]} {$k <= 2} {incr k 1} {
set B($i) [expr {$B($i) - $A($i,$k) * $B($k)}]
}
set B($i) [expr {$B($i) / $A($i,$i)}]
}
Best Fit Circle Using Least Squares Method
where di is the distance from the point (xi, yi) to the perimeter. The equation of circle is
where (a, b) is the circle center and R is the radius. Then the di is
where B=-2a, C=-2b, and D=a^2+b^2-R^2. Next, differentiating F with respect to B, C, D yields a system of linear equations
B, C, and D can be solved by solving matrix
LetThe equation of matrix calculation can be rewritten as
The X can be solved by calculating the equation
where A^-1 is the inverse matrix of A. The matrix X can be solved using LU decomposition to get B, C, and D. The x coordinate of the center (a) equals to -B/2, the y coordinate of the center (b) equals to -C/2, and the radius (R) equals toset sumX 0 ; set sumY 0 ; set sumXX 0 ; set sumYY 0 ; set sumXY 0
set sumXXY 0 ; set sumYYY 0 ; set sumXXX 0 ; set sumXYY 0
set sumXXplusYY 0 ; set sumXXYplusYYY 0 ; set sumXXXplusXYY 0
for {set i 0} {$i < $n} {incr i 1} { set XX [lappend XX [expr {[lindex $X $i] * [lindex $X $i]}]] set YY [lappend YY [expr {[lindex $Y $i] * [lindex $Y $i]}]] set XY [lappend XY [expr {[lindex $X $i] * [lindex $Y $i]}]] set XXY [lappend XXY [expr {[lindex $X $i] * [lindex $X $i] * [lindex $Y $i]}]] set YYY [lappend YYY [expr {[lindex $Y $i] * [lindex $Y $i] * [lindex $Y $i]}]] set XXX [lappend XXX [expr {[lindex $X $i] * [lindex $X $i] * [lindex $X $i]}]] set XYY [lappend XYY [expr {[lindex $X $i] * [lindex $Y $i] * [lindex $Y $i]}]] set sumX [expr {$sumX + [lindex $X $i]}] set sumY [expr {$sumY + [lindex $Y $i]}] set sumXX [expr {$sumXX + [lindex $XX $i]}] set sumYY [expr {$sumYY + [lindex $YY $i]}] set sumXY [expr {$sumXY + [lindex $XY $i]}] set sumXXY [expr {$sumXXY + [lindex $XXY $i]}] set sumYYY [expr {$sumYYY + [lindex $YYY $i]}] set sumXXX [expr {$sumXXX + [lindex $XXX $i]}] set sumXYY [expr {$sumXYY + [lindex $XYY $i]}] } set nsumXXplusYY -[expr {$sumXX + $sumYY}] set nsumXXYplusYYY -[expr {$sumXXY + $sumYYY}] set nsumXXXplusXYY -[expr {$sumXXX + $sumXYY}] set A(0,0) $sumX ; set A(0,1) $sumY ; set A(0,2) $n set A(1,0) $sumXY ; set A(1,1) $sumYY ; set A(1,2) $sumY set A(2,0) $sumXX ; set A(2,1) $sumXY ; set A(2,2) $sumX set B(0) $nsumXXplusYY ; set B(1) $nsumXXYplusYYY ; set B(2) $nsumXXXplusXYY ## Gaussian elimination. Find X if AX=B by LU decomposition. After calculation X=B. for {set i 0} {$i <= 1} {incr i 1} { for {set k [expr {$i + 1}]} {$k <= 2} {incr k 1} { set temp [expr {double($A($k,$i)) / double($A($i,$i))}] for {set l [expr {$i + 1}]} {$l <= 2} {incr l 1} { set A($k,$l) [expr {$A($k,$l) - ($A($i,$l) * $temp)}] } set B($k) [expr {$B($k) - (($B($i)) * $temp)}] } } set B(2) [expr {$B(2) / $A(2,2)}] for {set i 1} {$i >= 0} {incr i -1} {
for {set k [expr {$i + 1}]} {$k <= 2} {incr k 1} { set B($i) [expr {$B($i) - $A($i,$k) * $B($k)}] } set B($i) [expr {$B($i) / $A($i,$i)}] } ## Calculate the center and radius of the circle set XC [expr {-(0.5 * $B(0))}] set YC [expr {-(0.5 * $B(1))}] set R [expr {sqrt((pow($B(0),2) + pow($B(1),2)) / 4 - $B(2))}] return [list $XC $YC $R] }