TPCCLIB
Loading...
Searching...
No Matches
parfit.c
Go to the documentation of this file.
1
4/*****************************************************************************/
5#include "tpcclibConfig.h"
6/*****************************************************************************/
7#include <stdio.h>
8#include <stdlib.h>
9#include <math.h>
10#include <time.h>
11#include <string.h>
12/*****************************************************************************/
13#include "tpcextensions.h"
14#include "tpcmodels.h"
15#include "tpccsv.h"
16#include "tpcift.h"
17/*****************************************************************************/
18#include "tpcpar.h"
19/*****************************************************************************/
20
21/*****************************************************************************/
29 PAR *par,
31 FILE *fp,
33 TPCSTATUS *status
34) {
35 int verbose=0; if(status!=NULL) verbose=status->verbose;
36 if(fp==NULL) {
37 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
39 }
40 if(verbose>0) printf("%s():\n", __func__);
41 if(par==NULL || par->tacNr<1 || par->parNr<1) {
42 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
43 return TPCERROR_NO_DATA;
44 }
45
46 int i, j, n;
47 char tmp[256];
48
49 /* Write magic string and fit program name */
50 i=iftFindKey(&par->h, "program", 0);
51 if(i<0 || !strnlen(par->h.item[i].value, 10)) strcpy(tmp, "libtpcpar");
52 else strlcpy(tmp, par->h.item[i].value, 256);
53 n=fprintf(fp, "%-11.11s %s\n", "FIT1", tmp);
54 if(n<5) {
55 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
57 }
58
59 /* Write fit date and time */
60 i=iftFindKey(&par->h, "analysis_time", 0);
61 if(i>=0) strlcpy(tmp, par->h.item[i].value, 256); else strcpy(tmp, "");
62 fprintf(fp, "Date:\t%s\n", tmp);
63
64 /* Write the name of the original datafile */
65 i=iftFindKey(&par->h, "datafile", 0);
66 if(i>=0) fprintf(fp, "Data file:\t%s\n", par->h.item[i].value);
67 else fprintf(fp, "Data file:\t\n");
68
69 /* Write the study number */
70 i=iftFindKey(&par->h, "studynr", 0);
71 if(i<0) i=iftFindKey(&par->h, "study_number", 0);
72 if(i>=0) fprintf(fp, "Study number:\t%s\n", par->h.item[i].value);
73
74 /* Write the concentration (y) unit of the original data */
75 i=iftFindKey(&par->h, "unit", 0);
76 if(i<0) i=iftFindKey(&par->h, "calibration_unit", 0);
77 if(i>=0) fprintf(fp, "Data unit:\t%s\n", par->h.item[i].value);
78 else fprintf(fp, "Data unit:\t\n");
79
80 /* Write the time (x) unit of the original data */
81 i=iftFindKey(&par->h, "timeunit", 0);
82 if(i<0) i=iftFindKey(&par->h, "time_unit", 0);
83 if(i>=0) fprintf(fp, "Time unit:\t%s\n", par->h.item[i].value);
84 else fprintf(fp, "Time unit:\t\n");
85
86 /* Write the tacNr to be saved */
87 fprintf(fp, "Nr of VOIs:\t%d\n", par->tacNr);
88
89 /* Write the Fit title */
90 fprintf(fp, "%s %s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
91 "Region", "Plane", "Start", "End", "dataNr", "WSS", "parNr", "Type", "Parameters");
92
93 /* Write the individual fits */
94 for(i=0; i<par->tacNr; i++) {
95 /* Tac id */
96 if(strlen(par->r[i].name)>0) {
97 if(!roinameSubpart(par->r[i].name, "_- ", 0, tmp, 7)) strcpy(tmp, ".");
98 fprintf(fp, "%s ", tmp);
99 if(!roinameSubpart(par->r[i].name, "_- ", 1, tmp, 7)) strcpy(tmp, ".");
100 fprintf(fp, "%s ", tmp);
101 if(!roinameSubpart(par->r[i].name, "_- ", 2, tmp, 7)) strcpy(tmp, ".");
102 fprintf(fp, "%s", tmp);
103 } else {
104 fprintf(fp, "tac%d . .", 1+i);
105 }
106 /* Time range, sample nr, (W)SS, parameter nr, function id */
107 fprintf(fp, "\t%.3f\t%.3f\t%d\t%.2E\t%d\t%04d",
108 par->r[i].start, par->r[i].end, par->r[i].dataNr,
109 par->r[i].wss, par->parNr, modelOldId(par->r[i].model) );
110 /* Function parameters */
111 for(j=0; j<par->parNr; j++) fprintf(fp, "\t%.6E", par->r[i].p[j]);
112 n=fprintf(fp, "\n");
113 } // next fit
114 if(n==0) {
115 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
117 }
118
119 /* Quit */
120 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
121 return(TPCERROR_OK);
122}
123/*****************************************************************************/
124
125/*****************************************************************************/
133 PAR *par,
135 CSV *csv,
138 IFT *ift,
140 TPCSTATUS *status
141) {
142 int verbose=0; if(status!=NULL) verbose=status->verbose;
143 if(par==NULL) {
144 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
145 return TPCERROR_FAIL;
146 }
147 parFree(par);
148
149 if(csv==NULL || ift==NULL || csv->row_nr<1 || csv->col_nr<1) {
150 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
151 return TPCERROR_NO_DATA;
152 }
153 if(verbose>0) printf("%s()\n", __func__);
154
155 if(verbose>10) {
156 printf("\n CSV contents shown with separator ; \n\n");
157 char sep=csv->separator;
158 csv->separator=';'; csvWrite(csv, 0, stdout, NULL); csv->separator=sep;
159 printf("\n IFT contents \n\n");
160 iftWrite(ift, stdout, NULL);
161 printf("\n");
162 }
163
164 int i, n, ret, titlerow, tunit=UNIT_UNKNOWN;
165 char *cptr, tmp[256];
166
167 /* TAC nr */
168 i=iftFindKey(ift, "Nr of VOIs", 0);
169 if(i<0) i=iftFindKey(ift, "voiNr", 0);
170 if(i<0) i=iftFindKey(ift, "tacNr", 0);
171 if(i<0) {
172 parFree(par);
173 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_UNSUPPORTED);
175 }
176 int tacNr=atoi(ift->item[i].value);
177
178 /* Find (and ignore) the parameter title line */
179 i=0; if(verbose>2) printf("estimating parNr\n");
180 while(i<csv->nr) {
181 i=csvSearchField(csv, "Region", i); if(i<0) break;
182 if(i>=0 && csv->c[i].col==0) break;
183 i++;
184 }
185 if(i<0 || i==csv->nr) {
186 parFree(par);
187 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
189 }
190 titlerow=csv->c[i].row; if(verbose>3) printf("titlerow := %d\n", titlerow);
191#if(1)
192 /* Parameter nr from the row with most columns */
193 int parNr=0;
194 for(int r=0; r<tacNr; r++) {
195 int n=csvRowLength(csv, r+titlerow+1); if(verbose>5) printf("n=%d at row %d\n", n, r+titlerow+1);
196 if(n>parNr) parNr=n;
197 }
198 if(verbose>4) printf(" initial_parNr := %d\n", parNr);
199#else
200 /* Parameter nr from the next row */
201 int parNr=csvRowLength(csv, titlerow+1);
202#endif
203 if(csv->separator!=' ') parNr-=7; else parNr-=9;
204 if(verbose>2) {
205 printf(" parNr := %d\n", parNr);
206 printf(" tacNr := %d\n", tacNr);
207 }
208 if(parNr<1 || tacNr<1) {
209 parFree(par);
210 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
212 }
213 /* Allocate space for parameters */
214 ret=parAllocate(par, parNr, tacNr); if(ret!=TPCERROR_OK) {
215 parFree(par);
216 statusSet(status, __func__, __FILE__, __LINE__, ret);
217 return ret;
218 }
219 par->parNr=parNr; par->tacNr=tacNr;
220
221 /* Check magic string and get program name from the first non-comment IFT field */
222 i=0;
223 while(ift->item[i].comment && i<ift->keyNr && ift->item[i].key!=NULL) i++;
224 if(verbose>3) {
225 printf("ift->item[%d].value := '%s'\n", i, ift->item[i].value);
226 }
227 if(i==ift->keyNr || strncasecmp(ift->item[i].value, "FIT1", 4)) {
228 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_UNSUPPORTED);
230 }
231 cptr=ift->item[i].value+4;
232 if(strncpyCleanSpaces(tmp, cptr, 256)<1) {
233 parFree(par);
234 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_UNSUPPORTED);
236 }
237 iftPut(&par->h, "program", tmp, 0, NULL);
238
239 /* Get analysis time from IFT struct */
240 i=iftFindKey(ift, "Date", 0);
241 if(i>=0) iftPut(&par->h, "analysis_time", ift->item[i].value, 0, NULL);
242
243 /* Filename of the original data */
244 i=iftFindKey(ift, "Data file", 0);
245 if(i>=0) iftPut(&par->h, "datafile", ift->item[i].value, 0, NULL);
246
247 /* Study number */
248 i=iftFindKey(ift, "Study number", 0);
249 if(i<0) i=iftFindKey(ift, "studynr", 0);
250 if(i>=0) iftPut(&par->h, "studynr", ift->item[i].value, 0, NULL);
251
252 /* Units of the original data */
253 i=iftFindKey(ift, "Data unit", 0);
254 if(i>=0) iftPut(&par->h, "unit", ift->item[i].value, 0, NULL);
255 i=iftFindKey(ift, "Time unit", 0);
256 if(i>=0) {
257 iftPut(&par->h, "timeunit", ift->item[i].value, 0, NULL);
258 tunit=unitIdentify(ift->item[i].value);
259 }
260
261 /* Set parameter names */
262 for(i=0; i<parNr; i++) sprintf(par->n[i].name, "p%d", 1+i);
263
264 /* Read TAC parameters */
265 ret=0; if(verbose>2) {printf("reading individual parameter values...\n"); fflush(stdout);}
266 for(int j=0; j<tacNr; j++) {
267 n=csvRowLength(csv, 1+j+titlerow); if(csv->separator!=' ') n-=7; else n-=9;
268 if(n>parNr) {ret++; break;}
269 i=0; n=1+j+titlerow;
270 /* copy tac name */
271 strlcpy(par->r[j].name, csvCell(csv, n, i), MAX_TACNAME_LEN);
272 if(csv->separator==' ') {
273 i++;
274 strlcat(par->r[j].name, " ", MAX_TACNAME_LEN);
275 strlcat(par->r[j].name, cptr=csvCell(csv, n, i), MAX_TACNAME_LEN);
276 i++;
277 strlcat(par->r[j].name, " ", MAX_TACNAME_LEN);
278 strlcat(par->r[j].name, cptr=csvCell(csv, n, i), MAX_TACNAME_LEN);
279 }
280 /* fit start and end times */
281 i++; par->r[j].start=atofVerified(csvCell(csv, n, i));
282 i++; par->r[j].end=atofVerified(csvCell(csv, n, i));
283 if(tunit==UNIT_SEC) {par->r[j].start/=60.; par->r[j].end/=60.;}
284 /* nr of fitted samples */
285 i++; par->r[j].dataNr=atoi(csvCell(csv, n, i));
286 /* (W)SS */
287 i++; par->r[j].wss=atofVerified(csvCell(csv, n, i));
288 /* nr of parameters for this TAC; this is not the same as the nr of fitted (free)
289 parameters that would be stored in PAR struct */
290 i++; int tacParNr=atoi(csvCell(csv, n, i));
291 par->r[j].fitNr=0;
292 /* function id */
293 i++; par->r[j].model=modelOld2New(atoi(csvCell(csv, n, i)));
294 /* function parameter values */
295#if(1)
296 int k; // read the ones that actually are saved... and then fill the rest with NaNs
297 for(k=0; k<tacParNr; k++) {
298 i++; par->r[j].p[k]=atofVerified(csvCell(csv, n, i));
299 }
300 for(; k<parNr; k++) par->r[j].p[k]=nan("");
301#else
302 for(int k=0; k<parNr; k++) {
303 i++; par->r[j].p[k]=atofVerified(csvCell(csv, n, i));}
304#endif
305 }
306 if(ret>0) {
307 parFree(par);
308 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FORMAT);
310 }
311
312 /* Fix region names (mainly, remove dots) */
313 {
314 int i, tac;
315 char fnsp[3][MAX_TACNAME_LEN+1];
316 for(tac=0; tac<par->tacNr; tac++) {
317 for(i=0; i<3; i++) {
318 if(roinameSubpart(par->r[tac].name, "_ ", i, fnsp[i], MAX_TACNAME_LEN)==NULL ||
319 strcmp(fnsp[i], ".")==0)
320 strcpy(fnsp[i], "");
321 }
322 strcpy(par->r[tac].name, fnsp[0]);
323 if(strlen(fnsp[1]) || strlen(fnsp[2])) strcat(par->r[tac].name, "_");
324 if(strlen(fnsp[1])) strcat(par->r[tac].name, fnsp[1]);
325 if(strlen(fnsp[2])) {strcat(par->r[tac].name, "_"); strcat(par->r[tac].name, fnsp[2]);}
326 }
327 }
328
329 /* Set format in struct */
331
332 /* Quit */
333 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
334 return(TPCERROR_OK);
335}
336/*****************************************************************************/
337
338/*****************************************************************************/
char * csvCell(CSV *csv, int row, int col)
Definition csv.c:358
int csvRowLength(CSV *csv, int row)
Definition csv.c:244
int csvSearchField(CSV *csv, const char *s, int start_index)
Definition csvfind.c:50
int csvWrite(CSV *csv, int regular, FILE *fp, TPCSTATUS *status)
Definition csvio.c:52
double atofVerified(const char *s)
Definition decpoint.c:75
int iftPut(IFT *ift, const char *key, const char *value, char comment, TPCSTATUS *status)
Definition ift.c:63
int iftFindKey(IFT *ift, const char *key, int start_index)
Definition iftfind.c:30
int iftWrite(IFT *ift, FILE *fp, TPCSTATUS *status)
Definition iftio.c:98
unsigned int modelOldId(const unsigned int i)
Definition modell.c:190
unsigned int modelOld2New(const unsigned int i)
Definition modell.c:204
void parFree(PAR *par)
Definition par.c:75
int parAllocate(PAR *par, int parNr, int tacNr)
Definition par.c:108
int parWriteFIT(PAR *par, FILE *fp, TPCSTATUS *status)
Definition parfit.c:27
int parReadFIT(PAR *par, CSV *csv, IFT *ift, TPCSTATUS *status)
Definition parfit.c:131
char * roinameSubpart(const char *roiname, const char *dlm, const unsigned int si, char *subpart, const unsigned int slen)
Definition roiname.c:20
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
Definition statusmsg.c:142
size_t strnlen(const char *s, size_t n)
Definition stringext.c:566
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
size_t strlcat(char *dst, const char *src, size_t dstsize)
Definition stringext.c:592
int col
Definition tpccsv.h:28
int row
Definition tpccsv.h:26
Definition tpccsv.h:36
int row_nr
Definition tpccsv.h:44
int col_nr
Definition tpccsv.h:46
char separator
Definition tpccsv.h:49
CSV_item * c
Definition tpccsv.h:38
char comment
Definition tpcift.h:27
char * value
Definition tpcift.h:37
char * key
Definition tpcift.h:32
Definition tpcift.h:43
IFT_ITEM * item
Definition tpcift.h:57
int keyNr
Definition tpcift.h:47
Definition tpcpar.h:101
int format
Definition tpcpar.h:103
IFT h
Optional (but often useful) header information.
Definition tpcpar.h:148
int parNr
Definition tpcpar.h:109
int tacNr
Definition tpcpar.h:105
PARR * r
Definition tpcpar.h:115
PARN * n
Definition tpcpar.h:113
char name[MAX_PARNAME_LEN+1]
Definition tpcpar.h:83
double wss
Definition tpcpar.h:73
int fitNr
Definition tpcpar.h:59
char name[MAX_TACNAME_LEN+1]
Definition tpcpar.h:50
int dataNr
Definition tpcpar.h:63
unsigned int model
Definition tpcpar.h:48
double * p
Definition tpcpar.h:65
double start
Definition tpcpar.h:52
double end
Definition tpcpar.h:54
int verbose
Verbose level, used by statusPrint() etc.
Header file for library libtpccsv.
Header file for library libtpcextensions.
#define MAX_TACNAME_LEN
Max length of TAC ID name (not including trailing zero)
@ UNIT_UNKNOWN
Unknown unit.
@ UNIT_SEC
seconds
@ TPCERROR_FAIL
General error.
@ TPCERROR_INVALID_FORMAT
Invalid file format.
@ TPCERROR_UNSUPPORTED
Unsupported file type.
@ TPCERROR_OK
No error.
@ TPCERROR_NO_DATA
File contains no data.
@ TPCERROR_CANNOT_WRITE
Cannot write file.
int unitIdentify(const char *s)
Definition units.c:162
Header file for library libtpcift.
Header file for libtpcmodels.
Header file for libtpcpar.
@ PAR_FORMAT_FIT
Function fit format of Turku PET Centre.
Definition tpcpar.h:30