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

TPC result (*.fit) file format I/O functions. More...

#include "tpcclibConfig.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <string.h>
#include "tpcextensions.h"
#include "tpcmodels.h"
#include "tpccsv.h"
#include "tpcift.h"
#include "tpcpar.h"

Go to the source code of this file.

Functions

int parWriteFIT (PAR *par, FILE *fp, TPCSTATUS *status)
 
int parReadFIT (PAR *par, CSV *csv, IFT *ift, TPCSTATUS *status)
 

Detailed Description

TPC result (*.fit) file format I/O functions.

Definition in file parfit.c.

Function Documentation

◆ parReadFIT()

int parReadFIT ( PAR * par,
CSV * csv,
IFT * ift,
TPCSTATUS * status )

Read (old) fit data into PAR struct.

Returns
enum tpcerror (TPCERROR_OK when successful).
Author
Vesa Oikonen
See also
parRead, parWriteFIT
Parameters
parPointer to target PAR struct.
csvPointer to source CSV from which data is read.
iftPointer to source IFT struct which contains whole result file data, in case the data could not be read into CSV.
statusPointer to status data; enter NULL if not needed

Definition at line 131 of file parfit.c.

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}
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 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
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
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
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
IFT_ITEM * item
Definition tpcift.h:57
int keyNr
Definition tpcift.h:47
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.
#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.
int unitIdentify(const char *s)
Definition units.c:162
@ PAR_FORMAT_FIT
Function fit format of Turku PET Centre.
Definition tpcpar.h:30

Referenced by parRead().

◆ parWriteFIT()

int parWriteFIT ( PAR * par,
FILE * fp,
TPCSTATUS * status )

Write FIT data into specified file pointer in (old) fit file format.

See also
parWrite
Returns
enum tpcerror (TPCERROR_OK when successful).
Author
Vesa Oikonen
Parameters
parPointer to PAR struct, contents of which are to be written.
fpOutput file pointer.
statusPointer to status data; enter NULL if not needed.

Definition at line 27 of file parfit.c.

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}
unsigned int modelOldId(const unsigned int i)
Definition modell.c:190
size_t strnlen(const char *s, size_t n)
Definition stringext.c:566
@ TPCERROR_CANNOT_WRITE
Cannot write file.

Referenced by parWrite().