Skip to content
Snippets Groups Projects
Commit acdb3fef authored by Vesa Oikonen's avatar Vesa Oikonen
Browse files

new app

parent ba7ad45b
Branches
Tags
No related merge requests found
......@@ -8,7 +8,7 @@ This is a concise list of changes; commit messages can be found in the
## version 0.7.1 (2019-06-26 under development)
- Added applications perfrat, iftedit, sim_av, convexpf, convsurg, fit_xexp, fit_xsur, fit_pbr,
tacmsamp, imglhbdv, and imgledif.
tacmsamp, imglhbdv, imgslope, and imgledif.
- Added application parai, replacing old application resai.
- Imported and rewritten application yokoi.
- Application tacsetx can add x column to data that originally has only one column.
......
......@@ -40,6 +40,7 @@ add_executable (imgpeak imgpeak.c)
add_executable (imgposv imgposv.c)
add_executable (imgprofi imgprofi.c)
add_executable (imgqntls imgqntls.c)
add_executable (imgslope imgslope.c)
add_executable (imgunit imgunit.c)
add_executable (pxl2tac pxl2tac.c)
add_executable (siflist siflist.c)
......@@ -58,6 +59,7 @@ target_link_libraries (imgpeak tpcimgp tpcimgio tpccurveio tpcmodel tpcmisc m)
target_link_libraries (imgposv tpcimgio tpcmisc m)
target_link_libraries (imgprofi tpcimgp tpcimgio tpccurveio tpcmisc m)
target_link_libraries (imgqntls tpcimgp tpcimgio tpccurveio tpcmisc m)
target_link_libraries (imgslope tpcimgp tpcimgio tpccurveio tpcmodel tpcmisc m)
target_link_libraries (imgunit tpcimgp tpcimgio tpcmisc m)
target_link_libraries (pxl2tac tpcmodext tpcimgp tpcimgio tpcmodel tpccurveio tpcmisc m)
target_link_libraries (siflist tpcimgio tpcmisc m)
......@@ -78,6 +80,7 @@ INSTALL(
${CMAKE_CURRENT_BINARY_DIR}/imgposv${CMAKE_EXECUTABLE_SUFFIX}
${CMAKE_CURRENT_BINARY_DIR}/imgprofi${CMAKE_EXECUTABLE_SUFFIX}
${CMAKE_CURRENT_BINARY_DIR}/imgqntls${CMAKE_EXECUTABLE_SUFFIX}
# ${CMAKE_CURRENT_BINARY_DIR}/imgslope${CMAKE_EXECUTABLE_SUFFIX}
${CMAKE_CURRENT_BINARY_DIR}/imgunit${CMAKE_EXECUTABLE_SUFFIX}
${CMAKE_CURRENT_BINARY_DIR}/pxl2tac${CMAKE_EXECUTABLE_SUFFIX}
${CMAKE_CURRENT_BINARY_DIR}/siflist${CMAKE_EXECUTABLE_SUFFIX}
......@@ -155,6 +158,10 @@ add_test (imgqntlsUsage imgqntls "--help")
set_tests_properties (imgqntlsUsage
PROPERTIES PASS_REGULAR_EXPRESSION "Usage: *"
)
add_test (imgslopeUsage imgslope "--help")
set_tests_properties (imgslopeUsage
PROPERTIES PASS_REGULAR_EXPRESSION "Usage: *"
)
add_test (imgunitUsage imgunit "--help")
set_tests_properties (imgunitUsage
PROPERTIES PASS_REGULAR_EXPRESSION "Usage: *"
......@@ -227,6 +234,11 @@ add_test (
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test/imgqntls
COMMAND bash "./test_imgqntls.sh"
)
add_test (
NAME imgslopeTests
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test/imgslope
COMMAND bash "./test_imgslope.sh"
)
add_test (
NAME imgunitTests
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test/imgunit
......
/** @file imgslope.c
* @brief Calculate the slope of pixel TACs in dynamic PET image.
* @copyright (c) Turku PET Centre
* @author Vesa Oikonen
*/
/// @cond
/*****************************************************************************/
#include "tpcclibConfig.h"
/*****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
/*****************************************************************************/
#include "libtpcmisc.h"
#include "libtpcmodel.h"
#include "libtpccurveio.h"
#include "libtpcimgio.h"
#include "libtpcimgp.h"
/*****************************************************************************/
/*****************************************************************************/
static char *info[] = {
"Calculate the slope of pixel TACs in dynamic PET image.",
"Slope is calculated between given start and end times (min).",
"Static image containing the slope value of each pixel TAC is written.",
" ",
"Usage: @P [Options] imgfile starttime endtime slopefile",
" ",
"Options:",
" -stdoptions", // List standard options like --help, -v, etc
" ",
"See also: imgcalc, imgpeak, imgaumc, imgthrs",
" ",
"Keywords: image, peak, mask",
0};
/*****************************************************************************/
/*****************************************************************************/
/* Turn on the globbing of the command line, since it is disabled by default in
mingw-w64 (_dowildcard=0); in MinGW32 define _CRT_glob instead, if necessary;
In Unix&Linux wildcard command line processing is enabled by default. */
/*
#undef _CRT_glob
#define _CRT_glob -1
*/
int _dowildcard = -1;
/*****************************************************************************/
/*****************************************************************************/
/**
* Main
*/
int main(int argc, char **argv)
{
int ai, help=0, version=0, verbose=1;
char imgfile[FILENAME_MAX], slopefile[FILENAME_MAX];
double v, tstart=0.0, tstop=0.0;
/*
* Get arguments
*/
if(argc==1) {tpcPrintUsage(argv[0], info, stderr); return(1);}
imgfile[0]=slopefile[0]=(char)0;
/* Options */
for(ai=1; ai<argc; ai++) if(*argv[ai]=='-') { /* options */
char *cptr=argv[ai]+1; if(*cptr=='-') cptr++; if(cptr==NULL) continue;
if(tpcProcessStdOptions(argv[ai], &help, &version, &verbose)==0) continue;
fprintf(stderr, "Error: invalid option '%s'\n", argv[ai]);
return(1);
} else break;
/* Print help or version? */
if(help==2) {tpcHtmlUsage(argv[0], info, ""); return(0);}
if(help) {tpcPrintUsage(argv[0], info, stdout); return(0);}
if(version) {tpcPrintBuild(argv[0], stdout); return(0);}
/* Process other arguments, starting from the first non-option */
if(ai<argc) {strlcpy(imgfile, argv[ai], FILENAME_MAX); ai++;}
if(ai<argc && atof_with_check(argv[ai], &v)==0) {tstart=v; ai++;}
if(ai<argc && atof_with_check(argv[ai], &v)==0) {tstop=v; ai++;}
if(ai<argc) {strlcpy(slopefile, argv[ai], FILENAME_MAX); ai++;}
if(ai<argc) {fprintf(stderr, "Error: too many arguments.\n"); return(1);}
/* Is something missing or wrong? */
if(!slopefile[0]) {
fprintf(stderr, "Error: missing command-line argument; use option --help\n");
return(1);
}
/* In verbose mode print arguments and options */
if(verbose>1) {
printf("imgfile := %s\n", imgfile);
printf("tstart := %g\n", tstart);
printf("tstop := %g\n", tstop);
printf("slopefile := %s\n", slopefile);
fflush(stdout);
}
/*
* Read dynamic image
*/
if(verbose>0) printf("reading dynamic image %s\n", imgfile);
IMG img; imgInit(&img);
if(imgRead(imgfile, &img)) {
fprintf(stderr, "Error: %s\n", img.statmsg);
return(2);
}
if(verbose>1) {
printf("img_dimx := %d\n", img.dimx);
printf("img_dimy := %d\n", img.dimy);
printf("img_dimz := %d\n", img.dimz);
printf("img_dimt := %d\n", img.dimt);
fflush(stdout);
}
if(img.dimt<2) {
fprintf(stderr, "Error: %s contains only 1 time frame.\n", imgfile);
imgEmpty(&img); return(2);
}
/* Check that times are available */
if(imgExistentTimes(&img)==0) {
fprintf(stderr, "Error: image does not contain frame times.\n");
imgEmpty(&img); return(2);
}
/* Check and set time range */
if(tstop<1.0E-10) {
tstop=img.end[img.dimt-1]/60.0;
if(verbose>0) {printf("tstop set to %g min\n", tstop); fflush(stdout);}
}
tstart*=60.0; tstop*=60.0;
/* Get the time range in frame indices */
int fstart=img.dimt-1;
int fstop=0;
for(int i=img.dimt-1; i>=0; i--) if(img.mid[i]>=tstart) fstart=i; else break;
for(int i=0; i<img.dimt; i++) if(img.mid[i]<=tstop) fstop=i; else break;
if(verbose>1) {
printf("fstart := %d\n", fstart);
printf("fstop := %d\n", fstop);
}
int sampleNr=1+fstop-fstart;
if(sampleNr<2) {
fprintf(stderr, "Error: invalid time range.\n");
imgEmpty(&img); return(2);
}
/*
* Allocate IMG for slope image
*/
if(verbose>1) printf("allocating memory for parametric image\n");
IMG sout; imgInit(&sout);
if(imgAllocateWithHeader(&sout, img.dimz, img.dimy, img.dimx, 1, &img)) {
fprintf(stderr, "Error: cannot allocate IMG data.\n");
imgEmpty(&img); return(4);
}
/* Set the frame time */
sout.start[0]=img.start[fstart]; sout.end[0]=img.end[fstop];
/* and set the units */
sout.unit=CUNIT_UNITLESS;
/*
* Compute pixel-by-pixel
*/
{
double x[sampleNr], y[sampleNr], a, b;
for(int i=0; i<sampleNr; i++) x[i]=img.mid[i+fstart];
for(int zi=0; zi<img.dimz; zi++) {
for(int yi=0; yi<img.dimy; yi++) for(int xi=0; xi<img.dimx; xi++) {
/* Set results to zero */
sout.m[zi][yi][xi][0]=0.0;
/* Line fit */
for(int i=0; i<sampleNr; i++) y[i]=img.m[zi][yi][xi][i+fstart];
if(regr_line(x, y, sampleNr, &a, &b)) continue;
sout.m[zi][yi][xi][0]=60.0*(float)a;
}
}
}
/*
* Save the slope data
*/
{
if(verbose>1) printf("writing slopes\n");
if(imgWrite(slopefile, &sout)) {
fprintf(stderr, "Error: %s\n", sout.statmsg);
imgEmpty(&img); imgEmpty(&sout);
return(11);
}
if(verbose>0) fprintf(stdout, "Image %s saved.\n", slopefile);
}
imgEmpty(&img); imgEmpty(&sout);
return(0);
}
/*****************************************************************************/
/*****************************************************************************/
/// @endcond
#!/bin/bash
#: Title : test_imgslope
#: Date : 2019-06-26
#: Author : "Vesa Oikonen" <vesa.oikonen@utu.fi>
#: Options : None
# Set the name of executable to test
if [ -n "${OS+1}" ] && [ "$OS" = "Windows_NT" ]; then
EXT=.exe;
else
EXT=;
fi
PROGRAM=../../imgslope$EXT;
if [ ! -f $PROGRAM ]; then
printf "Failed: executable does not exist.\n"
exit 1
fi
printf "=====================================================================\n"
printf "creating test data for %s\n" $PROGRAM
printf "=====================================================================\n"
#printf "\n verifying that required data exists \n"
printf "\n making test data \n"
if [ ! -f data1.tac ] || [ ! -f data1.v ]; then
printf "start[minutes] end[kBq/cc] roi1 roi2 roi3 roi4\n" > data1.tac
printf "0.0 2.0 1 12.5 -1 2\n" >> data1.tac
printf "2.0 4.0 3 3 -3 4\n" >> data1.tac
printf "4.0 8.0 6 6 -6 7\n" >> data1.tac
printf "8.0 12.0 10 10 -10 1.8\n" >> data1.tac
dft2img -zoom=2 -scanner=HRRT -dim=8 data1.tac data1.v data.roi
if [ $? -ne 0 ] ; then printf "Failed!\n" ; exit 1 ; fi
fi
if [ ! -f correct_0-12.v ]; then
printf "start[minutes] end[kBq/cc] roi1 roi2 roi3 roi4\n" > temp.tac
printf "0.0 12.0 1 0 -1 0\n" >> temp.tac
dft2img -zoom=2 -scanner=HRRT -dim=8 temp.tac correct_0-12.v
if [ $? -ne 0 ] ; then printf "Failed!\n" ; exit 1 ; fi
fi
if [ ! -f correct_2-8.v ]; then
printf "start[minutes] end[kBq/cc] roi1 roi2 roi3 roi4\n" > temp.tac
printf "2.0 8.0 1 1 -1 1\n" >> temp.tac
dft2img -zoom=2 -scanner=HRRT -dim=8 temp.tac correct_2-8.v
if [ $? -ne 0 ] ; then printf "Failed!\n" ; exit 1 ; fi
fi
printf "\n\n"
printf "=====================================================================\n"
printf "testing %s\n" $PROGRAM
printf "=====================================================================\n"
printf "\n 1.0.0 \n"
printf " Test case 1: Dynamic image in ECAT 7 format. \n"
printf " Test case 2: Whole time range. \n"
printf " Expected result: Correct output image. \n\n"
rm -f output.v output.tac
$PROGRAM data1.v 0 12 output.v
if [ $? -ne 0 ] ; then printf "Failed!\n" ; exit 1 ; fi
printf "\n ok \n"
img2dft output.v data.roi output.tac
if [ $? -ne 0 ] ; then printf "Failed!\n" ; exit 1 ; fi
printf "\n ok \n"
imgmatch -abs=0.001 correct_0-12.v output.v
if [ $? -ne 0 ] ; then printf "Failed!\n" ; exit 1 ; fi
printf "\n passed. \n\n"
printf "\n 1.0.1 \n"
printf " Test case 1: Dynamic image in ECAT 7 format. \n"
printf " Test case 2: Mid time range. \n"
printf " Expected result: Correct output image. \n\n"
rm -f output.v output.tac
$PROGRAM data1.v 2 8 output.v
if [ $? -ne 0 ] ; then printf "Failed!\n" ; exit 1 ; fi
printf "\n ok \n"
img2dft output.v data.roi output.tac
if [ $? -ne 0 ] ; then printf "Failed!\n" ; exit 1 ; fi
printf "\n ok \n"
imgmatch -abs=0.001 correct_2-8.v output.v
if [ $? -ne 0 ] ; then printf "Failed!\n" ; exit 1 ; fi
printf "\n passed. \n\n"
printf "\n===================================================================\n"
printf " All passed! \n"
printf "===================================================================\n"
exit 0
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment