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

Reading TACs to be used in modelling. More...

#include "tpcclibConfig.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <string.h>
#include "tpcextensions.h"
#include "tpcli.h"
#include "tpctac.h"
#include "tpctacmod.h"

Go to the source code of this file.

Functions

int tacFittime (TAC *d, double *startTime, double *endTime, int *first, int *last, TPCSTATUS *status)
int tacReadModelingData (const char *tissuefile, const char *inputfile1, const char *inputfile2, const char *inputfile3, double *fitdur, int cutInput, int *fitSampleNr, TAC *tis, TAC *inp, TPCSTATUS *status)
 Read tissue and input data for modelling.
int tacReadReference (TAC *tis, const char *reference, TAC *ref, int *refIndex, TPCSTATUS *status)
 Read reference tissue TAC.
int tacReadModelingInput (const char *inputfile1, const char *inputfile2, const char *inputfile3, TAC *inp, TPCSTATUS *status)
 Read arterial input data for modelling.

Detailed Description

Reading TACs to be used in modelling.

Definition in file tacmodelinput.c.

Function Documentation

◆ tacFittime()

int tacFittime ( TAC * d,
double * startTime,
double * endTime,
int * first,
int * last,
TPCSTATUS * status )

Reset user-defined fit time range to comply with TAC data.

Returns
Returns the number of samples included in the fit range, or <0 in case of an error.
See also
tacReadModelingData, tacVerifyTimeOrder, tacSortByTime
Parameters
dPointer to TAC containing (regional tissue) data; times can be in minutes or seconds, as long as units are defined. TAC sampleNr is not changed in this function.
startTimePointer containing originally the requested fit start time (min). This is changed to contain the time of the first included frame. Unit must be minutes. Initially, set to <0 to start from the beginning of the data.
endTimePointer containing originally the requested fit end time (min). This is changed to contain the time of the last included frame. Unit must be minutes. Initially, set to <0 or to a very large value to reach to the end of data.
firstFunction writes the index of the first included sample (frame) here; enter NULL if not needed.
lastFunction writes the index of the last included sample (frame) here; enter NULL if not needed.
statusPointer to status data; enter NULL if not needed.

Definition at line 25 of file tacmodelinput.c.

49 {
50 int verbose=0; if(status!=NULL) verbose=status->verbose;
51 if(verbose>0) printf("%s()\n", __func__);
52 if(first!=NULL) *first=0;
53 if(last!=NULL) *last=0;
54 if(d==NULL || startTime==NULL || endTime==NULL) {
55 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
56 return(-1);
57 }
58
59 if(d->sampleNr<=0) {
60 *startTime=*endTime=0.0;
61 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
62 return(0);
63 }
64 if(*endTime<0.0) *endTime=1.0E+100;
65
66 /* Change start and end times to seconds if necessary */
67 double cf;
69 if(!isnan(cf)) {*startTime*=cf; *endTime*=cf;}
70 if(verbose>1) {
71 printf("startTime := %g\n", *startTime);
72 printf("endTime := %g\n", *endTime);
73 }
74
75#if(0)
76 /* Check that data range is not outside required range */
77 {
78 double s, e;
79 if(tacXRange(d, &s, &e) || e<*startTime || s>*endTime) {
80 *startTime=*endTime=0.0;
81 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_X_RANGE);
82 return(0);
83 }
84 }
85#endif
86
87 /* Get first and last data point inside the range */
88 int s, e;
89 {
90 double f;
91 s=e=-1;
92 for(int i=0; i<d->sampleNr; i++) {
93 if(d->isframe) f=0.5*(d->x1[i]+d->x2[i]); else f=d->x[i];
94 if(verbose>3) printf(" f := %g\n", f);
95 if(s<0 && f>=*startTime) s=i;
96 if(f<=*endTime) e=i; else break;
97 }
98 if(s<0 || e<0) {
99 *startTime=*endTime=0.0;
100 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_XRANGE);
101 return(0);
102 }
103 if(first!=NULL) *first=s;
104 if(last!=NULL) *last=e;
105 }
106
107 /* Correct fit range to frame start and end times */
108 *startTime=(d->isframe ? d->x1[s] : d->x[s]);
109 *endTime= (d->isframe ? d->x2[e] : d->x[e]);
110 /* Change start and end times back to minutes if necessary */
111 if(!isnan(cf)) {*startTime/=cf; *endTime/=cf;}
112 /* Return the sample number in the fit range */
113 return(1+e-s);
114}
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
Definition statusmsg.c:142
double * x
Definition tpctac.h:97
int sampleNr
Definition tpctac.h:89
int isframe
Definition tpctac.h:95
double * x2
Definition tpctac.h:101
unit tunit
Definition tpctac.h:109
double * x1
Definition tpctac.h:99
int verbose
Verbose level, used by statusPrint() etc.
int tacXRange(TAC *d, double *xmin, double *xmax)
Get the range of x values (times) in TAC structure.
Definition tacx.c:124
@ UNIT_MIN
minutes
@ TPCERROR_INVALID_XRANGE
Invalid sample time range.
@ TPCERROR_FAIL
General error.
@ TPCERROR_NO_DATA
File contains no data.
double unitConversionFactor(const int u1, const int u2)
Definition units.c:487

Referenced by tacReadModelingData().

◆ tacReadModelingData()

int tacReadModelingData ( const char * tissuefile,
const char * inputfile1,
const char * inputfile2,
const char * inputfile3,
double * fitdur,
int cutInput,
int * fitSampleNr,
TAC * tis,
TAC * inp,
TPCSTATUS * status )

Read tissue and input data for modelling.

Time units are converted to min and input calibration units to the units of tissue data. Input data is NOT interpolated to tissue times, but original sample times are kept. If input data extends much further than fit duration, the last part is removed to save computation time in simulations. Input data ranges or TAC shapes are NOT verified.

See also
tacReadReference, tacReadModelingInput, tacFittime, tacRead, tacInit, tacInterpolate
Returns
enum tpcerror (TPCERROR_OK when successful).
Author
Vesa Oikonen
Parameters
tissuefileTissue data file name; one time sample is sufficient here; required.
inputfile11st input data file name; required.
inputfile22nd input data file name (or NULL or empty string if not needed); required, if inputfile3 is given.
inputfile33rd input data file name (or NULL or empty string if not needed).
fitdurFit duration (in minutes); shortened if longer than tissue data; input data is cut (if requested) so that it will not be much longer. Tissue TACs are NOT cut to this time.
cutInputCut off too many input samples to make calculation faster by entering <>0 here, or 0 to keep all input samples (which may be needed for delay correction).
fitSampleNrNr of time frames (samples) in tissue data that are inside fitdur will be written here; enter NULL if not needed.
tisPointer to initiated TAC struct into which tissue data will be written; required.
inpPointer to initiated TAC struct into which input data (plasma and/or blood) TACs will be written; required.
statusPointer to status data; enter NULL if not needed.

Definition at line 130 of file tacmodelinput.c.

157 {
158 int verbose=0; if(status!=NULL) verbose=status->verbose;
159 if(verbose>0) printf("%s()\n", __func__);
160 if(tis==NULL || inp==NULL) {
161 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
162 return TPCERROR_FAIL;
163 }
164 if(tissuefile==NULL || inputfile1==NULL || strnlen(inputfile1, 1)<1) {
165 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
166 return TPCERROR_NO_DATA;
167 }
168
169 /* Check the function input */
170 int input_nr=1;
171 if(inputfile2!=NULL && strnlen(inputfile2, 1)>0) input_nr++;
172 if(inputfile3!=NULL && strnlen(inputfile3, 1)>0) {
173 if(input_nr<2) {
174 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
175 return TPCERROR_NO_DATA;
176 }
177 input_nr++;
178 }
179 if(verbose>2) printf("input_nr := %d\n", input_nr);
180
181 /* Delete any previous data */
182 tacFree(tis); tacFree(inp);
183 if(fitSampleNr!=NULL) *fitSampleNr=0;
184
185 int ret;
186 /*
187 * Read tissue data
188 */
189 if(verbose>1) printf("reading tissue data in %s\n", tissuefile);
190 ret=tacRead(tis, tissuefile, status);
191 if(ret!=TPCERROR_OK) return(ret);
192
193 /* Do not check frame number; static scan is fine here */
194
195 /* Check for NaN's */
196 if(tacNaNs(tis)>0) {
197 tacFree(tis);
198 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_MISSING_DATA);
200 }
201
202 /* Sort the tissue data by increasing sample times */
203 ret=tacSortByTime(tis, status);
204 if(ret!=TPCERROR_OK) {
205 tacFree(tis);
206 statusSet(status, __func__, __FILE__, __LINE__, ret);
207 return ret;
208 }
209
210 /* Make sure that there is no overlap in sample frame times; samples must
211 be sorted before this */
212 ret=tacCorrectFrameOverlap(tis, status);
213 if(ret!=TPCERROR_OK) {tacFree(tis); return ret;}
214
215 /*
216 * Read first input data
217 */
218 if(verbose>1) printf("reading input data 1 in %s\n", inputfile1);
219 ret=tacRead(inp, inputfile1, status);
220 if(ret!=TPCERROR_OK) {tacFree(tis); return ret;}
221 /* Check and correct the sample time unit */
222 if(tis->tunit==UNIT_UNKNOWN) tis->tunit=inp->tunit;
223 else if(inp->tunit==UNIT_UNKNOWN) inp->tunit=tis->tunit;
224 if(inp->tunit==UNIT_UNKNOWN && verbose>0) {
225 fprintf(stderr, "Warning: input sample time units not known.\n");}
226 if(tis->tunit!=inp->tunit && tacXUnitConvert(inp, tis->tunit, status)) {
227 tacFree(tis); tacFree(inp); return ret;
228 }
229 /* Check TAC nr */
230 if(inp->tacNr>1) {
231 if(verbose>0)
232 fprintf(stderr, "Warning: using only first TAC in %s\n", inputfile1);
233 inp->tacNr=1;
234 }
235 /* Check sample nr */
236 if(inp->sampleNr<4) {
237 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_TOO_FEW);
238 tacFree(tis); tacFree(inp); return TPCERROR_TOO_FEW;
239 }
240 /* Sort the data by increasing sample times */
241 tacSortByTime(inp, NULL);
242 /* If inp contains isotope and tis does not, then copy it */
244 int isotope=tacGetIsotope(inp);
246 }
247
248 /*
249 * Read following input files, if available
250 */
251 char *fname;
252 TAC tmptac; tacInit(&tmptac);
253 for(int ii=2; ii<=input_nr; ii++) {
254 if(ii==2) fname=(char*)inputfile2; else fname=(char*)inputfile3;
255 if(verbose>1) printf("reading input data %d in %s\n", ii, fname);
256 ret=tacRead(&tmptac, fname, status);
257 if(ret!=TPCERROR_OK) {
258 tacFree(tis); tacFree(inp); tacFree(&tmptac); return ret;}
259 /* Check TAC nr */
260 if(tmptac.tacNr>1) {
261 if(verbose>0)
262 fprintf(stderr, "Warning: using only first TAC in %s\n", fname);
263 tmptac.tacNr=1;
264 }
265 /* Check sample nr */
266 if(tmptac.sampleNr<4) {
267 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_TOO_FEW);
268 tacFree(tis); tacFree(inp); tacFree(&tmptac); return TPCERROR_TOO_FEW;
269 }
270 /* Sort the data by increasing sample times */
271 tacSortByTime(&tmptac, NULL);
272
273 /* Check and correct the sample time unit */
274 if(tis->tunit==UNIT_UNKNOWN) tis->tunit=tmptac.tunit;
275 else if(tmptac.tunit==UNIT_UNKNOWN) tmptac.tunit=tis->tunit;
276 if(inp->tunit!=tmptac.tunit && tacXUnitConvert(&tmptac, inp->tunit, status))
277 {
278 tacFree(tis); tacFree(inp); tacFree(&tmptac); return ret;
279 }
280
281 /* Check and correct the sample concentration unit */
282 if(inp->cunit==UNIT_UNKNOWN) inp->cunit=tmptac.cunit;
283 else if(tmptac.cunit==UNIT_UNKNOWN) tmptac.cunit=inp->cunit;
284 if(inp->cunit!=tmptac.cunit && tacYUnitConvert(&tmptac, inp->cunit, status))
285 {
286 tacFree(tis); tacFree(inp); tacFree(&tmptac); return ret;
287 }
288
289 /* Copy to input data */
290 if(tacInterpolateInto(&tmptac, inp, NULL, NULL, status)!=TPCERROR_OK) {
291 tacFree(tis); tacFree(inp); tacFree(&tmptac); return ret;
292 }
293
294 tacFree(&tmptac);
295 } // next input file
296
297 /* Set time unit to min */
298 ret=tacXUnitConvert(tis, UNIT_MIN, status);
299 if(ret && verbose>0) {
300 fprintf(stderr, "Warning: check that regional data times are in minutes.\n");
301 }
302 ret=tacXUnitConvert(inp, UNIT_MIN, status);
303 if(ret && verbose>0) {
304 fprintf(stderr, "Warning: check that input data times are in minutes.\n");
305 }
306 /* Check that input and tissue time ranges are about the same */
307 double iend, tend;
308 {
309 ret=tacXRange(inp, NULL, &iend); if(ret==0) ret=tacXRange(tis, NULL, &tend);
310 if(ret || iend<=0.0 || tend<=0.0) {
311 tacFree(tis); tacFree(inp);
312 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_XRANGE);
314 }
315 if(tend>10.0*iend || tend<0.10*iend) {
316 if(verbose>0) fprintf(stderr, "Warning: check the sample time units.\n");
317 }
318 }
319 ret=tacYUnitConvert(inp, tis->cunit, status);
320 if(ret && verbose>0) {
321 fprintf(stderr, "Warning: check the calibration units.\n");
322 }
323
324 /*
325 * Check and set fit time length
326 */
327 if(verbose>1) printf("checking and setting fit time length\n");
328 /* Set fit duration */
329 double starttime=0, endtime=*fitdur;
330 int fnr=tacFittime(tis, &starttime, &endtime, NULL, NULL, status);
331 if(verbose>3) {
332 fprintf(stdout, "tis.sampleNr := %d\n", tis->sampleNr);
333 fprintf(stdout, "starttime := %g\n", starttime);
334 fprintf(stdout, "endtime := %g\n", endtime);
335 //fprintf(stdout, "first := %d\n", first);
336 //fprintf(stdout, "last := %d\n", last);
337 fprintf(stdout, "fitSampleNr := %d\n", fnr);
338 }
339 *fitdur=endtime;
340 if(fitSampleNr!=NULL) *fitSampleNr=fnr;
341
342 /* Check that input data does not end much before fitdur */
343 if(*fitdur>1.2*iend) {
344 tacFree(tis); tacFree(inp);
345 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_TOO_FEW);
346 return TPCERROR_TOO_FEW;
347 }
348
349 /* Cut off too many input samples to make calculation faster */
350 if(cutInput && iend>*fitdur) {
351 if(verbose>1) printf("cut off too many input samples\n");
352 int i; double f;
353 for(i=0; i<inp->sampleNr; i++) {
354 if(inp->isframe) f=0.5*(inp->x1[i]+inp->x2[i]); else f=inp->x[i];
355 if(f>(*fitdur)) break;
356 }
357 if(i<inp->sampleNr) i++;
358 inp->sampleNr=i;
359 if(inp->sampleNr<4) {
360 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_TOO_FEW);
361 tacFree(tis); tacFree(inp); return TPCERROR_TOO_FEW;
362 }
363 }
364 if(verbose>2) fprintf(stdout, "inp.sampleNr := %d\n", inp->sampleNr);
365
366 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
367 return(TPCERROR_OK);
368}
int tacInterpolateInto(TAC *inp, TAC *tac, TAC *itac, TAC *iitac, TPCSTATUS *status)
Add TACs from one TAC structure into another TAC structure, interpolating the input TACs and allocati...
Definition litac.c:330
size_t strnlen(const char *s, size_t n)
Definition stringext.c:566
Definition tpctac.h:87
unit cunit
Definition tpctac.h:105
int tacNr
Definition tpctac.h:91
void tacFree(TAC *tac)
Definition tac.c:106
void tacInit(TAC *tac)
Definition tac.c:24
int tacGetIsotope(TAC *tac)
Definition tacdc.c:25
void tacSetIsotope(TAC *tac, int isotope)
Definition tacdc.c:41
int tacRead(TAC *d, const char *fname, TPCSTATUS *status)
Definition tacio.c:413
int tacFittime(TAC *d, double *startTime, double *endTime, int *first, int *last, TPCSTATUS *status)
int tacNaNs(TAC *tac)
Definition tacnan.c:71
int tacSortByTime(TAC *d, TPCSTATUS *status)
Definition tacorder.c:74
int tacYUnitConvert(TAC *tac, const int u, TPCSTATUS *status)
Definition tacunits.c:72
int tacXUnitConvert(TAC *tac, const int u, TPCSTATUS *status)
Definition tacunits.c:23
int tacCorrectFrameOverlap(TAC *d, TPCSTATUS *status)
Correct PET frame start and end times if frames are slightly overlapping or have small gaps in betwee...
Definition tacx.c:65
@ UNIT_UNKNOWN
Unknown unit.
@ TPCERROR_OK
No error.
@ TPCERROR_TOO_FEW
File contains too few samples.
@ TPCERROR_MISSING_DATA
File contains missing values.
isotope
Definition tpcisotope.h:50
@ ISOTOPE_UNKNOWN
Unknown.
Definition tpcisotope.h:51

◆ tacReadModelingInput()

int tacReadModelingInput ( const char * inputfile1,
const char * inputfile2,
const char * inputfile3,
TAC * inp,
TPCSTATUS * status )

Read arterial input data for modelling.

Time and calibration units to the units of the first data. Input data ranges or TAC shapes are NOT verified.

See also
tacReadModelingData, tacReadReference, tacFittime, tacInterpolate
Returns
enum tpcerror (TPCERROR_OK when successful).
Author
Vesa Oikonen
Parameters
inputfile11st input data file name; required.
inputfile22nd input data file name (or NULL or empty string if not needed); required, if inputfile3 is given.
inputfile33rd input data file name (or NULL or empty string if not needed).
inpPointer to initiated TAC data structure into which input data (plasma and/or blood) TACs will be written; required.
See also
tacInit, tacFree
Parameters
statusPointer to status data; enter NULL if not needed.

Definition at line 560 of file tacmodelinput.c.

575 {
576 int verbose=0; if(status!=NULL) verbose=status->verbose;
577 if(verbose>0) {printf("%s()\n", __func__); fflush(stdout);}
578 if(inp==NULL) {
579 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
580 return TPCERROR_FAIL;
581 }
582 if(inputfile1==NULL || strnlen(inputfile1, 1)<1) {
583 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
584 return TPCERROR_NO_DATA;
585 }
586
587 /* Check the function input */
588 int input_nr=1;
589 if(inputfile2!=NULL && strnlen(inputfile2, 1)>0) input_nr++;
590 if(inputfile3!=NULL && strnlen(inputfile3, 1)>0) {
591 if(input_nr<2) {
592 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
593 return TPCERROR_NO_DATA;
594 }
595 input_nr++;
596 }
597 if(verbose>2) {printf("input_nr := %d\n", input_nr); fflush(stdout);}
598
599 /* Delete any previous data */
600 tacFree(inp);
601
602 int ret;
603 /*
604 * Read first input data
605 */
606 if(verbose>1) {
607 printf("reading input data 1 in %s\n", inputfile1); fflush(stdout);
608 }
609 ret=tacRead(inp, inputfile1, status);
610 if(ret!=TPCERROR_OK) {return ret;}
611 /* Check for NaN's */
612 if(tacNaNs(inp)>0) {
613 tacFree(inp);
614 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_MISSING_DATA);
616 }
617 /* Sort the data by increasing sample times */
618 ret=tacSortByTime(inp, status);
619 if(ret!=TPCERROR_OK) {
620 tacFree(inp); return ret;
621 }
622 /* Check TAC nr */
623 if(inp->tacNr>1) {
624 if(verbose>0)
625 fprintf(stderr, "Warning: using only first TAC in %s\n", inputfile1);
626 inp->tacNr=1;
627 }
628 /* Check sample nr */
629 if(inp->sampleNr<4) {
630 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_TOO_FEW);
631 tacFree(inp); return TPCERROR_TOO_FEW;
632 }
633
634 /*
635 * Read following input files, if available
636 */
637 char *fname;
638 TAC tmptac; tacInit(&tmptac);
639 for(int ii=2; ii<=input_nr; ii++) {
640 if(ii==2) fname=(char*)inputfile2; else fname=(char*)inputfile3;
641 if(verbose>1) {
642 printf("reading input data %d in %s\n", ii, fname);
643 fflush(stdout);
644 }
645 ret=tacRead(&tmptac, fname, status);
646 if(ret!=TPCERROR_OK) {
647 tacFree(inp); tacFree(&tmptac); return ret;}
648 /* Check TAC nr */
649 if(tmptac.tacNr>1) {
650 if(verbose>0)
651 fprintf(stderr, "Warning: using only first TAC in %s\n", fname);
652 tmptac.tacNr=1;
653 }
654 /* Check sample nr */
655 if(tmptac.sampleNr<4) {
656 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_TOO_FEW);
657 tacFree(inp); tacFree(&tmptac); return TPCERROR_TOO_FEW;
658 }
659 /* Sort the data by increasing sample times */
660 tacSortByTime(&tmptac, status);
661 if(ret!=TPCERROR_OK) {
662 tacFree(inp); tacFree(&tmptac); return ret;
663 }
664 /* Check and correct the sample time unit */
665 if(inp->tunit==UNIT_UNKNOWN) inp->tunit=tmptac.tunit;
666 else if(tmptac.tunit==UNIT_UNKNOWN) tmptac.tunit=inp->tunit;
667 if(inp->tunit!=tmptac.tunit && tacXUnitConvert(&tmptac, inp->tunit, status))
668 {
669 tacFree(inp); tacFree(&tmptac); return ret;
670 }
671 /* Check and correct the sample concentration unit */
672 if(inp->cunit==UNIT_UNKNOWN) inp->cunit=tmptac.cunit;
673 else if(tmptac.cunit==UNIT_UNKNOWN) tmptac.cunit=inp->cunit;
674 if(inp->cunit!=tmptac.cunit && tacYUnitConvert(&tmptac, inp->cunit, status))
675 {
676 tacFree(inp); tacFree(&tmptac); return ret;
677 }
678 /* Copy to input data */
679 if(tacInterpolateInto(&tmptac, inp, NULL, NULL, status)!=TPCERROR_OK) {
680 tacFree(inp); tacFree(&tmptac); return ret;
681 }
682 tacFree(&tmptac);
683 } // next input file
684
685 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
686 return(TPCERROR_OK);
687}

◆ tacReadReference()

int tacReadReference ( TAC * tis,
const char * reference,
TAC * ref,
int * refIndex,
TPCSTATUS * status )

Read reference tissue TAC.

Reference tissue TAC is read either from a TAC file or from TAC structure containing all regional TACs based on its name. Reference tissue TACs are then either placed in a separate TAC structure, if provided by the user, or added/marked inside the existing TAC structure. Reference TAC(s) are marked with sw=2 (best or only match) or sw=1; if reference region file contains several TACs then the one which contains name 'mean' or 'avg' or has shortest total name length is assumed to be the best guess of true reference region and marked with value sw=2. When necessary, reference data units are converted to match the existing tissue TAC. If reference TAC(s) are read from a file, then this function verifies that the sample times do match the existing TACs. Reference TAC shapes are NOT verified.

See also
tacReadModelingData, tacFittime, tacRead, tacInit, tacInterpolate, tacSelectedTACs, tacSelectBestReference, tacReadModelingInput.
Returns
The number of reference TACs, and 0 in case of an error.
Author
Vesa Oikonen
Parameters
tisPointer to TAC structure containing the regional tissue TACs, possibly also the reference TAC(s). If pointer to reference TAC structure is not given (below), then the reference TAC(s) are marked/added in this TAC structure; otherwise reference TAC(s) may be moved from this structure into the reference TAC structure.
referenceString containing either the name of reference TAC file, or reference region name or number in the TAC structure (above).
refPointer to output TAC structure into which the reference tissue TACs are placed. Enter NULL, if reference TACs are to be placed/kept in the TAC structure with all tissue TACs. TACs in this structure will be marked with either sw=2 (best guess of true reference region) or sw=1 (less probable reference TACs). Any previous contents are deleted.
Precondition
Struct must be initiated before calling this function.
Parameters
refIndexIndex of the best reference region; enter NULL if not needed.
statusPointer to status data; enter NULL if not needed.

Definition at line 390 of file tacmodelinput.c.

411 {
412 int verbose=0; if(status!=NULL) verbose=status->verbose;
413 if(verbose>0) printf("%s()\n", __func__);
414 if(tis==NULL || reference==NULL) {
415 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
416 return 0;
417 }
418 if(strnlen(reference, 1)<1 || tis->sampleNr<1 || !tacIsX(tis)) {
419 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA);
420 return 0;
421 }
422
423 /* First, try to read reference from file */
424 TAC temp; tacInit(&temp);
425 if(verbose>1) printf("trying to read file %s\n", reference);
426 if(tacRead(&temp, reference, status)==TPCERROR_OK) {
427 /* Check sample nr */
428 if(temp.sampleNr<tis->sampleNr) {
429 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_TOO_FEW);
430 tacFree(&temp); return 0;
431 }
432 int n, ret=0, refi=0;
433 /* Convert units */
434 if(tacXUnitConvert(&temp, tis->tunit, status)) ret++;
435 if(tacYUnitConvert(&temp, tis->cunit, status)) ret++;
436 if(verbose>0 && ret>0)
437 fprintf(stderr, "Warning: check the units of reference and tissue data.\n");
438 /* Check that sample times do match */
439 if(!tacXMatch(tis, &temp, verbose-1)) {
440 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_X);
441 tacFree(&temp); return 0;
442 } else if(tis->isframe && !temp.isframe) {
443 /* Copy frame start and end times, in case those had been lost */
444 tacXCopy(tis, &temp, 0, tis->sampleNr-1);
445 temp.isframe=1;
446 }
447 /* Select the best reference region */
448 if(temp.tacNr==1) {
449 temp.c[0].sw=2; refi=0; // just one
450 } else {
451 for(int i=0; i<temp.tacNr; i++) temp.c[i].sw=1;
452 refi=tacSelectBestReference(&temp); if(refi<0) refi=0;
453 temp.c[refi].sw=2;
454 }
455 if(verbose>1) printf("selected ref region := %s\n", temp.c[refi].name);
456 /* If ref contains isotope and tis does not, then copy it */
458 int isotope=tacGetIsotope(&temp);
460 }
461 /* Copy to output struct, if pointer is given; otherwise copy to tis */
462 if(ref!=NULL) {
463 if(verbose>2) printf("adding %d ref tacs to ref struct\n", temp.tacNr);
464 ret=tacDuplicate(&temp, ref);
465 if(ret!=TPCERROR_OK) {
466 statusSet(status, __func__, __FILE__, __LINE__, ret);
467 tacFree(&temp); return 0;
468 }
469 if(refIndex!=NULL) *refIndex=refi;
470 } else {
471 if(verbose>2) printf("adding %d ref tacs to tis struct\n", temp.tacNr);
472 for(int i=0; i<tis->tacNr; i++) tis->c[i].sw=0;
473 ret=tacAllocateMore(tis, temp.tacNr);
474 for(int i=0; i<temp.tacNr && ret==TPCERROR_OK; i++)
475 ret=tacCopyTacc(&temp.c[i], &tis->c[tis->tacNr+i], tis->sampleNr);
476 if(ret!=TPCERROR_OK) {
477 statusSet(status, __func__, __FILE__, __LINE__, ret);
478 tacFree(&temp); return 0;
479 }
480 if(refIndex!=NULL) *refIndex=tis->tacNr+refi;
481 tis->tacNr+=temp.tacNr;
482 }
483 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
484 n=temp.tacNr; tacFree(&temp);
485 if(verbose>1) printf("%d ref region(s) found in file.\n", n);
486 return(n);
487 // reference file was read and processed
488 } else if(verbose>1) {
489 printf(" '%s' was not a file\n", reference); fflush(stdout);
490 }
491
492 /* So 'reference' did not contain valid, accessible filename,
493 but is it a region name or number? */
494 if(verbose>1) printf("trying to find reference in TAC struct\n");
495 int n, refi;
496 n=tacSelectTACs(tis, reference, 1, status);
497 if(verbose>1) {printf("%d region(s) matched.\n", n); fflush(stdout);}
498 if(n<1) {
499 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_REFERENCE);
500 return(0);
501 }
502 if(n==tis->tacNr) {
503 if(verbose>2) {printf("... which means all region(s) matched.\n"); fflush(stdout);}
504 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_VALUE);
505 return(0);
506 }
507 refi=tacSelectBestReference(tis);
508 if(refi<0) {
509 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_VALUE);
510 return(0);
511 }
512 tis->c[refi].sw=2; if(refIndex!=NULL) *refIndex=refi;
513
514 /* If output struct was not given, then we are ready */
515 if(ref==NULL) {
516 if(verbose>1) {printf("reference TAC tagged.\n"); fflush(stdout);}
517 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
518 return(n);
519 }
520
521 /* Move reference TACs to output struct */
522 if(verbose>1) printf("moving reference TAC(s) to output TAC struct\n");
523 int ret;
524 ret=tacDuplicate(tis, ref);
525 if(ret!=TPCERROR_OK) {
526 statusSet(status, __func__, __FILE__, __LINE__, ret);
527 return 0;
528 }
529 int i=ref->tacNr-1; ret=0;
530 while(i>=0 && !ret) {
531 if(ref->c[i].sw==0) ret=tacDeleteTACC(ref, i);
532 i--;
533 }
534 i=tis->tacNr-1;
535 while(i>=0 && !ret) {
536 if(tis->c[i].sw) ret=tacDeleteTACC(tis, i);
537 i--;
538 }
539 if(ret) {
540 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_FAIL);
541 return 0;
542 }
543 if(refIndex!=NULL) { // set reference index to index inside ref struct
544 *refIndex=-1;
545 for(i=0; i<ref->tacNr; i++) if(ref->c[i].sw==2) {*refIndex=i; break;}
546 }
547 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
548 return(n);
549}
char sw
Definition tpctac.h:77
char name[MAX_TACNAME_LEN+1]
Definition tpctac.h:81
TACC * c
Definition tpctac.h:117
int tacDuplicate(TAC *tac1, TAC *tac2)
Make a duplicate of TAC structure.
Definition tac.c:356
int tacAllocateMore(TAC *tac, int tacNr)
Definition tac.c:178
int tacCopyTacc(TACC *d1, TACC *d2, int sampleNr)
Definition tac.c:233
int tacDeleteTACC(TAC *d, int i)
Definition tacorder.c:310
int tacSelectTACs(TAC *d, const char *region_name, int reset, TPCSTATUS *status)
Definition tacselect.c:24
int tacSelectBestReference(TAC *d)
Definition tacselect.c:139
int tacXMatch(TAC *d1, TAC *d2, const int verbose)
Check whether sample (frame) times are the same (or very close to) in two TAC structures.
Definition tacx.c:249
int tacXCopy(TAC *tac1, TAC *tac2, int i1, int i2)
Definition tacx.c:24
int tacIsX(TAC *d)
Verify if TAC structure contains reasonable x values (times).
Definition tacx.c:226
@ TPCERROR_NO_REFERENCE
Reference not found.
@ TPCERROR_INVALID_VALUE
Invalid value.
@ TPCERROR_INVALID_X
Invalid sample time.