TPCCLIB
Loading...
Searching...
No Matches
4dmio.c
1
4/*****************************************************************************/
5#include "tpcclibConfig.h"
6/*****************************************************************************/
7#include "tpcift.h"
8#include "tpcisotope.h"
9#include "tpccsv.h"
10/*****************************************************************************/
11#include <stdio.h>
12#include <stdlib.h>
13#include <math.h>
14#include <time.h>
15#include <string.h>
16/*****************************************************************************/
17#include "tpctac.h"
18/*****************************************************************************/
19
20/*****************************************************************************/
26int tacRead4DM(
28 TAC *tac,
30 CSV *csv,
32 TPCSTATUS *status
33) {
34 int verbose=0; if(status!=NULL) verbose=status->verbose;
35 if(tac==NULL) {
36 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
37 return TPCERROR_FAIL;
38 }
39 if(verbose>0) {printf("%s()\n", __func__); fflush(stdout);}
40
41 tacFree(tac);
42
43 if(csv==NULL || csv->row_nr<4 || csv->col_nr<2) {
44 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
45 return TPCERROR_NO_DATA;
46 }
47
48 int ret=0;
49
50 /* Check from the first column that data indeed is 4DM data */
51 if(strcasecmp(csv->c[0].content, "PatientName")!=0 ||
52 strcasecmp(csv->c[2].content, "Patient MRN")!=0)
53 {
54 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
56 }
57
58 /* Find the frame number from specific field */
59 int frameNr=0;
60 {
61 int i=csvFindField(csv, "Number of Frames", 4);
62 if(i<0 || i>=csv->nr-1) {
63 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
65 }
66 i++;
67 strClean(csv->c[i].content);
68 frameNr=atoi(csv->c[i].content);
69 if(verbose>1) printf("frameNr := %d\n", frameNr);
70 if(frameNr<1) {
71 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
72 return TPCERROR_NO_DATA;
73 }
74 }
75
76 /* Estimate the number of ROIs */
77 int maxTacNr=0;
78 {
79 int i=4;
80 do {
81 i=csvSearchField(csv, "TAC ROI ", ++i);
82 if(i<0) break;
83 if(csv->c[i].col==0) maxTacNr++;
84 } while(i<csv->nr);
85 if(verbose>1) printf("maxTacNr := %d\n", maxTacNr);
86 if(maxTacNr<1) {
87 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
88 return TPCERROR_NO_DATA;
89 }
90 }
91
92 /* Allocate memory for TAC data */
93 ret=tacAllocate(tac, frameNr, maxTacNr);
94 statusSet(status, __func__, __FILE__, __LINE__, ret);
95 if(ret!=TPCERROR_OK) return(ret);
96 tac->isframe=1;
97 tac->sampleNr=frameNr;
98
99 /* Copy frame start times from CSV into TAC structure */
100 {
101 int i=csvSearchField(csv, "Frame Start Times", 4);
102 char tmp[64];
103 strncpyCleanSpaces(tmp, csv->c[i].content+17, 30); strCleanPars(tmp);
104 tac->tunit=unitIdentify(tmp);
105 if(verbose>2) printf("tunit := %s\n", unitName(tac->tunit));
106 int row=csv->c[i].row;
107 int fails=0;
108 for(int fi=0; fi<tac->sampleNr; fi++) {
109 i++;
110 if(csv->c[i].row!=row) {fails++; break;}
111 strClean(csv->c[i].content);
112 tac->x1[fi]=atofVerified(csv->c[i].content);
113 }
114 if(fails>0) {
115 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
117 }
118 }
119
120 /* Get frame durations from CSV to write frame end times into TAC structure */
121 {
122 int i=csvSearchField(csv, "Frame Durations", 4);
123 int row=csv->c[i].row;
124 int fails=0;
125 for(int fi=0; fi<tac->sampleNr; fi++) {
126 i++;
127 if(csv->c[i].row!=row) {fails++; break;}
128 strClean(csv->c[i].content);
129 tac->x2[fi]=tac->x1[fi]+atofVerified(csv->c[i].content);
130 tac->x[fi]=0.5*(tac->x1[fi]+tac->x2[fi]);
131 }
132 if(fails>0) {
133 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
135 }
136 }
137
138 /* Copy ROI data from CSV into TAC structure */
139 tac->tacNr=0;
140 {
141 int i=4;
142 while((i=csvSearchField(csv, "TAC ROI ", i))>0) {
143 int row=csv->c[i].row;
144 strlcpy(tac->c[tac->tacNr].name, csv->c[i].content+8, MAX_TACNAME_LEN+1);
145 int fails=0, goods=0;
146 for(int fi=0; fi<tac->sampleNr; fi++) {
147 i++;
148 if(csv->c[i].row!=row) {fails++; break;}
149 strClean(csv->c[i].content);
150 tac->c[tac->tacNr].y[fi]=atofVerified(csv->c[i].content);
151 if(isnormal(tac->c[tac->tacNr].y[fi])) goods++; // zero is not accepted here on purpose
152 }
153 if(fails==0 && goods>0) tac->tacNr++;
154 }
155 if(tac->tacNr<1) {
156 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
157 return TPCERROR_NO_DATA;
158 }
159 }
160
161 /* Get concentration units */
162 {
163 int i=csvSearchField(csv, "TAC FA Blood LV ", 4);
164 if(i>=0) {
165 char tmp[64];
166 strncpyCleanSpaces(tmp, csv->c[i].content+16, 64); strCleanPars(tmp);
167 tac->cunit=unitIdentify(tmp);
168 if(verbose>2) printf("cunit := %s\n", unitName(tac->cunit));
169 }
170 }
171
172 /* Get isotope */
173 {
175 int i=csvFindField(csv, "Radionuclide Name", 4);
176 if(i>=0 && i<csv->nr-1 && csv->c[i].row==csv->c[i+1].row) {
177 char *buf=strTokenDup(csv->c[++i].content, " ", NULL);
179 free(buf);
180 }
182 if(verbose>2) printf("isotope := %s\n", isotopeName(isotope));
183 }
184
185 if(tac->sampleNr<1 || tac->tacNr<1) {
186 tacFree(tac);
187 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
189 }
190
192
193 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
194 return(TPCERROR_OK);
195}
196/*****************************************************************************/
197
198/*****************************************************************************/
int csvFindField(CSV *csv, const char *s, int start_index)
Definition csvfind.c:27
int csvSearchField(CSV *csv, const char *s, int start_index)
Definition csvfind.c:50
double atofVerified(const char *s)
Definition decpoint.c:75
char * isotopeName(int isotope_code)
Definition isotope.c:101
int isotopeIdentify(const char *isotope)
Definition isotope.c:145
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
Definition statusmsg.c:142
void strCleanPars(char *s)
Definition stringext.c:476
int strncpyCleanSpaces(char *s1, const char *s2, int maxlen)
Definition stringext.c:265
size_t strlcpy(char *dst, const char *src, size_t dstsize)
Definition stringext.c:632
char * strTokenDup(const char *s1, const char *s2, int *next)
Definition stringext.c:413
int strClean(char *s)
Definition stringext.c:389
int col
Definition tpccsv.h:28
int row
Definition tpccsv.h:26
char * content
Definition tpccsv.h:30
Definition tpccsv.h:36
int row_nr
Definition tpccsv.h:44
int col_nr
Definition tpccsv.h:46
CSV_item * c
Definition tpccsv.h:38
int nr
Definition tpccsv.h:42
char name[MAX_TACNAME_LEN+1]
Definition tpctac.h:81
double * y
Definition tpctac.h:75
Definition tpctac.h:87
double * x
Definition tpctac.h:97
tacformat format
Definition tpctac.h:93
int sampleNr
Definition tpctac.h:89
int cunit
Definition tpctac.h:105
int isframe
Definition tpctac.h:95
TACC * c
Definition tpctac.h:117
int tunit
Definition tpctac.h:109
double * x2
Definition tpctac.h:101
double * x1
Definition tpctac.h:99
int tacNr
Definition tpctac.h:91
int verbose
Verbose level, used by statusPrint() etc.
void tacFree(TAC *tac)
Definition tac.c:106
int tacAllocate(TAC *tac, int sampleNr, int tacNr)
Definition tac.c:130
void tacSetIsotope(TAC *tac, int isotope)
Definition tacdc.c:41
Header file for library libtpccsv.
#define MAX_TACNAME_LEN
Max length of TAC ID name (not including trailing zero)
@ TPCERROR_FAIL
General error.
@ TPCERROR_INVALID_FORMAT
Invalid file format.
@ TPCERROR_OK
No error.
@ TPCERROR_NO_DATA
File contains no data.
int unitIdentify(const char *s)
Definition units.c:162
char * unitName(int unit_code)
Definition units.c:143
Header file for library libtpcift.
Header file for library libtpcisotope.
isotope
Definition tpcisotope.h:50
@ ISOTOPE_UNKNOWN
Unknown.
Definition tpcisotope.h:51
Header file for library libtpctac.
@ TAC_FORMAT_4DM
4DM TAC format (reading supported)
Definition tpctac.h:50