TPCCLIB
Loading...
Searching...
No Matches
libtpccurveio.h File Reference

Header file for libtpccurveio. More...

#include "tpcclibConfig.h"
#include "libtpcmisc.h"
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <ctype.h>
#include <math.h>
#include <time.h>

Go to the source code of this file.

Data Structures

struct  Voi
 
struct  DFT
 
struct  ResVOI
 
struct  RES
 
struct  FitVOI
 
struct  FIT
 
struct  CSV_item
 
struct  CSV
 

Macros

#define BACKUP_EXTENSION   ".bak"
 
#define MAX_RESPARAMS   100
 
#define MAX_RESPARNAME_LEN   15
 
#define MAX_FITPARAMS   100
 
#define DFT_FORMAT_UNKNOWN   -1
 
#define DFT_FORMAT_PLAIN   0
 
#define DFT_FORMAT_STANDARD   1
 
#define DFT_FORMAT_IFT   2
 
#define DFT_FORMAT_FIT   3
 
#define DFT_FORMAT_NCI   4
 
#define DFT_FORMAT_PMOD   5
 
#define DFT_FORMAT_CSV_INT   6
 
#define DFT_FORMAT_CSV_UK   7
 
#define DFT_FORMAT_CPT   8
 
#define DFT_FORMAT_IDWC   9
 
#define DFT_FORMAT_IF   10
 
#define DFT_FORMAT_XML   11
 
#define DFT_FORMAT_HTML   12
 
#define DFT_FORMAT_XELERIS   13
 
#define DFT_TIME_MIDDLE   0
 
#define DFT_TIME_START   1
 
#define DFT_TIME_END   2
 
#define DFT_TIME_STARTEND   3
 
#define DFT_DECAY_UNKNOWN   0
 
#define DFT_DECAY_CORRECTED   1
 
#define DFT_DECAY_NOTCORRECTED   2
 

Enumerations

enum  mathfuncs {
  MF_LEVEL =100 , MF_LINE , MF_POL2 , MF_POL3 ,
  MF_POL4 , MF_POL5 , MF_POL6 , MF_POL7 ,
  MF_POL8 , MF_POL9 , MF_RATF11 =211 , MF_RATF21 =221 ,
  MF_RATF22 =222 , MF_RATF32 =232 , MF_RATF33 =233 , MF_EXP1 =301 ,
  MF_EXP2 , MF_EXP3 , MF_EXP4 , MF_EXP5 ,
  MF_LUNDQVIST =321 , MF_LUNDQVIST2 , MF_LUNDQVIST3 , MF_EXPBOLUSINF =331 ,
  MF_EXPBOLUSINF_RW =332 , MF_MF_EXPBOLUSINF_AZ =334 , MF_PK11195 =351 , MF_PPFIGAM =403 ,
  MF_PF_MU =831 , MF_HILL =841 , MF_1MHILL =842 , MF_1MHILL_ADE =843 ,
  MF_HILL_B =844 , MF_AMHILL =845 , MF_EHILL_PAR =846 , MF_EHILL_MET =847 ,
  MF_EHILL2_PAR =848 , MF_EHILL2_MET =849 , MF_MAMEDE =851 , MF_1MMAMEDE ,
  MF_MAYER_PAR =861 , MF_MAYER_MET , MF_EMAYER_PAR =863 , MF_EMAYER_MET ,
  MF_HILL3M_PAR =871 , MF_HILL3M_M1 , MF_HILL3M_M2 , MF_HILL3M_M3 ,
  MF_PF3M_PAR =881 , MF_PF3M_M1 , MF_PF3M_M2 , MF_PF3M_M3 ,
  MF_STEP =1010 , MF_RATF33D =1232 , MF_FENGM2S =1312 , MF_FENGM2 =1313 ,
  MF_FENGM2E =1314 , MF_GAMMAV =1401 , MF_GAMMAVB =1402 , MF_GAMMAVR =1403 ,
  MF_WEIBULLCDF_D =1421 , MF_WEIBULLCDF_DD =1423 , MF_SURGE =1431 , MF_SURGE_TRAD =1432 ,
  MF_SURGE_RECIRC =1433 , MF_P2B_SRC =1434 , MF_SURGE_FDG =1435 , MF_ERLANGPDF =1441 ,
  MF_HILL_D =1801 , MF_HILL_DD =1811 , MF_HILL_SDD =1821 , MF_IMGPROFILE =2111 ,
  MF_P2B_RF =2233 , MF_P2B_FM2 =2313 , MF_P2B_HILL =2841 , MF_GRAHAM_INP =9501 ,
  MF_GRAHAM_EINP , MF_GRAHAM_INPM , MF_HUANG_MET =9601 , MF_CARSON_EMET ,
  MF_NEW_MET , MF_MLMCM =9701
}
 
enum  {
  CSV_OK , CSV_ERROR , CSV_CANNOTOPEN , CSV_INVALIDFORMAT ,
  CSV_TOOBIG , CSV_OUTOFMEMORY , CSV_NOTABLE
}
 

Functions

int cptrnameSplit (char *rname, char *name1, char *name2, char *name3, int max_name_len)
 
int cptReadOne (char *cptfile, DFT *dft, int verbose)
 
int cptWrite (DFT *dft, char *filename, int cpt_format)
 
void csvInit (CSV *csv)
 
void csvEmpty (CSV *csv)
 
int csvRead (CSV *csv, char *fname)
 
int csv2dft (CSV *csv, DFT *dft)
 
int csv2dft_a (CSV *csv, DFT *dft)
 
int csv2dft_b (CSV *csv, DFT *dft)
 
int csv2dft_linkset (CSV *csv, DFT *dft)
 
int csv2dft_mat (CSV *csv, DFT *dft)
 
int csvIsRegular (CSV *csv)
 
char * csvCell (CSV *csv, int row, int col)
 
void dftInit (DFT *data)
 
void dftEmpty (DFT *data)
 
int dftSetmem (DFT *data, int frameNr, int voiNr)
 
int dftAddmem (DFT *data, int voiNr)
 
int dftAdd (DFT *data1, DFT *data2, int voi)
 
int dftSelect (DFT *data, char *name)
 
int dftSelectRegions (DFT *dft, char *region_name, int reset)
 
int dftSelectBestReference (DFT *dft)
 
void dftFrametimes (DFT *data)
 
int dftOverflow (DFT *data)
 
int dftCopyvoi (DFT *data, int from, int to)
 
int dftMovevoi (DFT *dft, int from, int to)
 
int dftDelete (DFT *dft, int voi)
 
int dftCopymainhdr (DFT *dft1, DFT *dft2)
 
int dftCopymainhdr2 (DFT *dft1, DFT *dft2, int ow)
 
int dftCopyvoihdr (DFT *dft1, int from, DFT *dft2, int to)
 
int dftdup (DFT *dft1, DFT *dft2)
 
int dftAllocateWithHeader (DFT *dft, int frameNr, int voiNr, DFT *dft_from)
 
int dftAddnullframe (DFT *data)
 
int dftSort (DFT *data)
 
int dftSortPlane (DFT *data)
 
int dft_nr_of_NA (DFT *dft)
 
int dftNAfill (DFT *dft)
 
int dftMinMax (DFT *dft, double *minx, double *maxx, double *miny, double *maxy)
 
int dftMinMaxTAC (DFT *dft, int tacindex, double *minx, double *maxx, double *miny, double *maxy, int *mini, int *maxi, int *mins, int *maxs)
 
int dftMaxY (DFT *dft, double t1, double t2, double *miny, double *maxy)
 
double dft_kBqMin (DFT *data)
 
double dft_kBqMax (DFT *data)
 
int dftSortByFrame (DFT *dft)
 
int dftDeleteFrameOverlap (DFT *dft)
 
int dftDeleteFrameOverlap_old (DFT *dft)
 
int dftRemoveTimeRange (DFT *dft, double startT, double endT)
 
void dftSetComments (DFT *dft)
 
int dftFillInitialGap (DFT *dft)
 
int dftAddSpaceForFrames (DFT *dft, int nr_to_add)
 
void dftRNameSimplify (DFT *dft, int hemisphere, int place)
 
int dftMeanTAC (DFT *dft, DFT *mean)
 
int dftValidNr (DFT *dft, double tstart, double tstop, int index)
 
int dftDecayCorrection (DFT *dft, double hl, int mode, int y, int y2, int y3, char *status, int verbose)
 
int dftRead (char *filename, DFT *data)
 
int dftWrite (DFT *data, char *filename)
 
void dftPrint (DFT *data)
 
int dftFormat (char *fname)
 
int dftType (FILE *fp)
 
int dftWriteHTML (DFT *dft, char *fname, int orientation)
 
int dftWriteXHTML11_doctype (FILE *fp)
 
int dftWriteXHTML11_head (FILE *fp, char *author_name)
 
int dft_fill_hdr_from_IFT (DFT *dft, IFT *ift)
 
int dftGetPmodTitle (DFT *dft, char *title_line)
 
int res_allocate_with_dft (RES *res, DFT *dft)
 
int dftToResult (DFT *dft, RES *res, char *status)
 
void dftUnitToDFT (DFT *dft, int dunit)
 
int dftUnitConversion (DFT *dft, int dunit)
 
int dftTimeunitToDFT (DFT *dft, const char *timeunit)
 
int dftTimeunitConversion (DFT *dft, int tunit)
 
void dftMin2sec (DFT *data)
 
void dftSec2min (DFT *data)
 
int fit_allocate_with_dft (FIT *fit, DFT *dft)
 
int fitToResult (FIT *fit, RES *res, char *status)
 
int idwcWrite (DFT *dft, char *filename)
 
int idwcRead (char *filename, DFT *dft)
 
int ifWrite (DFT *dft, char *filename)
 
int ifRead (char *filename, DFT *dft)
 
void fitEmpty (FIT *fit)
 
void fitInit (FIT *fit)
 
int fitSetmem (FIT *fit, int voiNr)
 
void fitPrint (FIT *fit)
 
int fitWrite (FIT *fit, char *filename)
 
int fitRead (char *filename, FIT *fit, int verbose)
 
int fitEval (FitVOI *r, double x, double *y)
 
int fitEvaltac (FitVOI *r, double *x, double *y, int dataNr)
 
int fitFunctionname (int type, char *str)
 
int fitFunctionformat (int type, char *str)
 
int fitIntegralEval (FitVOI *r, double x, double *yi)
 
int fitIntegralEvaltac (FitVOI *r, double *x, double *yi, int dataNr)
 
int fitDerivEval (FitVOI *r, double x, double *yd)
 
int fitDerivEvaltac (FitVOI *r, double *x, double *yd, int dataNr)
 
unsigned int factorial (unsigned int n)
 
unsigned long long int lfactorial (unsigned long long int n)
 
double igam (double a, double x)
 
double igamc (double a, double x)
 
int roikbqWrite (DFT *dft, char *fname)
 
int roikbqRead (char *fname, DFT *dft)
 
int res2ift (RES *res, IFT *ift, int verbose)
 
void resEmpty (RES *res)
 
void resInit (RES *res)
 
int resSetmem (RES *res, int voiNr)
 
void resFixParnames (RES *res)
 
void resPrint (RES *res)
 
int resRead (char *filename, RES *res, int verbose)
 
int resWrite (RES *res, char *filename, int verbose)
 
int resWriteHTML (RES *res, char *fname, int verbose)
 
int resFName2study (char *fname, char *studyNumber)
 
int resMedian (double *data, int nr, double *median, double *min, double *max)
 
int resMean (double *data, int nr, double *mean, double *sd)
 
void resSortByName (RES *res)
 
int resCopyMHeader (RES *res1, RES *res2)
 
int resDelete (RES *res, int voi)
 
int resSelect (RES *data, char *name)
 
int resSelectRegions (RES *res, char *region_name, int reset)
 
int resParameterPrintType (RES *res, int parIndex)
 
int resWriteXHTML11_doctype (FILE *fp)
 
int resWriteXHTML11_head (FILE *fp, char *author_name)
 
int resWriteHTML_table (RES *res, FILE *fp)
 
int resIsDuplicateNames (RES *res)
 
int resMatchHeader (RES *res1, RES *res2)
 
int resMatchRegions (RES *res1, RES *res2)
 
int resMatchParameternames (RES *res1, RES *res2)
 
int resMatchParameters (RES *res1, RES *res2, int test_par, double test_limit, int test_sd)
 
int resMatchParametersAbs (RES *res1, RES *res2, int test_par, double test_limit, int test_sd)
 
int resRNameSubfieldExists (RES *res)
 
int tsvRead (char *filename, DFT *dft)
 
int xelRead (char *filename, DFT *dft)
 

Variables

char cpterrmsg [128]
 
int CSV_TEST
 
char dfterrmsg [64]
 
int DFT_NR_OF_DECIMALS
 
int MATHFUNC_TEST
 
char fiterrmsg [64]
 
int RESULT_TEST
 
char reserrmsg [64]
 

Detailed Description

Header file for libtpccurveio.

Author
Vesa Oikonen

Definition in file libtpccurveio.h.

Macro Definition Documentation

◆ BACKUP_EXTENSION

#define BACKUP_EXTENSION   ".bak"

Backup file extension

Definition at line 27 of file libtpccurveio.h.

Referenced by dftWriteHTML(), ecat63Create(), ecat7Create(), idwcWrite(), ifWrite(), resWriteHTML(), and roikbqWrite().

◆ DFT_DECAY_CORRECTED

#define DFT_DECAY_CORRECTED   1

Definition for Decay correction status in DFT structure.

Definition at line 443 of file libtpccurveio.h.

Referenced by dft_fill_hdr_from_IFT(), dftDecayCorrection(), dftPrint(), dftSetComments(), and noiseSD4SimulationFromDFT().

◆ DFT_DECAY_NOTCORRECTED

#define DFT_DECAY_NOTCORRECTED   2

Definition for Decay correction status in DFT structure.

Definition at line 445 of file libtpccurveio.h.

Referenced by dft_fill_hdr_from_IFT(), dftDecayCorrection(), dftPrint(), and dftSetComments().

◆ DFT_DECAY_UNKNOWN

#define DFT_DECAY_UNKNOWN   0

Definition for Decay correction status in DFT structure.

Definition at line 441 of file libtpccurveio.h.

Referenced by dftCopymainhdr2(), dftSetComments(), and noiseSD4SimulationFromDFT().

◆ DFT_FORMAT_CPT

#define DFT_FORMAT_CPT   8

TAC file format (DFT type)

Definition at line 419 of file libtpccurveio.h.

◆ DFT_FORMAT_CSV_INT

#define DFT_FORMAT_CSV_INT   6

TAC file format (DFT type)

Definition at line 415 of file libtpccurveio.h.

Referenced by dftFormat(), and dftRead().

◆ DFT_FORMAT_CSV_UK

#define DFT_FORMAT_CSV_UK   7

TAC file format (DFT type)

Definition at line 417 of file libtpccurveio.h.

Referenced by dftFormat(), and dftRead().

◆ DFT_FORMAT_FIT

#define DFT_FORMAT_FIT   3

TAC file format (DFT type)

Definition at line 409 of file libtpccurveio.h.

Referenced by dftFormat(), dftRead(), dftReadinput(), and dftReadReference().

◆ DFT_FORMAT_HTML

#define DFT_FORMAT_HTML   12

TAC file format (DFT type)

Definition at line 427 of file libtpccurveio.h.

Referenced by dftWrite().

◆ DFT_FORMAT_IDWC

#define DFT_FORMAT_IDWC   9

TAC file format (DFT type)

Definition at line 421 of file libtpccurveio.h.

Referenced by dftFormat(), and dftRead().

◆ DFT_FORMAT_IF

#define DFT_FORMAT_IF   10

TAC file format (DFT type)

Definition at line 423 of file libtpccurveio.h.

Referenced by dftFormat(), and dftRead().

◆ DFT_FORMAT_IFT

#define DFT_FORMAT_IFT   2

TAC file format (DFT type)

Definition at line 407 of file libtpccurveio.h.

Referenced by dftRead().

◆ DFT_FORMAT_NCI

#define DFT_FORMAT_NCI   4

TAC file format (DFT type)

Definition at line 411 of file libtpccurveio.h.

Referenced by dftFormat(), and dftRead().

◆ DFT_FORMAT_PLAIN

#define DFT_FORMAT_PLAIN   0

TAC file format (DFT type)

Definition at line 403 of file libtpccurveio.h.

Referenced by csv2dft(), dftAdd(), dftFormat(), dftRead(), dftWrite(), and dftWriteHTML().

◆ DFT_FORMAT_PMOD

#define DFT_FORMAT_PMOD   5

TAC file format (DFT type)

Definition at line 413 of file libtpccurveio.h.

Referenced by dftFormat(), dftRead(), dftSetComments(), and dftWrite().

◆ DFT_FORMAT_STANDARD

#define DFT_FORMAT_STANDARD   1

◆ DFT_FORMAT_UNKNOWN

#define DFT_FORMAT_UNKNOWN   -1

TAC file format (DFT type)

Definition at line 401 of file libtpccurveio.h.

Referenced by dftFormat(), dftRead(), and dftReadinput().

◆ DFT_FORMAT_XELERIS

#define DFT_FORMAT_XELERIS   13

TAC file format (DFT type)

Definition at line 429 of file libtpccurveio.h.

◆ DFT_FORMAT_XML

#define DFT_FORMAT_XML   11

TAC file format (DFT type)

Definition at line 425 of file libtpccurveio.h.

◆ DFT_TIME_END

#define DFT_TIME_END   2

Definition for DFT (frame) time type

Definition at line 436 of file libtpccurveio.h.

Referenced by check_times_dft_vs_dft(), check_times_dft_vs_img(), dftEndtime(), dftFrametimes(), dftRead(), and dftWrite().

◆ DFT_TIME_MIDDLE

◆ DFT_TIME_START

#define DFT_TIME_START   1

Definition for DFT (frame) time type

Definition at line 434 of file libtpccurveio.h.

Referenced by check_times_dft_vs_dft(), check_times_dft_vs_img(), dftEndtime(), dftFrametimes(), dftRead(), and dftWrite().

◆ DFT_TIME_STARTEND

◆ MAX_FITPARAMS

#define MAX_FITPARAMS   100

Max nr of parameters in FIT

Definition at line 239 of file libtpccurveio.h.

◆ MAX_RESPARAMS

#define MAX_RESPARAMS   100

Max nr of parameters

Definition at line 133 of file libtpccurveio.h.

Referenced by dftToResult(), rescoll_tabulate(), resEmpty(), resFixParnames(), resRead(), resSetmem(), resWrite(), and resWriteHTML_table().

◆ MAX_RESPARNAME_LEN

#define MAX_RESPARNAME_LEN   15

Max length of parameter names and units

Definition at line 137 of file libtpccurveio.h.

Referenced by resFixParnames(), and resRead().

Enumeration Type Documentation

◆ anonymous enum

anonymous enum

CSV structure status.

Definition at line 348 of file libtpccurveio.h.

348 {CSV_OK, CSV_ERROR, CSV_CANNOTOPEN, CSV_INVALIDFORMAT, CSV_TOOBIG,
349 CSV_OUTOFMEMORY, CSV_NOTABLE
350 };

◆ mathfuncs

enum mathfuncs

FIT functions

Definition at line 243 of file libtpccurveio.h.

243 {
244 MF_LEVEL=100, MF_LINE, MF_POL2, MF_POL3, MF_POL4, MF_POL5, MF_POL6, MF_POL7,
245 MF_POL8, MF_POL9,
246 MF_RATF11=211, MF_RATF21=221, MF_RATF22=222, MF_RATF32=232, MF_RATF33=233,
247 MF_EXP1=301, MF_EXP2, MF_EXP3, MF_EXP4, MF_EXP5,
248 MF_LUNDQVIST=321, MF_LUNDQVIST2, MF_LUNDQVIST3,
249 MF_EXPBOLUSINF=331, MF_EXPBOLUSINF_RW=332, MF_MF_EXPBOLUSINF_AZ=334,
250 MF_PK11195=351,
251 MF_PPFIGAM=403,
252 MF_PF_MU=831,
253 MF_HILL=841, MF_1MHILL=842, MF_1MHILL_ADE=843, MF_HILL_B=844, MF_AMHILL=845,
254 MF_EHILL_PAR=846, MF_EHILL_MET=847,
255 MF_EHILL2_PAR=848, MF_EHILL2_MET=849,
256 MF_MAMEDE=851, MF_1MMAMEDE,
257 MF_MAYER_PAR=861, MF_MAYER_MET, MF_EMAYER_PAR=863, MF_EMAYER_MET,
258 MF_HILL3M_PAR=871, MF_HILL3M_M1, MF_HILL3M_M2, MF_HILL3M_M3,
259 MF_PF3M_PAR=881, MF_PF3M_M1, MF_PF3M_M2, MF_PF3M_M3,
260 MF_STEP=1010,
261 MF_RATF33D=1232,
262 MF_FENGM2S=1312, MF_FENGM2=1313, MF_FENGM2E=1314,
263 MF_GAMMAV=1401, MF_GAMMAVB=1402, MF_GAMMAVR=1403,
264 MF_WEIBULLCDF_D=1421, MF_WEIBULLCDF_DD=1423,
265 MF_SURGE=1431, MF_SURGE_TRAD=1432, MF_SURGE_RECIRC=1433, MF_P2B_SRC=1434, MF_SURGE_FDG=1435,
266 MF_ERLANGPDF=1441,
267 MF_HILL_D=1801, MF_HILL_DD=1811, MF_HILL_SDD=1821,
268 MF_IMGPROFILE=2111,
269 MF_P2B_RF=2233, MF_P2B_FM2=2313, MF_P2B_HILL=2841,
270 MF_GRAHAM_INP=9501, MF_GRAHAM_EINP, MF_GRAHAM_INPM,
271 MF_HUANG_MET=9601, MF_CARSON_EMET, MF_NEW_MET,
272 MF_MLMCM=9701,
273};

Function Documentation

◆ cptReadOne()

int cptReadOne ( char * cptfile,
DFT * dft,
int verbose )
extern

Read TACs from CPT file into a DFT.

Returns
Returns 0 if successful, sets cpterrmsg in case of an error.
See also
cptWrite, dftInit, cptrnameSplit
Parameters
cptfileCPT filename
dftPointer to DFT where TACs are read; must be empty and initialized
verboseVerbose level; if zero, then only warnings are printed into stderr

Definition at line 59 of file cpt.c.

66 {
67 int fi, fj, ri, ii, li, rn, fn, n, ret, colNr=10, lineNr=0;
68 char *cptr, tmp[512];
69 IFT ift;
70 int title_line, roi_col, roi_nr=0, frame_nr=0;
71
72 if(verbose>0) printf("%s('%s', *dft)\n", __func__, cptfile);
73
74 /* Check input */
75 if(cptfile==NULL || strlen(cptfile)<1 || dft==NULL) {
76 strcpy(cpterrmsg, "program error"); return(1);
77 }
78 dftEmpty(dft);
79
80 /*
81 * Read CPT file as IFT
82 */
83 iftInit(&ift);
84 ret=iftRead(&ift, cptfile, 0, verbose-1);
85 if(ret) {
86 strcpy(cpterrmsg, ift.status);
87 iftEmpty(&ift); return(4);
88 }
89 if(verbose>0) iftWrite(&ift, "stdout", 0);
90
91 /*
92 * Find the line of data titles
93 */
94 title_line=iftFindNthValue(&ift, " ROI Avg ", 1, 0);
95 if(title_line<0) {
96 sprintf(cpterrmsg, "unsupported filetype");
97 iftEmpty(&ift); return(6);
98 }
99 /* From title line, check if data consists of 10 or 11 columns */
100 strcpy(tmp, ift.item[title_line].value);
101 cptr=strtok(tmp, " \t\n\r");
102 if(strcasecmp(cptr, "Frame")!=0) {
103 sprintf(cpterrmsg, "unsupported filetype");
104 iftEmpty(&ift); return(7);
105 }
106 cptr=strtok(NULL, " \t\n\r");
107 colNr=10; if(strcasecmp(cptr, "ROI")!=0) colNr++;
108 if(colNr==10) roi_col=1; else roi_col=2;
109 if(verbose>1) printf("title_line=%d colNr=%d\n", title_line, colNr);
110
111 /*
112 * Mark data lines with sw=1
113 */
114 for(ii=lineNr=0; ii<ift.keyNr; ii++) {
115 /* Data can not start before title line and the unit line below it */
116 if(ii<title_line+2) {ift.item[ii].sw=0; continue;}
117 /* Comment lines cannot contain data, or at least we don't read it */
118 if(ift.item[ii].type!=' ' && ift.item[ii].type!='\0') {
119 ift.item[ii].sw=0; continue;}
120 /* and there cannot be any key */
121 if(ift.item[ii].key!=NULL && strlen(ift.item[ii].key)>0) {
122 ift.item[ii].sw=0; continue;}
123 /* Check that column number matches */
124 n=0; strncpy(tmp, ift.item[ii].value, 511); tmp[511]=(char)0;
125 cptr=strtok(tmp, " \t\n\r");
126 while(cptr!=NULL) {n++; cptr=strtok(NULL, " \t\n\r");}
127 if(n!=colNr) {ift.item[ii].sw=0; continue;}
128 ift.item[ii].sw=1; lineNr++;
129 }
130 if(lineNr<1) {
131 sprintf(cpterrmsg, "unsupported filetype");
132 iftEmpty(&ift); return(8);
133 }
134 if(verbose>1) printf("lineNr=%d\n", lineNr);
135
136 /*
137 * Read the data into a new, local table
138 */
139 double tactable[colNr][lineNr];
140 for(ii=0, n=0; ii<ift.keyNr; ii++) if(ift.item[ii].sw==1) {
141 ret=sscanf(ift.item[ii].value, "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf",
142 &tactable[0][n], &tactable[1][n], &tactable[2][n], &tactable[3][n],
143 &tactable[4][n], &tactable[5][n], &tactable[6][n], &tactable[7][n],
144 &tactable[8][n], &tactable[9][n], &tactable[10][n] );
145 n++; /*printf("ret=%d\n", ret);*/
146 }
147 if(verbose>2) { /* print the table */
148 printf("\n");
149 for(fi=0; fi<lineNr; fi++) {
150 for(ri=0; ri<colNr; ri++) printf(" %g", tactable[ri][fi]);
151 printf("\n");
152 }
153 printf("\n");
154 }
155
156 /*
157 * Compute the number of ROIs and Frames from the data lines
158 */
159 for(fi=1, roi_nr=frame_nr=1; fi<lineNr; fi++) {
160 /* have these been seen before? */
161 for(fj=0, fn=rn=0; fj<fi; fj++) {
162 if(tactable[roi_col][fj]==tactable[roi_col][fi]) rn++;
163 if(tactable[0][fj]==tactable[0][fi]) fn++;
164 }
165 if(rn==0) roi_nr++;
166 if(fn==0) frame_nr++;
167 }
168 if(verbose>1) printf("roi_nr=%d frame_nr=%d\n", roi_nr, frame_nr);
169 /* Also, test that the highest frame number equals number of frames */
170 for(fi=0, n=0; fi<lineNr; fi++) if(tactable[0][fi]>n) n=tactable[0][fi];
171 if(n!=frame_nr) {
172 sprintf(cpterrmsg, "frames are not consequential");
173 iftEmpty(&ift); return(9);
174 }
175 /* And also, test that roi_nr*frame_nr == nr of data lines */
176 if(roi_nr*frame_nr!=lineNr) {
177 sprintf(cpterrmsg, "missing or extra samples");
178 iftEmpty(&ift); return(10);
179 }
180
181 /*
182 * Copy data into DFT
183 */
184
185 /* Allocate memory for DFT */
186 ret=dftSetmem(dft, frame_nr, roi_nr);
187 if(ret) {
188 sprintf(cpterrmsg, "cannot allocate memory");
189 iftEmpty(&ift); dftEmpty(dft); return(11);
190 }
191 dft->frameNr=frame_nr; dft->voiNr=roi_nr; dft->_type=1;
192
193 /* Make a list of ROI ID numbers */
194 int roi_id[roi_nr];
195 n=0; roi_id[n++]=tactable[roi_col][0];
196 for(fi=1; fi<lineNr; fi++) {
197 for(fj=0; fj<fi; fj++)
198 if(tactable[roi_col][fj]==tactable[roi_col][fi]) continue;
199 roi_id[n++]=(int)(0.5+tactable[roi_col][fi]);
200 }
201 if(verbose>2) {
202 printf("List of ROI ID numbers:\n");
203 for(ri=0; ri<roi_nr; ri++) printf(" %d : %d\n", ri+1, roi_id[ri]);
204 }
205
206 /* Extract data for one ROI at a time */
207 for(int ri=0; ri<roi_nr; ri++) {
208 fi=0; /* all frames of this ROI */
209 for(li=0; li<lineNr; li++) if(roi_id[ri]==(int)(0.5+tactable[roi_col][li])) {
210 /* Activity average value */
211 dft->voi[ri].y[fi]=tactable[colNr-8][li];
212 /* Only once for each ROI */
213 if(fi==0) {
214 /* ROI volume */
215 dft->voi[ri].size=tactable[colNr-1][li];
216 /* ROI name (may be changed later) */
217 sprintf(dft->voi[ri].voiname, "ROI%03d", roi_id[ri]);
218 if(colNr>10) sprintf(dft->voi[ri].place, "Pl%04.0f", tactable[1][ri]);
219 snprintf(dft->voi[ri].name, MAX_REGIONNAME_LEN, "%s . %s",
220 dft->voi[ri].voiname, dft->voi[ri].place);
221 }
222 /* Get frame times from the first ROI */
223 if(ri==0) {
224 dft->x1[fi]=tactable[colNr-4][li];
225 dft->x2[fi]=dft->x1[fi]+tactable[colNr-3][li];
226 dft->x[fi]=0.5*(dft->x1[fi]+dft->x2[fi]);
227 }
228 fi++;
229 } /* next frame */
230 } /* next ROI */
231 /* Convert frame times into minutes */
232 dftSec2min(dft); dft->timetype=3;
233
234 /*
235 * Get studynumber from filename
236 */
237 studynr_from_fname(cptfile, dft->studynr);
238
239 /*
240 * Try to find the data unit
241 */
242 ii=iftFindNthValue(&ift, "In units of ", 1, 0);
243 if(ii>=0) {
244 strncpy(tmp, ift.item[ii].value+12, 511); tmp[511]=(char)0;
245 cptr=strtok(tmp, " \t\n\r,;");
246 strncpy(dft->unit, cptr, MAX_UNITS_LEN);
247 dft->unit[MAX_UNITS_LEN]=(char)0;
248 } else {
249 strcpy(tmp, "Units"); ii=iftGet(&ift, tmp, 0);
250 if(ii>=0) {
251 strncpy(dft->unit, ift.item[ii].value, MAX_UNITS_LEN);
252 dft->unit[MAX_UNITS_LEN]=(char)0;
253 }
254 }
255
256 /*
257 * Try to extract the region name (if only one ROI)
258 */
259 if(dft->voiNr==1) {
260 ii=iftFindNthKey(&ift, "Using ROI ", 1, 0);
261 if(ii>=0) {
262 cptr=strchr(ift.item[ii].key, '\"');
263 if(cptr!=NULL) {
264 strncpy(dft->voi[0].name, cptr+1, MAX_REGIONNAME_LEN);
265 dft->voi[0].name[MAX_REGIONNAME_LEN]=(char)0;
266 cptr=strchr(dft->voi[0].name, '\"');
267 if(cptr!=NULL) *cptr=(char)0;
268 }
269 }
270 cptrnameSplit(dft->voi[0].name,
271 dft->voi[0].voiname, dft->voi[0].hemisphere, dft->voi[0].place,
273 }
274
275 /*
276 * Try to find the plane number
277 */
278 ii=iftFindNthKey(&ift, "Plane ", 1, 0);
279 if(ii>=0) {
280 n=atoi(ift.item[ii].key+6);
281 if(verbose>2) printf("Plane %d\n", n);
282 if(n>0) for(ri=0; ri<dft->voiNr; ri++) snprintf(dft->voi[ri].place, 7, "Pl%04d", n);
283 } else {
284 ii=iftFindNthValue(&ift, "Plane ", 1, 0);
285 if(ii>=0) {
286 n=atoi(ift.item[ii].value+6);
287 if(verbose>2) printf("Plane %d\n", n);
288 if(n>0) for(ri=0; ri<dft->voiNr; ri++) snprintf(dft->voi[ri].place, 7, "Pl%04d", n);
289 }
290 }
291
292 /* Set weights in DFT to 1.0 */
293 dft->isweight=0;
294 for(fi=0; fi<dft->frameNr; fi++) dft->w[fi]=1.0;
295
296
297 iftEmpty(&ift);
298 return(0);
299}
int cptrnameSplit(char *rname, char *name1, char *name2, char *name3, int max_name_len)
Definition cpt.c:24
char cpterrmsg[128]
Definition cpt.c:6
int dftSetmem(DFT *data, int frameNr, int voiNr)
Definition dft.c:57
void dftEmpty(DFT *data)
Definition dft.c:20
void dftSec2min(DFT *dft)
Definition dftunit.c:160
void iftEmpty(IFT *ift)
Definition ift.c:60
void iftInit(IFT *ift)
Definition ift.c:45
int iftRead(IFT *ift, char *filename, int is_key_required, int verbose)
Definition iftfile.c:24
int iftWrite(IFT *ift, char *filename, int verbose)
Definition iftfile.c:282
int iftFindNthValue(IFT *ift, char *str, int n, int verbose)
Definition iftsrch.c:120
int iftFindNthKey(IFT *ift, char *str, int n, int verbose)
Definition iftsrch.c:84
int iftGet(IFT *ift, char *key, int verbose)
Definition iftsrch.c:15
#define MAX_REGIONNAME_LEN
Definition libtpcmisc.h:154
int studynr_from_fname(char *fname, char *studynr)
Definition studynr.c:119
#define MAX_UNITS_LEN
Definition libtpcmisc.h:95
#define MAX_REGIONSUBNAME_LEN
Definition libtpcmisc.h:158
int _type
int timetype
Voi * voi
char studynr[MAX_STUDYNR_LEN+1]
double * w
double * x1
int voiNr
double * x2
int frameNr
int isweight
double * x
char unit[MAX_UNITS_LEN+1]
int keyNr
Definition libtpcmisc.h:270
const char * status
Definition libtpcmisc.h:277
IFT_KEY_AND_VALUE * item
Definition libtpcmisc.h:279
double size
char voiname[MAX_REGIONSUBNAME_LEN+1]
double * y
char name[MAX_REGIONNAME_LEN+1]
char hemisphere[MAX_REGIONSUBNAME_LEN+1]
char place[MAX_REGIONSUBNAME_LEN+1]

◆ cptrnameSplit()

int cptrnameSplit ( char * rname,
char * name1,
char * name2,
char * name3,
int max_name_len )
extern

Split region name into 1-3 subparts of given max length.

Returns
Returns the number of subparts.
See also
cptReadOne
Parameters
rnameRegion name to split (string is not edited)
name1Pointer to 1st subname (anatomical region)
name2Pointer to 2nd subname (usually hemisphere)
name3Pointer to 3rd subname (usually image plane)
max_name_lenMax lenght of subnames, excluding terminal null

Definition at line 24 of file cpt.c.

35 {
36 char temp[MAX_REGIONNAME_LEN+1], *cptr, *cptr2;
37 int nr=0;
38
39 if(rname==NULL || name1==NULL || name2==NULL || name3==NULL) return(0);
40 if(max_name_len<1) return(0);
41 name1[0]=name2[0]=name3[0]=(char)0;
42 strncpy(temp, rname, MAX_REGIONNAME_LEN); temp[MAX_REGIONNAME_LEN]=(char)0;
43 cptr=strtok(temp, " _\t\n\r"); if(cptr==NULL) return(nr);
44 cptr2=strstr(cptr, "dx"); if(cptr2==NULL) cptr2=strstr(cptr, "sin");
45 if(cptr2!=NULL) {strcpy(name2, cptr2); *cptr2=(char)0; nr++;}
46 else strcpy(name2, ".");
47 strncpy(name1, cptr, max_name_len); name1[max_name_len]=(char)0; nr++;
48 cptr=strtok(NULL, " _\t\n\r"); if(cptr==NULL) return(nr);
49 strncpy(name3, cptr, max_name_len); name3[max_name_len]=(char)0; nr++;
50 return(nr);
51}

Referenced by cptReadOne().

◆ cptWrite()

int cptWrite ( DFT * dft,
char * filename,
int cpt_format )
extern

Write TAC data in CPT (Imagetool) format. If TACs are from different planes, then each plane will be saved in its own file.

Returns
Returns 0 if successful; in case of an error, sets string cpterrmsg.
See also
cptReadOne, dftInit
Parameters
dftTAC data to write
filenameCPT path and file name without extension, because this function may need to add plane number before .cpt
cpt_formatSpecific CPT format: 0=default, others not yet supported

Definition at line 308 of file cpt.c.

316 {
317 int ri, fi, ret, n, roi_id;
318 FILE *fp;
319 char cptfile[FILENAME_MAX], tmp[256];
320
321 /* Check input */
322 if(dft==NULL || dft->voiNr<1 || dft->frameNr<1 || strlen(filename)<1) {
323 strcpy(cpterrmsg, "program error"); return(1);
324 }
325 if(cpt_format!=0) strcpy(cpterrmsg, "cpt format not supported yet");
326 /* Sort data by plane */
327 ret=dftSortPlane(dft);
328 if(ret) {
329 strcpy(cpterrmsg, "error in data file"); return(2);
330 }
331 /* Convert times to seconds if necessary */
332 if(dft->timeunit==TUNIT_MIN) dftMin2sec(dft);
333
334
335 for(ri=0; ri<dft->voiNr; ri++) {
336 /* Construct CPT filename */
337 strcpy(cptfile, filename);
338 if(strlen(dft->voi[ri].place)>0 && strcmp(dft->voi[ri].place, ".")!=0) {
339 snprintf(cptfile, FILENAME_MAX, "%s_%s.cpt", filename, dft->voi[ri].place);
340 } else {
341 snprintf(cptfile, FILENAME_MAX, "%s.cpt", filename);
342 }
343 /* Open file */
344 fp=fopen(cptfile, "w");
345 if(fp==NULL) {
346 sprintf(cpterrmsg, "cannot open file for write"); return(5);
347 }
348 /* Write 1st title */
349 if(strlen(dft->unit)==0) strcpy(tmp, "unknown"); else strcpy(tmp, dft->unit);
350 //fprintf(fp, "# In units of %s per pixel per second\n", tmp);
351 fprintf(fp, "# In units of %s\n", tmp);
352 /* Write 2nd title */
353 if(strncasecmp(dft->voi[ri].place, "Pl", 2)==0)
354 sprintf(tmp, "%d", atoi(dft->voi[ri].place+2));
355 else if(strlen(dft->voi[ri].place)==0 || strcmp(dft->voi[ri].place, ".")==0)
356 strcpy(tmp, "1");
357 else
358 strcpy(tmp, dft->voi[ri].place);
359 fprintf(fp, "Plane %-6.6s Scan Start Date (d m y): 1 1 1980 Scan Start Time (h m s): 0 0 0\n\n", tmp);
360 /* Write 3rd title */
361 fprintf(fp, "Frame ROI ID ROI Avg #pixels ROI Total %%Stdev Offset Duration ROI Surf. ROI Vol.\n");
362 fprintf(fp, " (screen) (sec) (sec) mmxmm mmxmmxmm\n");
363 /* Write all frames */
364 for(fi=0, n=ri; fi<dft->frameNr; fi++) {
365 n=ri;
366 /* current region */
367 strcpy(tmp, dft->voi[ri].voiname);
368 if(strlen(dft->voi[ri].hemisphere)>0 && strcmp(dft->voi[ri].hemisphere, ".")!=0) {
369 strcat(tmp, " "); strcat(tmp, dft->voi[ri].hemisphere);}
370 strcpy(tmp, "");
371 if(strncasecmp(dft->voi[ri].voiname, "ROI", 3)==0 && atoi(dft->voi[ri].voiname+3)>0)
372 roi_id=atoi(dft->voi[ri].voiname+3); else roi_id=1;
373 fprintf(fp, "%-6d %-3d %-8.8s %11.4e %5d %10.4e %7.1f %9.1f %9.1f %10.4e %10.4e\n",
374 fi+1, roi_id, tmp, dft->voi[ri].y[fi], 0, 0.0, 0.0,
375 dft->x1[fi], dft->x2[fi]-dft->x1[fi], 0.0, dft->voi[ri].size );
376 /* the rest of regions on the same plane */
377 while(n<dft->voiNr-1 && strcasecmp(dft->voi[ri].place, dft->voi[n+1].place)==0) {
378 n++; strcpy(tmp, dft->voi[n].voiname);
379 if(strlen(dft->voi[n].hemisphere)>0 && strcmp(dft->voi[n].hemisphere, ".")!=0) {
380 strcat(tmp, " "); strcat(tmp, dft->voi[n].hemisphere);}
381 strcpy(tmp, "");
382 if(strncasecmp(dft->voi[n].voiname, "ROI", 3)==0 && atoi(dft->voi[n].voiname+3)>0)
383 roi_id=atoi(dft->voi[n].voiname+3); else roi_id=n-ri+1;
384 fprintf(fp, "%-6d %-3d %-8.8s %11.4e %5d %10.4e %7.1f %9.1f %9.1f %10.4e %10.4e\n",
385 fi+1, roi_id, tmp, dft->voi[n].y[fi], 0, 0.0, 0.0,
386 dft->x1[fi], dft->x2[fi]-dft->x1[fi], 0.0, dft->voi[n].size );
387 }
388 }
389 ri=n;
390#if(0)
391 /* DON'T DO THIS; at least "asetaatti" program does not work with this */
392 /* In the end, write the number of frames */
393 fprintf(fp, "\n# %d Frame(s) analyzed.\n", dft->frameNr);
394#endif
395 fclose(fp);
396 }
397
398 return(0);
399}
int dftSortPlane(DFT *data)
Definition dft.c:875
void dftMin2sec(DFT *dft)
Definition dftunit.c:145
int timeunit

◆ csv2dft()

int csv2dft ( CSV * csv,
DFT * dft )
extern

Reads different CSV formats into DFT struct

Returns
Returns 0 when successful, otherwise an error code.
Parameters
csvPointer to CSV data to be converted
dftPointer to empty DFT struct which will be allocated and filled here

Definition at line 200 of file csv.c.

205 {
206 int ret, i, u, n, m;
207
208 if(CSV_TEST>2) {printf("csv2dft()\n"); fflush(stdout);}
209 if(csv==NULL || dft==NULL) return CSV_ERROR;
210 if(csv->row_nr<1 || csv->col_nr<1) return CSV_INVALIDFORMAT;
211
212 /* Is this LinkSet format? */
213 if(strcasecmp(csv->c[0].content, "LinkSet")==0) {
214 ret=csv2dft_linkset(csv, dft);
215 if(ret!=CSV_OK) {
216 if(CSV_TEST>2) printf("reading LinkSet CSV format failed.\n");
217 }
218 return(ret);
219 }
220
221 /* Maybe mat file? */
222 ret=csv2dft_mat(csv, dft);
223 if(ret==CSV_OK) {
224 if(CSV_TEST>2) printf("reading Mat CSV format successful.\n");
225 return(ret);
226 }
227
228 /* Many CSV formats are impossible to identify, therefore we will just
229 try to convert different formats until one succeeds or all are failed */
230 if(CSV_TEST>2) printf("trying to read 1st CSV format\n");
231 ret=csv2dft_a(csv, dft);
232 if(ret!=CSV_OK) {
233 if(CSV_TEST>2) printf("reading 1st CSV format failed; trying 2nd format\n");
234 ret=csv2dft_b(csv, dft);
235 }
236 if(ret!=CSV_OK) {
237 if(CSV_TEST>2) printf("2nd CSV format failed\n");
238 }
239 if(ret!=CSV_OK) {dft->_type=DFT_FORMAT_PLAIN; return ret;}
240 /* Make sure that TAC names are filled */
241 u=dft->voiNr; n=1; while((u/=10)>=1) n++;
243 for(i=0, m=0; i<dft->voiNr; i++) {
244 if(strlen(dft->voi[i].voiname)<1 || strcmp(dft->voi[i].voiname, ".")==0) {
245 snprintf(dft->voi[i].voiname, 7, "%0*d", n, i+1);
246 strcpy(dft->voi[i].name, dft->voi[i].voiname);
247 m++;
248 }
249 }
250 /* If none of TACs had a name, then set DFT plain format */
251 if(m==dft->voiNr) dft->_type=DFT_FORMAT_PLAIN;
252
253 if(CSV_TEST>3) dftPrint(dft);
254 return CSV_OK;
255}
int csv2dft_a(CSV *csv, DFT *dft)
Definition csv.c:262
int CSV_TEST
Definition csv.c:6
int csv2dft_mat(CSV *csv, DFT *dft)
Definition csv.c:713
int csv2dft_linkset(CSV *csv, DFT *dft)
Definition csv.c:584
int csv2dft_b(CSV *csv, DFT *dft)
Definition csv.c:458
void dftPrint(DFT *data)
Definition dftio.c:538
#define DFT_FORMAT_PLAIN
char * content
int row_nr
int col_nr
CSV_item * c

Referenced by dftRead().

◆ csv2dft_a()

int csv2dft_a ( CSV * csv,
DFT * dft )
extern

Reads simple and Inveon type 1 data into DFT struct

Returns
Returns 0 when successful, otherwise an error code.
Parameters
csvPointer to CSV data to be converted
dftPointer to empty DFT struct which will be allocated and filled here

Definition at line 262 of file csv.c.

267 {
268 int ri, ci, sci, ii, ret;
269 char *cptr;
270
271 if(CSV_TEST>2) {printf("csv2dft_a()\n"); fflush(stdout);}
272 if(csv==NULL || dft==NULL) return CSV_ERROR;
273 if(csv->row_nr<1 || csv->col_nr<1) return CSV_INVALIDFORMAT;
274
275
276 if(CSV_TEST>2)
277 for(int i=0; i<csv->nr; i++)
278 printf("row=%d col=%d content='%s'\n", csv->c[i].row, csv->c[i].col, csv->c[i].content);
279
280
281 /* Allocate memory for DFT */
282 dftEmpty(dft);
283 if(CSV_TEST>2) {
284 printf("frame_nr=%d voi_nr=%d\n", csv->row_nr, csv->col_nr-1);
285 fflush(stdout);
286 }
287 ret=dftSetmem(dft, csv->row_nr, csv->col_nr-1);
288 if(ret!=0) return CSV_OUTOFMEMORY;
289 /* Set DFT defaults */
292 dft->isweight=0;
293 dftUnitToDFT(dft, CUNIT_UNKNOWN);
294 dft->timeunit=TUNIT_UNKNOWN;
295 for(ri=0; ri<csv->row_nr; ri++) dft->w[ri]=1.0;
296 for(ci=0; ci<csv->col_nr-1; ci++) dft->voi[ci].sw=0;
297
298 /* Fill DFT */
299 ri=0;
300 for(ii=0; ii<csv->nr;) {
301 // goto start of row
302 for(; ii<csv->nr && csv->c[ii].col!=1; ii++) {}
303 if(ii==csv->nr) break;
304 if(CSV_TEST>10) {
305 printf("\nline start at %d\n", ii);
306 printf(" ri=%d\n", ri);
307 fflush(stdout);
308 }
309 // ignore line with empty first column
310 if(csv->c[ii].content==NULL) {
311 if(CSV_TEST>11) {printf(" empty first column\n"); fflush(stdout);}
312 ii++; continue;
313 }
314 // ignore comment line
315 if(csv->c[ii].content[0]=='#') {
316 if(CSV_TEST>11) {printf(" comment line\n"); fflush(stdout);}
317 ii++; continue;
318 }
319 // ignore line that does not start with number
320 // unless it contains TAC titles
321 if(!isdigit(csv->c[ii].content[0]) && csv->c[ii].content[0]!='-') {
322 if(strstr(csv->c[ii].content, "Time")==NULL &&
323 strstr(csv->c[ii].content, "TIME")==NULL &&
324 strstr(csv->c[ii].content, "time")==NULL)
325 {
326 if(CSV_TEST>11) {printf(" not a numerical value or title\n"); fflush(stdout);}
327 ii++; continue;
328 }
330 if(strncasecmp(csv->c[ii].content, "Start time", 10)==0 &&
331 strncasecmp(csv->c[ii+1].content, "End time", 8)==0)
332 {
334 if(CSV_TEST>6) printf("timetype := %d\n", dft->timetype);
335 }
336 if(CSV_TEST>7) {
337 printf("first title field := '%s'\n", csv->c[ii].content);
338 fflush(stdout);
339 }
340 if(strstr(csv->c[ii].content, "min")!=NULL) dft->timeunit=TUNIT_MIN;
341 else if(strstr(csv->c[ii].content, "sec")!=NULL) dft->timeunit=TUNIT_SEC;
342 else dft->timeunit=TUNIT_UNKNOWN;
343 ii++;
344
345 if(dft->timetype==DFT_TIME_MIDDLE) sci=2; else {sci=3; ii++;}
346 for(ci=sci; ci<=csv->col_nr && ii<csv->nr; ci++, ii++) {
347 if(CSV_TEST>2) {
348 printf("col=%d row=%d\n", csv->c[ii].col, csv->c[ii].row);
349 if(CSV_TEST>3) printf("ci=%d ii=%d\n", ci, ii);
350 fflush(stdout);
351 }
352 if(csv->c[ii].col!=ci) {dftEmpty(dft); return CSV_NOTABLE;}
353 if(csv->c[ii].content!=NULL) {
354 /* Check if this column should be omitted from DFT */
355 if(strstr(csv->c[ii].content, " - Time")!=NULL) {
356 if(CSV_TEST>2) printf(" ignored time column.\n");
357 dft->voi[ci-sci].sw=1; continue;
358 }
359 if(strstr(csv->c[ii].content, "(upper bound)")!=NULL) {
360 if(CSV_TEST>2) printf(" ignored upper bound column.\n");
361 dft->voi[ci-sci].sw=2; continue;
362 }
363 if(strstr(csv->c[ii].content, "(lower bound)")!=NULL) {
364 if(CSV_TEST>2) printf(" ignored lower bound column.\n");
365 dft->voi[ci-sci].sw=3; continue;
366 }
367 if(strstr(csv->c[ii].content, "(standard deviation)")!=NULL) {
368 if(CSV_TEST>2) printf(" ignored s.d. column.\n");
369 dft->voi[ci-sci].sw=4; continue;
370 }
371 /* Search calibration unit from name */
372 if(petCunitId(dft->unit)==CUNIT_UNKNOWN) {
373 if(strstr(csv->c[ii].content, "(Bq/ml)")!=NULL)
374 dftUnitToDFT(dft, CUNIT_BQ_PER_ML);
375 else if(strstr(csv->c[ii].content, "(kBq/ml)")!=NULL)
376 dftUnitToDFT(dft, CUNIT_KBQ_PER_ML);
377 else if(strstr(csv->c[ii].content, "(MBq/ml)")!=NULL)
378 dftUnitToDFT(dft, CUNIT_MBQ_PER_ML);
379 else if(strstr(csv->c[ii].content, "(% ID/g)")!=NULL)
380 dftUnitToDFT(dft, CUNIT_PIDM);
381 else if(strstr(csv->c[ii].content, "Bq/ml")!=NULL)
382 dftUnitToDFT(dft, CUNIT_BQ_PER_ML);
383 else if(strstr(csv->c[ii].content, "kBq/ml")!=NULL)
384 dftUnitToDFT(dft, CUNIT_KBQ_PER_ML);
385 else if(strstr(csv->c[ii].content, "MBq/ml")!=NULL)
386 dftUnitToDFT(dft, CUNIT_MBQ_PER_ML);
387 else if(strstr(csv->c[ii].content, "% ID/g")!=NULL)
388 dftUnitToDFT(dft, CUNIT_PIDM);
389 }
390 }
391 if(csv->c[ii].content==NULL) {
392 sprintf(dft->voi[ci-sci].name, "%d", ci-sci+1);
393 strcpy(dft->voi[ci-sci].voiname, dft->voi[ci-sci].name);
394 } else {
395 cptr=strstr(csv->c[ii].content, " - "); if(cptr!=NULL) *cptr=(char)0;
396 strncpy(dft->voi[ci-sci].name, csv->c[ii].content, MAX_REGIONNAME_LEN);
397 dft->voi[ci-sci].name[MAX_REGIONNAME_LEN]=(char)0;
398 rnameSplit(csv->c[ii].content, dft->voi[ci-sci].voiname,
399 dft->voi[ci-sci].hemisphere, dft->voi[ci-sci].place, MAX_REGIONSUBNAME_LEN);
400 }
401 if(CSV_TEST>8) printf("name[%d]=%s\n", ci-sci, dft->voi[ci-sci].name);
402 }
403 }
404
405 // check that allocated DFT frame nr is not exceeded
406 if(ri>=csv->row_nr) {dftEmpty(dft); return CSV_INVALIDFORMAT;}
407 // read the sample time
408 if(dft->timetype==DFT_TIME_MIDDLE) {
409 dft->x[ri]=atof_dpi(csv->c[ii++].content);
410 if(CSV_TEST>3) printf("x[%d]=%g\n", ri, dft->x[ri]);
411 } else {
412 dft->x1[ri]=atof_dpi(csv->c[ii++].content);
413 dft->x2[ri]=atof_dpi(csv->c[ii++].content);
414 dft->x[ri]=0.5*(dft->x1[ri]+dft->x2[ri]);
415 if(CSV_TEST>3) printf("x1[%d]=%g x2[%d]=%g\n", ri, dft->x1[ri], ri, dft->x2[ri]);
416 }
417 // read the sample values
418 if(dft->timetype==DFT_TIME_MIDDLE) sci=2; else sci=3;
419 for(ci=sci; ci<=csv->col_nr && ii<csv->nr; ci++, ii++) {
420 if(CSV_TEST>2) {
421 printf(" col=%d row=%d\n", csv->c[ii].col, csv->c[ii].row);
422 if(CSV_TEST>3) printf(" ci=%d ii=%d\n", ci, ii);
423 fflush(stdout);
424 }
425 if(csv->c[ii].col!=ci) {dftEmpty(dft); return CSV_NOTABLE;}
426 if(strlen(csv->c[ii].content)==0 || strcmp(csv->c[ii].content, ".")==0)
427 dft->voi[ci-sci].y[ri]=nan("");
428 else
429 dft->voi[ci-sci].y[ri]=atof_dpi(csv->c[ii].content);
430 if(CSV_TEST>4)
431 printf(" y[%d][%d]=%g\n", ri, ci-sci, dft->voi[ci-sci].y[ri]);
432 }
433 ri++; //if(ri>csv->row_nr) {dftEmpty(dft); return CSV_INVALIDFORMAT;}
434 }
435 if(CSV_TEST>1) printf(" %d frame(s) read from CSV\n", ri);
436 if(ri<1) {dftEmpty(dft); return CSV_INVALIDFORMAT;}
437 dft->frameNr=ri;
438 dft->voiNr=csv->col_nr-1; if(dft->timetype==DFT_TIME_STARTEND) dft->voiNr--;
439
440 /* Remove those DFT VOIs which where above set to be deleted (where sw!=0) */
441 for(ci=dft->voiNr-1, ret=0; ci>=0; ci--) if(dft->voi[ci].sw!=0) {
442 ret=dftDelete(dft, ci); if(ret!=0) break;}
443 if(ret!=0) {dftEmpty(dft); return CSV_INVALIDFORMAT;}
444 if(dft->voiNr<1) {dftEmpty(dft); return CSV_INVALIDFORMAT;}
445
446 /* Calculate frame mid times, or frame start and end times;
447 this works only if time units are known */
448 dftFrametimes(dft);
449
450 return CSV_OK;
451}
double atof_dpi(char *str)
Definition decpoint.c:59
int dftDelete(DFT *dft, int voi)
Definition dft.c:538
void dftFrametimes(DFT *data)
Definition dft.c:340
void dftUnitToDFT(DFT *dft, int dunit)
Definition dftunit.c:11
#define DFT_TIME_MIDDLE
#define DFT_FORMAT_STANDARD
#define DFT_TIME_STARTEND
int petCunitId(const char *unit)
Definition petunits.c:74
int rnameSplit(char *rname, char *name1, char *name2, char *name3, int max_name_len)
Definition rname.c:14
char sw

Referenced by csv2dft().

◆ csv2dft_b()

int csv2dft_b ( CSV * csv,
DFT * dft )
extern

Reads Inveon type 2 data into DFT struct

Returns
Returns 0 when successful, otherwise an error code.
Parameters
csvPointer to CSV data to be converted
dftPointer to empty DFT struct which will be allocated and filled here

Definition at line 458 of file csv.c.

463 {
464 int ri, fi, fip, ii, ret;
465 char *cptr, *cptr2, tmp[256];
466 double v1, v2;
467
468 if(CSV_TEST>2) {printf("csv2dft_b()\n"); fflush(stdout);}
469 if(csv==NULL || dft==NULL) return CSV_ERROR;
470 //printf("row_nr=%d col_nr=%d\n", csv->row_nr, csv->col_nr);
471 if(csv->row_nr<4 || csv->col_nr!=9) return CSV_INVALIDFORMAT;
472 dftEmpty(dft);
473
474 /* Check the format; first line (containing titles) */
475 if(strcasecmp(csv->c[0].content, "#Subject ID")!=0) return CSV_INVALIDFORMAT;
476 if(strcasecmp(csv->c[1].content, "Subject Weight")!=0) return CSV_INVALIDFORMAT;
477 if(strcasecmp(csv->c[2].content, "Subject Sex")!=0) return CSV_INVALIDFORMAT;
478 if(strcasecmp(csv->c[3].content, "Unique Series ID")!=0) return CSV_INVALIDFORMAT;
479 if(strcasecmp(csv->c[4].content, "Series Date")!=0) return CSV_INVALIDFORMAT;
480 if(strcasecmp(csv->c[5].content, "Series Description")!=0) return CSV_INVALIDFORMAT;
481
482 /* Check the format; third line (containing titles) */
483 if(strcasecmp(csv->c[12].content, "#Name")!=0) return CSV_INVALIDFORMAT;
484 if(strcasecmp(csv->c[13].content, "Volume (mm^3)")!=0) return CSV_INVALIDFORMAT;
485 if(strcasecmp(csv->c[14].content, "Mean")!=0) return CSV_INVALIDFORMAT;
486 if(strcasecmp(csv->c[15].content, "SD")!=0) return CSV_INVALIDFORMAT;
487 if(strcasecmp(csv->c[16].content, "Min")!=0) return CSV_INVALIDFORMAT;
488 if(strcasecmp(csv->c[17].content, "Max")!=0) return CSV_INVALIDFORMAT;
489 if(strcasecmp(csv->c[18].content, "Frame Index")!=0) return CSV_INVALIDFORMAT;
490 if(strncasecmp(csv->c[19].content, "Mid time (sec)", 10)!=0) return CSV_INVALIDFORMAT;
491 if(strncasecmp(csv->c[20].content, "Duration (sec)", 10)!=0) return CSV_INVALIDFORMAT;
492
493 /* Calculate the number of ROIs and time frames */
494 ri=1; fi=0; fip=-1; ii=21; cptr=csv->c[ii].content;
495 //printf("cell[%d] := '%s'\n", ii, cptr); fflush(stdout);
496 for(; ii<csv->nr; ii+=9) {
497 cptr2=csv->c[ii].content;
498 //printf("cell[%d] := '%s'\n", ii, cptr2); fflush(stdout);
499 if(strcmp(cptr, cptr2)==0) fi++;
500 else {
501 ri++; cptr=cptr2;
502 if(fip<0) fip=fi; else if(fi!=fip) return CSV_INVALIDFORMAT;
503 fi=1;
504 }
505 //printf("ri=%d fi=%d fip=%d\n", ri, fi, fip);
506 }
507 //printf("ri=%d fi=%d\n", ri, fi);
508
509 /* Allocate memory for DFT */
510 if(CSV_TEST>2) {printf("frame_nr=%d voi_nr=%d\n", fi, ri); fflush(stdout);}
511 ret=dftSetmem(dft, fi, ri);
512 if(ret!=0) return CSV_OUTOFMEMORY;
513 dft->voiNr=ri; dft->frameNr=fi;
516 dft->isweight=0;
517 dftUnitToDFT(dft, CUNIT_UNKNOWN); dft->timeunit=TUNIT_UNKNOWN;
518 for(fi=0; fi<dft->frameNr; fi++) dft->w[fi]=1.0;
519
520 /* Fill DFT */
521 /* time unit */
522 ii=19;
523 if(strstr(csv->c[ii].content, "min")!=NULL) dft->timeunit=TUNIT_MIN;
524 else if(strstr(csv->c[ii].content, "sec")!=NULL) dft->timeunit=TUNIT_SEC;
525 else dft->timeunit=TUNIT_UNKNOWN;
526 /* study number */
527 ii=6;
528 cptr=csv->c[ii].content; strlcpy(dft->studynr, cptr, MAX_STUDYNR_LEN);
529 cptr=strchr(dft->studynr, '.'); if(cptr!=NULL) *cptr=(char)0;
530 cptr=strchr(dft->studynr, ','); if(cptr!=NULL) *cptr=(char)0;
531 cptr=strchr(dft->studynr, ' '); if(cptr!=NULL) *cptr=(char)0;
532 /* subject weight */
533 ii=7; if(ii>=csv->nr) {dftEmpty(dft); return CSV_INVALIDFORMAT;}
534 v1=atof_dpi(csv->c[ii].content);
535 if(v1>0.0) sprintf(dft->comments, "# weight := %g\n", v1);
536 /* scan start time */
537 ii=10; if(ii>=csv->nr) {dftEmpty(dft); return CSV_INVALIDFORMAT;}
538 if(strlen(csv->c[ii].content)>9) {
539 sprintf(tmp, "# scan_start_time := %s\n", csv->c[ii].content);
540 strcat(dft->comments, tmp);
541 }
542 /* frame times */
543 for(fi=0; fi<dft->frameNr; fi++) {
544 ii= 21 + fi*9 + 7; if(ii>csv->nr-2) {dftEmpty(dft); return CSV_INVALIDFORMAT;}
545 //printf("cell[%d] := '%s'\n", ii, csv->c[ii].content); fflush(stdout);
546 v1=atof_dpi(csv->c[ii].content); v2=atof_dpi(csv->c[ii+1].content);
547 dft->x[fi]=v1; dft->x1[fi]=v1-0.5*v2; dft->x2[fi]=v1+0.5*v2;
548 }
549 /* region names, volumes, and concentrations */
550 for(ri=0; ri<dft->voiNr; ri++) {
551 /* ROI name */
552 ii= 21 + ri*dft->frameNr*9;
553 if(ii>=csv->nr) {dftEmpty(dft); return CSV_INVALIDFORMAT;}
554 //printf("ri=%d cell[%d] := '%s'\n", ri, ii, csv->c[ii].content); fflush(stdout);
555 strncpy(dft->voi[ri].name, csv->c[ii].content, MAX_REGIONNAME_LEN);
556 dft->voi[ri].name[MAX_REGIONNAME_LEN]=(char)0;
557 rnameSplit(csv->c[ii].content, dft->voi[ri].voiname, dft->voi[ri].hemisphere, dft->voi[ri].place,
559 /* Volume */
560 ii++; if(ii>=csv->nr) {dftEmpty(dft); return CSV_INVALIDFORMAT;}
561 dft->voi[ri].size=atof_dpi(csv->c[ii].content);
562 /* Frame concentrations */
563 ii++; for(fi=0; fi<dft->frameNr; fi++) {
564 if((ii+6)>=csv->nr) {dftEmpty(dft); return CSV_INVALIDFORMAT;}
565 /* Get concentration */
566 dft->voi[ri].y[fi]=atof_dpi(csv->c[ii].content);
567 /* Get concentration SD (probably not needed) */
568 dft->voi[ri].y2[fi]=atof_dpi(csv->c[ii+1].content);
569 /* check that frame times are correct */
570 v1=atof_dpi(csv->c[ii+5].content);
571 if(dft->x[fi]!=v1) {dftEmpty(dft); return CSV_INVALIDFORMAT;}
572 ii+=9;
573 } // next frame
574 } // next region
575
576 return CSV_OK;
577}
size_t strlcpy(char *dst, const char *src, size_t dstsize)
Definition strext.c:245
#define MAX_STUDYNR_LEN
Definition libtpcmisc.h:163
char comments[_DFT_COMMENT_LEN+1]
double * y2

Referenced by csv2dft().

◆ csv2dft_linkset()

int csv2dft_linkset ( CSV * csv,
DFT * dft )
extern

Reads LinkSet data into DFT struct.

Returns
Returns 0 when successful, otherwise an error code.
Parameters
csvPointer to CSV data to be converted
dftPointer to empty DFT struct which will be allocated and filled here

Definition at line 584 of file csv.c.

589 {
590 int ri, ci, fi, sci, ii, ret;
591 double v;
592 char *cptr;
593
594 /* Check input data */
595 if(CSV_TEST>2) {printf("csv2dft_linkset()\n"); fflush(stdout);}
596 if(csv==NULL || dft==NULL) return CSV_ERROR;
597 if(csv->nr<2 || csv->row_nr<1 || csv->col_nr<1) return CSV_INVALIDFORMAT;
598 if(strcasecmp(csv->c[0].content, "LinkSet")!=0) return CSV_INVALIDFORMAT;
599 /* Get the ROI nr */
600 for(ii=1, ri=0; ii<csv->nr; ii++) if(csv->c[ii].col==1) {
601 if(csv->c[ii].content==NULL) continue;
602 if(strncmp(csv->c[ii].content, "VOI:", 4)==0) ri++;
603 }
604 if(CSV_TEST>2) {
605 printf("frame_nr=%d voi_nr=%d\n", csv->col_nr-2, ri);
606 fflush(stdout);
607 }
608 if(ri<1 || csv->col_nr<3) return CSV_INVALIDFORMAT;
609 /* Delete previous DFT contents */
610 dftEmpty(dft);
611 /* Allocate memory for DFT */
612 ret=dftSetmem(dft, csv->col_nr-2, ri); if(ret!=0) return CSV_OUTOFMEMORY;
613 dft->voiNr=ri;
614 dft->frameNr=csv->col_nr-2;
615
616 /* Set DFT defaults */
619 dft->isweight=0;
620 dftUnitToDFT(dft, CUNIT_UNKNOWN);
621 dft->timeunit=TUNIT_UNKNOWN;
622 for(fi=0; fi<dft->frameNr; fi++) dft->w[fi]=1.0;
623 for(ri=0; ri<dft->voiNr; ri++) dft->voi[ri].sw=0;
624
625 /* Fill DFT contents */
626 for(ri=0; ri<dft->voiNr; ri++) {
627 if(CSV_TEST>3) printf("reading VOI %d\n", 1+ri);
628 /* Search the (ri+1)th VOI */
629 sci=0;
630 for(ii=1; ii<csv->nr; ii++) if(csv->c[ii].col==1) {
631 if(csv->c[ii].content==NULL) continue;
632 if(strncmp(csv->c[ii].content, "VOI:", 4)==0) sci++;
633 if(sci==ri+1) break;
634 }
635 if(sci!=ri+1) break; // not found
636 // ii is not the index of the start of data for one VOI
637 if(CSV_TEST>5) printf(" ri=%d ii=%d row=%d col=%d\n", ri, ii, csv->c[ii].row, csv->c[ii].col);
638 /* Take the ROI number from there in case better name is not found later */
639 strncpy(dft->voi[ri].name, csv->c[ii].content+4, MAX_REGIONNAME_LEN);
640 dft->voi[ri].name[MAX_REGIONNAME_LEN]=(char)0;
641 /* Read time unit from the next field */
642 if(CSV_TEST>4 && ri==0) printf("reading time unit\n");
643 cptr=strchr(csv->c[ii+1].content, '(');
644 if(cptr!=NULL) {
645 ci=petTunitId(cptr+1);
646 if(ri==0) {
647 dft->timeunit=ci;
648 } else if(dft->timeunit!=ci) {
649 if(CSV_TEST>0) printf("different time units.\n");
650 return CSV_INVALIDFORMAT;
651 }
652 }
653 if(CSV_TEST>4 && ri==0) printf("time unit: %s\n", petTunit(dft->timeunit));
654 /* Read the times */
655 for(fi=0; fi<dft->frameNr; fi++) {
656 ci=ii+fi+2; if(ci>=csv->nr) return CSV_INVALIDFORMAT;
657 cptr=csv->c[ci].content;
658 if(atof_with_check(cptr, &v)!=0) return CSV_INVALIDFORMAT;
659 if(ri==0) {
660 dft->x[fi]=v;
661 } else {
662 if(fabs(v-dft->x[fi])>1.0E-003) return CSV_INVALIDFORMAT;
663 }
664 } // next frame time
665 /* First column on the 2nd row should contain the region name */
666 if(CSV_TEST>4) printf("reading VOI name\n");
667 ii+=csv->col_nr; if(ii>=csv->nr) return CSV_INVALIDFORMAT;
668 cptr=csv->c[ii].content;
669 if(cptr!=NULL) {
670 strncpy(dft->voi[ri].name, cptr, MAX_REGIONNAME_LEN);
671 dft->voi[ri].name[MAX_REGIONNAME_LEN]=(char)0;
672 } // default name was set before
673 rnameSplit(dft->voi[ri].name, dft->voi[ri].voiname, dft->voi[ri].hemisphere, dft->voi[ri].place,
675 /* VOI average values should be two rows below this */
676 if(CSV_TEST>4) printf("reading VOI values\n");
677 ii+=2*csv->col_nr; if(ii>=csv->nr) return CSV_INVALIDFORMAT;
678 /* Check that from 2nd column, and get from there the unit, too */
679 ii++; if(ii>=csv->nr) return CSV_INVALIDFORMAT;
680 cptr=csv->c[ii].content; if(cptr==NULL) return CSV_INVALIDFORMAT;
681 if(strncasecmp(cptr, "Average", 7)!=0) return CSV_INVALIDFORMAT;
682 cptr=strchr(csv->c[ii].content, '(');
683 if(cptr!=NULL) {
684 if(CSV_TEST>4 && ri==0)
685 printf("reading activity unit from string: '%s'\n", cptr+1);
686 ci=petCunitId(cptr+1);
687 if(ri==0) {
688 strcpy(dft->unit, petCunit(ci));
689 } else if(ci!=petCunitId(dft->unit)) {
690 if(CSV_TEST>0) printf("different concentration units.\n");
691 return CSV_INVALIDFORMAT;
692 }
693 if(CSV_TEST>5 && ri==0) printf("unit := %s (%d)\n", petCunit(ci), ci);
694 }
695 /* then read the concentrations */
696 for(fi=0; fi<dft->frameNr; fi++) {
697 ci=ii+fi+1; if(ci>=csv->nr) return CSV_INVALIDFORMAT;
698 cptr=csv->c[ci].content;
699 if(atof_with_check(cptr, &v)!=0) return CSV_INVALIDFORMAT;
700 dft->voi[ri].y[fi]=v;
701 } // next frame time
702 }
703 if(ri<dft->voiNr) return CSV_INVALIDFORMAT;
704
705 return CSV_OK;
706}
int atof_with_check(char *double_as_string, double *result_value)
Definition decpoint.c:107
char * petCunit(int cunit)
Definition petunits.c:211
char * petTunit(int tunit)
Definition petunits.c:226
int petTunitId(const char *timeunit)
Definition petunits.c:187

Referenced by csv2dft().

◆ csv2dft_mat()

int csv2dft_mat ( CSV * csv,
DFT * dft )
extern

Reads Mat data into DFT struct.

Returns
Returns 0 when successful, otherwise an error code.
Parameters
csvPointer to CSV data to be converted
dftPointer to empty DFT struct which will be allocated and filled here

Definition at line 713 of file csv.c.

718 {
719 int ri, fi, ret;
720 char *cptr;
721
722 /* Check input data */
723 if(CSV_TEST>2) {printf("csv2dft_mat()\n"); fflush(stdout);}
724 if(csv==NULL || dft==NULL) return CSV_ERROR;
725 if(csv->nr<4 || csv->row_nr<2 || csv->col_nr<2) return CSV_INVALIDFORMAT;
726 if(!csvIsRegular(csv)) return CSV_INVALIDFORMAT;
727
728 /* Delete previous DFT contents */
729 dftEmpty(dft);
730 /* Allocate memory for DFT */
731 ret=dftSetmem(dft, csv->col_nr-1, csv->row_nr-1); if(ret!=0) return CSV_OUTOFMEMORY;
732 dft->voiNr=csv->row_nr-1;
733 dft->frameNr=csv->col_nr-1;
734 if(CSV_TEST>2) {printf("frame_nr=%d voi_nr=%d\n", dft->frameNr, dft->voiNr); fflush(stdout);}
735
736 /* Set DFT defaults */
739 dft->isweight=0;
740 dftUnitToDFT(dft, CUNIT_UNKNOWN);
741 dft->timeunit=TUNIT_UNKNOWN;
742 for(fi=0; fi<dft->frameNr; fi++) dft->w[fi]=1.0;
743 for(ri=0; ri<dft->voiNr; ri++) dft->voi[ri].sw=0;
744
745 if(CSV_TEST>200)
746 for(int i=0; i<csv->nr; i++)
747 printf("row=%d col=%d content='%s'\n", csv->c[i].row, csv->c[i].col, csv->c[i].content);
748
749 /* First cell may contain study number */
750 cptr=csvCell(csv, 1, 1);
751 if(cptr!=NULL && cptr[0] && strnlen(cptr, 20)<20) {
752 strlcpy(dft->studynr, cptr, MAX_STUDYNR_LEN);
753 if(CSV_TEST>3) printf("studynr := %s\n", dft->studynr);
754 }
755
756 /* Fill DFT contents */
757 ret=0;
758 for(ri=0; ri<dft->voiNr; ri++) {
759 if(CSV_TEST>3) printf("reading VOI %d\n", 1+ri);
760 /* Get ROI name */
761 cptr=csvCell(csv, ri+2, 1); //printf("cptr='%s'\n", cptr);
762 if(cptr==NULL) {ret++; break;}
763 int n=strlen(cptr); if(n<3) {ret++; break;}
764 if(cptr[n-1]=='\'') {cptr[n-1]=(char)0; n--;} else {ret++; break;}
765 if(cptr[0]=='\'') {cptr++; n--;} else {ret++; break;}
766 strlcpy(dft->voi[ri].name, cptr, MAX_REGIONNAME_LEN);
767 rnameSplit(dft->voi[ri].name, dft->voi[ri].voiname, dft->voi[ri].hemisphere, dft->voi[ri].place,
769 /* Get concentrations */
770 for(fi=0; fi<dft->frameNr; fi++) {
771 cptr=csvCell(csv, ri+2, fi+2); // printf("cptr='%s'\n", cptr);
772 ret=atof_with_check(cptr, &dft->voi[ri].y[fi]);
773 if(ret) break;
774 }
775 if(ret!=0) break;
776 }
777 if(ret!=0) {dftEmpty(dft); return CSV_INVALIDFORMAT;}
778
779 /* Get frame times */
780 if(CSV_TEST>3) printf("reading frames\n");
781 ret=0;
782 for(fi=0; fi<dft->frameNr; fi++) {
783 cptr=csvCell(csv, 1, fi+2); if(cptr==NULL) {ret++; break;}
784 int n=strlen(cptr); if(n<3) {ret++; break;}
785 char *cptr2=strchr(cptr+1, '-'); if(cptr2!=NULL) {*cptr2=(char)0; cptr2++;}
786 ret=atof_with_check(cptr, &dft->x1[fi]);
787 if(ret==0) ret=atof_with_check(cptr2, &dft->x2[fi]);
788 if(ret) break;
789 dft->x[fi]=0.5*(dft->x1[fi]+dft->x2[fi]);
790 }
791 if(ret!=0) {dftEmpty(dft); return CSV_INVALIDFORMAT;}
792
793 return CSV_OK;
794}
int csvIsRegular(CSV *csv)
Definition csv.c:803
char * csvCell(CSV *csv, int row, int col)
Definition csv.c:827
size_t strnlen(const char *s, size_t n)
Definition strext.c:181

Referenced by csv2dft().

◆ csvCell()

char * csvCell ( CSV * csv,
int row,
int col )
extern

Get the CVS field contents in specified row and column.

Returns
Returns pointer to the content string, or NULL if not found.
Author
Vesa Oikonen
See also
csvRead
Parameters
csvPointer to CSV
rowCSV row index
colCSV column index

Definition at line 827 of file csv.c.

834 {
835 if(csv==NULL) return((char*)NULL);
836 for(int i=0; i<csv->nr; i++)
837 if(csv->c[i].row==row && csv->c[i].col==col)
838 return(csv->c[i].content);
839 return((char*)NULL);
840}

Referenced by csv2dft_mat().

◆ csvEmpty()

void csvEmpty ( CSV * csv)
extern

Free allocated memory in CSV struct

Parameters
csvPointer to CSV struct

Definition at line 24 of file csv.c.

27 {
28 int i;
29 if(csv==NULL) return;
30 for(i=0; i<csv->nr; i++)
31 if(csv->c[i].content!=NULL) free(csv->c[i].content);
32 free(csv->c); csv->c=NULL;
33 csv->nr=csv->row_nr=csv->col_nr=0;
34 csv->separator=(char)0;
35}
char separator

Referenced by dftFormat(), and dftRead().

◆ csvInit()

void csvInit ( CSV * csv)
extern

Initiate CSV struct

Parameters
csvPointer to CSV struct

Definition at line 13 of file csv.c.

16 {
17 if(csv==NULL) return;
18 csv->c=NULL;
19 csv->nr=csv->row_nr=csv->col_nr=0;
20 csv->separator=(char)0;
21}

Referenced by dftFormat(), and dftRead().

◆ csvIsRegular()

int csvIsRegular ( CSV * csv)
extern

Check whether CSV is regular, that is, each row contain the same number of columns.

Author
Vesa Oikonen
See also
csvRead
Returns
Returns 1 if CSV is regular, 0 if not.
Parameters
csvPointer to CSV

Definition at line 803 of file csv.c.

806 {
807 if(csv==NULL) return(0);
808 if(csv->nr<2) return(1);
809 int i, r, n=0, m=0;
810 i=0; r=csv->c[i].row; m++;
811 for(i=1; i<csv->nr; i++) {
812 if(r==csv->c[i].row) {m++; continue;}
813 if(n>0 && m!=n) return(0);
814 r=csv->c[i].row; n=m; m=1;
815 }
816 if(n>0 && m!=n) return(0);
817 return(1);
818}

Referenced by csv2dft_mat().

◆ csvRead()

int csvRead ( CSV * csv,
char * fname )
extern

Read CSV file.

Returns
Non-zero in case of an error.
Parameters
csvPointer to CSV struct
fnameFilename

Definition at line 42 of file csv.c.

47 {
48 if(CSV_TEST>2) {printf("csvRead('%s')\n", fname); fflush(stdout);}
49
50 FILE *fp;
51 int i, nr, ret, nonprintable=0, inside_quotes=0, previous, col_nr=0;
52 const int MAX_CSV_FIELD_LENGTH=1024;
53 char buf[MAX_CSV_FIELD_LENGTH+1];
54 int tabnr, spacenr, commanr;
55
56
57 if(csv==NULL || fname==NULL) return CSV_ERROR;
58 /* Open file */
59 fp=fopen(fname, "r"); if(fp==NULL) return CSV_CANNOTOPEN;
60
61 /* Check the file size */
62 nr=nonprintable=0; while((ret=fgetc(fp))!=EOF) {
63 if(iscntrl(ret) && ret!=13 && ret!=10 && ret!=9) {nonprintable=1; break;}
64 nr++;
65 }
66 if(CSV_TEST>0) printf("filesize := %d\n", nr);
67 if(nr<2) {fclose(fp); return CSV_INVALIDFORMAT;}
68 if(nr>5000000) {fclose(fp); return CSV_TOOBIG;}
69 rewind(fp);
70
71 /* Determine the field separator (unless set outside) */
72 if(csv->separator==(char)0) {
73 /* Check if ; or tab or space or comma character is found outside double quotes */
74 inside_quotes=0; nr=0; tabnr=0; spacenr=0; commanr=0;
75 while((ret=fgetc(fp))!=EOF) {
76 if(ret=='"') {
77 if(inside_quotes==0) inside_quotes=1; else inside_quotes=0;
78 continue;
79 }
80 if(inside_quotes==1) continue;
81 if(ret==';') nr++;
82 else if(ret=='\t') tabnr++;
83 else if(ret==',') commanr++;
84 else if(ret==' ') spacenr++;
85 }
86 if(CSV_TEST>0) {
87 printf("semicolon_nr := %d\n", nr);
88 printf("tab_nr := %d\n", tabnr);
89 printf("comma_nr := %d\n", commanr);
90 printf("space_nr := %d\n", spacenr);
91 }
92 /* If at least one, then assume that ; is the separator, otherwise , or tab */
93 if(nr>0) csv->separator=';';
94 else if(tabnr>0) csv->separator='\t';
95 else if(commanr>spacenr) csv->separator=',';
96 else csv->separator=' ';
97 rewind(fp);
98 }
99 if(CSV_TEST>0) printf("separator := '%c'\n", csv->separator);
100 /* We will not accept space as separator for CSV */
101 if(csv->separator==' ') {fclose(fp); return CSV_INVALIDFORMAT;}
102
103
104 /* Determine the number of fields in CSV file */
105 inside_quotes=0; nr=0; previous=0;
106 while((ret=fgetc(fp))!=EOF) {
107 if((previous==13 || previous==10) && (ret==13 || ret==10)) {previous=ret; continue;}
108 if(ret=='"') {
109 if(inside_quotes==0) inside_quotes=1; else inside_quotes=0;
110 previous=ret; continue;
111 }
112 if(inside_quotes==0) {
113 if(ret==csv->separator) {
114 nr++; previous=ret;
115 continue;
116 }
117 if( (ret==13 || ret==10) && previous!=13 && previous!=10) {
118 nr++; previous=ret;
119 continue;
120 }
121
122 int next=fgetc(fp);
123 if(next!=EOF) {
124 ungetc(next, fp);
125 } else {
126 nr++; previous=ret;
127 continue;
128 }
129
130 } //printf("%c", (char)ret);
131 previous=ret;
132 }
133 rewind(fp); if(CSV_TEST>0) printf("field_nr := %d\n", nr);
134
135 /* Allocate memory for fields */
136 csv->c=(CSV_item*)calloc(nr, sizeof(CSV_item));
137 if(csv->c==NULL) {fclose(fp); return CSV_OUTOFMEMORY;}
138 csv->nr=nr;
139
140 /* Copy field contents from CSV file */
141 if(CSV_TEST>0) printf(" copying contents...\n");
142 inside_quotes=0; nr=0; previous=0; i=0; col_nr=0;
143 while((ret=fgetc(fp))!=EOF) {
144 if((previous==13 || previous==10) && (ret==13 || ret==10)) {previous=ret; continue;}
145 if(ret=='"') {
146 if(inside_quotes==0) inside_quotes=1; else inside_quotes=0;
147 previous=ret; continue;
148 }
149 if(inside_quotes==0) {
150 if(ret==csv->separator) {
151 buf[i]=(char)0; strCleanSpaces(buf); if(CSV_TEST>10) printf("'%s'\n", buf);
152 if(nr>=csv->nr) {printf(" index overflow\n"); break;}
153 csv->c[nr].content=strdup(buf);
154 csv->c[nr].row=1+csv->row_nr; csv->c[nr].col=1+col_nr;
155 i=0; nr++; col_nr++; previous=ret;
156 continue;
157 }
158 if( (ret==13 || ret==10) && previous!=13 && previous!=10) {
159 buf[i]=(char)0; strCleanSpaces(buf); if(CSV_TEST>10) printf("'%s'\n", buf);
160 if(nr>=csv->nr) {printf(" index overflow\n"); break;}
161 csv->c[nr].content=strdup(buf);
162 if(CSV_TEST>10) printf("===\n");
163 col_nr++; if(col_nr>csv->col_nr) csv->col_nr=col_nr;
164 csv->c[nr].row=1+csv->row_nr; csv->c[nr].col=col_nr;
165 i=0; nr++; col_nr=0; previous=ret; csv->row_nr++;
166 continue;
167 }
168
169 int next=fgetc(fp);
170 if(next!=EOF) {
171 ungetc(next, fp);
172 } else {
173 buf[i]=(char)0; strCleanSpaces(buf); if(CSV_TEST>10) printf("'%s'\n", buf);
174 if(nr>=csv->nr) {printf(" index overflow\n"); break;}
175 csv->c[nr].content=strdup(buf);
176 if(CSV_TEST>10) printf("===\n");
177 col_nr++; if(col_nr>csv->col_nr) csv->col_nr=col_nr;
178 csv->c[nr].row=1+csv->row_nr; csv->c[nr].col=col_nr;
179 i=0; nr++; col_nr=0; previous=ret; csv->row_nr++;
180 continue;
181 }
182
183 }
184 if(i<MAX_CSV_FIELD_LENGTH) buf[i]=(char)ret;
185 i++;
186 previous=ret;
187 }
188 if(CSV_TEST>0) printf(" ... copied: nr=%d\n", nr);
189
190
191 fclose(fp);
192 return CSV_OK;
193}
int strCleanSpaces(char *s)
Definition strext.c:343

Referenced by dftFormat(), and dftRead().

◆ dft_fill_hdr_from_IFT()

int dft_fill_hdr_from_IFT ( DFT * dft,
IFT * ift )
extern

Read certain keys from IFT and set DFT fields accordingly.

Returns
Returns the nr of identified keys.
Parameters
dftPointer to allocated DFT struct where information will be written
iftPointer to IFT struct from where information is retrieved

Definition at line 971 of file dftio.c.

976 {
977 int ki, ri, ok_nr=0, ret;
978 char keystr[256], *cptr;
979
980 //printf("dft_fill_hdr_from_IFT()\n");
981
982 /* Check for study number */
983 strcpy(keystr, "studynr"); ki=iftGet(ift, keystr, 0);
984 if(ki==-1) {strcpy(keystr, "study number"); ki=iftGet(ift, keystr, 0);}
985 if(ki==-1) {strcpy(keystr, "study_number"); ki=iftGet(ift, keystr, 0);}
986 if(ki>=0) {
987 strlcpy(dft->studynr, ift->item[ki].value, MAX_STUDYNR_LEN);
988 ok_nr++;
989 }
990
991 /* Check for time unit */
992 strcpy(keystr, "timeunit"); ki=iftGet(ift, keystr, 0);
993 if(ki==-1) {strcpy(keystr, "time unit"); ki=iftGet(ift, keystr, 0);}
994 if(ki==-1) {strcpy(keystr, "time_unit"); ki=iftGet(ift, keystr, 0);}
995 if(ki==-1) {strcpy(keystr, "Time units"); ki=iftGet(ift, keystr, 0);}
996 if(ki>=0) {
997 ret=petTunitId(ift->item[ki].value);
998 if(ret>=0 && ret!=TUNIT_UNKNOWN) {dft->timeunit=ret; ok_nr++;}
999 }
1000
1001 /* Check for sample unit */
1002 strcpy(keystr, "unit"); ki=iftGet(ift, keystr, 0);
1003 if(ki==-1) {strcpy(keystr, "Activity units"); ki=iftGet(ift, keystr, 0);}
1004 if(ki>=0) {
1005 strncpy(dft->unit, ift->item[ki].value, 12); dft->unit[12]=(char)0;
1006 ok_nr++;
1007 }
1008
1009 /* Check for region names */
1010 ri=0;
1011 do {
1012 strcpy(keystr, "voiname"); ki=iftGetNth(ift, keystr, ri+1, 0);
1013 if(ki>=0) {
1014 strncpy(dft->voi[ri].name, ift->item[ki].value, MAX_REGIONNAME_LEN);
1015 dft->voi[ri].name[MAX_REGIONNAME_LEN]=(char)0;
1016 rnameSplit(ift->item[ki].value, dft->voi[ri].voiname,
1017 dft->voi[ri].hemisphere, dft->voi[ri].place, MAX_REGIONSUBNAME_LEN);
1018 }
1019 ri++; ok_nr++;
1020 } while(ki>=0 && ri<dft->_voidataNr);
1021
1022 /* Check for region volumes */
1023 strcpy(keystr, "sizes"); ki=iftGet(ift, keystr, 0);
1024 if(ki==-1) {strcpy(keystr, "volumes"); ki=iftGet(ift, keystr, 0);}
1025 if(ki>=0 && strlen(ift->item[ki].value)) {
1026 ri=0; cptr=strtok(ift->item[ki].value, " ;\t");
1027 while(cptr!=NULL && ri<dft->_voidataNr) {
1028 if(strcmp(cptr, ".")==0) {ri++; continue;}
1029 dft->voi[ri++].size=atof_dpi(cptr);
1030 cptr=strtok(NULL, " ;\t");
1031 }
1032 ok_nr++;
1033 }
1034
1035 /* Check for the name of radiopharmaceutical */
1036 strcpy(keystr, "radiopharmaceutical"); ki=iftGet(ift, keystr, 0);
1037 if(ki>=0 && strlen(ift->item[ki].value)) {
1038 strncpy(dft->radiopharmaceutical, ift->item[ki].value, 31);
1039 dft->radiopharmaceutical[31]=(char)0;
1040 ok_nr++;
1041 }
1042
1043 /* Check for isotope name */
1044 strcpy(keystr, "isotope"); ki=iftGet(ift, keystr, 0);
1045 if(ki>=0 && strlen(ift->item[ki].value)) {
1046 strncpy(dft->isotope, ift->item[ki].value, 6); dft->isotope[6]=(char)0;
1047 ok_nr++;
1048 }
1049
1050 /* Check if there is anything about correction for physical decay */
1051 strcpy(keystr, "decay_correction"); ki=iftGet(ift, keystr, 0);
1052 if(ki==-1) {strcpy(keystr, "decay correction"); ki=iftGet(ift, keystr, 0);}
1053 if(ki>=0 && strlen(ift->item[ki].value)) {
1054 if(strncasecmp(ift->item[ki].value, "Yes", 1)==0) {
1055 dft->decayCorrected=DFT_DECAY_CORRECTED; ok_nr++;
1056 } else if(strncasecmp(ift->item[ki].value, "No", 1)==0) {
1058 }
1059 }
1060
1061 /* Check for injection time */
1062 strcpy(keystr, "injection time"); ki=iftGet(ift, keystr, 0);
1063 if(ki==-1) {strcpy(keystr, "injection_time"); ki=iftGet(ift, keystr, 0);}
1064 if(ki>=0 && strlen(ift->item[ki].value)) {
1065 /* check if time is in correct format; otherwise try to correct it */
1066 if(ift->item[ki].value[4]=='-' && ift->item[ki].value[7]=='-' &&
1067 ift->item[ki].value[13]==':' && ift->item[ki].value[16]==':') {
1068 strncpy(dft->injectionTime, ift->item[ki].value, 19);
1069 dft->injectionTime[19]=(char)0; ok_nr++;
1070 } else if(ift->item[ki].value[2]=='.' && ift->item[ki].value[5]=='.' &&
1071 ift->item[ki].value[13]==':' && ift->item[ki].value[16]==':') {
1072 sprintf(dft->injectionTime, "%4.4s-%2.2s-%2.2s %8.8s",
1073 ift->item[ki].value+6, ift->item[ki].value+3, ift->item[ki].value,
1074 ift->item[ki].value+11);
1075 ok_nr++;
1076 }
1077 }
1078
1079 /* Check for scan start time */
1080 strcpy(keystr, "scan start time"); ki=iftGet(ift, keystr, 0);
1081 if(ki==-1) {strcpy(keystr, "scan_start_time"); ki=iftGet(ift, keystr, 0);}
1082 if(ki==-1) {strcpy(keystr, "scan_start"); ki=iftGet(ift, keystr, 0);}
1083 if(ki==-1) {strcpy(keystr, "scan start"); ki=iftGet(ift, keystr, 0);}
1084 if(ki>=0 && strlen(ift->item[ki].value)) {
1085 /* check if time is in correct format; otherwise try to correct it */
1086 if(ift->item[ki].value[4]=='-' && ift->item[ki].value[7]=='-' &&
1087 ift->item[ki].value[13]==':' && ift->item[ki].value[16]==':') {
1088 strncpy(dft->scanStartTime, ift->item[ki].value, 19);
1089 dft->scanStartTime[19]=(char)0; ok_nr++;
1090 } else if(ift->item[ki].value[2]=='.' && ift->item[ki].value[5]=='.' &&
1091 ift->item[ki].value[13]==':' && ift->item[ki].value[16]==':') {
1092 sprintf(dft->scanStartTime, "%4.4s-%2.2s-%2.2s %8.8s",
1093 ift->item[ki].value+6, ift->item[ki].value+3, ift->item[ki].value,
1094 ift->item[ki].value+11);
1095 ok_nr++;
1096 }
1097 }
1098
1099 return(ok_nr);
1100}
int iftGetNth(IFT *ift, char *key, int n, int verbose)
Definition iftsrch.c:48
#define DFT_DECAY_NOTCORRECTED
#define DFT_DECAY_CORRECTED
char scanStartTime[20]
char decayCorrected
char injectionTime[20]
char isotope[8]
char radiopharmaceutical[32]

Referenced by dftRead().

◆ dft_kBqMax()

double dft_kBqMax ( DFT * data)
extern

Returns the highest activity value in DFT

Parameters
dataPointer to DFT struct

Definition at line 1148 of file dft.c.

1151 {
1152 int i, j;
1153 double max=-1e+99;
1154
1155 if(data==NULL) return(nan(""));
1156 for(i=0; i<data->voiNr ;i++){
1157 for(j=0; j<data->frameNr; j++){
1158 if(!isnan(data->voi[i].y[j]) && data->voi[i].y[j]>max) max=data->voi[i].y[j];
1159 }
1160 }
1161 return(max);
1162}

Referenced by dftInterpolateCheckStart().

◆ dft_kBqMin()

double dft_kBqMin ( DFT * data)
extern

Returns the lowest activity value in DFT

Parameters
dataPointer to DFT struct

Definition at line 1129 of file dft.c.

1132 {
1133 int i, j;
1134 double min=1e+99;
1135
1136 if(data==NULL) return(nan(""));
1137 for(i=0; i<data->voiNr ;i++) {
1138 for(j=0; j<data->frameNr; j++) {
1139 if(!isnan(data->voi[i].y[j]) && data->voi[i].y[j]<min) min=data->voi[i].y[j];
1140 }
1141 }
1142 return(min);
1143}

◆ dft_nr_of_NA()

int dft_nr_of_NA ( DFT * dft)
extern

Check DFT for NA's in sample times and values.

Returns
Returns the number of NA's that were found.
Parameters
dftPointer to DFT struct

Definition at line 905 of file dft.c.

908 {
909 int ri, fi, na_nr=0;
910 if(dft==NULL) return 0;
911 for(fi=0; fi<dft->frameNr; fi++) {
912 if(dft->timetype==DFT_TIME_STARTEND) {
913 if(isnan(dft->x1[fi])) na_nr++;
914 if(isnan(dft->x2[fi])) na_nr++;
915 } else {
916 if(isnan(dft->x[fi])) na_nr++;
917 }
918 for(ri=0; ri<dft->voiNr; ri++) if(isnan(dft->voi[ri].y[fi])) na_nr++;
919 }
920 return(na_nr);
921}

Referenced by dftInterpolateInto(), dftReadModelingData(), and imgReadModelingData().

◆ dftAdd()

int dftAdd ( DFT * data1,
DFT * data2,
int voi )
extern

Add the specified voi [0,voiNr-1] from data2 to data1. Allocates memory for additional data VOI, if necessary.

Returns
Returns 0 if ok.
Parameters
data1Pointer to DFT struct data
data2Pointer to DFT struct data
voiIndex of TAC in the 2nd DFT

Definition at line 188 of file dft.c.

195 {
196 int i, n;
197
198 if(data1==NULL || data2==NULL) return 1;
199 /* Check that voi exists */
200 if(data2->voiNr<=voi || voi<0) {
201 strcpy(dfterrmsg, "there is no region to combine"); return 8;}
202
203 /* Check that frame number etc is the same */
204 if(data1->frameNr!=data2->frameNr ||
205 (data1->_type!=DFT_FORMAT_PLAIN && data2->_type!=DFT_FORMAT_PLAIN &&
206 (data1->timeunit!=data2->timeunit || strcasecmp(data1->unit, data2->unit))
207 )) {
208 strcpy(dfterrmsg, "data does not match"); return 8;}
209
210 /* Allocate more memory if necessary */
211 if(data1->_voidataNr==data1->voiNr)
212 if(dftAddmem(data1, 1)) {
213 strcpy(dfterrmsg, "cannot allocate memory"); return 8;}
214
215 /* Copy data */
216 n=data1->voiNr;
217 (void)dftCopyvoihdr(data2, voi, data1, n);
218 for(i=0; i<data1->frameNr; i++) {
219 data1->voi[n].y[i]=data2->voi[voi].y[i];
220 data1->voi[n].y2[i]=data2->voi[voi].y2[i];
221 data1->voi[n].y3[i]=data2->voi[voi].y3[i];
222 }
223 data1->voiNr+=1;
224
225 /* If data2 contains weights and data1 does not, then copy those */
226 if(data2->isweight && !data1->isweight)
227 for(i=0; i<data1->frameNr; i++) data1->w[i]=data2->w[i];
228
229 return 0;
230}
int dftCopyvoihdr(DFT *dft1, int from, DFT *dft2, int to)
Definition dft.c:623
char dfterrmsg[64]
Definition dft.c:6
int dftAddmem(DFT *dft, int voiNr)
Definition dft.c:107
double * y3

◆ dftAddmem()

int dftAddmem ( DFT * dft,
int voiNr )
extern

Adds room for additional VOI TAC(s) into DFT data structure.

Old data is left unchanged.

Returns
Returns 0 when successful.
Parameters
dftPointer to DFT data structure
voiNrNr of additional VOI memory blocks

Definition at line 107 of file dft.c.

112 {
113 Voi *voi2;
114 double *data2, *dptr, *newx, *newx1, *newx2, *neww;
115 int ri, fi, dataSize2, voidataNr2;
116
117 /* Check the input */
118 if(dft==NULL || dft->voi==NULL || dft->frameNr<1 || dft->voiNr<1) return 1;
119 if(voiNr<0) return 1; else if(voiNr==0) return 0;
120
121 /* Allocate memory for new set of curve data (plus additional 'frame') */
122 voidataNr2=voiNr+dft->_voidataNr;
123 voi2=(Voi*)calloc(voidataNr2, sizeof(Voi));
124 if(voi2==NULL) return 3;
125 dataSize2=(dft->frameNr+1)*(3*voidataNr2+4);
126 data2=(double*)calloc(dataSize2, sizeof(double)); if(data2==NULL) return 3;
127 /* Set pointers for new curve data */
128 dptr=data2; newx=dptr; newx[dft->frameNr]=0.0;
129 dptr+=dft->frameNr+1; newx1=dptr; newx1[dft->frameNr]=0.0;
130 dptr+=dft->frameNr+1; newx2=dptr; newx2[dft->frameNr]=0.0;
131 dptr+=dft->frameNr+1; neww=dptr; neww[dft->frameNr]=0.0;
132 for(ri=0; ri<voidataNr2; ri++) {
133 dptr+=dft->frameNr+1; voi2[ri].y = dptr;
134 dptr+=dft->frameNr+1; voi2[ri].y2 = dptr;
135 dptr+=dft->frameNr+1; voi2[ri].y3 = dptr;
136 }
137
138 /* Copy the original contents */
139 for(ri=0; ri<dft->voiNr; ri++) {
140 /* Copy Voi header */
141 strcpy(voi2[ri].name, dft->voi[ri].name);
142 strcpy(voi2[ri].voiname, dft->voi[ri].voiname);
143 strcpy(voi2[ri].hemisphere, dft->voi[ri].hemisphere);
144 strcpy(voi2[ri].place, dft->voi[ri].place);
145 voi2[ri].size=dft->voi[ri].size;
146 voi2[ri].sw=dft->voi[ri].sw;
147 voi2[ri].sw2=dft->voi[ri].sw2;
148 voi2[ri].sw3=dft->voi[ri].sw3;
149 /* Copy Voi data */
150 for(fi=0; fi<dft->frameNr; fi++) {
151 voi2[ri].y[fi]=dft->voi[ri].y[fi];
152 voi2[ri].y2[fi]=dft->voi[ri].y2[fi];
153 voi2[ri].y3[fi]=dft->voi[ri].y3[fi];
154 }
155 }
156 for(fi=0; fi<dft->frameNr; fi++) {
157 newx[fi]=dft->x[fi]; newx1[fi]=dft->x1[fi]; newx2[fi]=dft->x2[fi];
158 neww[fi]=dft->w[fi];
159 }
160
161 /* Replace original pointers */
162 free(dft->_data); dft->_data=data2;
163 free(dft->voi); dft->voi=voi2;
164 dft->x=newx; dft->x1=newx1; dft->x2=newx2; dft->w=neww;
165 dft->_voidataNr=voidataNr2; dft->_dataSize=dataSize2;
166
167 /* Initiate values */
168 for(ri=dft->voiNr; ri<dft->_voidataNr; ri++) {
169 strcpy(dft->voi[ri].name, "");
170 strcpy(dft->voi[ri].voiname, "");
171 strcpy(dft->voi[ri].hemisphere, "");
172 strcpy(dft->voi[ri].place, "");
173 dft->voi[ri].size=1.0;
174 dft->voi[ri].sw=dft->voi[ri].sw2=dft->voi[ri].sw3=0;
175 for(fi=0; fi<dft->frameNr+1; fi++)
176 dft->voi[ri].y[fi]=dft->voi[ri].y2[fi]=dft->voi[ri].y3[fi]=0.0;
177 }
178
179 return 0;
180}
char sw2
char sw3

Referenced by dftAdd(), dftInterpolateInto(), dftReadModelingData(), and imgReadModelingData().

◆ dftAddnullframe()

int dftAddnullframe ( DFT * data)
extern

Include a frame with time 0, unless one already exists.

Returns
Returns <> 0 in case of an error.
Parameters
dataPointer to DFT struct

Definition at line 752 of file dft.c.

755 {
756 int i, j, n;
757 DFT temp;
758
759
760 /* Check whether nullframe exists */
761 if(data==NULL) return 1;
762 if(data->frameNr<1 || data->x[0]==0.0) return 0;
763
764 /* Allocate memory for temp data */
765 dftInit(&temp);
766 if(dftSetmem(&temp, data->frameNr, data->voiNr)) return 1;
767 temp.frameNr=data->frameNr; temp.voiNr=data->voiNr;
768
769 /* Copy data to temp */
770 strcpy(temp.studynr, data->studynr);
771 strcpy(temp.unit, data->unit);
772 temp.timeunit=data->timeunit; temp.timetype=data->timetype;
773 temp.isweight=data->isweight; temp._type=data->_type;
774 strcpy(temp.comments, data->comments);
775 for(j=0; j<data->frameNr; j++) {
776 temp.x[j]=data->x[j]; temp.x1[j]=data->x1[j]; temp.x2[j]=data->x2[j];
777 temp.w[j]=data->w[j];
778 for(i=0; i<data->voiNr; i++) {
779 temp.voi[i].y[j]=data->voi[i].y[j];
780 temp.voi[i].y2[j]=data->voi[i].y2[j];
781 temp.voi[i].y3[j]=data->voi[i].y3[j];
782 }
783 }
784 for(i=0; i<data->voiNr; i++) {
785 strcpy(temp.voi[i].name, data->voi[i].name);
786 strcpy(temp.voi[i].voiname, data->voi[i].voiname);
787 strcpy(temp.voi[i].hemisphere, data->voi[i].hemisphere);
788 strcpy(temp.voi[i].place, data->voi[i].place);
789 temp.voi[i].size=data->voi[i].size;
790 temp.voi[i].sw=data->voi[i].sw;
791 temp.voi[i].sw2=data->voi[i].sw2;
792 temp.voi[i].sw3=data->voi[i].sw3;
793 }
794
795 /* Reallocate memory for data */
796 dftEmpty(data);
797 if(dftSetmem(data, temp.frameNr+1, temp.voiNr)) {dftEmpty(&temp); return 2;}
798
799 /* Set nullframe */
800 data->x[0]=data->x1[0]=data->x2[0]=0.0; data->w[0]=0.0;
801 for(i=0; i<temp.voiNr; i++)
802 data->voi[i].y[0]=data->voi[i].y2[0]=data->voi[i].y3[0]=0.0;
803
804 /* Copy data back from temp */
805 strcpy(data->studynr, temp.studynr);
806 data->voiNr=temp.voiNr;
807 strcpy(data->unit, temp.unit);
808 data->timeunit=temp.timeunit; data->timetype=temp.timetype;
809 data->isweight=temp.isweight; data->_type=temp._type;
810 strcpy(data->comments, temp.comments);
811 for(j=0, n=1; j<temp.frameNr; j++) {
812 if(temp.x[j]<0.0) continue;
813 if(n==1) data->x2[0]=temp.x1[j];
814 data->x[n]=temp.x[j]; data->x1[n]=temp.x1[j]; data->x2[n]=temp.x2[j];
815 data->w[n]=temp.w[j];
816 for(i=0; i<temp.voiNr; i++) {
817 data->voi[i].y[n]=temp.voi[i].y[j];
818 data->voi[i].y2[n]=temp.voi[i].y2[j];
819 data->voi[i].y3[n]=temp.voi[i].y3[j];
820 }
821 n++;
822 }
823 data->frameNr=n;
824 for(i=0; i<temp.voiNr; i++) {
825 strcpy(data->voi[i].name, temp.voi[i].name);
826 strcpy(data->voi[i].voiname, temp.voi[i].voiname);
827 strcpy(data->voi[i].hemisphere, temp.voi[i].hemisphere);
828 strcpy(data->voi[i].place, temp.voi[i].place);
829 data->voi[i].size=temp.voi[i].size;
830 data->voi[i].sw=temp.voi[i].sw;
831 data->voi[i].sw2=temp.voi[i].sw2;
832 data->voi[i].sw3=temp.voi[i].sw3;
833 }
834
835 dftEmpty(&temp);
836
837 return 0;
838}
void dftInit(DFT *data)
Definition dft.c:38

◆ dftAddSpaceForFrames()

int dftAddSpaceForFrames ( DFT * dft,
int nr_to_add )
extern

Add space for additional frames into DFT, keeping the existing data. frameNr is increased by nr_to_add, but new last frame(s) are empty.

Returns
Returns zero if successful, otherwise <>0.
Parameters
dftAllocated and data-filled DFT where new frame(s) are added to the end
nr_to_addNr of frames to add

Definition at line 1465 of file dft.c.

1470 {
1471 DFT temp;
1472 int ret, ri, fi;
1473
1474 /* Check input */
1475 if(dft==NULL || dft->frameNr<1 || dft->voiNr<1) return 1;
1476 if(nr_to_add<1) return 0;
1477
1478 /* Make a temporary storage of the data */
1479 dftInit(&temp); ret=dftdup(dft, &temp); if(ret!=0) return 10+ret;
1480 /* Delete and reallocate the original data pointer */
1481 dftEmpty(dft); ret=dftSetmem(dft, temp.frameNr+nr_to_add, temp.voiNr);
1482 if(ret!=0) {
1483 dftdup(&temp, dft); dftEmpty(&temp);
1484 return 20+ret;
1485 }
1486 /* Copy data back, leaving last frame(s) empty */
1487 ret=dftCopymainhdr(&temp, dft);
1488 if(ret!=0) {
1489 dftdup(&temp, dft); dftEmpty(&temp);
1490 return 30+ret;
1491 }
1492 dft->voiNr=temp.voiNr; dft->frameNr=nr_to_add+temp.frameNr;
1493 dft->isweight=temp.isweight;
1494 strcpy(dft->comments, temp.comments);
1495 for(ri=0; ri<temp.voiNr; ri++) {
1496 ret=dftCopyvoihdr(&temp, ri, dft, ri);
1497 if(ret!=0) {
1498 dftdup(&temp, dft); dftEmpty(&temp);
1499 return 40+ret;
1500 }
1501 for(fi=0; fi<temp.frameNr; fi++) {
1502 dft->voi[ri].y[fi]=temp.voi[ri].y[fi];
1503 dft->voi[ri].y2[fi]=temp.voi[ri].y2[fi];
1504 dft->voi[ri].y3[fi]=temp.voi[ri].y3[fi];
1505 }
1506 /* Fill in the first frame */
1507 dft->voi[ri].y[0]=0.0;
1508 dft->voi[ri].y2[0]=0.0;
1509 dft->voi[ri].y3[0]=0.0;
1510 }
1511 for(fi=0; fi<temp.frameNr; fi++) {
1512 dft->x1[fi]=temp.x1[fi];
1513 dft->x2[fi]=temp.x2[fi];
1514 dft->x[fi]=temp.x[fi];
1515 dft->w[fi]=temp.w[fi];
1516 }
1517
1518 /* Fill the last frames with NAs */
1519 for(fi=temp.frameNr; fi<dft->frameNr; fi++) {
1520 dft->w[fi]=1.0;
1521 dft->x1[fi]=dft->x2[fi]=dft->x[0]=0.0;
1522 for(ri=0; ri<dft->voiNr; ri++) dft->voi[ri].y[fi]=nan("");
1523 }
1524 dftEmpty(&temp);
1525
1526 return 0;
1527}
int dftdup(DFT *dft1, DFT *dft2)
Definition dft.c:655
int dftCopymainhdr(DFT *dft1, DFT *dft2)
Definition dft.c:561

◆ dftAllocateWithHeader()

int dftAllocateWithHeader ( DFT * dft,
int frameNr,
int voiNr,
DFT * dft_from )
extern

Allocates a DFT structure with specified size, containing no TAC data but header information as available in another DFT struct.

Any existing content of dft2 will be deleted. Dft2 must be initiated.

Returns
Returns 0 if ok.
Parameters
dftPointer to initiated DFT struct which will be allocated here; any previous contents will be deleted.
frameNrNr of frames to be allocated
voiNrNr of planes to be allocated
dft_fromPointer to DFT struct where header contents will be copied from

Definition at line 702 of file dft.c.

712 {
713 int ri, fi, ret;
714
715 /* Check the input */
716 if(dft==NULL || dft_from==NULL || frameNr<1 || voiNr<0) return 1;
717 /* Empty the new data */
718 dftEmpty(dft);
719 /* Allocate memory for dft */
720 ret=dftSetmem(dft, frameNr, voiNr); if(ret) return(ret);
721 dft->voiNr=voiNr; dft->frameNr=frameNr;
722 /* Copy the contents */
723 ret=dftCopymainhdr(dft_from, dft); if(ret) return(ret);
724 if(dft->voiNr==dft_from->voiNr) {
725 for(ri=0; ri<dft->voiNr; ri++) {
726 ret=dftCopyvoihdr(dft_from, ri, dft, ri); if(ret) return(ret);
727 if(dft->frameNr==dft_from->frameNr) {
728 for(fi=0; fi<dft->frameNr; fi++) {
729 dft->voi[ri].y[fi]=dft_from->voi[ri].y[fi];
730 dft->voi[ri].y2[fi]=dft_from->voi[ri].y2[fi];
731 dft->voi[ri].y3[fi]=dft_from->voi[ri].y3[fi];
732 }
733 }
734 }
735 }
736 if(dft->frameNr==dft_from->frameNr) {
737 for(fi=0; fi<dft->frameNr; fi++) {
738 dft->x[fi]=dft_from->x[fi];
739 dft->x1[fi]=dft_from->x1[fi]; dft->x2[fi]=dft_from->x2[fi];
740 dft->w[fi]=dft_from->w[fi];
741 }
742 dft->isweight=dft_from->isweight;
743 }
744 return(0);
745}

Referenced by dftInterpolateForIMG(), dftMeanTAC(), and dftTimeIntegral().

◆ dftCopymainhdr()

int dftCopymainhdr ( DFT * dft1,
DFT * dft2 )
extern

Copy main header info from dft1 to dft2.

Returns
Returns <> 0 in case of an error.
Parameters
dft1Pointer to DFT struct from where information is copied
dft2Pointer to DFT struct into which information is copied to

Definition at line 561 of file dft.c.

566 {
567 if(dft1==NULL || dft2==NULL) return 1;
568 strcpy(dft2->studynr, dft1->studynr);
569 strcpy(dft2->unit, dft1->unit);
570 dft2->timeunit=dft1->timeunit; dft2->timetype=dft1->timetype;
571 strcpy(dft2->comments, dft1->comments);
572 strcpy(dft2->radiopharmaceutical, dft1->radiopharmaceutical);
573 strcpy(dft2->isotope, dft1->isotope);
574 strcpy(dft2->scanStartTime, dft1->scanStartTime);
575 strcpy(dft2->injectionTime, dft1->injectionTime);
576 dft2->decayCorrected=dft1->decayCorrected;
577 dft2->_type=dft1->_type;
578 return 0;
579}

Referenced by dftAddSpaceForFrames(), dftAllocateWithHeader(), dftAutointerpolate(), dftDivideFrames(), dftDoubleFrames(), dftdup(), dftFillInitialGap(), dftInterpolate(), extrapolate_monoexp(), and plotdata_as_dft().

◆ dftCopymainhdr2()

int dftCopymainhdr2 ( DFT * dft1,
DFT * dft2,
int ow )
extern

Copy main header info from dft1 to dft2. Comments are not copied, because those may contain outdated units and other information.

Returns
Returns <> 0 in case of an error.
Parameters
dft1Pointer to DFT struct from where information is copied
dft2Pointer to DFT struct into which information is copied to
owExisting header field content is overwritten (1) or kept (0)

Definition at line 587 of file dft.c.

594 {
595 if(dft1==NULL || dft2==NULL) return 1;
596 if(ow || (strlen(dft2->studynr)<1 && strcmp(dft2->studynr, ".")==0))
597 strcpy(dft2->studynr, dft1->studynr);
598 if(ow || dftUnitId(dft2->unit)==CUNIT_UNKNOWN)
599 strcpy(dft2->unit, dft1->unit);
600 if(ow || dft2->timeunit==TUNIT_UNKNOWN)
601 dft2->timeunit=dft1->timeunit;
602 dft2->timetype=dft1->timetype;
603 if(ow || strlen(dft2->radiopharmaceutical)<1)
604 strcpy(dft2->radiopharmaceutical, dft1->radiopharmaceutical);
605 if(ow || strlen(dft2->isotope)<1)
606 strcpy(dft2->isotope, dft1->isotope);
607 if(ow || strlen(dft2->scanStartTime)<1)
608 strcpy(dft2->scanStartTime, dft1->scanStartTime);
609 if(ow || strlen(dft2->injectionTime)<1)
610 strcpy(dft2->injectionTime, dft1->injectionTime);
611 if(ow || dft2->decayCorrected==DFT_DECAY_UNKNOWN)
612 dft2->decayCorrected=dft1->decayCorrected;
613 if(ow)
614 dft2->_type=dft1->_type;
615 return 0;
616}
#define DFT_DECAY_UNKNOWN

Referenced by bfIrr2TCM(), and bfRadiowater().

◆ dftCopyvoi()

int dftCopyvoi ( DFT * data,
int from,
int to )
extern

Copy VOI data inside DFT data structure from one place to another.

Parameters
dataPointer to DFT struct
fromTAC index
toTAC index

Definition at line 472 of file dft.c.

479 {
480 int i;
481
482 /* Check that required data exists */
483 if(data==NULL || to>=data->_voidataNr || from>=data->_voidataNr) return 1;
484 if(from==to) return 0;
485
486 /* Copy VOI info */
487 strcpy(data->voi[to].name, data->voi[from].name);
488 strcpy(data->voi[to].voiname, data->voi[from].voiname);
489 strcpy(data->voi[to].hemisphere, data->voi[from].hemisphere);
490 strcpy(data->voi[to].place, data->voi[from].place);
491 data->voi[to].size=data->voi[from].size;
492 data->voi[to].sw=data->voi[from].sw;
493 data->voi[to].sw2=data->voi[from].sw2;
494 data->voi[to].sw3=data->voi[from].sw3;
495 /* Copy VOI curves */
496 for(i=0; i<data->frameNr; i++) {
497 data->voi[to].y[i]=data->voi[from].y[i];
498 data->voi[to].y2[i]=data->voi[from].y2[i];
499 data->voi[to].y3[i]=data->voi[from].y3[i];
500 }
501
502 return 0;
503}

Referenced by dftRead().

◆ dftCopyvoihdr()

int dftCopyvoihdr ( DFT * dft1,
int from,
DFT * dft2,
int to )
extern

Copy voi header info from dft1.voi[from] to dft2.voi[to].

Returns
Returns <> 0 in case of an error.
Parameters
dft1Pointer to DFT struct
fromTAC index
dft2Pointer to DFT struct
toTAC index

Definition at line 623 of file dft.c.

632 {
633 /* Check that required data exists */
634 if(dft1==NULL || dft2==NULL) return 1;
635 if(to>=dft2->_voidataNr || from>=dft1->_voidataNr) return 1;
636
637 /* Copy VOI info */
638 strcpy(dft2->voi[to].name, dft1->voi[from].name);
639 strcpy(dft2->voi[to].voiname, dft1->voi[from].voiname);
640 strcpy(dft2->voi[to].hemisphere, dft1->voi[from].hemisphere);
641 strcpy(dft2->voi[to].place, dft1->voi[from].place);
642 dft2->voi[to].size=dft1->voi[from].size;
643 dft2->voi[to].sw=dft1->voi[from].sw;
644 dft2->voi[to].sw2=dft1->voi[from].sw2;
645 dft2->voi[to].sw3=dft1->voi[from].sw3;
646
647 return 0;
648}

Referenced by dftAdd(), dftAddSpaceForFrames(), dftAllocateWithHeader(), dftAutointerpolate(), dftDivideFrames(), dftDoubleFrames(), dftdup(), dftFillInitialGap(), dftInterpolate(), dftInterpolateInto(), extrapolate_monoexp(), and plotdata_as_dft().

◆ dftDecayCorrection()

int dftDecayCorrection ( DFT * dft,
double hl,
int mode,
int y,
int y2,
int y3,
char * status,
int verbose )
extern

Corrects TAC data for physical decay, or removed the correction.

Weights are not modified.

Returns
Returns 0 if conversion was successful, and <> 0 if failed.
Parameters
dftPointer to existing DFT data; status of decay correction in DFT is not verified, but set in this function; DFT must contain valid sample time unit.
hlHalf-life of isotope in minutes; enter <=0, if correct isotope code is given in DFT
mode0=Remove decay correction; 1=Correct for decay
yApply (1) or do not apply (0) correction to y[] data in DFT
y2Apply (1) or do not apply (0) correction to y2[] data in DFT
y3Apply (1) or do not apply (0) correction to y3[] data in DFT
statusPointer to a string (allocated for at least 64 chars) where error message or other execution status will be written; enter NULL, if not needed
verboseVerbose level; if zero, then nothing is printed to stderr or stdout

Definition at line 16 of file dftdecayc.c.

37 {
38 int ri, fi, isotopeID=-1;
39 double lambda, dc;
40
41 if(verbose>0) printf("dftDecayCorrection(dft, %g, %d, %d, %d, %d, ...)\n",
42 hl, mode, y, y2, y3);
43
44 /* Check the input */
45 if(status!=NULL) strcpy(status, "invalid input");
46 if(dft==NULL) return(1);
47 if(dft->voiNr<1 || dft->frameNr<1) return(1);
48
49 /* Check that DFT contains time unit */
50 if(dft->timeunit!=TUNIT_SEC && dft->timeunit!=TUNIT_MIN &&
51 dft->timeunit!=TUNIT_HOUR)
52 {
53 if(verbose>0) printf("dft->timeunit := %d\n", dft->timeunit);
54 if(status!=NULL) strcpy(status, "sample time unit is not specified");
55 return(2);
56 }
57
58 /* Check and set isotope code and half-life */
59 if(hl>1.0E-10) {
60 /* Try to identify the isotope from given half-life */
61 isotopeID=hlIsotopeFromHalflife(hl);
62 if(isotopeID>=0) {
63 /* If identified, then set the code in DFT */
64 strcpy(dft->isotope, hlIsotopeCode(isotopeID));
65 if(verbose>1) printf(" isotope := %s\n", dft->isotope);
66 } else {
67 /* If not identified, that may just be because isotope is not yet listed
68 in TPC library, but give a warning */
69 fprintf(stderr, "Warning: halflife %g min is not identified.\n", hl);
70 }
71 } else {
72 /* Check that valid isotope code is found in DFT */
73 hl=hlFromIsotope(dft->isotope); if(hl<=0.0) {
74 if(verbose>0) printf("dft->isotope := %s\n", dft->isotope);
75 if(status!=NULL) strcpy(status, "valid isotope is not specified");
76 return(11);
77 }
78 if(verbose>1) printf(" half-life := %g min\n", hl);
79 }
80
81 /*
82 * Calculate the lambda
83 */
84 if(dft->timeunit==TUNIT_SEC) hl*=60.0;
85 else if(dft->timeunit==TUNIT_HOUR) hl/=60.0;
86 lambda=hl2lambda(hl); if(mode==0) lambda=-lambda;
87 if(verbose>1) printf("lambda := %e\n", lambda);
88
89 /*
90 * Decay correction / removal
91 */
92 if(verbose>2) {
93 if(mode!=0) printf("decay correction\n");
94 else printf("removing decay correction\n");
95 }
96 for(fi=0; fi<dft->frameNr; fi++) {
97 /* Calculate decay factor */
98 if(dft->timetype==DFT_TIME_STARTEND) {
99 if(isnan(dft->x1[fi]) || isnan(dft->x2[fi])) continue;
100 dc=hlLambda2factor(lambda, dft->x1[fi], dft->x2[fi]-dft->x1[fi]);
101 } else {
102 if(isnan(dft->x[fi])) continue;
103 dc=hlLambda2factor(lambda, dft->x[fi], 0.0);
104 }
105 if(verbose>4) printf(" %10.4f -> %e\n", dft->x[fi], dc);
106 /* Correct all regions */
107 for(ri=0; ri<dft->voiNr; ri++) {
108 if(y!=0 && !isnan(dft->voi[ri].y[fi])) dft->voi[ri].y[fi]*=dc;
109 if(y2!=0 && !isnan(dft->voi[ri].y2[fi])) dft->voi[ri].y2[fi]*=dc;
110 if(y3!=0 && !isnan(dft->voi[ri].y3[fi])) dft->voi[ri].y3[fi]*=dc;
111 }
112 }
113 if(mode!=0) {
115 if(status!=NULL) strcpy(status, "decay corrected");
116 } else {
118 if(status!=NULL) strcpy(status, "decay correction removed");
119 }
120 return(0);
121}
double hl2lambda(double halflife)
Definition halflife.c:84
char * hlIsotopeCode(int isotope)
Definition halflife.c:36
double hlLambda2factor(double lambda, double frametime, double framedur)
Definition halflife.c:98
double hlFromIsotope(char *isocode)
Definition halflife.c:55
int hlIsotopeFromHalflife(double halflife)
Definition halflife.c:195

◆ dftDelete()

int dftDelete ( DFT * dft,
int voi )
extern

Delete specified TAC (0..voiNr-1) from the DFT structure.

Returns
Returns 0 if ok.
Parameters
dftPointer to DFT struct
voiTAC index

Definition at line 538 of file dft.c.

543 {
544 int ret;
545
546 /* Check that region exists */
547 if(dft==NULL || voi>dft->voiNr-1 || voi<0) return(1);
548 /* If it is the last one, then just decrease the voiNr */
549 if(voi==dft->voiNr-1) {dft->voiNr--; return(0);}
550 /* Otherwise move it to the last position, and then decrease voiNr */
551 ret=dftMovevoi(dft, voi, dft->voiNr-1); if(ret) return(10+ret);
552 dft->voiNr--;
553 return(0);
554}
int dftMovevoi(DFT *dft, int from, int to)
Definition dft.c:508

Referenced by csv2dft_a(), and dftReadinput().

◆ dftDeleteFrameOverlap()

int dftDeleteFrameOverlap ( DFT * dft)
extern

Correct frame start and end times if frames are slightly overlapping or have small gaps in between. Gap before the first time frame is not corrected. Large gap is not corrected and it does not lead to an error.

See also
dftFillInitialGap
Returns
If overlap is considerable (>20%), or another error is encountered, function returns a non-zero value. Otherwise 0 is returned.
Parameters
dftPointer to DFT data. Data must be sorted by increasing time. Time unit does not need to be set. Timetype must be DFT_TIME_STARTEND, i.e. both frame start and end time must be present; if not, then return value is always 0 (passed).

Definition at line 1237 of file dft.c.

1243 {
1244 int fi;
1245 double overlap, overlap_limit=0.0, flen1, flen2;
1246
1247 if(dft==NULL) return(1);
1248 if(dft->timetype!=DFT_TIME_STARTEND) return(0);
1249 for(fi=0; fi<dft->frameNr-1; fi++) {
1250 overlap=dft->x2[fi] - dft->x1[fi+1];
1251 if(overlap==0.0) continue; // no gap or overlap
1252 /* Calculate the frame length of current frame and the next frame */
1253 flen1=dft->x2[fi]-dft->x1[fi]; flen2=dft->x2[fi+1]-dft->x1[fi+1];
1254 if(flen1<0.0 || flen2<0.0) return(1);
1255 /* Set the limit */
1256 if(flen1<flen2) overlap_limit=0.2*flen1; else overlap_limit=0.2*flen2;
1257 /* Check if gap or overlap is too large to be fixed automatically */
1258 if(overlap<-overlap_limit) continue; // gap is too large, then do nothing
1259 if(overlap>overlap_limit) return(2); // overlap is too large: error
1260 /* Correct the small gap/overlap by making frame durations more similar */
1261 if(overlap>0.0) { // overlap
1262 if(flen1>flen2) dft->x2[fi]=dft->x1[fi+1]; else dft->x1[fi+1]=dft->x2[fi];
1263 } else { // gap
1264 if(flen1>flen2) dft->x1[fi+1]=dft->x2[fi]; else dft->x2[fi]=dft->x1[fi+1];
1265 }
1266 }
1267 return(0);
1268}

Referenced by dftReadModelingData().

◆ dftDeleteFrameOverlap_old()

int dftDeleteFrameOverlap_old ( DFT * dft)
extern

Correct frame start and end times if frames are slightly overlapping or have small gaps in between. Large gap is not corrected and it does not lead to an error.

Returns
If overlap is considerable (>1 s), or another error is encountered, function returns a non-zero value. Otherwise 0 is returned.
Parameters
dftPointer to DFT data. Time unit must be set, otherwise no checking is done. Timetype must be DFT_TIME_STARTEND, i.e. both frame start and end time must be present.

Definition at line 1200 of file dft.c.

1204 {
1205 int fi;
1206 double overlap, overlap_limit=1.8, flen1, flen2;
1207
1208 if(dft==NULL) return(1);
1209 if(dft->timetype!=DFT_TIME_STARTEND) return(0);
1210 if(dft->timeunit!=TUNIT_MIN && dft->timeunit!=TUNIT_SEC) return(0);
1211 if(dft->timeunit==TUNIT_MIN) overlap_limit/=60.0;
1212 for(fi=0; fi<dft->frameNr-1; fi++) {
1213 overlap=dft->x2[fi] - dft->x1[fi+1];
1214 if(overlap==0.0) continue; // no gap or overlap
1215 else if(overlap<-overlap_limit) continue; // gap is large, then do nothing
1216 else if(overlap>overlap_limit) return(2); // overlap is large: error
1217 /* Correct the small gap/overlap by making frame durations more similar */
1218 flen1=dft->x2[fi]-dft->x1[fi]; flen2=dft->x2[fi+1]-dft->x1[fi+1];
1219 if(overlap>0.0) { // overlap
1220 if(flen1>flen2) dft->x2[fi]=dft->x1[fi+1]; else dft->x1[fi+1]=dft->x2[fi];
1221 } else { // gap
1222 if(flen1>flen2) dft->x1[fi+1]=dft->x2[fi]; else dft->x2[fi]=dft->x1[fi+1];
1223 }
1224 }
1225 return(0);
1226}

◆ dftdup()

int dftdup ( DFT * dft1,
DFT * dft2 )
extern

Makes a duplicate of DFT structure pointed to by dft1 into dft2.

Returns
Returns 0 if ok.
Parameters
dft1Pointer to DFT struct
dft2Pointer to initiated DFT struct; any existing content of dft2 will be deleted.

Definition at line 655 of file dft.c.

661 {
662 int ri, fi, ret;
663
664 if(dft1==NULL || dft2==NULL) return 1;
665 /* Empty the new data */
666 dftEmpty(dft2);
667 /* Is that it? Is there any contents in dft1? */
668 if(dft1->voiNr==0 && dft1->frameNr==0) {
669 ret=dftCopymainhdr(dft1, dft2); return(ret);
670 }
671 /* Allocate memory for dft2 */
672 ret=dftSetmem(dft2, dft1->frameNr, dft1->voiNr); if(ret) return(ret);
673 dft2->voiNr=dft1->voiNr; dft2->frameNr=dft1->frameNr;
674 /* Copy the contents */
675 ret=dftCopymainhdr(dft1, dft2); if(ret) return(ret);
676 for(ri=0; ri<dft1->voiNr; ri++) {
677 ret=dftCopyvoihdr(dft1, ri, dft2, ri); if(ret) return(ret);
678 for(fi=0; fi<dft1->frameNr; fi++) {
679 dft2->voi[ri].y[fi]=dft1->voi[ri].y[fi];
680 dft2->voi[ri].y2[fi]=dft1->voi[ri].y2[fi];
681 dft2->voi[ri].y3[fi]=dft1->voi[ri].y3[fi];
682 }
683 }
684 for(fi=0; fi<dft1->frameNr; fi++) {
685 dft2->x[fi]=dft1->x[fi];
686 dft2->x1[fi]=dft1->x1[fi]; dft2->x2[fi]=dft1->x2[fi];
687 dft2->w[fi]=dft1->w[fi];
688 }
689 dft2->isweight=dft1->isweight;
690 return(0);
691}

Referenced by dftAddSpaceForFrames(), dftFillInitialGap(), dftReadinput(), and imgReadModelingData().

◆ dftEmpty()

void dftEmpty ( DFT * data)
extern

Free memory allocated for DFT. All data is cleared.

Parameters
dataPointer to initiated DFT struct data

Definition at line 20 of file dft.c.

23 {
24 if(data==NULL) return;
25 if(data->_voidataNr>0) free((char*)(data->voi));
26 if(data->_dataSize>0) free((char*)(data->_data));
27 data->_dataSize=data->_voidataNr=0;
28 data->frameNr=data->voiNr=0;
29 data->studynr[0]=data->comments[0]=data->unit[0]=(char)0;
30 data->radiopharmaceutical[0]=data->isotope[0]=data->decayCorrected=(char)0;
31 data->scanStartTime[0]=data->injectionTime[0]=(char)0;
32 data->timeunit=data->timetype=0;
33}

Referenced by bfIrr2TCM(), bfRadiowater(), clusterTACs(), cptReadOne(), csv2dft_a(), csv2dft_b(), csv2dft_linkset(), csv2dft_mat(), dftAddnullframe(), dftAddSpaceForFrames(), dftAllocateWithHeader(), dftAutointerpolate(), dftDivideFrames(), dftDoubleFrames(), dftdup(), dftFillInitialGap(), dftInterpolate(), dftInterpolateForIMG(), dftInterpolateInto(), dftMeanTAC(), dftRead(), dftReadinput(), dftReadModelingData(), dftReadReference(), dftSetmem(), extrapolate_monoexp(), idwcRead(), ifRead(), img_k1_using_ki(), img_logan(), img_patlak(), imgMaskPixelTACs(), imgReadModelingData(), noiseSD4SimulationFromDFT(), plotdata_as_dft(), roikbqRead(), and simMyocDiameterCurve().

◆ dftFillInitialGap()

int dftFillInitialGap ( DFT * dft)
extern

Check if there is a time gap between time zero and first sample time; if gap does not exist, then nothing is done; if gap exists, then gap is filled with an extra frame.

See also
dftDeleteFrameOverlap
Returns
Returns zero if successful, otherwise <>0.
Parameters
dftPointer to DFT struct

Definition at line 1385 of file dft.c.

1388 {
1389 DFT temp;
1390 int ret, ri, fi;
1391
1392 /* Check input */
1393 if(dft==NULL) return 1;
1394 if(dft->frameNr<1 || dft->voiNr<1) return 0;
1395
1396 /* Is there an initial gap? If not then we can finish here */
1397 if(dft->timetype==DFT_TIME_STARTEND) {
1398 if(dft->x1[0]<=0.0) return 0;
1399 } else {
1400 if(dft->x[0]<=0.0) return 0;
1401 }
1402
1403 /* Make a temporary storage of the data */
1404 dftInit(&temp); ret=dftdup(dft, &temp); if(ret!=0) return 10+ret;
1405 /* Delete and reallocate the original data pointer */
1406 dftEmpty(dft); ret=dftSetmem(dft, temp.frameNr+1, temp.voiNr);
1407 if(ret!=0) {
1408 dftdup(&temp, dft); dftEmpty(&temp);
1409 return 20+ret;
1410 }
1411 /* Copy data back, leaving first frame empty */
1412 ret=dftCopymainhdr(&temp, dft);
1413 if(ret!=0) {
1414 dftdup(&temp, dft); dftEmpty(&temp);
1415 return 30+ret;
1416 }
1417 dft->voiNr=temp.voiNr; dft->frameNr=1+temp.frameNr;
1418 dft->isweight=temp.isweight;
1419 strcpy(dft->comments, temp.comments);
1420 for(ri=0; ri<temp.voiNr; ri++) {
1421 ret=dftCopyvoihdr(&temp, ri, dft, ri);
1422 if(ret!=0) {
1423 dftdup(&temp, dft); dftEmpty(&temp);
1424 return 40+ret;
1425 }
1426 for(fi=0; fi<temp.frameNr; fi++) {
1427 dft->voi[ri].y[fi+1]=temp.voi[ri].y[fi];
1428 dft->voi[ri].y2[fi+1]=temp.voi[ri].y2[fi];
1429 dft->voi[ri].y3[fi+1]=temp.voi[ri].y3[fi];
1430 }
1431 /* Fill in the first frame */
1432 dft->voi[ri].y[0]=0.0;
1433 dft->voi[ri].y2[0]=0.0;
1434 dft->voi[ri].y3[0]=0.0;
1435 }
1436 for(fi=0; fi<temp.frameNr; fi++) {
1437 dft->x1[fi+1]=temp.x1[fi];
1438 dft->x2[fi+1]=temp.x2[fi];
1439 dft->x[fi+1]=temp.x[fi];
1440 dft->w[fi+1]=temp.w[fi];
1441 }
1442 dftEmpty(&temp);
1443
1444 /* Fill the first frame */
1445 dft->w[0]=1.0;
1446 if(dft->timetype==DFT_TIME_STARTEND) {
1447 dft->x1[0]=0.0;
1448 dft->x2[0]=dft->x1[1];
1449 dft->x[0]=0.5*(dft->x1[0]+dft->x2[0]);
1450 } else {
1451 dft->x1[0]=0.0;
1452 dft->x2[0]=dft->x1[1];
1453 dft->x[0]=0.0;
1454 }
1455
1456 return 0;
1457}

Referenced by dftFixPeak().

◆ dftFormat()

int dftFormat ( char * fname)
extern

Determine the type of DFT file. This will replace dftType().

Note that only some of formats are currently identified, and identification does not mean that dftRead() supports the format.

Returns
Returns DFT_FORMAT_UNKNOWN or other format id defined in dft.h.
See also
dftRead, dftWrite
Parameters
fnamePointer to file name; this string is not modified.

Definition at line 422 of file dftio.c.

425 {
426 if(CSV_TEST>0) {printf("%s('%s')\n", __func__, fname); fflush(stdout);}
427
428 FILE *fp;
429 char tmp[256];
430 int c;
431
432
433 /* Open file */
434 fp=fopen(fname, "r"); if(fp==NULL) return DFT_FORMAT_UNKNOWN;
435
436 /* Binary data? */
437 while((c=fgetc(fp))!=EOF) {
438 if(isalnum(c) || isspace(c) || isgraph(c)) continue;
439 if(c>=160) continue;
440 if(CSV_TEST>1) {printf(" invalid character %d\n", c); fflush(stdout);}
441 fclose(fp); return DFT_FORMAT_UNKNOWN;
442 }
443 rewind(fp);
444
445 /* File with one title line without comment mark? */
446 while(fgets(tmp, 10, fp) != NULL) {if(strlen(tmp)) break;}
447 if(strncasecmp(tmp, "Time[", 5)==0) {fclose(fp); return DFT_FORMAT_PMOD;}
448 if(strncasecmp(tmp, "Start[", 6)==0) {fclose(fp); return DFT_FORMAT_PMOD;}
449 if(strcasestr(tmp, "Start\tEnd\t")!=NULL) {fclose(fp); return DFT_FORMAT_PMOD;}
450 rewind(fp);
451
452 /* Read the first line that is not empty or comment line */
453 while(fgets(tmp, 32, fp) != NULL) {
454 if(strlen(tmp)==0) continue;
455 if(tmp[0]=='#') continue;
456 if(strncmp(tmp, "//", 2)==0) continue;
457 break;
458 }
459 rewind(fp);
460
461 /* Check for identification strings */
462 if(strncasecmp(tmp, "DFT", 3)==0) {fclose(fp); return DFT_FORMAT_STANDARD;}
463 else if(strncasecmp(tmp, "FIT1", 3)==0) {fclose(fp); return DFT_FORMAT_FIT;}
464 else if(strncasecmp(tmp, "cpt", 3)==0) {fclose(fp); return DFT_FORMAT_NCI;}
465
466 /* Identify certain file name extensions */
467 if(fncasematch(fname, "*.idwc")==1 || fncasematch(fname, "*.idw")==1) {
468 fclose(fp); return DFT_FORMAT_IDWC;}
469 if(fncasematch(fname, "*.if")==1) {fclose(fp); return DFT_FORMAT_IF;}
470
471 fclose(fp);
472
473 /* Try to read as CSV */
474 CSV csv; csvInit(&csv);
475 if(csvRead(&csv, fname)==0) {
476 int format=DFT_FORMAT_UNKNOWN;
477 if(csv.separator==';') format=DFT_FORMAT_CSV_INT;
478 else if(csv.separator==',') format=DFT_FORMAT_CSV_UK;
479 else if(csv.separator=='\t') {
480 int i, commas=0, dots=0;
481 for(i=0; i<csv.nr; i++) {
482 if(strchr(csv.c[i].content, ',')!=NULL) commas++;
483 else if(strchr(csv.c[i].content, '.')!=NULL) dots++;
484 }
485 if(dots>commas) format=DFT_FORMAT_CSV_UK; else format=DFT_FORMAT_CSV_INT;
486 }
487 if(CSV_TEST>1) printf(" format=%d\n", format);
488 csvEmpty(&csv);
489 if(format!=DFT_FORMAT_UNKNOWN) return(format);
490 }
491
492 return DFT_FORMAT_PLAIN;
493}
void csvInit(CSV *csv)
Definition csv.c:13
void csvEmpty(CSV *csv)
Definition csv.c:24
int csvRead(CSV *csv, char *fname)
Definition csv.c:42
int fncasematch(const char *fname, const char *key)
Definition filename.c:100
#define DFT_FORMAT_PMOD
#define DFT_FORMAT_CSV_INT
#define DFT_FORMAT_CSV_UK
#define DFT_FORMAT_IF
#define DFT_FORMAT_FIT
#define DFT_FORMAT_IDWC
#define DFT_FORMAT_NCI
#define DFT_FORMAT_UNKNOWN
char * strcasestr(const char *haystack, const char *needle)
Definition strext.c:279

Referenced by dftRead(), dftReadinput(), and dftReadReference().

◆ dftFrametimes()

void dftFrametimes ( DFT * data)
extern

Calculate frame mid or start and end times. Timetype is not changed.

Parameters
dataPointer to DFT struct

Definition at line 340 of file dft.c.

343 {
344 int i, j;
345 double f, fs;
346
347 if(data==NULL) return;
348 /* If data is told to contain frame start and end times, then check
349 that those really are there, or set to middle times, if necessary */
350 if(data->timetype==DFT_TIME_STARTEND) {
351 for(i=j=0; i<data->frameNr; i++) {
352 fs=data->x2[i]-data->x1[i]; if(fs>1.0E-10) {j=1; break;}
353 }
354 if(j==0) {
355 for(i=0; i<data->frameNr; i++) data->x[i]=0.5*(data->x1[i]+data->x2[i]);
357 }
358 }
359
360 /* Decide what to do, and get it done */
361 if(data->timetype==DFT_TIME_MIDDLE) {
362 /* frame start and end times from mid times */
363 /* Easy, if only one frame */
364 if(data->frameNr==1) {
365 if(data->x[0]<=0.0) {data->x1[0]=data->x[0]; data->x2[0]=0.0;}
366 else {data->x1[0]=0.0; data->x2[0]=2.0*data->x[0];}
367 return;
368 }
369 /* Fill start and end times with -999 */
370 for(i=0; i<data->frameNr; i++) data->x1[i]=data->x2[i]=-999.;
371 /* Search for sequences of nearly same frame lengths */
372 for(i=1; i<data->frameNr-1; i++) {
373 f=data->x[i]-data->x[i-1]; fs=data->x[i+1]-data->x[i];
374 if((f+fs)<=0.0 && fabs(fs-f)>=2.0) continue;
375 if((f+fs)>0.0 && (2.0*fabs(fs-f)/(f+fs))>0.1) continue;
376 //if(fabs(f-fs)>=2.0) continue;
377 f=(f+fs)/2.0;
378 data->x1[i-1]=data->x[i-1]-f/2.0; data->x2[i-1]=data->x[i-1]+f/2.0;
379 data->x1[i]=data->x[i]-f/2.0; data->x2[i]=data->x[i]+f/2.0;
380 data->x1[i+1]=data->x[i+1]-f/2.0; data->x2[i+1]=data->x[i+1]+f/2.0;
381 /* Check for negatives */
382 for(j=i-1; j<i+2; j++) {
383 if(data->x1[j]<0.0) data->x1[j]=0.0;
384 if(data->x2[j]<0.0) data->x2[j]=0.0;
385 }
386 }
387 /* If out-of-sequence frames were left out, fill those to the nearest one */
388 i=0; /* first frame */
389 if(data->x1[i]<0) {
390 if(data->x1[i+1]>0) data->x2[i]=data->x1[i+1];
391 else data->x2[i]=(data->x[i+1]+data->x[i])/2.0;
392 data->x1[i]=2.0*data->x[i]-data->x2[i];
393 }
394 i=data->frameNr-1; /* last frame */
395 if(data->x1[i]<0) {
396 if(data->x2[i-1]>0) data->x1[i]=data->x2[i-1];
397 else data->x1[i]=(data->x[i-1]+data->x[i])/2.0;
398 data->x2[i]=2.0*data->x[i]-data->x1[i];
399 }
400 /* other frames */
401 for(i=1; i<data->frameNr-1; i++) if(data->x1[i]<0.0) {
402 /* which frame is nearest? */
403 if(data->x[i]-data->x[i-1] <= data->x[i+1]-data->x[i]) { /* last one */
404 if(data->x2[i-1]>0) data->x1[i]=data->x2[i-1];
405 else data->x1[i]=(data->x[i-1]+data->x[i])/2.0;
406 data->x2[i]=2.*data->x[i]-data->x1[i];
407 } else { /* next one */
408 if(data->x1[i+1]>0) data->x2[i]=data->x1[i+1];
409 else data->x2[i]=(data->x[i+1]+data->x[i])/2.0;
410 data->x1[i]=2.0*data->x[i]-data->x2[i];
411 }
412 }
413 /* Check for negatives */
414 for(i=0; i<data->frameNr; i++) {
415 if(data->x1[i]<0.0) data->x1[i]=0.0;
416 if(data->x2[i]<0.0) data->x2[i]=data->x1[i];
417 }
418 /* Check for overlapping and very small gaps */
419 for(i=1; i<data->frameNr; i++) {
420 f=data->x1[i]-data->x2[i-1];
421 if(f<0.0) {
422 if(data->x[i]>data->x2[i-1]) data->x1[i]=data->x2[i-1];
423 else if(data->x[i-1]<data->x1[i]) data->x2[i-1]=data->x1[i];
424 else data->x1[i]=data->x2[i-1]=(data->x[i]+data->x[i-1])/2.0;
425 } else if(f>0.0 && f<1.0) {
426 data->x1[i]=data->x2[i-1]=(data->x1[i]+data->x2[i-1])/2.0;
427 }
428 }
429 } else if(data->timetype==DFT_TIME_STARTEND) {
430 /* mid times from frame start and end times */
431 for(i=0; i<data->frameNr; i++) data->x[i]=0.5*(data->x1[i]+data->x2[i]);
432 } else if(data->timetype==DFT_TIME_START) {
433 /* frame start times -> end and mid times */
434 for(i=0; i<data->frameNr-1; i++) data->x2[i]=data->x1[i+1];
435 data->x2[data->frameNr-1]=data->x1[data->frameNr-1]+
436 (data->x2[data->frameNr-2]-data->x1[data->frameNr-2]);
437 for(i=0; i<data->frameNr; i++) data->x[i]=0.5*(data->x1[i]+data->x2[i]);
438 } else if(data->timetype==DFT_TIME_END) {
439 /* frame end times -> start and mid times */
440 data->x1[0]=0.0;
441 for(i=1; i<data->frameNr; i++) data->x1[i]=data->x2[i-1];
442 for(i=0; i<data->frameNr; i++) data->x[i]=0.5*(data->x1[i]+data->x2[i]);
443 }
444
445 return;
446}
#define DFT_TIME_END
#define DFT_TIME_START

Referenced by csv2dft_a(), dftRead(), and idwcRead().

◆ dftGetPmodTitle()

int dftGetPmodTitle ( DFT * dft,
char * title_line )
extern

Read single title line from PMOD files and set DFT fields accordingly. Alternatively, reads the number of regions in PMOD title line.

Returns
Returns 0 if title contents were successfully saved in DFT struct; if pointer to DFT struct is not specified, then the number of regions is returned.
Parameters
dftPointer to allocated DFT struct where information will be written; Enter NULL, if only the nr of regions is to be returned.
title_linePointer to string containing the title line; string is not modified

Definition at line 1109 of file dftio.c.

1115 {
1116 //printf("dftGetPmodTitle()\n");
1117 //printf(" '%s'\n", title_line);
1118 //if(dft==NULL) printf(" dft=NULL\n");
1119
1120 int ti=0, ri, ret, tabs=0, timetype=DFT_TIME_MIDDLE;
1121 char *cptr, *cptr2, rname[MAX_REGIONNAME_LEN+1];
1122 char unit[MAX_UNITS_LEN+1], separs[8];
1123
1124 /* Check the input */
1125 if(strlen(title_line)<1) return 1;
1126
1127 /* Count the nr of tabs in title line */
1128 cptr=title_line; while(*cptr) {if(*cptr=='\t') tabs++; cptr++;}
1129 /* If tabs found, then do not use space as field separator */
1130 if(tabs>0) strcpy(separs, "\t\n\r"); else strcpy(separs, " \t\n\r");
1131
1132 /* Make a copy of title line */
1133 char ntl[1+strlen(title_line)], *tl;
1134 strcpy(ntl, title_line); tl=ntl;
1135 cptr=strtok(tl, separs); if(cptr==NULL) return 2;
1136 ti=ri=0;
1137 while(cptr!=NULL) {
1138 if(ti==0) {
1139 if(strlen(cptr)>6 && strncasecmp(cptr, "Time[", 5)==0) {
1140 strncpy(unit, cptr+5, MAX_UNITS_LEN); unit[MAX_UNITS_LEN]=(char)0;
1141 cptr2=strchr(unit, ']'); if(cptr2!=NULL) *cptr2=(char)0;
1142 if(dft!=NULL) dft->timeunit=petTunitId(unit);
1143 timetype=DFT_TIME_MIDDLE;
1144 } else if(strlen(cptr)>6 && strncasecmp(cptr, "start[", 6)==0) {
1145 strncpy(unit, cptr+6, MAX_UNITS_LEN); unit[MAX_UNITS_LEN]=(char)0;
1146 cptr2=strchr(unit, ']'); if(cptr2!=NULL) *cptr2=(char)0;
1147 if(dft!=NULL) dft->timeunit=petTunitId(unit);
1148 timetype=DFT_TIME_STARTEND;
1149 }
1150 } else if(ti==1 && timetype==DFT_TIME_STARTEND) {
1151 if(strlen(cptr)>5 && strncasecmp(cptr, "end[", 4)==0) {
1152 strncpy(unit, cptr+4, MAX_UNITS_LEN); unit[MAX_UNITS_LEN]=(char)0;
1153 cptr2=strchr(unit, ']'); if(cptr2!=NULL) *cptr2=(char)0;
1154 ret=petCunitId(unit);
1155 if(ret!=CUNIT_UNKNOWN && dft!=NULL) strcpy(dft->unit, petCunit(ret));
1156 }
1157 } else {
1158 // get tac name
1159 strncpy(rname, cptr, MAX_REGIONNAME_LEN);
1160 rname[MAX_REGIONNAME_LEN]=(char)0;
1161 cptr2=strchr(rname, '['); if(cptr2!=NULL) *cptr2=(char)0;
1162 while((cptr2=strchr(rname, '_'))!=NULL) *cptr2=' ';
1163 if(dft!=NULL && ri<dft->_voidataNr) strcpy(dft->voi[ri].name, rname);
1164 // get unit
1165 cptr2=strchr(cptr, '[');
1166 if(cptr2!=NULL) {
1167 strncpy(unit, cptr2+1, MAX_UNITS_LEN); unit[MAX_UNITS_LEN]=(char)0;
1168 cptr2=strchr(unit, ']'); if(cptr2!=NULL) *cptr2=(char)0;
1169 ret=petCunitId(unit);
1170 if(ret!=CUNIT_UNKNOWN && dft!=NULL) strcpy(dft->unit, petCunit(ret));
1171 }
1172 ri++;
1173 }
1174 ti++;
1175 cptr=strtok(NULL, separs);
1176 }
1177 if(dft==NULL) {
1178 return(ri);
1179 }
1180
1181 dft->timetype=timetype;
1182
1183 //for(int i=0; i<dft->_voidataNr; i++) printf(" '%s'\n", dft->voi[i].name);
1184
1185 /* Split ROI names */
1186 ti=ri;
1187 for(ri=0; ri<ti; ri++)
1188 rnameSplit(dft->voi[ri].name, dft->voi[ri].voiname,
1189 dft->voi[ri].hemisphere, dft->voi[ri].place, MAX_REGIONSUBNAME_LEN);
1190
1191 return(0);
1192}

Referenced by dftRead().

◆ dftInit()

void dftInit ( DFT * data)
extern

Initiate DFT structure. This should be called once before use.

Parameters
dataPointer to initiated DFT struct data

Definition at line 38 of file dft.c.

41 {
42 if(data==NULL) return;
43 memset(data, 0, sizeof(DFT));
44 data->_voidataNr=data->_dataSize=0;
45 data->frameNr=data->voiNr=0;
46 data->studynr[0]=data->comments[0]=data->unit[0]=(char)0;
47 data->radiopharmaceutical[0]=data->isotope[0]=data->decayCorrected=(char)0;
48 data->scanStartTime[0]=data->injectionTime[0]=(char)0;
49 data->timeunit=data->timetype=data->isweight=0;
50}

Referenced by dftAddnullframe(), dftAddSpaceForFrames(), dftFillInitialGap(), dftReadinput(), dftReadModelingData(), dftReadReference(), img_k1_using_ki(), img_logan(), img_patlak(), imgReadModelingData(), noiseSD4SimulationFromDFT(), and plotdata_as_dft().

◆ dftMaxY()

int dftMaxY ( DFT * dft,
double t1,
double t2,
double * miny,
double * maxy )
extern

Search the min and max values of DFT TAC data inside specified time range.

Data may contain NA's.

Returns
Returns 0 if successful.
Parameters
dftPointer to the DFT TAC data to search
t1Start time
t2End time
minyPointer to min Y; set to NULL if not needed
maxyPointer to max Y; set to NULL if not needed

Definition at line 1090 of file dft.c.

1101 {
1102 int ri, fi;
1103 double x1, x2, y1, y2;
1104
1105 if(dft==NULL) return(1);
1106 y1=y2=nan("");
1107 for(fi=0; fi<dft->frameNr; fi++) {
1108 if(dft->timetype==DFT_TIME_STARTEND) {
1109 if(!isfinite(dft->x1[fi]) || !isfinite(dft->x2[fi])) continue;
1110 x1=dft->x1[fi]; x2=dft->x2[fi];
1111 } else {
1112 if(!isfinite(dft->x[fi])) continue;
1113 x1=x2=dft->x[fi];
1114 }
1115 if(x2<t1 || x1>t2) continue; // outside time range
1116 for(ri=0; ri<dft->voiNr; ri++) if(!isnan(dft->voi[ri].y[fi])) {
1117 if(isnan(y1) || y1>dft->voi[ri].y[fi]) y1=dft->voi[ri].y[fi];
1118 if(isnan(y2) || y2<dft->voi[ri].y[fi]) y2=dft->voi[ri].y[fi];
1119 }
1120 }
1121 if(miny!=NULL) {if(isnan(y1)) return(5); else *miny=y1;}
1122 if(maxy!=NULL) {if(isnan(y2)) return(6); else *maxy=y2;}
1123 return(0);
1124}

Referenced by plot_fitrange_svg().

◆ dftMeanTAC()

int dftMeanTAC ( DFT * dft,
DFT * mean )
extern

Calculates mean TAC of all TACs in DFT struct. Mean is NOT weighted by VOI sizes. Also SD and CV for each sample time are calculated.

Returns
Returns 0 if successful.
Parameters
dftPointer to TAC data from which mean TAC is calculated; missing values (NaN) are allowed
meanPointer to initialized or pre-allocated DFT struct in where mean, SD, and CV will be written in y, y2, and y3, respectively.

Definition at line 1580 of file dft.c.

1587 {
1588 int ret, fi, ri, n;
1589 double sum, ssum;
1590
1591 if(dft==NULL || mean==NULL) return(1);
1592 if(dft->voiNr<1 || dft->frameNr<1) return(2);
1593
1594 /* Allocate memory for mean data, if necessary */
1595 if(mean->voiNr<1 || mean->frameNr!=dft->frameNr) {
1596 dftEmpty(mean); ret=dftAllocateWithHeader(mean, dft->frameNr, 1, dft);
1597 if(ret!=0) return(100+ret);
1598 }
1599 strcpy(mean->voi[0].name, "Mean");
1600 strcpy(mean->voi[0].voiname, mean->voi[0].name);
1601
1602 /* Calculate the mean TAC */
1603 ret=0;
1604 for(fi=0; fi<dft->frameNr; fi++) {
1605 sum=ssum=0.0; n=0;
1606 for(ri=0; ri<dft->voiNr; ri++) if(!isnan(dft->voi[ri].y[fi])) {
1607 sum+=dft->voi[ri].y[fi];
1608 ssum+=dft->voi[ri].y[fi]*dft->voi[ri].y[fi];
1609 n++;
1610 }
1611 if(n==0) {
1612 mean->voi[0].y[fi]=mean->voi[0].y2[fi]=mean->voi[0].y3[fi]=nan("");
1613 } else {
1614 mean->voi[0].y[fi]=sum/(double)n;
1615 if(n==1) {
1616 mean->voi[0].y2[fi]=mean->voi[0].y3[fi]=0.0;
1617 } else {
1618 mean->voi[0].y2[fi]=sqrt((ssum-sum*sum/(double)n)/(double)(n-1));
1619 if(fabs(mean->voi[0].y[fi])>1.0E-25)
1620 mean->voi[0].y3[fi]=fabs(mean->voi[0].y2[fi]/mean->voi[0].y[fi]);
1621 else
1622 mean->voi[0].y3[fi]=0.0;
1623 }
1624 }
1625 if(n>0) ret++;
1626 }
1627 /* Check that at least half of frames contained acceptable data */
1628 if(2*ret<dft->frameNr) {dftEmpty(mean); return(10);}
1629
1630 return(0);
1631}
int dftAllocateWithHeader(DFT *dft, int frameNr, int voiNr, DFT *dft_from)
Definition dft.c:702
int mean(double *x, double *y, int nr, double *xmean, double *xsd, double *ymean, double *ysd)
Definition pearson.c:341

Referenced by noiseSD4SimulationFromDFT().

◆ dftMin2sec()

void dftMin2sec ( DFT * dft)
extern

Change time unit from min to sec, without checking original unit.

Definition at line 145 of file dftunit.c.

146{
147 int i;
148
149 for(i=0; i<dft->frameNr; i++) {
150 if(!isnan(dft->x[i])) dft->x[i]*=60.;
151 if(!isnan(dft->x1[i])) dft->x1[i]*=60.;
152 if(!isnan(dft->x1[i])) dft->x2[i]*=60.;
153 }
154 dft->timeunit=TUNIT_SEC;
155}

Referenced by copy_times_from_img_to_dft(), cptWrite(), and dftTimeunitConversion().

◆ dftMinMax()

int dftMinMax ( DFT * dft,
double * minx,
double * maxx,
double * miny,
double * maxy )
extern

Search the min and max values of DFT TAC data. Data may contain NA's.

Note that minx and maxx are the smallest and highest x values in data, not the x values at y minimum and maximum; use dftMinMaxTAC() for that.

See also
dftMinMaxTAC, dftRobustMinMaxTAC
Returns
Returns 0 if successful.
Parameters
dftPointer to the DFT TAC data to search
minxPointer to min X; set to NULL if not needed
maxxPointer to max X; set to NULL if not needed
minyPointer to min Y; set to NULL if not needed
maxyPointer to max Y; set to NULL if not needed

Definition at line 974 of file dft.c.

985 {
986 int ri, fi, n;
987 double x1, x2, y1, y2;
988
989 if(dft==NULL) return(1);
990 x1=x2=y1=y2=nan("");
991 for(fi=0; fi<dft->frameNr; fi++) {
992 for(ri=0, n=0; ri<dft->voiNr; ri++) if(!isnan(dft->voi[ri].y[fi])) {
993 if(isnan(y1) || y1>dft->voi[ri].y[fi]) y1=dft->voi[ri].y[fi];
994 if(isnan(y2) || y2<dft->voi[ri].y[fi]) y2=dft->voi[ri].y[fi];
995 n++;
996 }
997 if(n==0) continue; // no true y values, thus do not use x either
998 if(dft->timetype==DFT_TIME_STARTEND) {
999 if(!isnan(dft->x1[fi])) {
1000 if(isnan(x1) || x1>dft->x1[fi]) x1=dft->x1[fi];
1001 }
1002 if(!isnan(dft->x2[fi])) {
1003 if(isnan(x2) || x2<dft->x2[fi]) x2=dft->x2[fi];
1004 }
1005 } else if(!isnan(dft->x[fi])) {
1006 if(isnan(x1) || x1>dft->x[fi]) x1=dft->x[fi];
1007 if(isnan(x2) || x2<dft->x[fi]) x2=dft->x[fi];
1008 }
1009 }
1010 if(minx!=NULL) {if(isnan(x1)) return(3); else *minx=x1;}
1011 if(maxx!=NULL) {if(isnan(x2)) return(4); else *maxx=x2;}
1012 if(miny!=NULL) {if(isnan(y1)) return(5); else *miny=y1;}
1013 if(maxy!=NULL) {if(isnan(y2)) return(6); else *maxy=y2;}
1014 return(0);
1015}

Referenced by plot_fit_svg(), and plot_fitrange_svg().

◆ dftMinMaxTAC()

int dftMinMaxTAC ( DFT * dft,
int tacindex,
double * minx,
double * maxx,
double * miny,
double * maxy,
int * mini,
int * maxi,
int * mins,
int * maxs )
extern

Search the min and max values of DFT TAC data. Data may contain NA's. This is not a replacement of dftMinMax() which is needed e.g. in plotting functions.

See also
dftMinMax, dftRobustMinMaxTAC
Returns
Returns 0 if successful.
Parameters
dftPointer to the DFT TAC data to search
tacindexIndex of the only TAC which is searched for min and max; <0 if all
minxPointer to X at TAC min; set to NULL if not needed
maxxPointer to X at TAC max; set to NULL if not needed
minyPointer to min Y; set to NULL if not needed
maxyPointer to max Y; set to NULL if not needed
miniIndex of min TAC; set to NULL if not needed
maxiIndex of max TAC; set to NULL if not needed
minsIndex of min sample; set to NULL if not needed
maxsIndex of max sample; set to NULL if not needed

Definition at line 1024 of file dft.c.

1045 {
1046 int ri, fi, i1, i2, s1, s2;
1047 double x, x1, x2, y1, y2;
1048
1049 if(dft==NULL) return(1);
1050 if(tacindex>=dft->voiNr) return(2);
1051 if(dft->voiNr<1 || dft->frameNr<1) return(3);
1052
1053 x1=x2=y1=y2=nan(""); i1=i2=s1=s2=0;
1054 for(fi=0; fi<dft->frameNr; fi++) {
1055 if(dft->timetype==DFT_TIME_STARTEND) {
1056 if(isnan(dft->x1[fi])) continue;
1057 if(isnan(dft->x2[fi])) continue;
1058 x=0.5*(dft->x1[fi]+dft->x2[fi]);
1059 } else {
1060 if(isnan(dft->x[fi])) continue;
1061 x=dft->x[fi];
1062 }
1063 for(ri=0; ri<dft->voiNr; ri++) if(!isnan(dft->voi[ri].y[fi])) {
1064 if(tacindex>=0 && ri!=tacindex) continue;
1065 if(isnan(y1) || y1>dft->voi[ri].y[fi]) {
1066 y1=dft->voi[ri].y[fi]; i1=ri; x1=x; s1=fi;}
1067 if(isnan(y2) || y2<dft->voi[ri].y[fi]) {
1068 y2=dft->voi[ri].y[fi]; i2=ri; x2=x; s2=fi;}
1069 }
1070 }
1071 if(minx!=NULL) {if(isnan(x1)) return(11); else *minx=x1;}
1072 if(maxx!=NULL) {if(isnan(x2)) return(12); else *maxx=x2;}
1073 if(miny!=NULL) {if(isnan(y1)) return(13); else *miny=y1;}
1074 if(maxy!=NULL) {if(isnan(y2)) return(14); else *maxy=y2;}
1075 if(mini!=NULL) {if(isnan(y1)) return(13); else *mini=i1;}
1076 if(maxi!=NULL) {if(isnan(y2)) return(14); else *maxi=i2;}
1077 if(mins!=NULL) {if(isnan(y1)) return(13); else *mins=s1;}
1078 if(maxs!=NULL) {if(isnan(y2)) return(14); else *maxs=s2;}
1079 return(0);
1080}

Referenced by dftFixPeak(), and dftVerifyPeak().

◆ dftMovevoi()

int dftMovevoi ( DFT * dft,
int from,
int to )
extern

Move VOI in DFT structure from one position to another.

Parameters
dftPointer to DFT struct
fromTAC index
toTAC index

Definition at line 508 of file dft.c.

515 {
516 int ri;
517 size_t voisize;
518 Voi voi;
519
520 if(dft==NULL || from<0 || to<0) return(1);
521 if(from+1>dft->_voidataNr || to+1>dft->_voidataNr) return(2);
522 if(from==to) return(0);
523 voisize=sizeof(Voi);
524 memcpy(&voi, dft->voi+from, voisize);
525 if(from>to) for(ri=from; ri>to; ri--)
526 memcpy(dft->voi+ri, dft->voi+(ri-1), voisize);
527 else for(ri=from; ri<to; ri++)
528 memcpy(dft->voi+ri, dft->voi+(ri+1), voisize);
529 memcpy(dft->voi+ri, &voi, voisize);
530 return(0);
531}

Referenced by dftDelete(), and dftReadinput().

◆ dftNAfill()

int dftNAfill ( DFT * dft)
extern

Replace NA's in basic DFT data with interpolated values. If extrapolation is necessary, then the values (0,0) and (Infinity,last measured) are assumed.

Returns
Returns 0, if NA's could be filled with sensible values.
Parameters
dftPointer to DFT struct

Definition at line 930 of file dft.c.

933 {
934 int ri, fi, fj;
935 double x1, x2, y1, y2, x, y;
936
937 if(dft==NULL || dft->voiNr<1 || dft->frameNr<1) return(1);
938 for(ri=0; ri<dft->voiNr; ri++) for(fi=0; fi<dft->frameNr; fi++) {
939 if(isnan(dft->x[fi])) return(2);
940 if(isnan(dft->voi[ri].y[fi])) {
941 /* NA's before zero time are always replaced with 0 */
942 if(dft->x[fi]<0.0) {dft->voi[ri].y[fi]=0.0; continue;}
943 x=dft->x[fi];
944 /* Get the previous data that is not NA */
945 for(x1=y1=nan(""), fj=fi-1; fj>=0; fj--) if(!isnan(dft->voi[ri].y[fj])) {
946 x1=dft->x[fj]; y1=dft->voi[ri].y[fj]; break;
947 }
948 if(isnan(x1) || isnan(y1)) x1=y1=0.0;
949 /* Get the following data that is not NA */
950 for(x2=y2=nan(""), fj=fi+1; fj<dft->frameNr; fj++) if(!isnan(dft->voi[ri].y[fj])) {
951 x2=dft->x[fj]; y2=dft->voi[ri].y[fj]; break;
952 }
953 if(isnan(x2) || isnan(y2)) for(fj=fi-1; fj>=0; fj--) if(!isnan(dft->voi[ri].y[fj])) {
954 x2=dft->x[fj]; y2=dft->voi[ri].y[fj]; break;
955 }
956 if(isnan(x2) || isnan(y2)) return(2);
957 /* Calculate new value */
958 if(x2==x1) y=0.5*(y1+y2); else y=y2-(x2-x)*(y2-y1)/(x2-x1);
959 dft->voi[ri].y[fi]=y;
960 }
961 }
962 return(0);
963}

◆ dftOverflow()

int dftOverflow ( DFT * data)
extern

Check for overflows in data structure. Returns 0, if ok.

Parameters
dataPointer to DFT struct

Definition at line 451 of file dft.c.

454 {
455 int i;
456
457 if(data==NULL || data->frameNr<1 || data->voiNr<1) return 0;
458 if(data->x[data->frameNr]!=0.0) return 1;
459 if(data->x1[data->frameNr]!=0.0) return 2;
460 if(data->x2[data->frameNr]!=0.0) return 3;
461 for(i=0; i<data->voiNr; i++) {
462 if(data->voi[i].y[data->frameNr]!=0.0) return 4;
463 if(data->voi[i].y2[data->frameNr]!=0.0) return 5;
464 if(data->voi[i].y3[data->frameNr]!=0.0) return 6;
465 }
466 return 0;
467}

◆ dftPrint()

void dftPrint ( DFT * data)
extern

Prints to stdout the contents of DFT data structure. Mainly for testing purposes.

See also
dftWrite

Definition at line 538 of file dftio.c.

539{
540 int voi, frame;
541
542 printf("Number of curves: %d Number of data points: %d\n",
543 data->voiNr, data->frameNr);
544 printf("Study: '%s' Unit: '%s'\n", data->studynr, data->unit);
545 printf("Time unit and type: %d %d\n", data->timeunit, data->timetype);
546 if(strlen(data->radiopharmaceutical))
547 printf("Radiopharmaceutical: %s\n", data->radiopharmaceutical);
548 if(strlen(data->isotope)) printf("Isotope: %s\n", data->isotope);
549 if(strlen(data->scanStartTime))
550 printf("Scan start time: %s\n", data->scanStartTime);
551 if(strlen(data->injectionTime))
552 printf("Injection time: %s\n", data->injectionTime);
554 printf("Corrected for physical decay: yes\n");
556 printf("Corrected for physical decay: no\n");
557 printf("_datasize = %d\n", data->_dataSize);
558 for(voi=0; voi<data->voiNr; voi++) {
559 if(strlen(data->voi[voi].name)>0)
560 printf("\nROI name: '%s' Size: %g\n",
561 data->voi[voi].name, data->voi[voi].size);
562 else
563 printf("\nROI name: '%s' '%s' '%s' Size: %g\n",
564 data->voi[voi].voiname, data->voi[voi].hemisphere, data->voi[voi].place,
565 data->voi[voi].size);
566 for(frame=0; frame<data->frameNr; frame++) {
567 printf("%03d: %11.3e %11.3e %11.3e %11.3e %11.3e %11.3e\n",
568 frame+1, data->x[frame], data->x1[frame], data->x2[frame],
569 data->voi[voi].y[frame], data->voi[voi].y2[frame],
570 data->voi[voi].y3[frame]);
571 }
572 }
573 printf("Comments:\n");
574 if(strlen(data->comments)>0) printf("%s\n", data->comments);
575 printf("Weights:\n");
576 if(data->isweight)
577 for(frame=0; frame<data->frameNr; frame++)
578 printf(" %03d %11.3e %11.3e %11.3e\n", frame+1,
579 data->x1[frame], data->x2[frame], data->w[frame]);
580 else
581 printf(" contains no weights.\n");
582 return;
583}

Referenced by csv2dft(), dftRead(), img_k1_using_ki(), img_logan(), and img_patlak().

◆ dftRead()

int dftRead ( char * filename,
DFT * data )
extern

Read TAC file contents into specified DFT data structure. Reads standard DFT files, plain DFT files, and some other formats.

See also
dftFormat, dftWrite
Returns
Returns 0 when successful, in case of error sets dfterrmsg.
Parameters
filenameName of file to be read.
dataPointer to initiated DFT struct where data will be written; any old content is deleted.

Definition at line 22 of file dftio.c.

27 {
28 const int verbose=0;
29 if(verbose>0) {printf("%s(%s, dft)\n", __func__, filename); fflush(stdout);}
30
31 FILE *fp;
32 char *cptr, *line, *lptr, temp[128];
33 int ret, i, j, c, type=0, voiNr=0, frameNr=0, longest=0;
34 double f;
35 IFT ift;
36
37
38 /* Empty data */
39 if(data==NULL) {strcpy(dfterrmsg, "invalid data"); return 1;}
40 dftEmpty(data);
41
42 /* Check if file can be opened for read; then close it for now */
43 if(verbose>1) {printf("opening file\n"); fflush(stdout);}
44 fp=fopen(filename, "r");
45 if(fp==NULL) {strcpy(dfterrmsg, "cannot open file"); return 1;}
46 fclose(fp);
47
48 /* Try to identify the file format */
49 type=dftFormat(filename); if(verbose>1) printf(" type := %d\n", type);
50 if(type==DFT_FORMAT_UNKNOWN) {
51 strcpy(dfterrmsg, "unknown file format"); return 1;
52 } else if(type==DFT_FORMAT_FIT) {
53 strcpy(dfterrmsg, "cannot read fit file"); return 1;
54 }
55
56 /* Read some special formats */
57 if(type==DFT_FORMAT_NCI) { // TPC format before DFT
58 if(verbose>1) {printf("calling roikbqRead()\n"); fflush(stdout);}
59 ret=roikbqRead(filename, data); if(ret!=0) return ret;
60 dftFrametimes(data);
61 return(0);
62 } else if(type==DFT_FORMAT_IDWC) {
63 if(verbose>1) {printf("calling idwcRead()\n"); fflush(stdout);}
64 ret=idwcRead(filename, data); if(ret!=0) return ret;
65 if(strlen(data->studynr)==0) studynr_from_fname(filename, data->studynr);
66 return(0);
67 } else if(type==DFT_FORMAT_IF) {
68 if(verbose>1) {printf("calling iftRead()\n"); fflush(stdout);}
69 ret=ifRead(filename, data); if(ret!=0) return ret;
70 if(strlen(data->studynr)==0) studynr_from_fname(filename, data->studynr);
71 return(0);
72 } else if(type==DFT_FORMAT_CSV_INT || type==DFT_FORMAT_CSV_UK) {
73 CSV csv;
74 csvInit(&csv); //CSV_TEST=100;
75 if(verbose>1) {printf("calling csvRead()\n"); fflush(stdout);}
76 ret=csvRead(&csv, filename);
77 if(ret==0) ret=csv2dft(&csv, data);
78 csvEmpty(&csv);
79 if(ret==0) {
80 /* Try to read information from an interfile-type header */
81 IFT ift; iftInit(&ift);
82 if(iftRead(&ift, filename, 1, 0)==0 && ift.keyNr>0) dft_fill_hdr_from_IFT(data, &ift);
83 iftEmpty(&ift);
84 /* study number, too */
85 if(strlen(data->studynr)==0) studynr_from_fname(filename, data->studynr);
86 /* Set DFT comments */
87 dftSetComments(data);
88 return(0);
89 }
90 // if not ok, then just drop through with plain format
92 }
93
94 /* Try to read supported TAC formats, not the others */
95 if(type!=DFT_FORMAT_PLAIN && type!=DFT_FORMAT_STANDARD &&
96 type!=DFT_FORMAT_IFT && type!=DFT_FORMAT_PMOD
97 ) {
98 strcpy(dfterrmsg, "unsupported file format"); return 1;
99 }
100
101 /* Try to read information from an interfile-type header */
102 if(verbose>1) {printf("calling iftRead()\n"); fflush(stdout);}
103 iftInit(&ift);
104 if(iftRead(&ift, filename, 1, 0)!=0) iftEmpty(&ift);
105
106 /* Open file */
107 if(verbose>1) {printf("re-opening file\n"); fflush(stdout);}
108 fp=fopen(filename, "r");
109 if(fp==NULL) {
110 strcpy(dfterrmsg, "cannot open file"); iftEmpty(&ift); return 1;
111 }
112
113 /* Get the length of the longest line */
114 i=0; while((c=fgetc(fp))!=EOF) {
115 if(c==10 || c==13) {if(i>longest) longest=i; i=0;} else i++;}
116 if(i>longest) longest=i;
117 rewind(fp); longest+=2;
118 if(verbose>1) {printf(" longest := %d\n", longest); fflush(stdout);}
119
120 /* and allocate memory for string of that length */
121 line=(char*)malloc((longest+1)*sizeof(char));
122 if(line==NULL) {strcpy(dfterrmsg, "out of memory"); iftEmpty(&ift); fclose(fp); return 2;}
123
124 /* Get the frame number */
125 i=0; while(fgets(line, longest, fp)!=NULL && *line) {
126 if(line[0]=='#') continue;
127 cptr=strchr(line, '#'); if(cptr!=NULL) *cptr=(char)0;
128 for(j=0; j<(int)strlen(line); j++)
129 if(isalnum((int)line[j]) || line[j]=='.') {i++; break;}
130 }
131 rewind(fp); frameNr=i;
132 if(type==DFT_FORMAT_STANDARD) frameNr-=4; /* title lines */
133 if(type==DFT_FORMAT_PMOD) frameNr-=1;
134 if(verbose>1) {printf("frameNr := %d\n", frameNr); fflush(stdout);}
135 if(frameNr<1) {
136 strcpy(dfterrmsg, "contains no data");
137 iftEmpty(&ift); free(line); fclose(fp); return 1;
138 }
139
140 /* Get the number of curves */
141 /* find first line that is not an empty or a comment line */
142 while(fgets(line, longest, fp)!=NULL) {
143 if(line[0]=='#') continue;
144 /* If PMOD file, then read it from the title */
145 if(type==DFT_FORMAT_PMOD) {voiNr=dftGetPmodTitle(NULL, line); break;}
146 /* In plain data file that is first frame, which starts with time */
147 /* In normal DFT file that is 1st title line, which starts with 'DFT' */
148 char *nline; nline=strdup(line); lptr=nline;
149 cptr=strtok(lptr, " \t\n\r"); if(cptr==NULL) {free(nline); continue;}
150 voiNr=0; while((cptr=strtok(NULL, " \t\n\r"))!=NULL) voiNr++;
151 free(nline);
152 break;
153 }
154 rewind(fp);
155 if(verbose>1) {printf("voiNr := %d\n", voiNr); fflush(stdout);}
156 if(voiNr<1) {
157 strcpy(dfterrmsg, "contains no curves");
158 iftEmpty(&ift); free(line); fclose(fp); return 1;
159 }
160
161 /* Allocate memory for data */
162 if(verbose>1) {printf("allocating memory\n"); fflush(stdout);}
163 if(dftSetmem(data, frameNr, voiNr)) {
164 strcpy(dfterrmsg, "out of memory");
165 iftEmpty(&ift); free(line); fclose(fp); return 2;
166 }
167
168 /* For plain data files, set defaults for title data */
169 if(type==DFT_FORMAT_PLAIN || type==DFT_FORMAT_IFT) {
170 if(verbose>1) {printf("setting title defaults for plain data\n"); fflush(stdout);}
171 int u, n; u=voiNr; n=1; while((u/=10)>=1) n++;
173 for(i=0; i<voiNr; i++) {
174 snprintf(data->voi[i].voiname, MAX_REGIONSUBNAME_LEN+1, "%0*d", n, i+1);
175 strcpy(data->voi[i].name, data->voi[i].voiname);
176 }
177 /* Default: times in minutes, and frame mid time */
178 data->timeunit=TUNIT_UNKNOWN; data->timetype=DFT_TIME_MIDDLE;
179 }
180
181 /*
182 * Try to read information from an interfile-type header
183 */
184 if(ift.keyNr>0) {
185 if(verbose>1) {printf("calling dft_fill_hdr_from_IFT\n"); fflush(stdout);}
186 dft_fill_hdr_from_IFT(data, &ift);
187 }
188 iftEmpty(&ift);
189
190 /* Try to read information from a single title line in PMOD files */
191 if(type==DFT_FORMAT_PMOD) {
192 if(fgets(line, longest, fp)==NULL) {
193 strcpy(dfterrmsg, "wrong format"); free(line); fclose(fp); return 101;}
194 if(verbose>1) {printf("calling dftGetPmodTitle\n"); fflush(stdout);}
195 dftGetPmodTitle(data, line);
196 // do not rewind!
197 }
198
199 /*
200 * Read DFT title lines, if they exist
201 */
202 i=0;
203 if(type==DFT_FORMAT_STANDARD) {
204 if(verbose>1) {printf("reading DFT title lines\n"); fflush(stdout);}
205 do {
206 if(fgets(line, longest, fp)==NULL) {
207 strcpy(dfterrmsg, "wrong format"); free(line); fclose(fp); return 102;}
208 lptr=line;
209 /* Check for comment line */
210 if(line[0]=='#') { /* Read comment only if there is space left */
211 strlcat(data->comments, line, _DFT_COMMENT_LEN);
212 continue;
213 }
214 cptr=strchr(line, '#'); if(cptr!=NULL) *cptr=(char)0;
215 /* Read first token, and check for empty lines as well */
216 cptr=strtok(lptr, " \t\n\r"); if(cptr==NULL) continue; else i++;
217 if(i==1) { /* VOI names */
218 for(j=0; j<voiNr; j++) {
219 cptr=strtok(NULL, " \t\n\r");
220 if(cptr==NULL) {strcpy(dfterrmsg, "wrong format"); free(line); fclose(fp); return 103;}
221 if(strlen(cptr)>1 || *cptr!='.') {
222 strncpy(data->voi[j].name, cptr, MAX_REGIONNAME_LEN);
223 data->voi[j].name[MAX_REGIONNAME_LEN]=(char)0;
224 strncpy(data->voi[j].voiname, cptr, MAX_REGIONSUBNAME_LEN);
225 data->voi[j].voiname[MAX_REGIONSUBNAME_LEN]=(char)0;
226 /* if name is long, then divide it into name subfields */
227 if(strlen(cptr)>MAX_REGIONSUBNAME_LEN) {
229 data->voi[j].hemisphere[MAX_REGIONSUBNAME_LEN]=(char)0;
230 if(strlen(cptr)>2*MAX_REGIONSUBNAME_LEN) {
231 strncpy(data->voi[j].place, cptr+2*MAX_REGIONSUBNAME_LEN, MAX_REGIONSUBNAME_LEN);
232 data->voi[j].place[MAX_REGIONSUBNAME_LEN]=(char)0;
233 }
234 }
235 } else {
236 int u, n; u=voiNr; n=1; while((u/=10)>=1) n++; if(n>6) n=6;
237 snprintf(data->voi[j].voiname, 7, "%0*d", n, j+1);
238 strcpy(data->voi[j].name, data->voi[j].voiname);
239 }
240 }
241 } else if(i==2) { /* 2nd VOI names (hemispheres) */
242 if(strcmp(cptr, ".")!=0) {
243 strlcpy(data->studynr, cptr, MAX_STUDYNR_LEN);
244 } else strcpy(data->studynr, "");
245 for(j=0; j<voiNr; j++) {
246 if((cptr=strtok(NULL, " \t\n\r"))==NULL) {
247 strcpy(dfterrmsg, "missing field on 2nd line");
248 free(line); fclose(fp); return 104;
249 }
250 if(strlen(cptr)>1 || *cptr!='.') {
251 strncpy(data->voi[j].hemisphere, cptr, MAX_REGIONSUBNAME_LEN);
252 data->voi[j].hemisphere[MAX_REGIONSUBNAME_LEN]=(char)0;
253 strcat(data->voi[j].name, " ");
254 strlcat(data->voi[j].name, data->voi[j].hemisphere, MAX_REGIONNAME_LEN);
255 } else {
256 strlcat(data->voi[j].name, " .", MAX_REGIONNAME_LEN+1);
257 }
258 }
259 /* check that there are no more contents */
260 if((cptr=strtok(NULL, " \t\n\r"))!=NULL) {
261 strcpy(dfterrmsg, "wrong format"); free(line); fclose(fp); return 105;}
262 } else if(i==3) { /* unit and VOI place (planes) */
263 /* first, copy the unit */
264 strlcpy(data->unit, cptr, 13); //data->unit[12]=(char)0;
265 /* then, copy the names */
266 int len, ii=0;
267 j=0;
268 while(j<voiNr) {
269 if((cptr=strtok(NULL, " \t\n\r"))==NULL) {
270 strcpy(dfterrmsg, "missing field on 3rd line");
271 free(line); fclose(fp); return 106;
272 }
273 len=strlen(cptr);
274 /* check if cunit consists of two parts */
275 if(ii==0 && cptr[0]=='(' && cptr[len-1]==')') {ii++; continue;}
276 /* copy the name */
277 if(len>1 || *cptr!='.') {
278 strlcpy(data->voi[j].place, cptr, MAX_REGIONSUBNAME_LEN+1);
279 //data->voi[j].place[MAX_REGIONSUBNAME_LEN]=(char)0;
280 strcat(data->voi[j].name, " ");
281 strlcat(data->voi[j].name, data->voi[j].place, MAX_REGIONNAME_LEN+1);
282 } else {
283 strlcat(data->voi[j].name, " .", MAX_REGIONNAME_LEN+1);
284 }
285 j++; ii++;
286 }
287 } else if(i==4) { /* time type, time unit, and VOI sizes */
288 /* time type */
289 if(strcasecmp(cptr, "Time")==0) data->timetype=DFT_TIME_MIDDLE;
290 else if(strcasecmp(cptr, "Times")==0) data->timetype=DFT_TIME_STARTEND;
291 else if(strcasecmp(cptr, "Start")==0) data->timetype=DFT_TIME_START;
292 else if(strcasecmp(cptr, "End")==0) data->timetype=DFT_TIME_END;
293 else if(strcasecmp(cptr, "Distance")==0) data->timetype=DFT_TIME_MIDDLE;
294 else if(strcasecmp(cptr, "Distances")==3) data->timetype=DFT_TIME_STARTEND;
295 else {strcpy(dfterrmsg, "wrong format"); free(line); fclose(fp); return 108;}
296 /* time unit */
297 if((cptr=strtok(NULL, " \t\n\r"))==NULL) {
298 strcpy(dfterrmsg, "wrong format"); free(line); fclose(fp); return 109;}
299 strcpy(temp, ""); j=sscanf(cptr, "(%127s)", temp);
300 j=strlen(temp)-1; if(j>=0 && temp[j]==')') temp[j]=(char)0;
301 data->timeunit=petTunitId(temp);
302 if(data->timeunit<0) {
303 strcpy(dfterrmsg, "wrong format"); free(line); fclose(fp); return 110;}
304 /* volumes */
305 for(j=0; j<voiNr; j++) {
306 if((cptr=strtok(NULL, " \t\n\r"))==NULL) {
307 strcpy(dfterrmsg, "wrong format"); free(line); fclose(fp); return 111;}
308 if(strlen(cptr)==1 && *cptr=='.') data->voi[j].size=0.0;
309 else data->voi[j].size=atof_dpi(cptr);
310 }
311 }
312 } while(i<4); // Standard DFT title lines are now read
313 }
314
315 /* Read data lines */
316 if(verbose>1) {printf("reading data lines\n"); fflush(stdout);}
317 i=0; while(fgets(line, longest, fp)!=NULL) {
318
319 /* Check for comment line */
320 if(line[0]=='#') { /* Read comment only if there is space left */
321 strlcat(data->comments, line, _DFT_COMMENT_LEN);
322 continue;
323 }
324 // remove end-of-line comment
325 cptr=strchr(line, '#'); if(cptr!=NULL) *cptr=(char)0;
326
327 /* Read first token, and check for empty lines as well */
328 char *nline; nline=strdup(line); lptr=nline;
329 cptr=strtok(lptr, " \t\n\r"); if(cptr==NULL) {free(nline); continue;}
330 if(i<frameNr) {
331 /* Read time(s) */
332 if(atof_with_check(cptr, &f)!=0) {
333 strcpy(dfterrmsg, "wrong format");
334 free(line); free(nline); fclose(fp); return 130;
335 }
336 if(data->timetype==DFT_TIME_STARTEND) {
337 data->x1[i]=f; cptr=strtok(NULL, " \t\n\r");
338 if(atof_with_check(cptr, &data->x2[i])!=0) {
339 strcpy(dfterrmsg, "wrong format");
340 free(line); free(nline); fclose(fp); return 131;
341 }
342 data->x[i]=0.5*(data->x1[i]+data->x2[i]);
343 } else data->x[i]=f;
344 /* curve data */
345 for(j=0; j<voiNr; j++) {
346 if((cptr=strtok(NULL, " \t\n\r"))==NULL) {
347 strcpy(dfterrmsg, "wrong format");
348 free(line); free(nline); fclose(fp); return 132;
349 }
350 if(strlen(cptr)==1 && *cptr=='.')
351 data->voi[j].y[i]=nan("");
352 else {
353 if(atof_with_check(cptr, &data->voi[j].y[i])!=0) {
354 strcpy(dfterrmsg, "wrong format");
355 free(line); free(nline); fclose(fp); return 133;
356 }
357 c=dec_nr(cptr);
359 }
360 }
361 }
362 free(nline);
363 i++;
364 }
365 if(i!=frameNr) {strcpy(dfterrmsg, "wrong format"); fclose(fp); free((char*)line); return 134;}
366
367 /* Close file */
368 fclose(fp); free((char*)line);
369
370 /* Set voiNr and frameNr, and type */
371 data->voiNr=voiNr; data->frameNr=frameNr;
372 if(type==DFT_FORMAT_IFT) {
374 } else if(type==DFT_FORMAT_PMOD) {
375 data->_type=type; // keeping PMOD format
376 // unless TAC names could not be read
377 for(i=0; i<data->voiNr; i++) if(strlen(data->voi[i].name)<1) {
378 data->_type=DFT_FORMAT_PLAIN; break;}
379 } else {
380 data->_type=type;
381 }
382
383 /* Set study number from file name, if necessary */
384 if(strlen(data->studynr)==0) studynr_from_fname(filename, data->studynr);
385
386 /* If weight 'voi' was read, move it to its own place */
387 for(i=0; i<data->voiNr; i++) if(!strcasecmp(data->voi[i].voiname, "weight")) {
388 data->isweight=1;
389 for(j=0; j<data->frameNr; j++) data->w[j]=data->voi[i].y[j];
390 /* Move the following VOIs one step backwards */
391 for(c=i+1; c<data->voiNr; c++) if(dftCopyvoi(data, c, c-1)) {
392 strcpy(dfterrmsg, "cannot read weight"); return 4;}
393 data->voiNr--;
394 break;
395 }
396 /* If no weights were found, set uniform weight */
397 if(!data->isweight) for(i=0; i<data->frameNr; i++) data->w[i]=1.0;
398
399 /* Calculate frame mid times, or frame start and end times;
400 this works only if time units are known */
401 dftFrametimes(data);
402
403 /* Make again the full ROI names from the separate sub parts */
404 for(i=0; i<data->voiNr; i++)
405 rnameCatenate(data->voi[i].name, MAX_REGIONNAME_LEN, data->voi[i].voiname,
406 data->voi[i].hemisphere, data->voi[i].place, ' ');
407
408
409 if(CSV_TEST>100) dftPrint(data);
410 return(0);
411}
int csv2dft(CSV *csv, DFT *dft)
Definition csv.c:200
int dec_nr(char *str)
Definition decpoint.c:81
void dftSetComments(DFT *dft)
Definition dft.c:1326
int dftCopyvoi(DFT *data, int from, int to)
Definition dft.c:472
int DFT_NR_OF_DECIMALS
Definition dftio.c:13
int dftFormat(char *fname)
Definition dftio.c:422
int dft_fill_hdr_from_IFT(DFT *dft, IFT *ift)
Definition dftio.c:971
int dftGetPmodTitle(DFT *dft, char *title_line)
Definition dftio.c:1109
int idwcRead(char *filename, DFT *dft)
Definition idwc.c:77
int ifRead(char *filename, DFT *dft)
Definition if.c:78
int roikbqRead(char *fname, DFT *dft)
Definition ncifile.c:95
#define DFT_FORMAT_IFT
int rnameCatenate(char *rname, int max_rname_len, char *name1, char *name2, char *name3, char space)
Definition rname.c:189
size_t strlcat(char *dst, const char *src, size_t dstsize)
Definition strext.c:206

Referenced by dftReadinput(), dftReadModelingData(), dftReadReference(), and imgReadModelingData().

◆ dftRemoveTimeRange()

int dftRemoveTimeRange ( DFT * dft,
double startT,
double endT )
extern

Extract specified sample time interval from TAC data.

Returns
Returns 0 when successful, otherwise <>0.
Parameters
dftPointer to DFT struct from where samples outside time range will be removed. Data must be sorted to increasing frame times before calling this function.
startTStart time of data that is preserved (in same units as in DFT)
endTEnd time of data that is preserved (in same units as in DFT)

Definition at line 1275 of file dft.c.

1284 {
1285 int i, j, voi, first, origNr;
1286
1287 if(dft==NULL || dft->frameNr<1 || dft->voiNr<1) return(1);
1288 if(endT<startT) return(2);
1289 if(startT<=dft->x[0] && endT>=dft->x[dft->frameNr-1]) return(0);
1290 origNr=dft->frameNr;
1291
1292 /* Delete end frames which are collected later than the end time */
1293 for(j=dft->frameNr-1; j>=0; j--) if(dft->x[j]<=endT) break;
1294 dft->frameNr=j+1;
1295
1296 /* Find the first frame that has been collected later than start time */
1297 for(j=0, first=-1; j<dft->frameNr; j++)
1298 if(dft->x[j]>=startT) {first=j; break;}
1299 if(first<0) {
1300 dft->frameNr=origNr; // undelete the end data
1301 return(3);
1302 }
1303
1304 /* Delete first frames */
1305 if(first>0) for(j=first, i=0; j<dft->frameNr; j++, i++) {
1306 dft->x[i]=dft->x[j]; dft->x1[i]=dft->x1[j]; dft->x2[i]=dft->x2[j];
1307 dft->w[i]=dft->w[j];
1308 for(voi=0; voi<dft->voiNr; voi++) {
1309 dft->voi[voi].y[i]=dft->voi[voi].y[j];
1310 dft->voi[voi].y2[i]=dft->voi[voi].y2[j];
1311 dft->voi[voi].y3[i]=dft->voi[voi].y3[j];
1312 }
1313 }
1314 dft->frameNr-=first;
1315
1316 return(0);
1317}

◆ dftRNameSimplify()

void dftRNameSimplify ( DFT * dft,
int hemisphere,
int place )
extern

Simplify TAC names in DFT struct: empty hemisphere and/or place field in case those are the same in all TACs.

Parameters
dftPointer to DFT struct
hemisphereIs hemisphere field simplified (1) or not (0), when possible
placeIs place field simplified (1) or not (0), when possible

Definition at line 1534 of file dft.c.

1541 {
1542 int ri, n;
1543
1544 if(dft==NULL || dft->voiNr<1) return;
1545 if(hemisphere==0 && place==0) return;
1546
1547 /* Check if all TACs have the same field content: if yes, then
1548 delete the field content */
1549 if(hemisphere!=0) {
1550 for(ri=n=1; ri<dft->voiNr; ri++)
1551 if(strcasecmp(dft->voi[0].hemisphere, dft->voi[ri].hemisphere)==0) n++;
1552 if(n==dft->voiNr)
1553 for(ri=0; ri<dft->voiNr; ri++)
1554 strcpy(dft->voi[ri].hemisphere, "");
1555 }
1556 if(place!=0) {
1557 for(ri=n=1; ri<dft->voiNr; ri++)
1558 if(strcasecmp(dft->voi[0].place, dft->voi[ri].place)==0) n++;
1559 if(n==dft->voiNr)
1560 for(ri=0; ri<dft->voiNr; ri++)
1561 strcpy(dft->voi[ri].place, "");
1562 }
1563
1564 /* Construct combined TAC names */
1565 for(ri=0; ri<dft->voiNr; ri++)
1567 dft->voi[ri].voiname, dft->voi[ri].hemisphere,
1568 dft->voi[ri].place, '_');
1569 /* Ready */
1570 return;
1571}

◆ dftSec2min()

void dftSec2min ( DFT * dft)
extern

Change time unit from sec to min, without checking original unit.

Definition at line 160 of file dftunit.c.

161{
162 int i;
163
164 for(i=0; i<dft->frameNr; i++) {
165 if(!isnan(dft->x[i])) dft->x[i]/=60.;
166 if(!isnan(dft->x1[i])) dft->x1[i]/=60.;
167 if(!isnan(dft->x1[i])) dft->x2[i]/=60.;
168 }
169 dft->timeunit=TUNIT_MIN;
170}

Referenced by copy_times_from_img_to_dft(), cptReadOne(), and dftTimeunitConversion().

◆ dftSelect()

int dftSelect ( DFT * data,
char * name )
extern

Select VOIs (sets sw=1), whose names are matching specified string. If no string is specified, then all VOIs are selected. This function is to replaced by dftSelectRegions().

Returns
Returns the number of matches, or <0, if an error occurred.
Parameters
dataPointer to DFT struct
nameString to search in TAC name fields

Definition at line 239 of file dft.c.

244 {
245 unsigned int i, j, n;
246 char *p, n1[128], n2[128], n3[128], tmp[128], sname[1024];
247
248 if(data==NULL) return -1;
249 /* Select all, if no string was specified */
250 if(name==NULL || strlen(name)==0) {
251 for(i=0; i<(unsigned int)data->voiNr; i++) data->voi[i].sw=1;
252 return data->voiNr;
253 }
254 /* Make a copy of 'name' and use it */
255 strcpy(sname, name);
256 /* Check if string contains several substrings (hemisphere and place) */
257 n1[0]=n2[0]=n3[0]=(char)0;
258 p=strtok(sname, " ,;\n\t|"); if(p!=NULL) strcpy(n1, p); else return -1;
259 p=strtok(NULL, " ,;\n\t|"); if(p!=NULL) {
260 strcpy(n2, p); p=strtok(NULL, " ,;\n\t|"); if(p!=NULL) strcpy(n3, p);}
261 /* Convert strings to lowercase */
262 for(i=0; i<strlen(n1); i++) n1[i]=tolower(n1[i]);
263 for(i=0; i<strlen(n2); i++) n2[i]=tolower(n2[i]);
264 for(i=0; i<strlen(n3); i++) n3[i]=tolower(n3[i]);
265 /* Search through the data */
266 for(i=0, n=0; i<(unsigned int)data->voiNr; i++) {
267 data->voi[i].sw=0;
268 snprintf(tmp, 128, "%s%s%s", data->voi[i].voiname, data->voi[i].hemisphere,
269 data->voi[i].place);
270 for(j=0; j<strlen(tmp); j++) tmp[j]=tolower(tmp[j]);
271 if(strstr(tmp, n1)==NULL) continue;
272 if(n2[0] && strstr(tmp, n2)==NULL) continue;
273 if(n3[0] && strstr(tmp, n3)==NULL) continue;
274 data->voi[i].sw=1; n++;
275 }
276 return n;
277}

◆ dftSelectBestReference()

int dftSelectBestReference ( DFT * dft)
extern

Select the best reference region in case that several were found with dftSelectRegions.

Returns
Returns the index of best region, or <0 in case of an error.
Parameters
dftPointer to DFT struct, after using dftSelectRegions()

Definition at line 314 of file dft.c.

317 {
318 int ri, len, min_len, i;
319
320 if(dft==NULL || dft->voiNr<1) return -1;
321 for(ri=0, i=-1, min_len=9999; ri<dft->voiNr; ri++) if(dft->voi[ri].sw) {
322 len=strlen(dft->voi[ri].voiname);
323 if(strcmp(dft->voi[ri].hemisphere, ".")!=0 &&
324 strcasecmp(dft->voi[ri].hemisphere, "AVG")!=0 &&
325 strcasecmp(dft->voi[ri].hemisphere, "MEAN")!=0)
326 len+=1+strlen(dft->voi[ri].hemisphere);
327 if(strcmp(dft->voi[ri].place, ".")!=0 &&
328 strcasecmp(dft->voi[ri].place, "ALL")!=0 &&
329 strcasecmp(dft->voi[ri].place, "AVG")!=0 &&
330 strcasecmp(dft->voi[ri].place, "MEAN")!=0)
331 len+=1+strlen(dft->voi[ri].place);
332 if(len<min_len) {min_len=len; i=ri;}
333 }
334 if(i<0) return -2; else return i;
335}

Referenced by dftReadinput(), and dftReadReference().

◆ dftSelectRegions()

int dftSelectRegions ( DFT * dft,
char * region_name,
int reset )
extern

Select the VOIs that have matching region name or number. Sets sw=1 or sw=0. This function will replace dftSelect().

Returns
Returns the number of selected VOIs, or <0 in case of an error.
Parameters
dftPointer to DFT data where VOIs are selected
region_nameName or VOI number which is searched
reset1=Non-matching VOIs are deselected, 0=Old selections are preserved

Definition at line 285 of file dft.c.

292 {
293 int ri, match_nr=0;
294
295 /* Check the input */
296 if(dft==NULL || dft->voiNr<1 || strlen(region_name)<1) return(-1);
297 /* Reset all selections if required */
298 if(reset!=0) for(ri=0; ri<dft->voiNr; ri++) dft->voi[ri].sw=0;
299 /* Check each VOI */
300 for(ri=0; ri<dft->voiNr; ri++) {
301 if(rnameMatch(dft->voi[ri].name, ri+1, region_name)!=0) {
302 dft->voi[ri].sw=1; match_nr++;
303 }
304 }
305 return(match_nr);
306}
int rnameMatch(char *rname, int rnr, char *test_str)
Definition rname.c:144

Referenced by dftReadinput(), and dftReadReference().

◆ dftSetComments()

void dftSetComments ( DFT * dft)
extern

Overwrites DFT comments with information in current DFT header.

If DFT format specifies that titles are to be saved, that information is not included in comments.

Parameters
dftPointer to DFT struct

Definition at line 1326 of file dft.c.

1329 {
1330 char tmp[512];
1331
1332 if(dft==NULL) return;
1333 strcpy(dft->comments, "");
1334 /* Write in comments the information that will not be included in titles */
1335 if(dft->scanStartTime[0]) {
1336 sprintf(tmp, "# scan_start_time := %s\n", dft->scanStartTime);
1337 strcat(dft->comments, tmp);
1338 }
1339 if(dft->injectionTime[0]) {
1340 sprintf(tmp, "# injection_time := %s\n", dft->injectionTime);
1341 strcat(dft->comments, tmp);
1342 }
1343 strcpy(tmp, "# decay_correction := ");
1344 if(dft->decayCorrected==DFT_DECAY_CORRECTED) strcat(tmp, "Yes\n");
1345 else if(dft->decayCorrected==DFT_DECAY_NOTCORRECTED) strcat(tmp, "No\n");
1346 else strcat(tmp, "Unknown\n");
1347 if(dft->decayCorrected!=DFT_DECAY_UNKNOWN) strcat(dft->comments, tmp);
1348 if(dft->isotope[0]) {
1349 sprintf(tmp, "# isotope := %s\n", dft->isotope);
1350 strcat(dft->comments, tmp);
1351 }
1352 if(dft->radiopharmaceutical[0]) {
1353 sprintf(tmp, "# radiopharmaceutical := %s\n", dft->radiopharmaceutical);
1354 strcat(dft->comments, tmp);
1355 }
1356 /* If titles are set to be saved, then there's no need to put more in comments */
1357 if(dft->_type==DFT_FORMAT_STANDARD || dft->_type==DFT_FORMAT_PMOD) return;
1358
1359 /* Ok then, lets write even title information in comments */
1360 if(dft->studynr[0]) {
1361 sprintf(tmp, "# study_number := %s\n", dft->studynr);
1362 strcat(dft->comments, tmp);
1363 }
1364 if(dft->timeunit!=TUNIT_UNKNOWN) {
1365 sprintf(tmp, "# timeunit := %s\n", petTunit(dft->timeunit) );
1366 strcat(dft->comments, tmp);
1367 }
1368 if(petCunitId(dft->unit)!=CUNIT_UNKNOWN) {
1369 sprintf(tmp, "# unit := %s\n", dft->unit );
1370 strcat(dft->comments, tmp);
1371 }
1372 // Region names and volumes are not saved in comments because of space limit
1373
1374 return;
1375}

Referenced by dftRead().

◆ dftSetmem()

int dftSetmem ( DFT * data,
int frameNr,
int voiNr )
extern

Allocate memory for DFT data and sets data pointers.

Returns
Returns <> 0 in case of an error.
Parameters
dataPointer to initiated DFT structure data; any old contents are deleted.
frameNrNr of time frames (samples) to allocate
voiNrNr of concentration arrays (regional TACs) to allocate

Definition at line 57 of file dft.c.

64 {
65 int i, n;
66 double *d;
67
68
69 if(data==NULL) return 1;
70 /* Clear previous data */
71 dftEmpty(data);
72
73 /* Allocate memory for curves */
74 data->voi=(Voi*)calloc(voiNr, sizeof(Voi));
75 if(data->voi==NULL) return 1;
76 data->_voidataNr=voiNr;
77
78 /* Allocate memory for frames */
79 /* For 3 axes, weights, and for curves (3 for each VOI) */
80 /* And one extra 'frame' for overflow testing */
81 n=(frameNr+1)*(3+1+3*voiNr);
82 data->_data=(double*)calloc(n, sizeof(double));
83 if(data->_data==NULL) return 1;
84 data->_dataSize=n;
85
86 /* Set pointers for curve data */
87 d=data->_data; data->x = d;
88 d += frameNr + 1; data->x1 = d;
89 d += frameNr + 1; data->x2 = d;
90 d += frameNr + 1; data->w = d;
91 for(i=0; i<voiNr; i++) {
92 d += frameNr + 1; data->voi[i].y = d;
93 d += frameNr + 1; data->voi[i].y2 = d;
94 d += frameNr + 1; data->voi[i].y3 = d;
95 }
96
97 return 0;
98}

Referenced by bf_srtm(), bfIrr2TCM(), bfRadiowater(), clusterTACs(), cptReadOne(), csv2dft_a(), csv2dft_b(), csv2dft_linkset(), csv2dft_mat(), dftAddnullframe(), dftAddSpaceForFrames(), dftAllocateWithHeader(), dftAllocateWithIMG(), dftAutointerpolate(), dftDivideFrames(), dftDoubleFrames(), dftdup(), dftFillInitialGap(), dftInterpolate(), dftRead(), extrapolate_monoexp(), idwcRead(), ifRead(), img_k1_using_ki(), img_logan(), img_patlak(), plotdata_as_dft(), roikbqRead(), sif2dft(), simMyocDiameterCurve(), tsvRead(), and xelRead().

◆ dftSort()

int dftSort ( DFT * data)
extern

Sort DFT regions in alphabetical order by their name.

Returns
Returns <> 0 in case of an error.
Parameters
dataPointer to DFT struct

Definition at line 845 of file dft.c.

848 {
849 if(data==NULL) return(1);
850 if(data->voiNr<=1) return(0);
851 qsort(data->voi, data->voiNr, sizeof(Voi), dftQSortName);
852 return(0);
853}

◆ dftSortByFrame()

int dftSortByFrame ( DFT * dft)
extern

Sorts TAC frames by increasing sample time.

Returns
Returns 0 if ok.
Parameters
dftPointer to DFT struct

Definition at line 1169 of file dft.c.

1172 {
1173 int ri, fi, fj;
1174 double d;
1175
1176 if(dft==NULL || dft->voiNr<1 || dft->frameNr<1) return(1);
1177 for(fi=0; fi<dft->frameNr-1; fi++) for(fj=fi+1; fj<dft->frameNr; fj++) {
1178 if(dft->x[fj]>=dft->x[fi]) continue;
1179 d=dft->x[fi]; dft->x[fi]=dft->x[fj]; dft->x[fj]=d;
1180 d=dft->x1[fi]; dft->x1[fi]=dft->x1[fj]; dft->x1[fj]=d;
1181 d=dft->x2[fi]; dft->x2[fi]=dft->x2[fj]; dft->x2[fj]=d;
1182 d=dft->w[fi]; dft->w[fi]=dft->w[fj]; dft->w[fj]=d;
1183 for(ri=0; ri<dft->voiNr; ri++) {
1184 d=dft->voi[ri].y[fi]; dft->voi[ri].y[fi]=dft->voi[ri].y[fj]; dft->voi[ri].y[fj]=d;
1185 d=dft->voi[ri].y2[fi]; dft->voi[ri].y2[fi]=dft->voi[ri].y2[fj]; dft->voi[ri].y2[fj]=d;
1186 d=dft->voi[ri].y3[fi]; dft->voi[ri].y3[fi]=dft->voi[ri].y3[fj]; dft->voi[ri].y3[fj]=d;
1187 }
1188 }
1189 return(0);
1190}

Referenced by dftReadModelingData(), and dftVerifyPeak().

◆ dftSortPlane()

int dftSortPlane ( DFT * data)
extern

Sort DFT regions in alphabetical order by their plane.

Returns
Returns <> 0 in case of an error.
Parameters
dataPointer to DFT struct

Definition at line 875 of file dft.c.

878 {
879 if(data==NULL) return(1);
880 if(data->voiNr<=1) return(0);
881 qsort(data->voi, data->voiNr, sizeof(Voi), dftQSortPlane);
882 return(0);
883}

Referenced by cptWrite().

◆ dftTimeunitConversion()

int dftTimeunitConversion ( DFT * dft,
int tunit )
extern

Conversion of the DFT timeunit. Changes both data values and timeunit code. Currently available conversions are: min <-> sec

Returns
Returns 0 if conversion was successful, and <> 0 if failed.
Parameters
dftPointer to existing DFT data, whose timeunit is to be changed
tunitNew timeunit code

Definition at line 119 of file dftunit.c.

124 {
125 /* Check the input */
126 if(dft==NULL || tunit<0) return(1);
127
128 /* Check if unit already is as required */
129 if(dft->timeunit==tunit) return(0);
130
131 /* Do the conversion, if supported */
132 if(dft->timeunit==TUNIT_MIN && tunit==TUNIT_SEC)
133 dftMin2sec(dft);
134 else if(dft->timeunit==TUNIT_SEC && tunit==TUNIT_MIN)
135 dftSec2min(dft);
136 else
137 return(2);
138
139 return(0);
140}

Referenced by dftInterpolateCheckEnd(), dftInterpolateCheckStart(), dftMatchTimeunits(), dftReadinput(), dftReadModelingData(), dftReadReference(), img_logan(), img_patlak(), and imgReadModelingData().

◆ dftTimeunitToDFT()

int dftTimeunitToDFT ( DFT * dft,
const char * timeunit )
extern

Set DFT timeunit; does not change the sample times.

Returns
Returns 0 if successful, and <> 0 if invalid timeunit.

Definition at line 103 of file dftunit.c.

104{
105 if(dft==NULL || timeunit==NULL) return(1);
106 int tunit=petTunitId(timeunit);
107 if(tunit<0) return(2); else dft->timeunit=tunit;
108 return(0);
109}

Referenced by tsvRead().

◆ dftToResult()

int dftToResult ( DFT * dft,
RES * res,
char * status )
extern

Copy the contents (both header and data) of DFT struct into RES struct.

See also
fitToResult, res_allocate_with_dft
Returns
Returns 0 if successful, in case of an error >0, and <0 if warning is suggested.
Parameters
dftRegional data from where necessary information is read.
resPointer to initiated RES struct which will be allocated here.
statusPointer to a string (allocated for at least 64 chars) where error message or other execution status will be written; enter NULL, if not needed.

Definition at line 60 of file dftres.c.

68 {
69 int ri, fi;
70
71 // Check the input data
72 if(status!=NULL) sprintf(status, "program error");
73 if(res==NULL || dft==NULL || dft->voiNr<1 || dft->frameNr<1) return 1;
74 // Allocate memory and copy most of headers
75 if(res_allocate_with_dft(res, dft) != 0) {
76 if(status!=NULL) sprintf(status, "cannot setup results data");
77 return 2;
78 }
79 res->parNr=dft->frameNr; if(res->parNr>MAX_RESPARAMS) {
80 sprintf(status, "only %d frames can be copied to results", MAX_RESPARAMS);
82 }
83 // Set parameter titles and units
84 for(fi=0; fi<res->parNr; fi++) {
85 sprintf(res->parname[fi], "%d", fi+1);
86 strcpy(res->parunit[fi], dft->unit);
87 }
88 // Copy regional values
89 for(ri=0; ri<dft->voiNr; ri++) for(fi=0; fi<res->parNr; fi++)
90 res->voi[ri].parameter[fi]=dft->voi[ri].y[fi];
91
92 if(dft->frameNr>MAX_RESPARAMS) return -1;
93 /* Set also deprecated parameter name and unit representations, for now */
94 resFixParnames(res);
95 return 0;
96}
int res_allocate_with_dft(RES *res, DFT *dft)
Definition dftres.c:14
void resFixParnames(RES *res)
Definition result.c:107
#define MAX_RESPARAMS
int parNr
char parname[MAX_RESPARAMS][MAX_RESPARNAME_LEN+1]
ResVOI * voi
char parunit[MAX_RESPARAMS][MAX_RESPARNAME_LEN+1]
double parameter[MAX_RESPARAMS]

◆ dftType()

int dftType ( FILE * fp)
extern

Determine the type of DFT file.

Deprecated
Replace calls to dftType() by dftFormat(), but note that return values have changed.
See also
dftFormat
Returns
0=unknown; 1=normal DFT; 2=plain data; 3=fit file; 4=nci file; 5=KI file

Definition at line 503 of file dftio.c.

504{
505 char tmp[256];
506 int c;
507
508 /* Find first line that is not empty or comment line */
509 rewind(fp);
510 while(fgets(tmp, 4, fp) != NULL) {if(strlen(tmp) && tmp[0]!='#') break;}
511 rewind(fp);
512
513 /* Check for identification strings */
514 if(strncasecmp(tmp, "DFT", 3)==0) return 1;
515 else if(strncasecmp(tmp, "FIT1", 3)==0) return 3;
516 else if(strncasecmp(tmp, "cpt", 3)==0) return 4;
517
518 /* Binary data? */
519 while((c=fgetc(fp))!=EOF)
520 if(!isalnum(c) && !isspace(c) && !isgraph(c) && c!=169) {
521 rewind(fp); return 0;
522 }
523
524 /* File with one title line without comment mark? */
525 rewind(fp);
526 while(fgets(tmp, 10, fp) != NULL) {if(strlen(tmp)) break;}
527 if(strncasecmp(tmp, "Time", 4)==0) {rewind(fp); return 5;}
528
529 rewind(fp); return 2;
530}

◆ dftUnitConversion()

int dftUnitConversion ( DFT * dft,
int dunit )
extern

Conversion of the DFT calibration unit. Changes both data values and unit string. Currently available conversions are: MBq/cc <-> kBq/cc <-> Bq/cc <-> nCi/cc <-> uCi/cc Bq <-> kBq <-> MBq <-> GBq <-> nCi <-> uCi <-> mCi

Returns
Returns 0 if conversion was successful, and <> 0 if failed.
Parameters
dftPointer to existing DFT data, whose calibration unit is to be changed
dunitNew unit code

Definition at line 25 of file dftunit.c.

30 {
31 int current_dunit=CUNIT_UNKNOWN;
32 double f=1.0;
33 int ri, fi;
34 int unit_type=0; /* 0=unknown; 1=concentration; 2=dose */
35
36 /* Check the input */
37 if(dft==NULL || dunit<0) return(1);
38
39 /* Identify the current unit */
40 current_dunit=petCunitId(dft->unit);
41 if(current_dunit==CUNIT_UNKNOWN) return(2);
42 /* If unit is already the requested one, then return */
43 if(current_dunit==dunit) return(0);
44
45 /* Determine the conversion factor to kBq/cc or MBq */
46 switch(current_dunit) {
47 case CUNIT_BQ_PER_ML: f*=0.001; unit_type=1; break;
48 case CUNIT_KBQ_PER_ML: f*=1.0; unit_type=1; break;
49 case CUNIT_MBQ_PER_ML: f*=1000.0; unit_type=1; break;
50 case CUNIT_NCI_PER_ML: f*=0.037; unit_type=1; break;
51 case CUNIT_UCI_PER_ML: f*=37.0; unit_type=1; break;
52 case CUNIT_BQ: f*=0.000001; unit_type=2; break;
53 case CUNIT_KBQ: f*=0.001; unit_type=2; break;
54 case CUNIT_MBQ: f*=1.0; unit_type=2; break;
55 case CUNIT_GBQ: f*=1000.0; unit_type=2; break;
56 case CUNIT_NCI: f*=0.000037; unit_type=2; break;
57 case CUNIT_UCI: f*=0.037; unit_type=2; break;
58 case CUNIT_MCI: f*=37.0; unit_type=2; break;
59 default: return(2);
60 }
61
62 /* Determine the conversion factor from kBq/cc or MBq to the required unit */
63 if(unit_type==1) switch(dunit) { // concentrations
64 case CUNIT_BQ_PER_ML: f*=1000.0; break;
65 case CUNIT_KBQ_PER_ML: f*=1.0; break;
66 case CUNIT_MBQ_PER_ML: f*=0.001; break;
67 case CUNIT_NCI_PER_ML: f/=0.037; break;
68 case CUNIT_UCI_PER_ML: f/=37.0; break;
69 default: return(3);
70 } else if(unit_type==2) switch(dunit) { // doses
71 case CUNIT_BQ: f*=1000000.0; break;
72 case CUNIT_KBQ: f*=1000.0; break;
73 case CUNIT_MBQ: f*=1.0; break;
74 case CUNIT_GBQ: f*=0.001; break;
75 case CUNIT_NCI: f/=0.000037; break;
76 case CUNIT_UCI: f/=0.037; break;
77 case CUNIT_MCI: f/=37.0; break;
78 default: return(3);
79 } else
80 return(3);
81
82 /* Convert the data values */
83 if(f==1.0) return(0);
84 for(fi=0; fi<dft->frameNr; fi++) {
85 for(ri=0; ri<dft->voiNr; ri++) {
86 if(!isnan(dft->voi[ri].y[fi])) dft->voi[ri].y[fi]*=f;
87 if(!isnan(dft->voi[ri].y2[fi])) dft->voi[ri].y2[fi]*=f;
88 if(!isnan(dft->voi[ri].y3[fi])) dft->voi[ri].y3[fi]*=f;
89 }
90 }
91
92 /* Set the new unit string */
93 dftUnitToDFT(dft, dunit);
94
95 return(0);
96}

Referenced by cunit_check_dft_vs_img(), dftReadinput(), dftReadModelingData(), and dftReadReference().

◆ dftUnitToDFT()

void dftUnitToDFT ( DFT * dft,
int dunit )
extern

Set DFT calibration unit string

Definition at line 11 of file dftunit.c.

12{
13 strcpy(dft->unit, dftUnit(dunit));
14}

Referenced by csv2dft_a(), csv2dft_b(), csv2dft_linkset(), csv2dft_mat(), dftUnitConversion(), and tsvRead().

◆ dftValidNr()

int dftValidNr ( DFT * dft,
double tstart,
double tstop,
int index )
extern

Determine the nr of valid data points inside the given time range.

Returns
The number of valid data points.
Parameters
dftPointer to DFT struct
tstartTime range start
tstopTime range stop
indexIndex of TAC to use; enter <0 to use all, in which case the minimum number of valid points is returned.

Definition at line 1638 of file dft.c.

1648 {
1649 if(dft==NULL || dft->voiNr<0 || dft->frameNr<0) return(0);
1650 if(index>dft->voiNr-1) return(0);
1651 if(index>=0) { // TAC index given
1652 int n=0;
1653 double x;
1654 for(int i=0; i<dft->frameNr; i++) {
1655 if(dft->timetype!=DFT_TIME_STARTEND) x=dft->x[i];
1656 else x=0.5*(dft->x1[i]+dft->x2[i]);
1657 if(isnan(x) || !isfinite(x)) continue;
1658 if(x<tstart || x>tstop) continue;
1659 if(isnan(dft->voi[index].y[i]) || !isfinite(dft->voi[index].y[i]))
1660 continue;
1661 n++;
1662 }
1663 return(n);
1664 }
1665 /* Get min nr of all TACs */
1666 int n=0, minn=0;
1667 minn=dftValidNr(dft, tstart, tstop, 0);
1668 for(int j=1; j<dft->voiNr; j++) {
1669 n=dftValidNr(dft, tstart, tstop, j);
1670 if(n<minn) minn=n;
1671 }
1672 return(minn);
1673}
int dftValidNr(DFT *dft, double tstart, double tstop, int index)
Definition dft.c:1638

Referenced by dftValidNr().

◆ dftWrite()

int dftWrite ( DFT * data,
char * filename )
extern

Write DFT data, usually containing regional time-activity curves (TACs) into specified file.

The file format specified in data is applied. Number of decimals can be determined by changing global variable DFT_NR_OF_DECIMALS.

See also
dftRead, resWrite
Returns
Returns 0 when successful, in case of error sets dfterrmsg.
Parameters
dataPointer to DFT structure which contents are to be written.
filenameFile name where DFT contents are written. If file exists, original file is renamed to a backup file.

Definition at line 594 of file dftio.c.

600 {
601 int i, j, n, sw, mfw, prec;
602 char tmp[1024], tmp2[128], is_stdout=0;
603 FILE *fp;
604
605
606 /* Check that there is some data to write */
607 if(data->voiNr<1 || data->frameNr<1) {strcpy(dfterrmsg, "no data"); return 1;}
608
609 /* If format if DFT_FORMAT_HTML or extension is *.HTM(L),
610 write in HTML format */
611 if(data->_type==DFT_FORMAT_HTML || fncasematch(filename, "*.htm")==1 || fncasematch(filename, "*.html")==1) {
612 return(dftWriteHTML(data, filename, 1));
613 }
614
615 /* Check if writing to stdout */
616 if(!strcasecmp(filename, "stdout")) is_stdout=1;
617
618 /* Set minimum field width and precision for concentrations */
619 mfw=11; if(DFT_NR_OF_DECIMALS>3) mfw+=DFT_NR_OF_DECIMALS-3;
620 prec=0; if(DFT_NR_OF_DECIMALS>prec) prec=DFT_NR_OF_DECIMALS;
621
622 /* Check if file exists; backup, if necessary */
623 if(!is_stdout) (void)backupExistingFile(filename, NULL, NULL);
624
625 /* Open output file */
626 if(is_stdout) fp=(FILE*)stdout;
627 else if((fp = fopen(filename, "w")) == NULL) {strcpy(dfterrmsg, "cannot open file"); return 2;}
628
629 /* Write title lines */
630 if(data->_type==DFT_FORMAT_STANDARD) {
631 /* 1st line with filetype identification string and region names */
632 n=fprintf(fp, "%s", DFT_VER);
633 if(n==0) {strcpy(dfterrmsg, "disk full"); if(!is_stdout) fclose(fp); return 3;}
634 for(i=0; i<data->voiNr; i++) fprintf(fp,"\t%s", data->voi[i].voiname);
635 if(data->isweight) fprintf(fp,"\t%s", "weight");
636 fprintf(fp, "\n");
637 /* 2nd line with study identification and 2nd name (hemisphere) */
638 if(strlen(data->studynr)) strlcpy(tmp, data->studynr, 11); else strcpy(tmp, ".");
639 fprintf(fp, "%s", tmp);
640 for(i=0; i<data->voiNr; i++) {
641 if(strlen(data->voi[i].hemisphere)) strcpy(tmp, data->voi[i].hemisphere);
642 else strcpy(tmp, ".");
643 fprintf(fp, "\t%s", tmp);
644 }
645 if(data->isweight) fprintf(fp,"\t%s", ".");
646 fprintf(fp, "\n");
647 /* 3rd line with unit and plane names */
648 if(strlen(data->unit)) strcpy(tmp, data->unit); else strcpy(tmp, ".");
649 fprintf(fp, "%s", tmp);
650 for(i=0; i<data->voiNr; i++) {
651 if(strlen(data->voi[i].place)) strcpy(tmp, data->voi[i].place);
652 else strcpy(tmp, ".");
653 fprintf(fp, "\t%s", tmp);
654 }
655 if(data->isweight) fprintf(fp,"\t%s", ".");
656 fprintf(fp, "\n");
657 /* 4th line with time type & unit and region volumes */
658 switch(data->timetype) {
659 case DFT_TIME_MIDDLE:
660 if(data->timeunit==TUNIT_MM || data->timeunit==TUNIT_UM || data->timeunit==TUNIT_CM)
661 strcpy(tmp, "Distance ");
662 else
663 strcpy(tmp, "Time ");
664 break;
665 case DFT_TIME_START: strcpy(tmp, "Start "); break;
666 case DFT_TIME_END: strcpy(tmp, "End "); break;
668 if(data->timeunit==TUNIT_MM || data->timeunit==TUNIT_UM || data->timeunit==TUNIT_CM)
669 strcpy(tmp, "Distances ");
670 else
671 strcpy(tmp, "Times ");
672 break;
673 }
674 snprintf(tmp2, 128, "(%s)", petTunit(data->timeunit)); strcat(tmp, tmp2);
675 fprintf(fp, "%s", tmp);
676 for(i=0; i<data->voiNr; i++) {
677 if(data->voi[i].size>=0.0) sprintf(tmp, "%.*e", prec, data->voi[i].size);
678 else strcpy(tmp, ".");
679 fprintf(fp, "\t%s", tmp);
680 }
681 if(data->isweight) fprintf(fp,"\t%s", ".");
682 fprintf(fp, "\n");
683 } else if(data->_type==DFT_FORMAT_PMOD) { // write PMOD title line
684 char *cptr, tunit[128], cunit[128]; // Set units to format accepted by PMOD
685 if(data->timeunit==TUNIT_SEC) strcpy(tunit, "seconds");
686 else if(data->timeunit==TUNIT_MIN) strcpy(tunit, "minutes");
687 else strcpy(tunit, petTunit(data->timeunit));
688 if(petCunitId(data->unit)==CUNIT_UNITLESS) strcpy(cunit, "1/1"); else strcpy(cunit, data->unit);
689 cptr=strstr(cunit, "mL"); if(cptr!=NULL) {*cptr='c'; cptr++; *cptr='c';}
690 if(data->timetype==DFT_TIME_STARTEND) fprintf(fp, "start[%s]\tend[%s]", tunit, cunit);
691 else fprintf(fp, "time[%s]", tunit);
692 for(i=0; i<data->voiNr; i++) {
693 /* write roi names, must not include spaces */
694 char *s=strdup(data->voi[i].name);
695 strReplaceChar(s, ' ', '-'); fprintf(fp, "\t%s", s); free(s);
696 /* write calibration unit when necessary */
697 if(i==0 && data->timetype!=DFT_TIME_STARTEND) fprintf(fp, "[%s]", cunit);
698 }
699 if(data->isweight) fprintf(fp,"\t%s", "weight");
700 fprintf(fp, "\n");
701 }
702
703 /* Make sure that only frame mid times are saved without titles */
704 if(data->_type==DFT_FORMAT_PLAIN && data->timetype!=DFT_TIME_MIDDLE) sw=0;
705 else sw=data->timetype;
706
707 /* Write data */
708 for(j=0; j<data->frameNr; j++) {
709 /* Time(s) */
710 switch(sw) {
711 case 0: fprintf(fp, "%.5f", data->x[j]); break;
712 case 1: fprintf(fp, "%.5f", data->x1[j]); break;
713 case 2: fprintf(fp, "%.5f", data->x2[j]); break;
714 case 3: fprintf(fp, "%.5f\t%.5f", data->x1[j], data->x2[j]); break;
715 }
716 /* y values */
717 for(i=0; i<data->voiNr; i++) {
718 if(!isnan(data->voi[i].y[j])) sprintf(tmp, "%.*e", prec, data->voi[i].y[j]);
719 else strcpy(tmp, ".");
720 fprintf(fp, "\t%s", tmp);
721 }
722 if(data->isweight) {
723 if(data->_type==DFT_FORMAT_STANDARD || data->_type==DFT_FORMAT_PMOD) {
724 if(!isnan(data->w[j])) sprintf(tmp, "%.*e", prec, data->w[j]);
725 else strcpy(tmp, ".");
726 fprintf(fp,"\t%s", tmp);
727 }
728 }
729 n=fprintf(fp, "\n");
730 if(n==0) {strcpy(dfterrmsg, "disk full"); if(!is_stdout) fclose(fp); return 3;}
731 }
732
733 /* Write comments */
734 if(1) { //data->_type!=DFT_FORMAT_PMOD) {
735 n=strnlen(data->comments, _DFT_COMMENT_LEN);
736 if(n) for(i=0; i<n; i++) {
737 if(i>0 && data->comments[i]=='#' && (data->comments[i-1]!='\n' && data->comments[i-1]!='\r'))
738 fputc('\n', fp);
739 fputc(data->comments[i], fp);
740 }
741 }
742
743 /* Close file */
744 if(!is_stdout) {fflush(fp); fclose(fp);}
745
746 return 0;
747}
int backupExistingFile(char *filename, char *backup_ext, char *status)
Definition backup.c:14
int dftWriteHTML(DFT *dft, char *fname, int orientation)
Definition dftio.c:757
#define DFT_FORMAT_HTML
void strReplaceChar(char *str, char c1, char c2)
Definition strext.c:159

Referenced by plotdata_as_dft().

◆ dftWriteHTML()

int dftWriteHTML ( DFT * dft,
char * fname,
int orientation )
extern

Write DFT contents in HTML table format If file exists, a backup file (+BACKUP_EXTENSION) is written also. If "stdout" is given as filename, output is directed to stdout In case of an error, description is written in dfterrmsg.

Returns
Returns 0 if ok.
Parameters
dftInput DFT
fnameHTML filename
orientationTable orientation: 1=original, 2=transposed

Definition at line 757 of file dftio.c.

764 {
765 int ri, fi, is_stdout=0, ret;
766 char tmp[FILENAME_MAX];
767 FILE *fp;
768
769
770 /* Check input */
771 strcpy(dfterrmsg, "invalid input to dftWriteHTML()");
772 if(dft==NULL || dft->frameNr<1 || dft->voiNr<1) return(1);
773 if(fname==NULL || strlen(fname)<1) return(1);
774 strcpy(dfterrmsg, "");
775 /* Check if writing to stdout */
776 if(!strcasecmp(fname, "stdout")) is_stdout=1;
777
778 /* Check if file exists; backup, if necessary */
779 if(!is_stdout && access(fname, 0) != -1) {
780 strcpy(tmp, fname); strcat(tmp, BACKUP_EXTENSION); rename(fname, tmp);}
781 strcpy(dfterrmsg, "cannot write file");
782
783 /* Open output file */
784 if(is_stdout) fp=(FILE*)stdout;
785 else if((fp=fopen(fname, "w"))==NULL) {strcpy(dfterrmsg, "cannot open file"); return(2);}
786
787 /* Write XHTML 1.1 doctype and head */
789 strcpy(dfterrmsg, "disk full"); if(!is_stdout) fclose(fp); return(3);
790 }
791
792 /* Start writing the body of the HTML file */
793 ret=fprintf(fp, "<body>\n");
794 if(ret==0) {strcpy(dfterrmsg, "disk full"); if(!is_stdout) fclose(fp); return(3);}
795
796 /* Start the div for table, and the table */
797 fprintf(fp, "\n<div id=\"table\">\n");
798 fprintf(fp, "<table>\n");
799
800 /* Write the title lines, if there are titles, into the head of the table */
801 if(dft->_type!=DFT_FORMAT_PLAIN) {
802 fprintf(fp, "<thead>\n");
803 if(orientation!=2) {
804 /* Empty cell and Region names */
805 fprintf(fp, "<tr><td> </td>\n");
806 for(ri=0; ri<dft->voiNr; ri++) {
807 char *senc=strEncodeForXML(dft->voi[ri].voiname);
808 if(senc==NULL) fprintf(fp, "<th>%s</th>\n", dft->voi[ri].voiname);
809 else {fprintf(fp, "<th>%s</th>\n", senc); free(senc);}
810 }
811 fprintf(fp, "</tr>\n");
812 /* Study number and Hemispheres */
813 fprintf(fp, "<tr><th>%s</th>\n", dft->studynr);
814 for(ri=0; ri<dft->voiNr; ri++) {
815 char *senc=strEncodeForXML(dft->voi[ri].hemisphere);
816 if(senc==NULL) fprintf(fp, "<th>%s</th>\n", dft->voi[ri].hemisphere);
817 else {fprintf(fp, "<th>%s</th>\n", senc); free(senc);}
818 }
819 fprintf(fp, "</tr>\n");
820 /* Unit and Places */
821 fprintf(fp, "<tr><th>%s</th>\n", dft->unit);
822 for(ri=0; ri<dft->voiNr; ri++) {
823 char *senc=strEncodeForXML(dft->voi[ri].place);
824 if(senc==NULL) fprintf(fp, "<th>%s</th>\n", dft->voi[ri].place);
825 else {fprintf(fp, "<th>%s</th>\n", senc); free(senc);}
826 }
827 fprintf(fp, "</tr>\n");
828 /* Time unit and Volumes */
829 fprintf(fp, "<tr><th>%s</th>\n", petTunit(dft->timeunit));
830 for(ri=0; ri<dft->voiNr; ri++)
831 fprintf(fp, "<th>%g</th>\n", dft->voi[ri].size);
832 fprintf(fp, "</tr>\n");
833 } else if(orientation==2) {
834 /* Study number and Unit */
835 fprintf(fp, "<tr><th>%s</th>\n", dft->studynr);
836 fprintf(fp, "<th>%s</th></tr>\n", dft->unit);
837 }
838 /* End the head of table */
839 fprintf(fp, "</thead>\n");
840 }
841
842 /* Write the DFT data into the body of the table */
843 fprintf(fp, "<tbody>\n");
844
845 /* If transposed, write titles */
846 if(orientation==2) {
847 fprintf(fp, "<tr><th>Region</th><th>Hemisphere</th><th>Plane</th>\n");
848 fprintf(fp, "<th>Volume</th></tr>\n");
849 }
850 if(orientation!=2) { /* Not transposed */
851 for(fi=0; fi<dft->frameNr; fi++) {
852 if(fi%2) strcpy(tmp, "evenframe"); else strcpy(tmp, "oddframe");
853 /* Time */
854 fprintf(fp, "<tr class=\"%s\"><th>%g</th>\n", tmp, dft->x[fi]);
855 /* Values */
856 for(ri=0; ri<dft->voiNr; ri++)
857 fprintf(fp, "<th>%g</th>", dft->voi[ri].y[fi]);
858 fprintf(fp, "</tr>\n");
859 }
860 } else { /* transposed */
861 for(ri=0; ri<dft->voiNr; ri++) {
862 if(ri%2) strcpy(tmp, "evenframe"); else strcpy(tmp, "oddframe");
863 fprintf(fp, "<tr class=\"%s\">", tmp);
864 /* Region names */
865 char *senc;
866 senc=strEncodeForXML(dft->voi[ri].voiname);
867 if(senc==NULL) fprintf(fp, "<th>%s</th>", dft->voi[ri].voiname);
868 else {fprintf(fp, "<th>%s</th>", senc); free(senc);}
869 senc=strEncodeForXML(dft->voi[ri].hemisphere);
870 if(senc==NULL) fprintf(fp, "<th>%s</th>", dft->voi[ri].hemisphere);
871 else {fprintf(fp, "<th>%s</th>", senc); free(senc);}
872 senc=strEncodeForXML(dft->voi[ri].place);
873 if(senc==NULL) fprintf(fp, "<th>%s</th>\n", dft->voi[ri].place);
874 else {fprintf(fp, "<th>%s</th>\n", senc); free(senc);}
875 /* Region volume */
876 fprintf(fp, "<td>%g</td>\n", dft->voi[ri].size);
877 /* Values */
878 for(fi=0; fi<dft->frameNr; fi++) {
879 fprintf(fp, "<td>%g</td>", dft->voi[ri].y[fi]);
880 }
881 fprintf(fp, "</tr>\n");
882 }
883 }
884 /* End the table body and table */
885 fprintf(fp, "</tbody></table>\n");
886
887 /* Stop writing the body of the HTML file, and end the file */
888 fprintf(fp, "</div>\n");
889 ret=fprintf(fp, "</body></html>\n\n");
890 if(ret==0) {
891 strcpy(dfterrmsg, "disk full");
892 if(!is_stdout) fclose(fp);
893 return(3);
894 }
895
896 /* Close file */
897 if(!is_stdout) {fflush(fp); fclose(fp);}
898 strcpy(dfterrmsg, "");
899
900 return(0);
901}
int dftWriteXHTML11_doctype(FILE *fp)
Definition dftio.c:908
int dftWriteXHTML11_head(FILE *fp, char *author_name)
Definition dftio.c:926
#define BACKUP_EXTENSION
char * strEncodeForXML(const char *s)
Definition strext.c:364

Referenced by dftWrite().

◆ dftWriteXHTML11_doctype()

int dftWriteXHTML11_doctype ( FILE * fp)
extern

Write XHTML 1.1 doctype into an opened file pointer.

Returns
Returns 0 if successful, non-zero in case of a failure.

Definition at line 908 of file dftio.c.

910 {
911 int n;
912 if(fp==NULL) return(1);
913 n=fprintf(fp, "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" ");
914 n+=fprintf(fp, "\"https://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n");
915 if(n<20) return(2);
916 n=fprintf(fp, "<html xmlns=\"https://www.w3.org/1999/xhtml\" xml:lang=\"en\">\n\n");
917 if(n<20) return(2);
918 return(0);
919}

Referenced by dftWriteHTML().

◆ dftWriteXHTML11_head()

int dftWriteXHTML11_head ( FILE * fp,
char * author_name )
extern

Write XHTML 1.1 head for DFT file into an opened file pointer.

Returns
Returns 0 if successful, non-zero in case of a failure.
Parameters
fpFile pointer where to write
author_nameAuthor name, for example software name

Definition at line 926 of file dftio.c.

931 {
932 int n;
933 if(fp==NULL) return(1);
934
935 n=fprintf(fp, "<head>\n"); if(n<6) return(2);
936 fprintf(fp, " <title>PET data</title>\n");
937 fprintf(fp, " <meta http-equiv=\"content-type\" content=\"text/html; charset=iso-8859-1\" />\n");
938 fprintf(fp, " <meta http-equiv=\"content-language\" content=\"en-gb\" />\n");
939 fprintf(fp, " <meta name=\"author\" content=\"%s\" />\n", author_name);
940 fprintf(fp, " <meta name=\"ProgId\" content=\"Excel.Sheet\" />\n");
941 fprintf(fp, " <link rel=\"icon\" href=\"https://www.turkupetcentre.net/favicon.ico\" type=\"image/x-icon\" />\n");
942 fprintf(fp, " <link rel=\"shortcut icon\" href=\"https://www.turkupetcentre.net/favicon.ico\" type=\"image/x-icon\" />\n");
943 /* write local CSS with basic settings in case that external CSS is not available */
944 fprintf(fp, " <style type=\"text/css\">\n");
945 fprintf(fp, " thead {background-color:#999999; color:black;}\n");
946 fprintf(fp, " table {text-align:left; width:100%%; border-collapse:collapse; empty-cells:show;}\n");
947 fprintf(fp, " td {border:1px solid black;}\n");
948 fprintf(fp, " .oddframe {background-color:#FFFFFF; color:black;}\n");
949 fprintf(fp, " .evenframe {background-color:#CCCCCC; color:black;}\n");
950 fprintf(fp, " #regcontainer ul {margin-left:0; padding-left:0;}\n");
951 fprintf(fp, " #regcontainer ul li {display:inline; list-style-type:none;}\n");
952 fprintf(fp, " #regcontainer a {padding:2px 4px;}\n");
953 fprintf(fp, " <!--table\n");
954 fprintf(fp, " {mso-displayed-decimal-separator:\"\\.\";\n");
955 fprintf(fp, " mso-displayed-thousand-separator:\" \";}\n");
956 fprintf(fp, " -->\n");
957 fprintf(fp, " </style>\n");
958 /* load external CSS with more fancy settings */
959 fprintf(fp, " <link rel=\"stylesheet\" type=\"text/css\" ");
960 fprintf(fp, "href=\"https://www.turkupetcentre.net/dft.css\" />\n");
961 fprintf(fp, "</head>\n");
962 if(n<7) return(2);
963 return(0);
964}

Referenced by dftWriteHTML().

◆ factorial()

unsigned int factorial ( unsigned int n)
extern

Calculate factorial of given number.

See also
lfactorial, igam, igamc
Returns
Returns factorial n!, or zero if factorial would cause wrap-around.
Parameters
nInteger n, from which the factorial is calculated.
Note
Wrap-around will occur if n>12.

Definition at line 1678 of file mathfunc.c.

1683 {
1684 if(n<1) return(1);
1685 if(n>12) return(0);
1686 return(n*factorial(n-1));
1687}
unsigned int factorial(unsigned int n)
Definition mathfunc.c:1678

Referenced by factorial().

◆ fit_allocate_with_dft()

int fit_allocate_with_dft ( FIT * fit,
DFT * dft )
extern

Allocate memory for regional function fits based on information in DFT.

Returns
Returns 0 if successful, otherwise <>0.
Parameters
fitPointer to initiated FIT struct which will be allocated here and filled with ROI names etc.
dftRegional data from where necessary information is read.

Definition at line 14 of file fitres.c.

19 {
20 int ri;
21
22 //printf("fit_allocate_with_dft()\n"); fflush(stdout);
23 // Check the input data
24 if(fit==NULL || dft==NULL || dft->voiNr<1) return 1;
25 // Allocate memory
26 if(fitSetmem(fit, dft->voiNr)!=0) return 2;
27 fit->voiNr=dft->voiNr;
28 /* Set header contents */
29 fit->time=time(NULL); // Set current time to results
30 strcpy(fit->unit, dft->unit);
31 fit->timeunit=dft->timeunit;
32 strcpy(fit->studynr, dft->studynr);
33 /* Copy region names, etc */
34 for(ri=0; ri<dft->voiNr; ri++) {
35 strcpy(fit->voi[ri].name, dft->voi[ri].name);
36 strcpy(fit->voi[ri].voiname, dft->voi[ri].voiname);
37 strcpy(fit->voi[ri].hemisphere, dft->voi[ri].hemisphere);
38 strcpy(fit->voi[ri].place, dft->voi[ri].place);
39 fit->voi[ri].dataNr=dft->frameNr;
40 if(dft->timetype==DFT_TIME_STARTEND) {
41 fit->voi[ri].start=dft->x1[0]; fit->voi[ri].end=dft->x2[dft->frameNr-1];
42 } else {
43 fit->voi[ri].start=dft->x[0]; fit->voi[ri].end=dft->x[dft->frameNr-1];
44 }
45 }
46
47 return 0;
48}
int fitSetmem(FIT *fit, int voiNr)
Definition mathfunc.c:154
int timeunit
int voiNr
char unit[MAX_UNITS_LEN+1]
char studynr[MAX_STUDYNR_LEN+1]
FitVOI * voi
time_t time
double end
char place[MAX_REGIONSUBNAME_LEN+1]
char hemisphere[MAX_REGIONSUBNAME_LEN+1]
char voiname[MAX_REGIONSUBNAME_LEN+1]
char name[MAX_REGIONNAME_LEN+1]
double start

Referenced by dft_end_line().

◆ fitDerivEval()

int fitDerivEval ( FitVOI * r,
double x,
double * yd )
extern

Evaluates yd=Df(x).

See also
fitEval, fitIntegralEval
Returns
Returns 0, if ok.
Parameters
rFit parameters of a single region
xTime where to evaluate the derivative of the function
ydThe derivative of the function is returned here

Definition at line 1540 of file mathfunc.c.

1547 {
1548 double a, f, xt, t;
1549
1550 if(r==NULL || yd==NULL) return 1;
1551 *yd=nan("");
1552 switch(r->type) {
1553 case 301:
1554 break;
1555 case 302:
1556 break;
1557 case 303:
1558 break;
1559 case 304:
1560 break;
1561 case 305:
1562 break;
1563 case 321:
1564 f=r->p[0]*r->p[1]*exp(r->p[1]*x)*(1.0-exp(r->p[2]*x)) - r->p[0]*r->p[2]*exp((r->p[1]+r->p[2])*x);
1565 *yd=f;
1566 break;
1567 case 322:
1568 f=0.0;
1569 a=r->p[0]*r->p[1]*exp(r->p[1]*x)*(1.0-exp(r->p[2]*x)) - r->p[0]*r->p[2]*exp((r->p[1]+r->p[2])*x); f+=a;
1570 a=r->p[3]*r->p[4]*exp(r->p[4]*x)*(1.0-exp(r->p[5]*x)) - r->p[3]*r->p[5]*exp((r->p[4]+r->p[5])*x); f+=a;
1571 *yd=f;
1572 break;
1573 case 323:
1574 f=0.0;
1575 a=r->p[0]*r->p[1]*exp(r->p[1]*x)*(1.0-exp(r->p[2]*x)) - r->p[0]*r->p[2]*exp((r->p[1]+r->p[2])*x); f+=a;
1576 a=r->p[3]*r->p[4]*exp(r->p[4]*x)*(1.0-exp(r->p[5]*x)) - r->p[3]*r->p[5]*exp((r->p[4]+r->p[5])*x); f+=a;
1577 a=r->p[6]*r->p[7]*exp(r->p[7]*x)*(1.0-exp(r->p[8]*x)) - r->p[6]*r->p[8]*exp((r->p[7]+r->p[8])*x); f+=a;
1578 *yd=f;
1579 break;
1580 case 331: break; /* not yet applied */
1581 case 351: break; /* not yet applied */
1582 case 1312:
1583 t=r->p[4]; xt=x-t; f=0.0;
1584 if(xt>0.0) {
1585 double A1, A2, L1, L2;
1586 A1=r->p[0]; L1=r->p[1]; A2=r->p[2]; L2=r->p[3];
1587 f= A1*exp(L1*xt) + A2*L2*exp(L2*xt) + (A1*xt -A2)*L1*exp(L1*xt);
1588 }
1589 *yd=f;
1590 break;
1591 case 1313:
1592 t=r->p[6]; xt=x-t; f=0.0;
1593 if(xt>0.0) {
1594 double A1, A2, A3, L1, L2, L3;
1595 A1=r->p[0]; L1=r->p[1]; A2=r->p[2]; L2=r->p[3]; A3=r->p[4]; L3=r->p[5];
1596 f= A1*exp(L1*xt) + A2*L2*exp(L2*xt) + A3*L3*exp(L3*xt) +
1597 (A1*xt -A2 -A3)*L1*exp(L1*xt);
1598 }
1599 *yd=f;
1600 break;
1601 case 1314: break;
1602 t=r->p[8]; xt=x-t; f=0.0;
1603 if(xt>0.0) {
1604 double A1, A2, A3, A4, L1, L2, L3, L4;
1605 A1=r->p[0]; L1=r->p[1]; A2=r->p[2]; L2=r->p[3]; A3=r->p[4]; L3=r->p[5];
1606 A4=r->p[6]; L4=r->p[7];
1607 f= A1*exp(L1*xt) + A2*L2*exp(L2*xt) + A3*L3*exp(L3*xt) +
1608 A4*L4*exp(L4*xt) + (A1*xt -A2 -A3 -A4)*L1*exp(L1*xt);
1609 }
1610 *yd=f;
1611 break;
1612 case 1401:
1613 case 1402:
1614 xt=x-r->p[3]; if(xt<=0.0 || r->p[2]==0.0) {
1615 f=0.0;
1616 } else {
1617 f=r->p[0]*pow(xt, r->p[1]-1.0)*exp(-xt/r->p[2])*(r->p[1]-(xt/r->p[2]));
1618 }
1619 *yd=f;
1620 break;
1621 case 1421:
1622 xt=x-r->p[0]; if(xt<=0.0) {
1623 *yd=0.0;
1624 } else {
1625 a=pow(xt/r->p[2], r->p[3]-1.0);
1626 *yd=r->p[1]*r->p[3]*a*exp(-a*xt/r->p[2])/r->p[2];
1627 }
1628 break;
1629 case 1801:
1630 xt=x-r->p[0]; if(xt<=0.0) {
1631 *yd=0.0;
1632 } else {
1633 a=pow(r->p[2], r->p[3])+pow(xt, r->p[3]);
1634 *yd=r->p[1]*r->p[3]*(pow(xt, r->p[3]-1.0)/a - pow(xt, 2.0*r->p[3]-1.0)/(a*a));
1635 }
1636 break;
1637 case 2111: *yd=nan(""); break; /* no application */
1638 case 9501: *yd=nan(""); break; /* cannot be applied to one point only */
1639 case 9502: *yd=nan(""); break; /* cannot be applied to one point only */
1640 case 9503: *yd=nan(""); break; /* cannot be applied to one point only */
1641 case 9701: *yd=nan(""); break; /* cannot be applied to one point only */
1642 default:
1643 *yd=nan("");
1644 }
1645 if(isnan(*yd)) return(3);
1646 return(0);
1647}
double p[MAX_FITPARAMS]

Referenced by fitDerivEvaltac().

◆ fitDerivEvaltac()

int fitDerivEvaltac ( FitVOI * r,
double * x,
double * yd,
int dataNr )
extern

Evaluates an array yd[i]=Df(x[i]).

See also
fitEvaltac, fitIntegralEvaltac, fitDerivEvaltac
Returns
Returns 0, if ok.
Parameters
rFit parameters of a single region
xTimes where to evaluate the function derivatives
ydArray for the function derivatives
dataNrNr of (x,yd) data

Definition at line 1655 of file mathfunc.c.

1664 {
1665 int i;
1666
1667 if(r==NULL || x==NULL || yd==NULL || dataNr<1) return(1);
1668 for(i=0; i<dataNr; i++) if(fitDerivEval(r, x[i], yd+i)) return(2);
1669 return(0);
1670}
int fitDerivEval(FitVOI *r, double x, double *yd)
Definition mathfunc.c:1540

◆ fitEmpty()

void fitEmpty ( FIT * fit)
extern

Free memory allocated for FIT. All contents are cleared.

See also
fitInit, fitRead, fitWrite
Parameters
fitPointer to FIT struct.

Definition at line 18 of file mathfunc.c.

21 {
22 if(fit==NULL) return;
23 if(fit->_voidataNr>0) {
24 free((char*)(fit->voi));
25 fit->_voidataNr=0;
26 }
27 fit->voiNr=0;
28 fit->datafile[0]=fit->studynr[0]=fit->unit[0]=fit->program[0]=(char)0;
29 fit->timeunit=0;
30 fit->time=0;
31}
int _voidataNr
char datafile[FILENAME_MAX]
char program[1024]

Referenced by fitRead(), and fitSetmem().

◆ fitEval()

int fitEval ( FitVOI * r,
double x,
double * y )
extern

Evaluate y=f(x).

See also
fitEvaltac, fitIntegralEval, fitDerivEval
Returns
Returns 0, if ok.
Parameters
rFit parameters of a single region
xTime where to evaluate the function
yThe value of the function is returned here

Definition at line 645 of file mathfunc.c.

652 {
653 double a, b, f, sqrx, cubx, xt;
654 int i, j, m, n;
655 double mp[3][5];
656 double mf[]={0.0,0.0,0.0};
657
658 if(r==NULL) return(1);
659 if(MATHFUNC_TEST>0) {
660 printf("fitEval(r, %g, %g): type=%d ;", x, *y, r->type);
661 for(i=0; i<r->parNr; i++) printf(" %g", r->p[i]);
662 printf("\n");
663 }
664 if(y==NULL) return(1);
665 *y=nan("");
666 switch(r->type) {
667 case 100:
668 case 101:
669 case 102:
670 case 103:
671 case 104:
672 case 105:
673 case 106:
674 case 107:
675 case 108:
676 case 109:
677 n=r->type-99; f=0.0; for(i=n-1; i>0; i--) {f+=r->p[i]; f*=x;} f+=r->p[0];
678 *y=f;
679 break;
680 case 211:
681 a=r->p[0]+r->p[2]*x; b=r->p[1]+r->p[3]*x; if(b==0.0) break;
682 f=a/b; *y=f;
683 break;
684 case 221:
685 sqrx=x*x;
686 a=r->p[0]+r->p[2]*x+r->p[4]*sqrx; b=r->p[1]+r->p[3]*x; if(b==0.0) break;
687 f=a/b; *y=f;
688 break;
689 case 222:
690 sqrx=x*x;
691 a=r->p[0]+r->p[2]*x+r->p[4]*sqrx;
692 b=r->p[1]+r->p[3]*x+r->p[5]*sqrx; if(b==0.0) break;
693 f=a/b; *y=f;
694 break;
695 case 232:
696 sqrx=x*x; cubx=sqrx*x;
697 a=r->p[0]+r->p[2]*x+r->p[4]*sqrx+r->p[6]*cubx;
698 b=r->p[1]+r->p[3]*x+r->p[5]*sqrx; if(b==0.0) break;
699 f=a/b; *y=f;
700 break;
701 case 233:
702 sqrx=x*x; cubx=sqrx*x;
703 a=r->p[0]+r->p[2]*x+r->p[4]*sqrx+r->p[6]*cubx;
704 b=r->p[1]+r->p[3]*x+r->p[5]*sqrx+r->p[7]*cubx; if(b==0.0) break;
705 f=a/b; *y=f;
706 break;
707 case 301:
708 f=r->p[0]*exp(r->p[1]*x); *y=f;
709 break;
710 case 302:
711 f=0;
712 a=r->p[0]*exp(r->p[1]*x); f+=a;
713 a=r->p[2]*exp(r->p[3]*x); f+=a;
714 *y=f;
715 break;
716 case 303:
717 f=0;
718 a=r->p[0]*exp(r->p[1]*x); f+=a;
719 a=r->p[2]*exp(r->p[3]*x); f+=a;
720 a=r->p[4]*exp(r->p[5]*x); f+=a;
721 *y=f;
722 break;
723 case 304:
724 f=0;
725 a=r->p[0]*exp(r->p[1]*x); f+=a;
726 a=r->p[2]*exp(r->p[3]*x); f+=a;
727 a=r->p[4]*exp(r->p[5]*x); f+=a;
728 a=r->p[6]*exp(r->p[7]*x); f+=a;
729 *y=f;
730 break;
731 case 305:
732 f=0;
733 a=r->p[0]*exp(r->p[1]*x); f+=a;
734 a=r->p[2]*exp(r->p[3]*x); f+=a;
735 a=r->p[4]*exp(r->p[5]*x); f+=a;
736 a=r->p[6]*exp(r->p[7]*x); f+=a;
737 a=r->p[8]*exp(r->p[9]*x); f+=a;
738 *y=f;
739 break;
740 case 321:
741 f=r->p[0]*exp(r->p[1]*x)*(1.0-exp(r->p[2]*x));
742 *y=f;
743 break;
744 case 322:
745 f=0.0;
746 a=r->p[0]*exp(r->p[1]*x)*(1.0-exp(r->p[2]*x)); f+=a;
747 a=r->p[3]*exp(r->p[4]*x)*(1.0-exp(r->p[5]*x)); f+=a;
748 *y=f;
749 break;
750 case 323:
751 f=0.0;
752 a=r->p[0]*exp(r->p[1]*x)*(1.0-exp(r->p[2]*x)); f+=a;
753 a=r->p[3]*exp(r->p[4]*x)*(1.0-exp(r->p[5]*x)); f+=a;
754 a=r->p[6]*exp(r->p[7]*x)*(1.0-exp(r->p[8]*x)); f+=a;
755 *y=f;
756 break;
757 case 1321:
758 /* A=p0 B=p1 C=p2 D=k=p3 dT=p4 */
759 xt=x-r->p[4]; if(xt<=0.0) {
760 f=0.0;
761 } else {
762 a=exp(-r->p[2]*xt); f=r->p[0]*exp(-r->p[1]*xt)*(1.0-a);
763 if(r->p[3]>0.0)
764 f+=r->p[3]*(r->p[0]/(r->p[1]*(r->p[1]+r->p[2])))
765 *(r->p[2]-((r->p[1]+r->p[2])/a-r->p[1])*exp(-(r->p[1]+r->p[2])*xt));
766 }
767 *y=f;
768 break;
769 case 331:
770 n=(r->parNr-2)/2;
771 if(x<=r->p[0])
772 *y=0.0;
773 else if(x<r->p[0]+r->p[1]) {
774 for(i=0, f=0.0; i<n; i++) {
775 if(r->p[2*i+3]>1.0E-12) b=r->p[2*i+2]/r->p[2*i+3]; else b=r->p[2*i+2];
776 f+=b*(1.0-exp(-r->p[2*i+3]*(x-r->p[0])));
777 }
778 if(r->p[1]>0.0) f*=(1.0/r->p[1]);
779 *y=f;
780 } else {
781 for(i=0, f=0.0; i<n; i++) {
782 if(r->p[2*i+3]>1.0E-12) b=r->p[2*i+2]/r->p[2*i+3]; else b=r->p[2*i+2];
783 f+=b*(exp(-r->p[2*i+3]*(x-r->p[0]-r->p[1])) - exp(-r->p[2*i+3]*(x-r->p[0])));
784 }
785 if(r->p[1]>0.0) f*=(1.0/r->p[1]);
786 *y=f;
787 }
788 break;
789 case 332:
790 if(x<=r->p[0])
791 *y=0.0;
792 else if(x<=r->p[0]+r->p[1]) {
793 f=exp(-r->p[3]*(x-r->p[0]));
794 *y=(r->p[2]/(r->p[3]*r->p[3]))*(1.0-f);
795 } else {
796 f=exp(-r->p[3]*r->p[1]);
797 f+=exp(-r->p[3]*(x-r->p[0]-r->p[1]));
798 f-=2.0*exp(-r->p[3]*(x-r->p[0]));
799 *y=(r->p[2]/(r->p[3]*r->p[3]))*f;
800 }
801 break;
802 case 334:
803 if(x<=r->p[0])
804 *y=0.0;
805 else if(x>r->p[0] && x<=r->p[1]) {
806 *y=r->p[2]*(1.0-exp(r->p[3]*(r->p[0]-x)))/(1.0-exp(r->p[3]*(r->p[0]-r->p[1])));
807 } else {
808 *y=r->p[2]*(exp(r->p[3]*(r->p[1]-x))-exp(r->p[3]*(r->p[0]-x)))/(1.0-exp(r->p[3]*(r->p[0]-r->p[1])));
809 }
810 break;
811 case 351:
812 f=1.0-r->p[0]*(2.0-exp(-r->p[1]*x)-exp(-r->p[2]*x)); *y=f;
813 break;
814 case 403:
815 xt=x-r->p[4]; if(xt<0.0) xt=0.0;
816 f=r->p[0]*(1.0 - r->p[1]*igam(r->p[3], r->p[2]*xt));
817 *y=f;
818 break;
819 case 831:
820 xt=x-r->p[0]; if(xt<=0.0) {
821 f=r->p[1];
822 } else {
823 f=r->p[2]*exp(-r->p[3]*xt*xt*xt/(xt*xt+r->p[4])) + (1.0-r->p[2])*exp(-r->p[5]*xt);
824 f*=r->p[1];
825 }
826 *y=f;
827 break;
828 case 841:
829 f=r->p[0]*pow(x, r->p[1]) / (pow(x, r->p[1]) + r->p[2]);
830 *y=f;
831 break;
832 case 842:
833 f=1.0-r->p[0]*pow(x, r->p[1]) / (pow(x, r->p[1]) + r->p[2]);
834 *y=f;
835 break;
836 case 843:
837 f=1.0 - r->p[0]*(1.0+r->p[3]*x)*pow(x, r->p[1]) / (pow(x, r->p[1]) + r->p[2]);
838 *y=f;
839 break;
840 case 844:
841 if(r->parNr>4) xt=x-r->p[4]; else xt=x; // delay time accounted, if avail
842 if(xt<=0.0) f=r->p[3];
843 else {a=pow(xt, r->p[1]); f=r->p[0]*a/(a + r->p[2]) + r->p[3];}
844 *y=f;
845 break;
846 case 845:
847 f=r->p[0] - r->p[0]*pow(x, r->p[1]) / (pow(x, r->p[1]) + r->p[2]);
848 *y=f;
849 break;
850 case 846:
851 xt=x-r->p[4]; if(xt<=0.0) {
852 f=r->p[3];
853 } else {
854 a=pow(xt, r->p[1]);
855 f=r->p[3]+(r->p[0]-r->p[3])*a/(a+r->p[2]);
856 }
857 *y=f;
858 break;
859 case 847:
860 xt=x-r->p[4]; if(xt<=0.0) {
861 f=1.0-r->p[3];
862 } else {
863 a=pow(xt, r->p[1]);
864 f=1.0-r->p[3]-(r->p[0]-r->p[3])*a/(a+r->p[2]);
865 }
866 *y=f;
867 break;
868 case 848:
869 xt=x-r->p[4]; if(xt<=0.0) {
870 f=r->p[3];
871 } else {
872 a=pow(xt, r->p[1]);
873 f=r->p[3] * (1.0 - (1.0-r->p[0])*a/(r->p[2]+a));
874 }
875 *y=f;
876 break;
877 case 849:
878 xt=x-r->p[4]; if(xt<=0.0) {
879 f=1.0-r->p[3];
880 } else {
881 a=pow(xt, r->p[1]);
882 f=1.0 - r->p[3] * (1.0 - (1.0-r->p[0])*a/(r->p[2]+a));
883 }
884 *y=f;
885 break;
886 case 851:
887 a=r->p[0]*x; a*=a; f=1.0/pow(1.0+a, r->p[1]);
888 *y=f;
889 break;
890 case 852:
891 a=r->p[0]*x; a*=a; f=1.0 - 1.0/pow(1.0+a, r->p[1]);
892 *y=f;
893 break;
894 case 861:
895 xt=x-r->p[3]; if(xt<=0.0) {
896 f=1.0;
897 } else {
898 f=pow(1.0+pow(r->p[0]*xt, r->p[1]), -r->p[2]);
899 }
900 *y=f;
901 break;
902 case 862:
903 xt=x-r->p[3]; if(xt<=0.0) {
904 f=1.0;
905 } else {
906 f=pow(1.0+pow(r->p[0]*xt, r->p[1]), -r->p[2]);
907 }
908 *y=1.0-f;
909 break;
910 case 863:
911 xt=x-r->p[4]; if(xt<=0.0) {
912 f=r->p[3];
913 } else {
914 f=pow(pow(r->p[3],-1.0/r->p[2])+pow(r->p[0]*xt, r->p[1]), -r->p[2]);
915 }
916 *y=f;
917 break;
918 case 864:
919 xt=x-r->p[4]; if(xt<=0.0) {
920 f=1.0-r->p[3];
921 } else {
922 f=1.0-pow(pow(r->p[3],-1.0/r->p[2])+pow(r->p[0]*xt, r->p[1]), -r->p[2]);
923 }
924 *y=f;
925 break;
926 case 871:
927 case 872:
928 case 873:
929 case 874:
930 for(m=0; m<3; m++) for(j=0; j<5; j++) mp[m][j]=0.0;
931 for(i=m=j=0; i<r->parNr; i++) {mp[m][j]=r->p[i]; j++; if(j>4) {j=0; m++;}}
932 n=r->parNr/5;
933 for(m=0; m<n; m++) {
934 xt=x-mp[m][4];
935 if(xt<=0.0) mf[m]=1.0-mp[m][3];
936 else {
937 f=pow(xt, mp[m][1]);
938 mf[m]=1.0-(mp[m][3]+(mp[m][0]-mp[m][3])*f/(mp[m][2]+f));
939 }
940 }
941 a=1.0-mf[0]*mf[1]-mf[0]*mf[2]-mf[1]*mf[2]+2.0*mf[0]*mf[1]*mf[2];
942 if(r->type==871) {
943 f=1.0;
944 f-=mf[0]*(1.0-mf[1]-mf[2]+mf[1]*mf[2])/a;
945 f-=mf[1]*(1.0-mf[0]-mf[2]+mf[0]*mf[2])/a;
946 f-=mf[2]*(1.0-mf[0]-mf[1]+mf[0]*mf[1])/a;
947 *y=f;
948 } else if(r->type==872) {
949 *y=mf[0]*(1.0-mf[1]-mf[2]+mf[1]*mf[2])/a;
950 } else if(r->type==873) {
951 *y=mf[1]*(1.0-mf[0]-mf[2]+mf[0]*mf[2])/a;
952 } else if(r->type==874) {
953 *y=mf[2]*(1.0-mf[0]-mf[1]+mf[0]*mf[1])/a;
954 }
955 break;
956 case 881:
957 case 882:
958 case 883:
959 case 884:
960 for(m=0; m<3; m++) for(j=0; j<5; j++) mp[m][j]=0.0;
961 for(i=m=j=0; i<r->parNr; i++) {mp[m][j]=r->p[i]; j++; if(j>4) {j=0; m++;}}
962 n=r->parNr/5;
963 for(m=0; m<n; m++) {
964 xt=x-mp[m][4];
965 if(xt<=0.0) mf[m]=1.0-mp[m][3];
966 else {
967 mf[m]=1.0 - pow(pow(mp[m][3], -1.0/mp[m][2]) + pow(mp[m][0]*(xt), mp[m][1]), -mp[m][2]);
968 }
969 }
970 a=1.0-mf[0]*mf[1]-mf[0]*mf[2]-mf[1]*mf[2]+2.0*mf[0]*mf[1]*mf[2];
971 if(r->type==881) {
972 f=1.0;
973 f-=mf[0]*(1.0-mf[1]-mf[2]+mf[1]*mf[2])/a;
974 f-=mf[1]*(1.0-mf[0]-mf[2]+mf[0]*mf[2])/a;
975 f-=mf[2]*(1.0-mf[0]-mf[1]+mf[0]*mf[1])/a;
976 *y=f;
977 } else if(r->type==882) {
978 *y=mf[0]*(1.0-mf[1]-mf[2]+mf[1]*mf[2])/a;
979 } else if(r->type==883) {
980 *y=mf[1]*(1.0-mf[0]-mf[2]+mf[0]*mf[2])/a;
981 } else if(r->type==884) {
982 *y=mf[2]*(1.0-mf[0]-mf[1]+mf[0]*mf[1])/a;
983 }
984 break;
985 case 1010: // step functions
986 /* Parameter number must be an even number and >=2 */
987 if(r->parNr<2 || r->parNr&1) return(2);
988 *y=0.0;
989 for(int i=0; i<r->parNr; i+=2) if(x>=r->p[i]) *y=r->p[i+1];
990 break;
991 case 2111:
992 xt=x-r->p[3]; a=sqrt(2.0)*(r->p[2]/2.355);
993 f=r->p[4]+(r->p[0]/2.0)*(erf((xt+r->p[1])/a)-erf((xt-r->p[1])/a));
994 *y=f;
995 break;
996 case 1232:
997 xt=x; if(r->parNr>7) xt-=r->p[7];
998 if(xt<=0.0) {
999 f=0.0;
1000 } else {
1001 sqrx=xt*xt; cubx=sqrx*xt;
1002 a=r->p[0]+r->p[2]*xt+r->p[4]*sqrx+r->p[6]*cubx;
1003 b=r->p[1]+r->p[3]*xt+r->p[5]*sqrx; if(b==0.0) break;
1004 f=a/b;
1005 }
1006 *y=f;
1007 break;
1008 case 1312:
1009 xt=x; if(r->parNr>4) xt-=r->p[4];
1010 if(xt<=0.0) {
1011 f=0.0;
1012 } else {
1013 f=0.0;
1014 a=(r->p[0]*(xt)-r->p[2])*exp(r->p[1]*(xt)); f+=a;
1015 a=r->p[2]*exp(r->p[3]*(xt)); f+=a;
1016 }
1017 *y=f;
1018 break;
1019 case 1313:
1020 xt=x; if(r->parNr>6) xt-=r->p[6];
1021 if(xt<=0.0) {
1022 f=0.0;
1023 } else {
1024 f=0.0;
1025 a=(r->p[0]*(xt)-r->p[2]-r->p[4])*exp(r->p[1]*(xt)); f+=a;
1026 a=r->p[2]*exp(r->p[3]*(xt)); f+=a;
1027 a=r->p[4]*exp(r->p[5]*(xt)); f+=a;
1028 }
1029 *y=f;
1030 break;
1031 case 1314:
1032 xt=x; if(r->parNr>8) xt-=r->p[8];
1033 if(xt<=0.0) {
1034 f=0.0;
1035 } else {
1036 f=0.0;
1037 a=(r->p[0]*(xt)-r->p[2]-r->p[4]-r->p[6])*exp(r->p[1]*(xt)); f+=a;
1038 a=r->p[2]*exp(r->p[3]*(xt)); f+=a;
1039 a=r->p[4]*exp(r->p[5]*(xt)); f+=a;
1040 a=r->p[6]*exp(r->p[7]*(xt)); f+=a;
1041 }
1042 *y=f;
1043 break;
1044 case 1401:
1045 xt=x-r->p[3]; if(xt<=0.0 || r->p[2]==0.0) {
1046 f=0.0;
1047 } else {
1048 f=r->p[0]*pow(xt, r->p[1])*exp(-xt/r->p[2]);
1049 }
1050 *y=f;
1051 break;
1052 case 1402:
1053 xt=x-r->p[3]; if(xt<=0.0 || r->p[2]==0.0) {
1054 f=r->p[4];
1055 } else {
1056 f=r->p[0]*pow(xt, r->p[1])*exp(-xt/r->p[2]) + r->p[4];
1057 }
1058 *y=f;
1059 break;
1060 case 1403:
1061 xt=x-r->p[0];
1062 f=0.0;
1063 if(xt>0.0) {
1064 a=exp(-xt/r->p[3]);
1065 if(r->p[1]>0.0) f += r->p[1]*pow(xt, r->p[2])*a;
1066 if(r->parNr==6 && r->p[4]>0.0) f += r->p[4]*(1.0-a)*exp(-xt/r->p[5]);
1067 }
1068 *y=f;
1069 break;
1070 case 1421:
1071 xt=x-r->p[0]; if(xt<=0.0) {
1072 f=0.0;
1073 } else {
1074 f=r->p[1]*(1.0-exp(-pow(xt/r->p[2], r->p[3])));
1075 }
1076 *y=f;
1077 break;
1078 case 1423:
1079 xt=x-r->p[0]; if(xt<=0.0) {
1080 f=0.0;
1081 } else {
1082 a=xt/r->p[2]; b=pow(a, r->p[3]-1.0); f=exp(-b*a);
1083 a=r->p[3]*b*f/r->p[2]; b=1.0-f;
1084 f=r->p[1]*(a+r->p[4]*b);
1085 }
1086 *y=f;
1087 break;
1088 case 1431:
1089 if(x<=0.0) {
1090 f=0.0;
1091 } else {
1092 f=r->p[0]*x*exp(-r->p[1]*x)*r->p[1]*r->p[1];
1093 }
1094 *y=f;
1095 break;
1096 case 1432:
1097 if(x<=0.0) {
1098 f=0.0;
1099 } else {
1100 f=r->p[0]*x*exp(-r->p[1]*x);
1101 }
1102 *y=f;
1103 break;
1104 case 1433:
1105 if(x<=0.0) {
1106 f=0.0;
1107 } else {
1108 double e=exp(-r->p[1]*x);
1109 f=x*e + (r->p[2]/(r->p[1]*r->p[1]))*(1.0-(r->p[1]*x+1.0)*e);
1110 f*=r->p[0];
1111 }
1112 *y=f;
1113 break;
1114 case 1434:
1115 if(x<=0.0) {
1116 f=1.0/(1.0-r->p[0]);
1117 } else {
1118 double e=exp(-r->p[2]*x);
1119 double rcp=x*e + (r->p[3]/(r->p[2]*r->p[2]))*(1.0-(r->p[2]*x+1.0)*e);
1120 rcp*=r->p[1];
1121 f=1.0/(1.0-r->p[0]*(1.0-rcp));
1122 }
1123 *y=f;
1124 break;
1125 case 1435:
1126 xt=x-r->p[0]; if(xt<=0.0) {
1127 f=0.0;
1128 } else {
1129 f=r->p[2]*(r->p[3]*xt*exp(-r->p[4]*r->p[1]*xt) + exp(-r->p[1]*xt) );
1130 }
1131 *y=f;
1132 break;
1133 case 1441: /* Probability density function of Erlang distribution */
1134 f=0.0;
1135 if(x>=0.0) {
1136 double A=r->p[0], k=r->p[1]; if(!(k>=0.0)) return(2);
1137 int N=(int)round(r->p[2]); if(!(N>0)) return(2);
1138 unsigned long long int f=lfactorial(N-1);
1139 f = A*pow(k, N)*pow(x, N-1)*exp(-k*x)/f;
1140 }
1141 *y=f;
1142 break;
1143 case 1801:
1144 xt=x-r->p[0]; if(xt<=0.0) {
1145 f=0.0;
1146 } else {
1147 f=r->p[1]*pow(xt, r->p[3])/(pow(r->p[2], r->p[3])+pow(xt, r->p[3]));
1148 }
1149 *y=f;
1150 break;
1151 case 1811:
1152 xt=x-r->p[0]; if(xt<=0.0) {
1153 f=0.0;
1154 } else {
1155 a=pow(r->p[2], r->p[3])+pow(xt, r->p[3]);
1156 f=r->p[1]*r->p[3]*
1157 (pow(xt, r->p[3]-1.0)/a - pow(xt, 2.0*r->p[3]-1.0)/(a*a));
1158 }
1159 *y=f;
1160 break;
1161 case 1821:
1162 xt=x-r->p[0]; if(xt<=0.0) {
1163 f=0.0;
1164 } else {
1165 double a, c, b, k, xb, cb, cbxb, hill, hilld;
1166 a=r->p[1]; c=r->p[2]; b=r->p[3]; k=r->p[4];
1167 cb=pow(c, b); xb=pow(xt, b); cbxb=cb+xb;
1168 hilld= b*pow(xt, b-1.0)/cbxb - b*pow(xt, 2.0*b-1.0)/(cbxb*cbxb);
1169 hill=k*xb/cbxb;
1170 f=a*(hilld+hill);
1171 }
1172 *y=f;
1173 break;
1174 case 1833:
1175 xt=x; if(r->parNr>3) xt-=r->p[3];
1176 if(xt<=0.0) {
1177 f=0.0;
1178 } else {
1179 double c=0.0; if(r->parNr>2) c=r->p[2];
1180 double e=exp(-r->p[1]*xt);
1181 f=xt*e + (c/(r->p[1]*r->p[1]))*(1.0-(r->p[1]*xt+1.0)*e);
1182 f*=r->p[0];
1183 }
1184 *y=f;
1185 break;
1186 case 2233:
1187 if(x<=0.0) {
1188 f=1.0/(1.0-r->p[0]);
1189 } else {
1190 sqrx=x*x; cubx=sqrx*x;
1191 a=0.0+r->p[1]*x+r->p[3]*sqrx+r->p[5]*cubx;
1192 b=1.0+r->p[2]*x+r->p[4]*sqrx+r->p[6]*cubx;
1193 f=1.0/(1.0-r->p[0]*(1.0-(a/b)));
1194 }
1195 *y=f;
1196 break;
1197 case 2313:
1198 if(r->parNr<3) return(2);
1199 if(x<=0.0) {
1200 f=0.0;
1201 } else {
1202 double A1=r->p[1];
1203 double L1=r->p[2];
1204 double A2=0.0; if(r->parNr>3) A2=r->p[3];
1205 double L2=0.0; if(r->parNr>4) L2=r->p[4];
1206 double A3=0.0; if(r->parNr>5) A3=r->p[5];
1207 double L3=0.0; if(r->parNr>6) L3=r->p[6];
1208 f=(A1*x - A2 - A3)*exp(-L1*x) + A2*exp(-L2*x) + A3*exp(-L3*x);
1209 }
1210 *y=1.0/(1.0-r->p[0]*(1.0-f));
1211 break;
1212 case 2801:
1213 {
1214 double top, bottom, ec50, hillslope;
1215 top=r->p[0]; bottom=r->p[1]; ec50=r->p[2]; hillslope=r->p[3];
1216 if(x<=0.0) f=bottom;
1217 else f=bottom+(top-bottom)/(1.0+pow(ec50/x,hillslope));
1218 }
1219 *y=f;
1220 break;
1221 case 2802:
1222 {
1223 double top, bottom, logec50, hillslope;
1224 top=r->p[0]; bottom=r->p[1]; logec50=r->p[2]; hillslope=r->p[3];
1225 f=bottom+(top-bottom)/(1.0+pow(10.0, (logec50-x)*hillslope));
1226 }
1227 *y=f;
1228 break;
1229 case 2841:
1230 a=r->p[1]*pow(x, r->p[2]) / (pow(x, r->p[2]) + r->p[3]);
1231 f=1.0/(1.0-r->p[0]*(1.0-a));
1232 *y=f;
1233 break;
1234 case 3331: *y=nan(""); break; /* cannot be applied to one point only */
1235 case 9501: *y=nan(""); break; /* cannot be applied to one point only */
1236 case 9502: *y=nan(""); break; /* cannot be applied to one point only */
1237 case 9503: *y=nan(""); break; /* cannot be applied to one point only */
1238 case 9701: *y=nan(""); break; /* cannot be applied to one point only */
1239 default:
1240 *y=nan("");
1241 }
1242 if(isnan(*y)) return 1;
1243 return 0;
1244}
double igam(double a, double x)
Definition mathfunc.c:1715
unsigned long long int lfactorial(unsigned long long int n)
Definition mathfunc.c:1695
int MATHFUNC_TEST
Definition mathfunc.c:5

Referenced by fitEvaltac().

◆ fitEvaltac()

int fitEvaltac ( FitVOI * r,
double * x,
double * y,
int dataNr )
extern

Evaluates an array y[i]=f(x[i]).

See also
fitEval, fitIntegralEvaltac, fitDerivEvaltac
Returns
Returns 0, if ok.
Parameters
rFit parameters of a single region
xTimes where to evaluate the function
yArray for the function values
dataNrNr of (x,y) data

Definition at line 1252 of file mathfunc.c.

1261 {
1262 if(r==NULL || x==NULL || y==NULL || dataNr<1) return(1);
1263
1264 /* Special cases that can only be computed as TACs */
1265 if(r->type==3331) {
1266 double Ta=r->p[0];
1267 double Ti=r->p[1];
1268 double dT=r->p[r->parNr-2]; Ta+=dT;
1269 double tau=r->p[r->parNr-1];
1270 int n=(r->parNr-4)/2; if(n<1) return(2);
1271 for(int i=0; i<dataNr; i++) {
1272 if(x[i]<=Ta) y[i]=0.0;
1273 else if(x[i]<Ta+Ti) {
1274 double f=0.0;
1275 for(int j=0; j<n; j++) {
1276 double b;
1277 if(r->p[2*j+3]>1.0E-12) b=r->p[2*j+2]/r->p[2*j+3]; else b=r->p[2*j+2];
1278 f+=b*(1.0-exp(-r->p[2*j+3]*(x[i]-Ta)));
1279 }
1280 if(Ti>0.0) f*=(1.0/Ti);
1281 y[i]=f;
1282 } else {
1283 double f=0.0;
1284 for(int j=0; j<n; j++) {
1285 double b;
1286 if(r->p[2*j+3]>1.0E-12) b=r->p[2*j+2]/r->p[2*j+3]; else b=r->p[2*j+2];
1287 f+=b*(exp(-r->p[2*j+3]*(x[i]-Ta-Ti)) - exp(-r->p[2*j+3]*(x[i]-Ta)));
1288 }
1289 if(Ti>0.0) f*=(1.0/Ti);
1290 y[i]=f;
1291 }
1292 }
1293 if(simDispersion(x, y, dataNr, tau, 0.0, NULL)) return(2);
1294 return(0);
1295 }
1296
1297 /* Usual functions */
1298 for(int i=0; i<dataNr; i++) if(fitEval(r, x[i], y+i)) return(2);
1299 return 0;
1300}
int simDispersion(double *x, double *y, int n, double tau1, double tau2, double *tmp)
Definition simulate.c:1911
int fitEval(FitVOI *r, double x, double *y)
Definition mathfunc.c:645

◆ fitFunctionformat()

int fitFunctionformat ( int type,
char * str )
extern

Copies the description of a function type to the specified string which must have space for >=128 characters.

Parameters
typeThe number of function
strRepresentation of the format of the function

Definition at line 381 of file mathfunc.c.

386 {
387 strcpy(str, "");
388 switch(type) {
389 /* Polynomials, including line */
390 case 100: strcpy(str, "f(x)=A"); break;
391 case 101: strcpy(str, "f(x)=A+B*x"); break;
392 case 102: strcpy(str, "f(x)=A+B*x+C*x^2"); break;
393 case 103: strcpy(str, "f(x)=A+B*x+C*x^2+D*x^3"); break;
394 case 104: strcpy(str, "f(x)=A+B*x+C*x^2+D*x^3+E*x^4"); break;
395 case 105: strcpy(str, "f(x)=A+B*x+C*x^2+D*x^3+E*x^4+F*x^5"); break;
396 case 106: strcpy(str, "f(x)=A+B*x+C*x^2+D*x^3+E*x^4+F*x^5+G*x^6"); break;
397 case 107: strcpy(str, "f(x)=A+B*x+C*x^2+D*x^3+E*x^4+F*x^5+G*x^6+H*x^7"); break;
398 case 108: strcpy(str, "f(x)=A+B*x+C*x^2+D*x^3+E*x^4+F*x^5+G*x^6+H*x^7+I*x^8"); break;
399 case 109: strcpy(str, "f(x)=A+B*x+C*x^2+D*x^3+E*x^4+F*x^5+G*x^6+H*x^7+I*x^8+J*x^9"); break;
400 /* Rational functions */
401 case 211: strcpy(str, "f(x)=(A+C*x)/(B+D*x)"); break;
402 case 221: strcpy(str, "f(x)=(A+C*x+E*x^2)/(B+D*x)"); break;
403 case 222: strcpy(str, "f(x)=(A+C*x+E*x^2)/(B+D*x+F*x^2)"); break;
404 case 232: strcpy(str, "f(x)=(A+C*x+E*x^2+G*x^3)/(B+D*x+F*x^2)"); break;
405 case 233: strcpy(str, "f(x)=(A+C*x+E*x^2+G*x^3)/(B+D*x+F*x^2+H*x^3)"); break;
406 case 1232: strcpy(str, "f(x)=(A+C*(x-t)+E*(x-t)^2+G*(x-t)^3)/(B+D*(x-t)+F*(x-t)^2)"); break;
407 /* Rational function for plasma-to-blood ratio */
408 case 2233: strcpy(str, "f(x)=1/(1-H*(1-r(x))), where r(x) is 3/3 order rational function for RBC-to-plasma"); break;
409 /* Exponential functions */
410 case 301: strcpy(str, "f(x)=A*exp(B*x)"); break;
411 case 302: strcpy(str, "f(x)=A*exp(B*x)+C*exp(D*x)"); break;
412 case 303: strcpy(str, "f(x)=A*exp(B*x)+C*exp(D*x)+E*exp(F*x)"); break;
413 case 304: strcpy(str, "f(x)=A*exp(B*x)+C*exp(D*x)+E*exp(F*x)+G*exp(H*x)"); break;
414 case 305: strcpy(str, "f(x)=A*exp(B*x)+C*exp(D*x)+E*exp(F*x)+G*exp(H*x)+I*exp(J*x)"); break;
415 /* Feng function */
416 case 1312: strcpy(str, "f(x)=(A*(x-t)-C)*exp(B*(x-t))+C*exp(D*(x-t))"); break;
417 case 1313: strcpy(str, "f(x)=(A*(x-t)-C-E)*exp(B*(x-t))+C*exp(D*(x-t))+E*exp(F*(x-t))"); break;
418 case 1314: strcpy(str, "f(x)=(A*(x-t)-C-E-G)*exp(B*(x-t))+C*exp(D*(x-t))+E*exp(F*(x-t))+G*exp(H*(x-t))"); break;
419 case 2313: strcpy(str, "f(x)=1/(1-A*(1-((B*x-D-F)*exp(C*x)+D*exp(E*x)+F*exp(G*x))))"); break;
420 /* Lundqvist function */
421 case 321: strcpy(str, "f(x)=A*exp(B*x)*(1-exp(C*x))"); break;
422 case 322: strcpy(str, "f(x)=A*exp(B*x)*(1-exp(C*x))+D*exp(E*x)*(1-exp(F*x))"); break;
423 case 323: strcpy(str, "f(x)=A*exp(B*x)*(1-exp(C*x))+D*exp(E*x)*(1-exp(F*x))+G*exp(H*x)*(1-exp(I*x))"); break;
424 case 1321: strcpy(str, "f(x)=A*exp(-B*(x-t))*(1-exp(-C*(x-t))) + D*(A/(B*(B+C)))*(C-((B+C)*exp(C*(x-t))-B)*exp(-(B+C)*(x-t))) "); break;
425 /* Exponential bolus infusion functions */
426 case 331: strcpy(str, "f(x)=(1/Ti)*Sum[i=1..n, (Ai/Li)*(exp(-Li*(x-tA-Ti)) - exp(-Li*(x-Ta)))], when x>=Ta+Ti\nf(x)=(1/Ti)*Sum[i=1..n, (Ai/Li)*(1-exp(-Li*(t-Ta)))], when x>Ta and x<Ta+Ti\nf(x)=0, when t<=Ta");
427 break;
428 /* Kudomi's function for radiowater */
429 case 332: strcpy(str, "f(x)=0, when x<=Ta \nf(x)=(A/L^2)*(1-exp(-L(x-Ta))), when Ta<x<=Ta+Ti \nf(x)=(A/L^2)*(exp(-L*Ti)+exp(-L(x-Ta-Ti))-2exp(-L(x-t1))), when x>Ta+Ti");
430 break;
431 /* Bolus infusion approaching zero */
432 case 334: strcpy(str, "f(x)=0, when x<=t1 \nf(x)=A*(1-exp(L(t1-x)))/(1-exp(L*(t1-t2))), when t1<x<=t2 \nf(x)=A*(exp(L(t2-x))-exp(L(t1-x)))/(1-exp(L*(t1-t2))), when x>t2");
433 break;
434 /* Exponential functions for plasma fractions */
435 case 351: strcpy(str, "f(x)=1-a*(2-exp(-b*x)-exp(-c*x))"); break;
436 /* Inverted gamma cdf for plasma parent fraction */
437 case 403: strcpy(str, "f(x)=A*(1-B*gammacdf(D,C*(x-t)))"); break;
438 /* Gamma variate function */
439 case 1401: strcpy(str, "f(x)=A*((x-D)^B)*exp(-(x-D)/C) , when x>=D, else f(x)=0"); break;
440 /* Gamma variate function with background */
441 case 1402: strcpy(str, "f(x)=A*((x-D)^B)*exp(-(x-D)/C) + E , when x>=D, else f(x)=E"); break;
442 /* Gamma variate bolus plus recirculation function */
443 case 1403: strcpy(str, "f(x)=B*((x-A)^C)*exp(-(x-A)/D) + E*(1-exp(-(x-A)/D))*exp(-(x-A)/F) , when x>A, else f(x)=0"); break;
444 /* Weibull cdf */
445 case 1421: strcpy(str, "f(x)=A*(1-exp(-((x-t)/B)^C) , when x>t, else f(x)=0"); break;
446 /* Weibull cdf plus pdf (derivative of cdf) */
447 case 1423: strcpy(str, "f(x)=A*[C*((x-t)/B)^(C-1)*exp(-((x-t)/B)^C))/B + k*(1-exp(-((x-t)/B)^C))] , when x>t, else f(x)=0"); break;
448 /* Surge function with AUC=A */
449 case 1431: strcpy(str, "f(x)=A*x*exp(-B*x)*B^2 , when x>0, else f(x)=0"); break;
450 /* Traditional Surge function */
451 case 1432: strcpy(str, "f(x)=A*x*exp(-B*x) , when x>0, else f(x)=0"); break;
452 /* Surge function with recirculation */
453 case 1433: strcpy(str, "f(x)=A*[x*exp(-B*x) + (C/B^2)*(1-(B*x+1)*exp(-B*x))], when x>0, else f(x)=0"); break;
454 /* Surge function with recirculation for plasma-to-blood ratio */
455 case 1434: strcpy(str, "f(x)=1/(1-H*(1-r(x))), where r(x) is function for RBC-to-plasma"); break;
456 /* Surge function for late FDG input */
457 case 1435: strcpy(str, "f(x)=b*(m*(x-t)*exp(-n*a*(x-t)) + exp(-a*(-t)x)) , when x>t, else f(x)=0"); break;
458 /* Probability density function of Erlang distribution */
459 case 1441: strcpy(str, "f(x)=A*(k^n)*(x^(n-1))*exp(-k*x)/(n-1)! , when x>0, else f(x)=0"); break;
460 /* Hill functions for TACs */
461 case 1801: strcpy(str, "f(x)=[A*(x-t)^B]/[(x-t)^B+C^B]"); break;
462 case 1811: strcpy(str, "f(x)=A*{[B*(x-t)^(B-1)]/[C^B+(x-t)^B] - [B*(x-t)^(2*B-1)]/[C^B+(x-t)^B]^2}"); break;
463 case 1821: strcpy(str, "f(x)=A*{[B*(x-t)^(B-1)]/[C^B+(x-t)^B] - [B*(x-t)^(2*B-1)]/[C^B+(x-t)^B]^2 + K*(x-t)^B]/[(x-t)^B+C^B}"); break;
464 /* Surge function with recirculation and delay */
465 case 1833: strcpy(str, "f(x)=A*[(x-D)*exp(-B*(x-D)) + (A*C/B^2)*(1-(B*(x-D)+1)*exp(-B*(x-D)))], when x>D, else f(x)=0"); break;
466 /* Hill functions for dose-response curves */
467 case 2801: strcpy(str, "f(x)=B+[A-B]/[1+(C/x)^D]"); break;
468 case 2802: strcpy(str, "f(x)=B+[A-B]/[1+10^{(C-x)*D}]"); break;
469 /* Exponential/power type functions for parent fractions */
470 case 831: strcpy(str, "f(x)=B*(C*exp(-D*(x-A)^3/((x-A)^2+E))+(1-C)*exp(-F*(x-A))), when x>A, else f(x)=B"); break;
471 /* Hill type functions for fractions */
472 case 841: strcpy(str, "f(x)=(A*x^B)/(x^B+C)"); break;
473 case 842: strcpy(str, "f(x)=1-((A*x^B)/(x^B+C))"); break;
474 case 843: strcpy(str, "f(x)=1-((A*(1+D*x)*x^B)/(x^B+C))"); break;
475 case 844: strcpy(str, "f(x)=(A*(x-t)^B)/((x-t)^B+C)+D, when x>t, else f(x)=D"); break;
476 case 845: strcpy(str, "f(x)=A-(A*x^B)/(x^B+C))"); break;
477 case 846: strcpy(str, "f(x)=D+((A-D)*(x-t)^B)/((x-t)^B+C), when x>t, else f(x)=D"); break;
478 case 847: strcpy(str, "f(x)=1-D-((A-D)*(x-t)^B)/((x-t)^B+C), when x>t, else f(x)=1-A"); break;
479 case 848: strcpy(str, "f(x)=D*((1-A)*(x-t)^B)/((x-t)^B+C), when x>t, else f(x)=D"); break;
480 case 849: strcpy(str, "f(x)=1-D*((1-A)*(x-t)^B)/((x-t)^B+C), when x>t, else f(x)=1-A"); break;
481 /* Hill function for plasma-to-blood ratio */
482 case 2841: strcpy(str, "f(x)=1/(1-H*(1-r(x))), where r(x) is Hill function for RBC-to-plasma"); break;
483 /* Mamede/Watabe function for fractions */
484 case 851: strcpy(str, "f(x)=1/(1+(A*x)^2)^B"); break;
485 case 852: strcpy(str, "f(x)=1-1/(1+(A*x)^2)^B"); break;
486 /* Mamede/Watabe function for fractions, as extended by Meyer */
487 case 861: strcpy(str, "f(x)=(1+(A*(x-t))^B)^(-C), when x>t, else f(x)=1"); break;
488 case 862: strcpy(str, "f(x)=1-(1+(A*(x-t))^B)^(-C), when x>t, else f(x)=0"); break;
489 /* ... and further extended by letting fraction start somewhere between 0 and 1 */
490 case 863: strcpy(str, "f(x)=(D^(-1/C)+(A*(x-t))^B)^(-C), when x>t, else f(x)=D"); break;
491 case 864: strcpy(str, "f(x)=1-(D^(-1/C)+(A*(x-t))^B)^(-C), when x>t, else f(x)=1-D"); break;
492 /* Functions for fitting plasma fractions via separate metabolite fractions */
493 case 871:
494 case 881:
495 strcpy(str, "f(x)=1-f1(x)-f2(x)-f3(x)"); break;
496 case 872:
497 case 882:
498 strcpy(str, "f1(x)=a(x)(1-b(x)-c(x)+b(x)c(x))/(1-a(x)b(x)-a(x)c(x)-b(x)c(x)+2a(x)b(x)c(x))"); break;
499 case 873:
500 case 883:
501 strcpy(str, "f2(x)=b(x)(1-a(x)-c(x)+a(x)c(x))/(1-a(x)b(x)-a(x)c(x)-b(x)c(x)+2a(x)b(x)c(x))"); break;
502 case 874:
503 case 884:
504 strcpy(str, "f3(x)=c(x)(1-a(x)-b(x)+a(x)b(x))/(1-a(x)b(x)-a(x)c(x)-b(x)c(x)+2a(x)b(x)c(x))"); break;
505 case 1010:
506 strcpy(str, "f(x)=p2 when x>=p1, f(x)=p4 when x>=p2, ..."); break;
507 break;
508 /* PET profile functions */
509 case 2111: strcpy(str, "P(x)=(C/2)*(erf((x-d+R)/(sqrt(2)*FWHM/2355))-erf((x-d-R)/(sqrt(2)*FWHM/2355)))+bkg");
510 break;
511 /* Combined functions and models */
512 case 3331: strcpy(str, "f(x)=(1/Ti)*Sum[i=1..n, (Ai/Li)*(exp(-Li*(x-tA-Ti)) - exp(-Li*(x-Ta)))], when x>=Ta+Ti\nf(x)=(1/Ti)*Sum[i=1..n, (Ai/Li)*(1-exp(-Li*(t-Ta)))], when x>Ta and x<Ta+Ti\nf(x)=0, when t<=Ta, with additional delay and dispersion");
513 break;
514 /* Compartmental model functions */
515 /* Graham's plasma curve smoothing function */
516 case 9501: strcpy(str, "Cp(t)<=>Ci(t)<=>Ct(t)"); break;
517 /* Extended Graham's plasma curve smoothing function */
518 case 9502: strcpy(str, "Ce(t)<=>Cp(t)<=>Ci(t)<=>Ct(t)"); break;
519 /* Extended Graham's plasma curve smoothing function with metabolite */
520 case 9503: strcpy(str, "Cpa(t)<=>Cia(t)<=>Cta(t)->Ctm(t)<=>Cim(t)<=>Cpm(t)"); break;
521 /* Huang's plasma metabolite model */
522 case 9601: strcpy(str, "C4(t)<=>C3(t)<-C0(t)->C1(t)<=>C2(t)"); break;
523 /* Extended Carson's plasma metabolite model */
524 case 9602: strcpy(str, "Cpa(t)<=>Cta(t)->Ctm(t)<=>Cpm(t)"); break;
525 /* New plasma metabolite model */
526 case 9603: strcpy(str, "Cpa(t)->Ct1(t)<=>Cpm(t)<=>Ct2(t)"); break;
527 /* Multi-linear multi-compartmental TAC fitting model */
528 case 9701: strcpy(str, "Ideal bolus -> n compartments"); break;
529 default: return(1);
530 }
531 return(0);
532}

◆ fitFunctionname()

int fitFunctionname ( int type,
char * str )
extern

Copies the name of the function to the specified string which must have space for >=128 characters.

Parameters
typeThe number of function
strName of the function

Definition at line 539 of file mathfunc.c.

544 {
545 strcpy(str, "");
546 switch(type) {
547 case 100: strcpy(str, "f(x)=A"); break;
548 case 101: strcpy(str, "line"); break;
549 case 102: strcpy(str, "2nd order polynomial"); break;
550 case 103: strcpy(str, "3rd order polynomial"); break;
551 case 104: strcpy(str, "4th order polynomial"); break;
552 case 105: strcpy(str, "5th order polynomial"); break;
553 case 106: strcpy(str, "6th order polynomial"); break;
554 case 107: strcpy(str, "7th order polynomial"); break;
555 case 108: strcpy(str, "8th order polynomial"); break;
556 case 109: strcpy(str, "9th order polynomial"); break;
557 case 211: strcpy(str, "1/1 order rational function"); break;
558 case 221: strcpy(str, "2/1 order rational function"); break;
559 case 222: strcpy(str, "2/2 order rational function"); break;
560 case 232: strcpy(str, "3/2 order rational function"); break;
561 case 233: strcpy(str, "3/3 order rational function"); break;
562 case 1232: strcpy(str, "3/2 order rational function with delay"); break;
563 case 2233: strcpy(str, "3/3 order rational function for plasma-to-blood ratio"); break;
564 case 301: strcpy(str, "exponential function"); break;
565 case 302: strcpy(str, "sum of 2 exponential functions"); break;
566 case 303: strcpy(str, "sum of 3 exponential functions"); break;
567 case 304: strcpy(str, "sum of 4 exponential functions"); break;
568 case 305: strcpy(str, "sum of 5 exponential functions"); break;
569 case 1312: strcpy(str, "Feng model 2 function with 2 exponentials"); break;
570 case 1313: strcpy(str, "Feng model 2 function"); break;
571 case 1314: strcpy(str, "Feng model 2 function with 4 exponentials"); break;
572 case 2313: strcpy(str, "Feng M2 function for plasma-to-blood ratio"); break;
573 case 321: strcpy(str, "Lundqvist function"); break;
574 case 322: strcpy(str, "sum of 2 Lundqvist functions"); break;
575 case 323: strcpy(str, "sum of 3 Lundqvist functions"); break;
576 case 1321: strcpy(str, "Lundqvist function with integral and delay"); break;
577 case 331: strcpy(str, "Exponential bolus infusion function"); break;
578 case 332: strcpy(str, "Kudomi's exponential bolus infusion function for radiowater"); break;
579 case 334: strcpy(str, "Exponential bolus function approaching zero"); break;
580 case 351: strcpy(str, "Exponential function for [C-11]PK11195 plasma fractions"); break;
581 case 403: strcpy(str, "Inverted gamma cdf for plasma parent fraction"); break;
582 case 1401: strcpy(str, "Gamma variate function"); break;
583 case 1402: strcpy(str, "Gamma variate with background"); break;
584 case 1403: strcpy(str, "Gamma variate bolus plus recirculation"); break;
585 case 1421: strcpy(str, "Weibull cdf with delay"); break;
586 case 1423: strcpy(str, "Weibull cdf and derivative with delay"); break;
587 case 1431: strcpy(str, "Surge function"); break;
588 case 1432: strcpy(str, "Surge function (trad)"); break;
589 case 1433: strcpy(str, "Surge function with recirculation"); break;
590 case 1434: strcpy(str, "Surge function with recirculation for plasma-to-blood ratio"); break;
591 case 1435: strcpy(str, "Surge function for late FDG AIF"); break;
592 case 1441: strcpy(str, "Probability density function of Erlang distribution"); break;
593 case 1801: strcpy(str, "Hill function with delay"); break;
594 case 1811: strcpy(str, "Derivative of Hill function with delay"); break;
595 case 1821: strcpy(str, "Sum of Hill function and derivative with delay"); break;
596 case 1833: strcpy(str, "Surge function with recirculation and delay"); break;
597 case 2801: strcpy(str, "Hill function for dose-response curve on linear scale"); break;
598 case 2802: strcpy(str, "Hill function for dose-response curve on log scale"); break;
599 case 831: strcpy(str, "Exponential/Power function for parent fractions"); break;
600 case 841: strcpy(str, "Hill function"); break;
601 case 842: strcpy(str, "Hill function (1-f(x))"); break;
602 case 843: strcpy(str, "Hill function (1-f(x)) with ascending or descending end"); break;
603 case 844: strcpy(str, "Hill function with background"); break;
604 case 845: strcpy(str, "Hill function (A-f(x))"); break;
605 case 846: strcpy(str, "Extended Hill function for plasma parent fraction"); break;
606 case 847: strcpy(str, "Extended Hill function for plasma metabolite fraction"); break;
607 case 848: strcpy(str, "Extended Hill function #2 for plasma parent fraction"); break;
608 case 849: strcpy(str, "Extended Hill function #2 for plasma metabolite fraction"); break;
609 case 851: strcpy(str, "Mamede function"); break;
610 case 852: strcpy(str, "Mamede function (1-f(x)"); break;
611 case 861: strcpy(str, "Meyer parent fraction function"); break;
612 case 862: strcpy(str, "Meyer metabolite fraction function"); break;
613 case 863: strcpy(str, "Extended Meyer parent fraction function"); break;
614 case 864: strcpy(str, "Extended Meyer metabolite fraction function"); break;
615 case 871: strcpy(str, "1-3 metabolite Hill function for parent"); break;
616 case 872: strcpy(str, "1-3 metabolite Hill function for metab1"); break;
617 case 873: strcpy(str, "1-3 metabolite Hill function for metab2"); break;
618 case 874: strcpy(str, "1-3 metabolite Hill function for metab3"); break;
619 case 881: strcpy(str, "1-3 metabolite power function for parent"); break;
620 case 882: strcpy(str, "1-3 metabolite power function for metab1"); break;
621 case 883: strcpy(str, "1-3 metabolite power function for metab2"); break;
622 case 884: strcpy(str, "1-3 metabolite power function for metab3"); break;
623 case 1010: strcpy(str, "Step function"); break;
624 case 2111: strcpy(str, "Image profile function"); break;
625 case 2841: strcpy(str, "Hill function for plasma-to-blood ratio"); break;
626 case 3331: strcpy(str, "Exponential bolus infusion function with delay and dispersion"); break;
627 case 9501: strcpy(str, "Graham's input function"); break;
628 case 9502: strcpy(str, "Extended Graham's input function"); break;
629 case 9503: strcpy(str, "Graham's input function with metabolite"); break;
630 case 9601: strcpy(str, "Huang's plasma metabolite model"); break;
631 case 9602: strcpy(str, "Extended Carson's plasma metabolite model"); break;
632 case 9603: strcpy(str, "New plasma metabolite model"); break;
633 case 9701: strcpy(str, "Multilinear multicompartmental TAC fitting model"); break;
634 default: return(1);
635 }
636 return(0);
637}

◆ fitInit()

void fitInit ( FIT * fit)
extern

Initiate FIT structure. Call this once before first use.

See also
fitEmpty, fitRead, fitWrite

Definition at line 38 of file mathfunc.c.

40 {
41 if(fit==NULL) return;
42 memset(fit, 0, sizeof(FIT));
43 fit->_voidataNr=0; fit->voiNr=0;
44}

◆ fitIntegralEval()

int fitIntegralEval ( FitVOI * r,
double x,
double * yi )
extern

Evaluates yi=Integral of f(x) between 0 and x.

See also
fitEval, fitDerivEval, fitIntegralEvaltac
Returns
Returns 0, if ok.
Parameters
rFit parameters of a single region
xTime where to evaluate integral of the function
yiThe integral value of the function is returned here

Definition at line 1308 of file mathfunc.c.

1315 {
1316 double a, f, xt, t;
1317
1318 if(r==NULL || yi==NULL) return 1;
1319 *yi=nan("");
1320 switch(r->type) {
1321 case 301:
1322 if(fabs(r->p[1])>1.0e-12) f=(r->p[0]/r->p[1])*(exp(r->p[1]*x)-1.0);
1323 else f=r->p[0]*x;
1324 *yi=f;
1325 break;
1326 case 302:
1327 f=0;
1328 if(fabs(r->p[1])>1.0e-12) a=(r->p[0]/r->p[1])*(exp(r->p[1]*x)-1.0);
1329 else a=r->p[0]*x;
1330 f+=a;
1331 if(fabs(r->p[3])>1.0e-12) a=(r->p[2]/r->p[3])*(exp(r->p[3]*x)-1.0);
1332 else a=r->p[2]*x;
1333 f+=a;
1334 *yi=f;
1335 break;
1336 case 303:
1337 f=0;
1338 if(fabs(r->p[1])>1.0e-12) a=(r->p[0]/r->p[1])*(exp(r->p[1]*x)-1.0);
1339 else a=r->p[0]*x;
1340 f+=a;
1341 if(fabs(r->p[3])>1.0e-12) a=(r->p[2]/r->p[3])*(exp(r->p[3]*x)-1.0);
1342 else a=r->p[2]*x;
1343 f+=a;
1344 if(fabs(r->p[5])>1.0e-12) a=(r->p[4]/r->p[5])*(exp(r->p[5]*x)-1.0);
1345 else a=r->p[4]*x;
1346 f+=a;
1347 *yi=f;
1348 break;
1349 case 304:
1350 f=0;
1351 if(fabs(r->p[1])>1.0e-12) a=(r->p[0]/r->p[1])*(exp(r->p[1]*x)-1.0);
1352 else a=r->p[0]*x;
1353 f+=a;
1354 if(fabs(r->p[3])>1.0e-12) a=(r->p[2]/r->p[3])*(exp(r->p[3]*x)-1.0);
1355 else a=r->p[2]*x;
1356 f+=a;
1357 if(fabs(r->p[5])>1.0e-12) a=(r->p[4]/r->p[5])*(exp(r->p[5]*x)-1.0);
1358 else a=r->p[4]*x;
1359 f+=a;
1360 if(fabs(r->p[7])>1.0e-12) a=(r->p[6]/r->p[7])*(exp(r->p[7]*x)-1.0);
1361 else a=r->p[6]*x;
1362 f+=a;
1363 *yi=f;
1364 break;
1365 case 305:
1366 f=0;
1367 if(fabs(r->p[1])>1.0e-12) a=(r->p[0]/r->p[1])*(exp(r->p[1]*x)-1.0);
1368 else a=r->p[0]*x;
1369 f+=a;
1370 if(fabs(r->p[3])>1.0e-12) a=(r->p[2]/r->p[3])*(exp(r->p[3]*x)-1.0);
1371 else a=r->p[2]*x;
1372 f+=a;
1373 if(fabs(r->p[5])>1.0e-12) a=(r->p[4]/r->p[5])*(exp(r->p[5]*x)-1.0);
1374 else a=r->p[4]*x;
1375 f+=a;
1376 if(fabs(r->p[7])>1.0e-12) a=(r->p[6]/r->p[7])*(exp(r->p[7]*x)-1.0);
1377 else a=r->p[6]*x;
1378 f+=a;
1379 if(fabs(r->p[9])>1.0e-12) a=(r->p[8]/r->p[9])*(exp(r->p[8]*x)-1.0);
1380 else a=r->p[8]*x;
1381 f+=a;
1382 *yi=f;
1383 break;
1384 case 321:
1385 f=(r->p[0]/r->p[1])*exp(r->p[1]*x)
1386 - r->p[0]*exp((r->p[1]+r->p[2])*x)/(r->p[1]+r->p[2]);
1387 *yi=f;
1388 break;
1389 case 322:
1390 f=0.0;
1391 a=(r->p[0]/r->p[1])*exp(r->p[1]*x)
1392 - r->p[0]*exp((r->p[1]+r->p[2])*x)/(r->p[1]+r->p[2]); f+=a;
1393 a=(r->p[3]/r->p[4])*exp(r->p[4]*x)
1394 - r->p[3]*exp((r->p[4]+r->p[5])*x)/(r->p[4]+r->p[5]); f+=a;
1395 *yi=f;
1396 break;
1397 case 323:
1398 f=0.0;
1399 a=(r->p[0]/r->p[1])*exp(r->p[1]*x)
1400 - r->p[0]*exp((r->p[1]+r->p[2])*x)/(r->p[1]+r->p[2]); f+=a;
1401 a=(r->p[3]/r->p[4])*exp(r->p[4]*x)
1402 - r->p[3]*exp((r->p[4]+r->p[5])*x)/(r->p[4]+r->p[5]); f+=a;
1403 a=(r->p[6]/r->p[7])*exp(r->p[7]*x)
1404 - r->p[6]*exp((r->p[7]+r->p[8])*x)/(r->p[7]+r->p[8]); f+=a;
1405 *yi=f;
1406 break;
1407 case 331: *yi=nan(""); break; /* not yet applied */
1408 case 351: *yi=nan(""); break; /* not yet applied */
1409 case 1312:
1410 t=r->p[4]; xt=x-t; f=0.0;
1411 if(xt>0.0) {
1412 double A1, A2, L1, L2;
1413 A1=r->p[0]; L1=r->p[1]; A2=r->p[2]; L2=r->p[3];
1414 if(L1!=0.0) {
1415 a=exp(L1*xt);
1416 f+=(A2/L1)*(1.0 - a);
1417 f+=(A1/(L1*L1))*(1.0 + a*(L1*xt - 1.0));
1418 }
1419 if(L2!=0.0) f+=(A2/L2)*(exp(L2*xt) - 1.0); else f+=A2*xt;
1420 }
1421 *yi=f;
1422 break;
1423 case 1313:
1424 t=r->p[6]; xt=x-t; f=0.0;
1425 if(xt>0.0) {
1426 double A1, A2, A3, L1, L2, L3;
1427 A1=r->p[0]; L1=r->p[1]; A2=r->p[2]; L2=r->p[3]; A3=r->p[4]; L3=r->p[5];
1428 if(L1!=0.0) {
1429 a=exp(L1*xt);
1430 f+=(A2/L1)*(1.0 - a);
1431 f+=(A3/L1)*(1.0 - a);
1432 f+=(A1/(L1*L1))*(1.0 + a*(L1*xt - 1.0));
1433 }
1434 if(L2!=0.0) f+=(A2/L2)*(exp(L2*xt) - 1.0); else f+=A2*xt;
1435 if(L3!=0.0) f+=(A3/L3)*(exp(L3*xt) - 1.0); else f+=A3*xt;
1436 }
1437 *yi=f;
1438 break;
1439 case 1314:
1440 t=r->p[8]; xt=x-t; f=0.0;
1441 if(xt>0.0) {
1442 double A1, A2, A3, A4, L1, L2, L3, L4;
1443 A1=r->p[0]; L1=r->p[1]; A2=r->p[2]; L2=r->p[3]; A3=r->p[4]; L3=r->p[5];
1444 A4=r->p[6]; L4=r->p[7];
1445 if(L1!=0.0) {
1446 a=exp(L1*xt);
1447 f+=(A2/L1)*(1.0 - a);
1448 f+=(A3/L1)*(1.0 - a);
1449 f+=(A4/L1)*(1.0 - a);
1450 f+=(A1/(L1*L1))*(1.0 + a*(L1*xt - 1.0));
1451 }
1452 if(L2!=0.0) f+=(A2/L2)*(exp(L2*xt) - 1.0); else f+=A2*xt;
1453 if(L3!=0.0) f+=(A3/L3)*(exp(L3*xt) - 1.0); else f+=A3*xt;
1454 if(L4!=0.0) f+=(A4/L4)*(exp(L4*xt) - 1.0); else f+=A4*xt;
1455 }
1456 *yi=f;
1457 break;
1458 case 1401: *yi=nan(""); break; /* not yet applied */
1459 case 1402: *yi=nan(""); break; /* not yet applied */
1460 case 1431:
1461 f=0.0;
1462 if(x>0.0) f=r->p[0]*(1.0 - (r->p[1]*x + 1.0)*exp(-r->p[1]*x));
1463 *yi=f;
1464 break;
1465 case 1432:
1466 f=0.0;
1467 if(x>0.0) {
1468 a=r->p[0]/(r->p[1]*r->p[1]);
1469 f=a*(1.0 - (r->p[1]*x + 1.0)*exp(-r->p[1]*x));
1470 }
1471 *yi=f;
1472 break;
1473 case 1435:
1474 xt=x-r->p[0]; f=0.0;
1475 if(xt>0.0) {
1476 double a, b, m, n; a=r->p[1]; b=r->p[2]; m=r->p[3]; n=r->p[4];
1477 f+=m*((1.0-(n*a*xt+1.0)*exp(-n*a*xt)))/(n*n*a*a) + (1.0-exp(-a*xt))/a;
1478 f*=b;
1479 }
1480 *yi=f;
1481 break;
1482 case 1441: /* Probability density function of Erlang distribution, or actually,
1483 its integral is the cumulative distribution function of Erlang distribution */
1484 f=0.0;
1485 if(x>=0.0) {
1486 double A, k; A=r->p[0]; k=r->p[1]; if(!(k>=0.0)) return(2);
1487 int N=(int)round(r->p[2]); if(!(N>=0) || N>20) return(2); // Supports only N=0,1,2,..,20
1488 if(N==0) f=A;
1489 else if(N==1) f=A*(1.0-exp(-k*x));
1490 else if(N==2) f=A*(1.0 - exp(-k*x) - k*x*exp(-k*x));
1491 else {
1492 double s=1.0+k*x;
1493 for(int j=2; j<N; j++) s+=pow(k*x, j)/lfactorial(j);
1494 f=A*(1.0-s*exp(-k*x));
1495 }
1496 }
1497 *yi=f;
1498 break;
1499 case 2111: *yi=nan(""); break; /* no application */
1500 case 9501: *yi=nan(""); break; /* cannot be applied to one point only */
1501 case 9502: *yi=nan(""); break; /* cannot be applied to one point only */
1502 case 9503: *yi=nan(""); break; /* cannot be applied to one point only */
1503 case 9701: *yi=nan(""); break; /* cannot be applied to one point only */
1504 default:
1505 *yi=nan("");
1506 }
1507 if(isnan(*yi)) return 3;
1508 return 0;
1509}

Referenced by fitIntegralEvaltac().

◆ fitIntegralEvaltac()

int fitIntegralEvaltac ( FitVOI * r,
double * x,
double * yi,
int dataNr )
extern

Evaluate an array yi[i]=Integral of f(x[i]) between 0 and x.

See also
fitEvaltac, fitIntegralEvaltac, fitDerivEvaltac
Returns
Returns 0, if ok.
Parameters
rFit parameters of a single region
xTimes where to evaluate the function integrals
yiArray for the function integral values
dataNrNr of (x,yi) data

Definition at line 1517 of file mathfunc.c.

1526 {
1527 int i;
1528
1529 if(r==NULL || x==NULL || yi==NULL || dataNr<1) return(1);
1530 for(i=0; i<dataNr; i++) if(fitIntegralEval(r, x[i], yi+i)) return(2);
1531 return(0);
1532}
int fitIntegralEval(FitVOI *r, double x, double *yi)
Definition mathfunc.c:1308

◆ fitPrint()

void fitPrint ( FIT * fit)
extern

Print to stdout the contents of FIT data structure.

Mainly for testing purposes.

Parameters
fitPointer to FIT struct.

Definition at line 180 of file mathfunc.c.

183 {
184 if(fit==NULL) {printf("FIT = Null\n"); return;}
185 if(MATHFUNC_TEST>0) printf("Number of curves: %d\n", fit->voiNr);
186 if(MATHFUNC_TEST>0) printf("_voidataNr = %d\n", fit->_voidataNr);
187 fitWrite(fit, "stdout");
188}
int fitWrite(FIT *fit, char *filename)
Definition mathfunc.c:54

◆ fitRead()

int fitRead ( char * filename,
FIT * fit,
int verbose )
extern

Read FIT file contents to the specified data structure, emptying its old contents.

Returns
In case of an error, >0 is returned, and a description is written in fiterrmsg.
See also
fitInit, fitPrint, fitWrite
Parameters
filenamePointer to file name.
fitPointer to initiated FIT struct.
verboseVerbose level; if <=0, then nothing is printed into stdout.

Definition at line 196 of file mathfunc.c.

203 {
204 char *cptr, line[1024], *lptr;
205 int i, ri, n, type=0;
206 struct tm st;
207
208
209 if(verbose>0) printf("fitRead(%s)\n", filename);
210 if(fit==NULL) return 1;
211 /* Empty data */
212 fitEmpty(fit);
213
214 /* Open file */
215 FILE *fp=fopen(filename, "r");
216 if(fp==NULL) {strcpy(fiterrmsg, "cannot open file"); return 1;}
217
218 /* Read data */
219 strcpy(fiterrmsg, "wrong format");
220 /* Read file type and program name */
221 while(fgets(line, 1024, fp)!=NULL) {
222 /* Ignore empty and comment lines */
223 if(strlen(line)<4 || line[0]=='#') continue;
224 /* Check for id string */
225 if(!strncmp(line, FIT_VER, strlen(FIT_VER))) type=1; else type=0;
226 break;
227 }
228 if(type!=1) {fclose(fp); return 3;}
229 lptr=line; cptr=strtok(lptr, " \t\n\r");
230 if(cptr!=NULL) cptr=strtok(NULL, " \t\n\r");
231 if(cptr!=NULL && strlen(cptr)<1024) strcpy(fit->program, cptr);
232#if(1)
233 /* Read optional fields until "Nr of VOIs:" */
234 while(1) {
235 /* Read title field */
236 while(fgets(line, 1024, fp)!=NULL) if(strlen(line)>2 && line[0]!='#') break;
237 /* Stop when "Nr of VOIs" is reached */
238 if(strncasecmp(line, "Nr of VOIs:", 11)==0) break;
239 /* Read fit date and time */
240 if(strncasecmp(line, "Date:", 5)==0) {
241 cptr=line+5; while(*cptr && !isdigit(*cptr)) cptr++;
242 if(get_datetime(cptr, &st, verbose-3)==0) fit->time=timegm(&st);
243 continue;
244 }
245 /* Read the name of the original datafile */
246 if(strncasecmp(line, "Data file:", 10)==0) {
247 lptr=&line[10]; cptr=strtok(lptr, " \t\n\r");
248 if(cptr!=NULL && strlen(cptr)<FILENAME_MAX) strcpy(fit->datafile, cptr);
249 continue;
250 }
251 /* Read study number */
252 if(strncasecmp(line, "Study number:", 13)==0) {
253 lptr=&line[13]; cptr=strtok(lptr, " \t\n\r");
254 if(cptr!=NULL && strlen(cptr)<MAX_STUDYNR_LEN+1) strcpy(fit->studynr, cptr);
255 continue;
256 }
257 /* Read the activity unit */
258 if(strncasecmp(line, "Data unit:", 10)==0) {
259 lptr=&line[10]; cptr=strtok(lptr, " \t\n\r");
260 if(cptr!=NULL && strlen(cptr)<1024) strcpy(fit->unit, cptr);
261 continue;
262 }
263 /* Read the time unit */
264 if(strncasecmp(line, "Time unit:", 10)==0) {
265 lptr=&line[10]; cptr=strtok(lptr, " \t\n\r");
266 fit->timeunit=petTunitId(cptr);
267 continue;
268 }
269 if(strncasecmp(line, "Distance unit:", 14)==0) {
270 lptr=&line[14]; cptr=strtok(lptr, " \t\n\r");
271 fit->timeunit=petTunitId(cptr);
272 continue;
273 }
274 fclose(fp); return 8;
275 }
276 /* Read the nr of regions */
277 if(strncasecmp(line, "Nr of VOIs:", 11)) {fclose(fp); return 8;}
278 lptr=&line[11]; cptr=strtok(lptr, " \t\n\r");
279 n=atoi(cptr); if(n<1 || n>32000) {fclose(fp); return 8;}
280#else
281 /* Read fit date and time */
282 while(fgets(line, 1024, fp)!=NULL) if(strlen(line)>2 && line[0]!='#') break;
283 if(strncasecmp(line, "Date:", 5)) {fclose(fp); return 4;}
284 cptr=line+5; while(*cptr && !isdigit(*cptr)) cptr++;
285 if(get_datetime(cptr, &st, verbose-3)==0) fit->time=timegm(&st);
286 /* Read the name of the original datafile */
287 while(fgets(line, 1024, fp)!=NULL) if(strlen(line)>2 && line[0]!='#') break;
288 if(strncasecmp(line, "Data file:", 10)) {fclose(fp); return 5;}
289 lptr=&line[10]; cptr=strtok(lptr, " \t\n\r");
290 if(cptr!=NULL && strlen(cptr)<FILENAME_MAX) strcpy(fit->datafile, cptr);
291 /* Read the activity unit */
292 while(fgets(line, 1024, fp)!=NULL) if(strlen(line)>2 && line[0]!='#') break;
293 if(strncasecmp(line, "Data unit:", 10)) {fclose(fp); return 6;}
294 lptr=&line[10]; cptr=strtok(lptr, " \t\n\r");
295 if(cptr!=NULL && strlen(cptr)<1024) strcpy(fit->unit, cptr);
296 /* Read the time unit */
297 while(fgets(line, 1024, fp)!=NULL) if(strlen(line)>2 && line[0]!='#') break;
298 if(strncasecmp(line, "Time unit:", 10)==0) lptr=&line[10];
299 else if(strncasecmp(line, "Distance unit:", 14)==0) lptr=&line[14];
300 else {fclose(fp); return 7;}
301 cptr=strtok(lptr, " \t\n\r");
302 fit->timeunit=petTunitId(cptr);
303 /* Read the nr of regions */
304 while(fgets(line, 1024, fp)!=NULL) if(strlen(line)>2 && line[0]!='#') break;
305 if(strncasecmp(line, "Nr of VOIs:", 11)) {fclose(fp); return 8;}
306 lptr=&line[11]; cptr=strtok(lptr, " \t\n\r");
307 n=atoi(cptr); if(n<1 || n>32000) {fclose(fp); return 8;}
308#endif
309 /* Allocate memory for regions */
310 if(fitSetmem(fit, n)) {strcpy(fiterrmsg, "out of memory"); fclose(fp); return 9;}
311 fit->voiNr=n;
312 /* Read (and ignore) title line */
313 strcpy(fiterrmsg, "wrong format");
314 while(fgets(line, 1024, fp)!=NULL) if(strlen(line)>2 && line[0]!='#') break;
315 if(strncasecmp(line, "Region", 6)) {fclose(fp); return 10;}
316 /* Read regional data */
317 for(ri=0; ri<fit->voiNr; ri++) {
318 /* Read line of data */
319 line[0]=(char)0;
320 while(fgets(line, 1024, fp)!=NULL) if(strlen(line)>2 && line[0]!='#') break;
321 if(!line[0]) break;
322 int pindx=0; char seps[8];
323 int sn=strTokenNr(line, " \t\n\r"); if(sn<8) {fclose(fp); fitEmpty(fit); return 11;}
324 int tn=strTokenNr(line, "\t\n\r");
325 if(tn==sn || tn==sn-1 || tn==sn-2) { // tab as separator
326 strcpy(seps, "\t\n\r"); n=tn;
327 char *s=strTokenDup(line, seps, NULL);
328 char *cptr=s;
329 int i=0, n=strlen(s);
330 strReplaceChar(cptr, ' ', (char)0);
331 strlcpy(fit->voi[ri].voiname, cptr, MAX_REGIONSUBNAME_LEN+1);
332 i+=strlen(fit->voi[ri].voiname);
333 cptr=s+i; if(i<n) {cptr++; i++;}
334 strReplaceChar(cptr, ' ', (char)0);
335 strlcpy(fit->voi[ri].hemisphere, cptr, MAX_REGIONSUBNAME_LEN+1);
336 i+=strlen(fit->voi[ri].hemisphere);
337 cptr=s+i; if(i<n) {cptr++; i++;}
338 strReplaceChar(cptr, ' ', (char)0);
339 strlcpy(fit->voi[ri].place, cptr, MAX_REGIONSUBNAME_LEN+1);
340 free(s);
341 pindx=2;
342 } else { // spaces as separators
343 strcpy(seps, " \t\n\r"); n=sn;
344 strTokenNCpy(line, seps, 1, fit->voi[ri].voiname, MAX_REGIONSUBNAME_LEN+1);
345 strTokenNCpy(line, seps, 2, fit->voi[ri].hemisphere, MAX_REGIONSUBNAME_LEN+1);
346 strTokenNCpy(line, seps, 3, fit->voi[ri].place, MAX_REGIONSUBNAME_LEN+1);
347 pindx=4;
348 }
350 fit->voi[ri].voiname, fit->voi[ri].hemisphere, fit->voi[ri].place, ' ');
351 /* Fit start and end times, and original data nr */
352 char s[128];
353 strTokenNCpy(line, seps, pindx++, s, 128); fit->voi[ri].start=atof_dpi(s);
354 strTokenNCpy(line, seps, pindx++, s, 128); fit->voi[ri].end=atof_dpi(s);
355 strTokenNCpy(line, seps, pindx++, s, 128); fit->voi[ri].dataNr=atoi(s);
356 /* Fit error, parameter nr and function number (type) */
357 strTokenNCpy(line, seps, pindx++, s, 128); fit->voi[ri].wss=atof_dpi(s);
358 strTokenNCpy(line, seps, pindx++, s, 128); fit->voi[ri].parNr=atoi(s);
359 strTokenNCpy(line, seps, pindx++, s, 128); fit->voi[ri].type=atoi(s);
360 /* Parameters */
361 for(i=0; i<fit->voi[ri].parNr; i++) {
362 strTokenNCpy(line, seps, pindx++, s, 128); fit->voi[ri].p[i]=atof_dpi(s);
363 }
364 }
365 if(ri==0) {fclose(fp); fitEmpty(fit); return(12);}
366 if(ri<fit->voiNr) fit->voiNr=ri;
367
368 /* Close file */
369 fclose(fp);
370 strcpy(fiterrmsg, "");
371
372 if(verbose>1) printf("done fitRead()\n");
373 return(0);
374}
int get_datetime(char *str, struct tm *date, int verbose)
Definition datetime.c:322
time_t timegm(struct tm *tm)
Inverse of gmtime, converting struct tm to time_t.
Definition datetime.c:69
int strTokenNCpy(const char *str1, const char *str2, int i, char *str3, int count)
Definition strext.c:45
int strTokenNr(const char *str1, const char *str2)
Definition strext.c:17
char * strTokenDup(const char *s1, const char *s2, int *next)
Definition strext.c:89
int fitSetmem(FIT *fit, int voiNr)
Definition mathfunc.c:154
void fitEmpty(FIT *fit)
Definition mathfunc.c:18
char fiterrmsg[64]
Definition mathfunc.c:6
double wss

◆ fitSetmem()

int fitSetmem ( FIT * fit,
int voiNr )
extern

Allocate memory for FIT data. Any previous contents are destroyed.

Returns
Returns 0 when successful, and >0 in case of an error.
See also
fitInit, fitEmpty, fitRead
Parameters
fitPointer to FIT struct.
voiNrNr of TACs to allocate.

Definition at line 154 of file mathfunc.c.

159 {
160 /* Check that there is something to do */
161 if(fit==NULL || voiNr<1) return 1;
162
163 /* Clear previous data, but only if necessary */
164 if(fit->_voidataNr>0 || fit->voiNr>0) fitEmpty(fit);
165
166 /* Allocate memory for regional curves */
167 fit->voi=(FitVOI*)calloc(voiNr, sizeof(FitVOI));
168 if(fit->voi==NULL) return 2;
169 fit->_voidataNr=voiNr;
170
171 return 0;
172}

Referenced by fit_allocate_with_dft(), and fitRead().

◆ fitToResult()

int fitToResult ( FIT * fit,
RES * res,
char * status )
extern

Conversion of FIT contents to RES.

See also
res_allocate_with_dft, dftToResult, res2ift
Returns
Returns 0 when successful.
Parameters
fitPointer to FIT structure, contents of which are written to RES struct.
resPointer to initiated RES struct where FIT contents are written; any previous contents are removed.
statusPointer to a string (allocated for at least 64 chars) where error message or other execution status will be written; enter NULL, if not needed.

Definition at line 56 of file fitres.c.

65 {
66 int pi, ri, maxParNr, ret;
67
68
69 //printf("fitToResult()\n"); fflush(stdout);
70 /* Check input */
71 if(status!=NULL) sprintf(status, "invalid data");
72 if(fit==NULL || res==NULL) return 1;
73 if(fit->voiNr<1) return 2;
74
75 /* Determine max parameter number in fits */
76 for(ri=0, maxParNr=0; ri<fit->voiNr; ri++)
77 if(fit->voi[ri].parNr>maxParNr) maxParNr=fit->voi[ri].parNr;
78 //printf("maxParNr := %d\n", maxParNr); fflush(stdout);
79
80 /* Allocate memory for results */
81 resEmpty(res); ret=resSetmem(res, fit->voiNr);
82 if(ret) {
83 if(status!=NULL) sprintf(status, "cannot allocate memory");
84 return 11;
85 }
86 /* Copy titles & filenames */
87 //printf("copy header contents\n"); fflush(stdout);
88 if(strlen(fit->program)>0 && strlen(fit->program)<512)
89 snprintf(res->program, 1024, "%.512s (c) 2014", fit->program);
90 else
91 strcpy(res->program, "fitToResult (c) 2014");
92 strcpy(res->datafile, fit->datafile);
93 strcpy(res->studynr, fit->studynr);
94 res->time=fit->time;
95 /* Copy region names, etc */
96 //printf("copy region names\n"); fflush(stdout);
97 res->voiNr=fit->voiNr;
98 for(ri=0; ri<fit->voiNr; ri++) {
99 strcpy(res->voi[ri].name, fit->voi[ri].name);
100 strcpy(res->voi[ri].voiname, fit->voi[ri].voiname);
101 strcpy(res->voi[ri].hemisphere, fit->voi[ri].hemisphere);
102 strcpy(res->voi[ri].place, fit->voi[ri].place);
103 }
104 /* Copy sample number, if equal in all TACs */
105 for(ri=1, ret=0; ri<fit->voiNr; ri++)
106 if(fit->voi[ri].dataNr!=fit->voi[0].dataNr) ret++;
107 if(ret==0) res->datanr=fit->voi[0].dataNr;
108 /* Set parameter names */
109 //printf("set parameter names\n"); fflush(stdout);
110 res->parNr=maxParNr+2; // function id and wss too
111 strcpy(res->parname[0], "Func");
112 for(pi=0; pi<maxParNr; pi++) sprintf(res->parname[pi+1], "p%d", pi+1);
113 strcpy(res->parname[pi+1], "WSS");
114 /* Copy parameter values */
115 //printf("copy parameter values\n"); fflush(stdout);
116 for(ri=0; ri<fit->voiNr; ri++) {
117 res->voi[ri].parameter[0]=fit->voi[ri].type; // function id
118 for(pi=0; pi<maxParNr; pi++) { // function parameters
119 if(pi>=fit->voi[ri].parNr) res->voi[ri].parameter[pi+1]=0.0;
120 else res->voi[ri].parameter[pi+1]=fit->voi[ri].p[pi];
121 }
122 res->voi[ri].parameter[pi+1]=fit->voi[ri].wss; // wss
123 }
124 /* Set also deprecated parameter name and unit representations, for now */
125 //printf("set deprecated info\n"); fflush(stdout);
126 resFixParnames(res);
127 return(0);
128}
int resSetmem(RES *res, int voiNr)
Definition result.c:70
void resEmpty(RES *res)
Definition result.c:22
char studynr[MAX_STUDYNR_LEN+1]
int voiNr
int datanr
char program[1024]
char datafile[FILENAME_MAX]
time_t time
char hemisphere[MAX_REGIONSUBNAME_LEN+1]
char place[MAX_REGIONSUBNAME_LEN+1]
char name[MAX_REGIONNAME_LEN+1]
char voiname[MAX_REGIONSUBNAME_LEN+1]

◆ fitWrite()

int fitWrite ( FIT * fit,
char * filename )
extern

Write function parameters in FIT into specified file.

If necessary, a backup file (+BACKUP_EXTENSION) is created.

Returns
In case of an error, >0 is returned, and a description is written in fiterrmsg.
See also
fitPrint, fitRead, fitInit
Parameters
fitPointer to FIT struct.
filenameFilename.

Definition at line 54 of file mathfunc.c.

59 {
60 int i, j, n, savedNr=0;
61 char tmp[1024], is_stdout=0;
62 FILE *fp;
63
64
65 if(MATHFUNC_TEST>0) printf("fitWrite(FIT, %s)\n", filename);
66 /* Check that there is some data to write */
67 if(fit==NULL || fit->voiNr<1) {strcpy(fiterrmsg, "no data"); return 1;}
68 for(i=0; i<fit->voiNr; i++)
69 if(!isnan(fit->voi[i].wss) && fit->voi[i].type>0) savedNr++;
70 if(savedNr<1) {strcpy(fiterrmsg, "no fitted data"); return 1;}
71
72 /* Check if writing to stdout */
73 if(!strcmp(filename, "stdout")) is_stdout=1;
74 if(MATHFUNC_TEST>1) {
75 if(is_stdout) printf(" output is stdout()\n");
76 else printf(" output in file\n");
77 }
78
79 /* Check if file exists; backup, if necessary */
80 if(!is_stdout) (void)backupExistingFile(filename, NULL, NULL);
81
82 /* Open output file */
83 if(is_stdout) fp=(FILE*)stdout;
84 else {
85 if(MATHFUNC_TEST>2) printf("opening file %s for write\n", filename);
86 if((fp = fopen(filename, "w")) == NULL) {
87 strcpy(fiterrmsg, "cannot open file"); return 2;
88 }
89 }
90
91 /* Fit file format */
92 n=fprintf(fp, "%-11.11s %s\n", FIT_VER, fit->program);
93 if(n==0) {
94 strcpy(fiterrmsg, "disk full");
95 if(!is_stdout) fclose(fp);
96 return 3;
97 }
98 /* Write fit date and time */
99 if(!ctime_r_int(&fit->time, tmp)) strcpy(tmp, "");
100 fprintf(fp, "Date:\t%s\n", tmp);
101 /* Write the name of the original datafile */
102 fprintf(fp, "Data file:\t%s\n", fit->datafile);
103 /* Write the studynr */
104 if(fit->studynr[0]) fprintf(fp, "Study number:\t%s\n", fit->studynr);
105 /* Write the 'activity' unit */
106 fprintf(fp, "Data unit:\t%s\n", fit->unit);
107 /* Write the time unit */
108 if(fit->timeunit==TUNIT_UM || fit->timeunit==TUNIT_MM)
109 fprintf(fp, "Distance unit:\t%s\n", petTunit(fit->timeunit));
110 else
111 fprintf(fp, "Time unit:\t%s\n", petTunit(fit->timeunit));
112
113 /* Write the voiNr to be saved */
114 fprintf(fp, "Nr of VOIs:\t%d\n", savedNr);
115 /* Write the Fit title */
116 fprintf(fp, "%s %s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n",
117 "Region", "Plane", "Start", "End", "dataNr", "WSS", "parNr", "Type", "Parameters");
118 /* Write regional fits */
119 for(i=0; i<fit->voiNr; i++) {
120 if(isnan(fit->voi[i].wss) || fit->voi[i].type<=0) continue;
121 if(fit->voi[i].voiname[0]) strcpy(tmp, fit->voi[i].voiname);
122 else strcpy(tmp, ".");
123 fprintf(fp, "%.*s ", MAX_REGIONSUBNAME_LEN, tmp);
124 if(fit->voi[i].hemisphere[0]) strcpy(tmp, fit->voi[i].hemisphere);
125 else strcpy(tmp, ".");
126 fprintf(fp, "%.*s ", MAX_REGIONSUBNAME_LEN, tmp);
127 if(fit->voi[i].place[0]) strcpy(tmp, fit->voi[i].place);
128 else strcpy(tmp, ".");
129 fprintf(fp, "%.*s\t", MAX_REGIONSUBNAME_LEN, tmp);
130 fprintf(fp, "%.3f\t%.3f\t%d\t%.2E\t%d\t%04d",
131 fit->voi[i].start, fit->voi[i].end, fit->voi[i].dataNr,
132 fit->voi[i].wss, fit->voi[i].parNr, fit->voi[i].type );
133 for(j=0; j<fit->voi[i].parNr; j++) fprintf(fp, "\t%.6E", fit->voi[i].p[j]);
134 fprintf(fp, "\n");
135 }
136
137 /* Close file */
138 if(!is_stdout) {
139 if(MATHFUNC_TEST>2) printf("closing file %s\n", filename);
140 fflush(fp); fclose(fp);
141 }
142 strcpy(fiterrmsg, "");
143
144 if(MATHFUNC_TEST>0) printf("done with fitWrite()\n");
145 return(0);
146}
char * ctime_r_int(const time_t *t, char *buf)
Convert calendard time t into a null-terminated string of the form YYYY-MM-DD hh:mm:ss,...
Definition datetime.c:110

Referenced by fitPrint().

◆ idwcRead()

int idwcRead ( char * filename,
DFT * dft )
extern

Read IDWC file into DFT data structure. Any previous content of DFT is deleted.

Returns
Returns nonzero in case an error is encountered and sets dfterrmsg.
Parameters
filenameName of IDWC file to be read
dftPointer to DFT data where to regional TAC data is read

Definition at line 77 of file idwc.c.

82 {
83 int ri, fi, n;
84 char tmp[MAX_IDWC_LINE_LEN], *lptr, *cptr;
85 FILE *fp;
86
87 /* Check the arguments */
88 if(filename==NULL || dft==NULL || strlen(filename)<1) {
89 strcpy(dfterrmsg, "program error"); return(1);
90 }
91
92 /* Open file */
93 fp=fopen(filename, "r");
94 if(fp==NULL) {
95 strcpy(dfterrmsg, "cannot open file"); return(2);
96 }
97
98 /* Read the line telling the sample number */
99 fi=0; do {
100 if(fgets(tmp, MAX_IDWC_LINE_LEN, fp)==NULL) {
101 strcpy(dfterrmsg, "wrong format"); fclose(fp); return(3);}
102 lptr=tmp;
103 /* Read first token, and check for empty lines as well */
104 cptr=strtok(lptr, "; \t\n\r"); if(cptr==NULL) continue;
105 /* Check for comment line */
106 if(cptr[0]=='#' || cptr[0]==';') continue;
107 /* Read the sample number */
108 fi=atoi(cptr); break;
109 } while(1);
110 if(fi<1) {strcpy(dfterrmsg, "wrong format"); fclose(fp); return(3);}
111
112 /* Read the line number */
113 n=0; while(fgets(tmp, MAX_IDWC_LINE_LEN, fp)!=NULL) {
114 lptr=tmp;
115 /* Read first token, and check for empty lines as well */
116 cptr=strtok(lptr, "; \t\n\r"); if(cptr==NULL) continue;
117 /* Check for comment line */
118 if(cptr[0]=='#' || cptr[0]==';') continue;
119 n++;
120 }
121 /* Calculate the number of TACs */
122 ri=n/fi; //printf("frameNr=%d voiNr=%d\n", fi, ri);
123 if(ri<1) {strcpy(dfterrmsg, "wrong format"); fclose(fp); return(4);}
124
125
126 /* Allocate memory for data */
127 if(dftSetmem(dft, fi, ri)) {
128 strcpy(dfterrmsg, "out of memory"); fclose(fp); return(11);}
129 dft->frameNr=fi; dft->voiNr=ri;
130
131 /* Read the data */
132 rewind(fp); n=ri=fi=0;
133 do {
134 if(fgets(tmp, MAX_IDWC_LINE_LEN, fp)==NULL) {
135 strcpy(dfterrmsg, "wrong format");
136 fclose(fp); dftEmpty(dft); return(3);
137 }
138 lptr=tmp;
139 /* Read first token, and check for empty lines as well */
140 cptr=strtok(lptr, "; \t\n\r"); if(cptr==NULL) continue;
141 /* Check for comment line */
142 if(cptr[0]=='#' || cptr[0]==';') continue;
143 n++; //printf("%d (fi=%d, ri=%d): %s\n", n, fi, ri, tmp);
144 /* This time forget the sample number */
145 if(n==1) {continue;}
146 /* read the sample time */
147 dft->x[fi]=atof(cptr);
148 /* read sample value */
149 cptr=strtok(NULL, "; \t\n\r"); if(cptr==NULL) continue;
150 dft->voi[ri].y[fi]=atof(cptr);
151 /* read sample weight */
152 cptr=strtok(NULL, "; \t\n\r"); if(cptr==NULL) continue;
153 dft->w[fi]+=atof(cptr);
154 /* read TAC number */
155 cptr=strtok(NULL, "; \t\n\r"); if(cptr==NULL) continue;
156 if(fi==0) sprintf(dft->voi[ri].voiname, "%-*.*s",
158 else if(strncasecmp(dft->voi[ri].voiname, cptr, strlen(cptr))!=0) {
159 strcpy(dfterrmsg, "wrong format");
160 //printf("'%s' '%s'\n", dft->voi[ri].voiname, cptr);
161 fclose(fp); dftEmpty(dft); return(4);
162 }
163 fi++;
164 if(fi==dft->frameNr) {fi=0; ri++;}
165 if(ri==dft->voiNr) break;
166 } while(1);
167 dft->voiNr=ri;
168 for(fi=0; fi<dft->frameNr; fi++) dft->w[fi]/=(double)dft->voiNr;
169
170 /* close file */
171 fclose(fp);
172
173 /* Set DFT "header" */
174 dft->_type=1;
175 dft->timetype=0; dftFrametimes(dft);
176 dft->timeunit=TUNIT_SEC; /* sec */
177 dft->isweight=1;
178
179 return(0);
180}
#define MAX_IDWC_LINE_LEN
Definition idwc.c:7

Referenced by dftRead().

◆ idwcWrite()

int idwcWrite ( DFT * dft,
char * filename )
extern

Write DFT data into IDWC file format. If file exists, a backup file (+BACKUP_EXTENSION) is written.

Returns
Returns nonzero in case an error is encountered and sets dfterrmsg.
Parameters
dftPointer to DFT data that is written in IDWC format
filenameName of IDWC file to be written; also "stdout" is accepted

Definition at line 18 of file idwc.c.

23 {
24 int ri, fi, n;
25 char tmp[1024], is_stdout=0;
26 FILE *fp;
27
28
29 /* Check that there is some data to write */
30 if(dft->voiNr<1 || dft->frameNr<1 || filename==NULL) {
31 strcpy(dfterrmsg, "no data"); return(1);}
32
33 /* Check if writing to stdout */
34 if(!strcasecmp(filename, "stdout")) is_stdout=1;
35
36 /* Check if file exists; backup, if necessary */
37 if(!is_stdout && access(filename, 0) != -1) {
38 strcpy(tmp, filename); strcat(tmp, BACKUP_EXTENSION);
39 if(access(tmp, 0) != -1) remove(tmp);
40 rename(filename, tmp);
41 }
42
43 /* Open output file */
44 if(is_stdout) fp=(FILE*)stdout;
45 else if((fp = fopen(filename, "w")) == NULL) {
46 strcpy(dfterrmsg, "cannot open file"); return(2);}
47
48 /* Write sample number */
49 n=fprintf(fp, "%d\n", dft->frameNr);
50 if(n<2) {
51 strcpy(dfterrmsg, "cannot write file");
52 fclose(fp); return(3);
53 }
54 /* write data lines */
55 for(ri=0; ri<dft->voiNr; ri++) {
56 for(fi=0; fi<dft->frameNr; fi++) {
57 n=fprintf(fp, "%6.1f %18.14f %18.14f %3d\n",
58 dft->x[fi], dft->voi[ri].y[fi], dft->w[fi], ri+1);
59 if(n<8) {
60 strcpy(dfterrmsg, "cannot write file");
61 fclose(fp); return(4);
62 }
63 }
64 }
65 /* close file */
66 fclose(fp);
67
68 return(0);
69}

◆ ifRead()

int ifRead ( char * filename,
DFT * dft )
extern

Read IF file into DFT data structure, metabolite corrected plasma as TAC #1 and whole blood as TAC #2. Any previous content of DFT is deleted.

Returns
Returns nonzero in case an error is encountered and sets dfterrmsg.
Parameters
filenameName of IDWC file to be read
dftPointer to DFT data where to regional TAC data is read

Definition at line 78 of file if.c.

83 {
84 int fi, n;
85 char tmp[MAX_IF_LINE_LEN], *lptr, *cptr;
86 FILE *fp;
87
88 /* Check the arguments */
89 if(filename==NULL || dft==NULL || strlen(filename)<1) {
90 strcpy(dfterrmsg, "program error"); return(1);
91 }
92
93 /* Open file */
94 fp=fopen(filename, "r");
95 if(fp==NULL) {
96 strcpy(dfterrmsg, "cannot open file"); return(2);
97 }
98
99 /* Read the line telling the sample number */
100 fi=n=0; do {
101 if(fgets(tmp, MAX_IF_LINE_LEN, fp)==NULL) {
102 strcpy(dfterrmsg, "wrong format"); fclose(fp); return(3);}
103 lptr=tmp; n++;
104 /* Read first token, and check for empty lines as well */
105 cptr=strtok(lptr, "; \t\n\r"); if(cptr==NULL) continue;
106 /* Check for comment line */
107 if(cptr[0]=='#' || cptr[0]==';') continue;
108 /* Read the sample number */
109 fi=atoi(cptr); break;
110 } while(1);
111 if(fi<1) {strcpy(dfterrmsg, "wrong format"); fclose(fp); return(3);}
112
113 /* Allocate memory for data */
114 if(dftSetmem(dft, fi, 2)) {
115 strcpy(dfterrmsg, "out of memory"); fclose(fp); return(11);}
116 dft->frameNr=fi; dft->voiNr=2;
117
118 /* Read the data */
119 n=fi=0;
120 do {
121 if(fgets(tmp, MAX_IF_LINE_LEN, fp)==NULL) {
122 strcpy(dfterrmsg, "wrong format");
123 fclose(fp); dftEmpty(dft); return(3);
124 }
125 lptr=tmp;
126 /* Read first token, and check for empty lines as well */
127 cptr=strtok(lptr, "; \t\n\r"); if(cptr==NULL) continue;
128 /* Check for comment line */
129 if(cptr[0]=='#' || cptr[0]==';') continue;
130 n++; //printf("%d (fi=%d): %s\n", n, fi, tmp);
131 /* read the sample time */
132 dft->x[fi]=atof(cptr);
133 /* read metabolite corrected plasma */
134 cptr=strtok(NULL, "; \t\n\r"); if(cptr==NULL) continue;
135 dft->voi[0].y[fi]=atof(cptr);
136 /* read whole blood */
137 cptr=strtok(NULL, "; \t\n\r"); if(cptr==NULL) continue;
138 dft->voi[1].y[fi]=atof(cptr);
139 fi++;
140 if(fi==dft->frameNr) break;
141 } while(1);
142
143 /* close file */
144 fclose(fp);
145
146 /* Set DFT "header" */
147 dft->_type=1;
148 dft->timetype=0;
149 dft->timeunit=TUNIT_SEC; /* sec */
150 dft->isweight=0;
151 strcpy(dft->voi[0].voiname, "Plasma");
152 strcpy(dft->voi[1].voiname, "Blood");
153
154 return(0);
155}
#define MAX_IF_LINE_LEN
Definition if.c:7

Referenced by dftRead().

◆ ifWrite()

int ifWrite ( DFT * dft,
char * filename )
extern

Write metabolite corrected plasma TAC and blood TAC into IF file format. If file exists, a backup file (+BACKUP_EXTENSION) is written.

Returns
Returns nonzero in case an error is encountered and sets dfterrmsg.
Parameters
dftPointer to DFT data that will be written in IF format: first TAC must be the metabolite corrected plasma, and the 2nd TAC must be the whole blood TAC.
filenameName of IF file to be written; also "stdout" is accepted

Definition at line 18 of file if.c.

25 {
26 int fi, n;
27 char tmp[1024], is_stdout=0;
28 FILE *fp;
29
30
31 /* Check that there is some data to write */
32 if(dft->voiNr<2 || dft->frameNr<1 || filename==NULL) {
33 strcpy(dfterrmsg, "no data"); return(1);}
34
35 /* Check if writing to stdout */
36 if(!strcasecmp(filename, "stdout")) is_stdout=1;
37
38 /* Check if file exists; backup, if necessary */
39 if(!is_stdout && access(filename, 0) != -1) {
40 strcpy(tmp, filename); strcat(tmp, BACKUP_EXTENSION);
41 if(access(tmp, 0) != -1) remove(tmp);
42 rename(filename, tmp);
43 }
44
45 /* Open output file */
46 if(is_stdout) fp=(FILE*)stdout;
47 else if((fp = fopen(filename, "w")) == NULL) {
48 strcpy(dfterrmsg, "cannot open file"); return(2);}
49
50 /* Write sample number */
51 n=fprintf(fp, "%d\n", dft->frameNr);
52 if(n<2) {
53 strcpy(dfterrmsg, "cannot write file");
54 fclose(fp); return(3);
55 }
56 /* Write data lines */
57 for(fi=0; fi<dft->frameNr; fi++) {
58 n=fprintf(fp, "%f\t%f\t%f\n",
59 dft->x[fi], dft->voi[0].y[fi], dft->voi[1].y[fi]);
60 if(n<6) {
61 strcpy(dfterrmsg, "cannot write file");
62 fclose(fp); return(4);
63 }
64 }
65 /* close file */
66 fclose(fp);
67
68 return(0);
69}

◆ igam()

double igam ( double a,
double x )
extern

Cumulative gamma distribution, or Regularized gamma function, more specifically, lower incomplete gamma function divided by gamma function.

Standard gamma distribution is assumed (Beta=1). f(a,x) = (1/Gamma(a)) * Integral(0,x)(e^-t * t^(a-1))dt

Returns
Returns the value of regularized gamma function, or NaN in case of an error.
See also
igamc, inverfc, factorial
Parameters
aShape parameter alpha; must be > 0.
xIntegral from 0 to x; must be >= 0.

Definition at line 1715 of file mathfunc.c.

1720 {
1721 /* Check parameters */
1722 if(x==0.0) return(0.0);
1723 if((x<0.0) || (a<=0.0)) return(nan(""));
1724
1725 if((x>1.0) && (x>a)) return(1.0 - igamc(a, x));
1726
1727 /* Left tail of incomplete Gamma function:
1728 x^a * e^-x * Sum(k=0,Inf)(x^k / Gamma(a+k+1)) */
1729
1730 double ans, ax, c, r;
1731
1732 /* Compute x**a * exp(-x) / Gamma(a) */
1733 ax=a*log(x) - x - lgamma(a);
1734 if(ax<-DBL_MAX_10_EXP) return(0.0); // underflow
1735 ax=exp(ax);
1736
1737 /* power series */
1738 r=a; c=1.0; ans=1.0;
1739 do {
1740 r+=1.0;
1741 c*=x/r;
1742 ans+=c;
1743 } while(c/ans > DBL_EPSILON);
1744 return(ans*ax/a);
1745}
double igamc(double a, double x)
Definition mathfunc.c:1756

Referenced by fitEval(), and igamc().

◆ igamc()

double igamc ( double a,
double x )
extern

Regularized gamma function, more specifically, upper incomplete gamma function divided by gamma function.

f(a,x) = (1/Gamma(a)) * Integral(x,Inf)(e^-t * t^(a-1))dt Standard gamma distribution is assumed (Beta=1).

Returns
Returns the value of regularized gamma function, or NaN in case of an error.
See also
igam, inverfc, factorial
Parameters
aShape parameter alpha; must be > 0.
xIntegral from x to infinity; must be >= 0

Definition at line 1756 of file mathfunc.c.

1761 {
1762 /* Check parameters */
1763 if((x<0.0) || (a<=0.0)) return(nan(""));
1764
1765 if((x<1.0) || (x<a)) return(1.0-igam(a, x));
1766
1767 double ans, ax, c, yc, r, t, y, z;
1768 double pk, pkm1, pkm2, qk, qkm1, qkm2;
1769 double big=4.503599627370496E+015;
1770 double biginv=2.22044604925031308085E-016;
1771
1772 ax = a*log(x) - x - lgamma(a);
1773 if(ax < -DBL_MAX_10_EXP) return(0.0); // underflow
1774 ax=exp(ax);
1775
1776 /* continued fraction */
1777 y=1.0-a; z=x+y+1.0; c=0.0;
1778 pkm2=1.0; qkm2=x; pkm1=x+1.0; qkm1=z*x;
1779 ans=pkm1/qkm1;
1780 do {
1781 c+=1.0; y+=1.0; z+=2.0;
1782 yc=y*c; pk=pkm1*z - pkm2*yc; qk=qkm1*z - qkm2*yc;
1783 if(qk!=0.0) {r=pk/qk; t=fabs((ans-r)/r); ans=r;}
1784 else t=1.0;
1785 pkm2=pkm1; pkm1=pk; qkm2=qkm1; qkm1=qk;
1786 if(fabs(pk)>big) {pkm2*=biginv; pkm1*=biginv; qkm2*=biginv; qkm1*=biginv;}
1787 } while(t>DBL_EPSILON);
1788 return(ans*ax);
1789}

Referenced by igam().

◆ lfactorial()

unsigned long long int lfactorial ( unsigned long long int n)
extern

Calculate factorial of given number.

See also
factorial, igam, igamc
Returns
Returns factorial n!, or zero if factorial would cause wrap-around.
Parameters
nInteger n, from which the factorial is calculated.
Note
Wrap-around will occur if n>20.

Definition at line 1695 of file mathfunc.c.

1700 {
1701 if(n<1) return(1);
1702 if(n>20) return(0);
1703 return(n*lfactorial(n-1));
1704}

Referenced by fitEval(), fitIntegralEval(), and lfactorial().

◆ res2ift()

int res2ift ( RES * res,
IFT * ift,
int verbose )
extern

Copy results in RES structure into IFT structure.

Returns
Returns 0 when successful.
See also
fit2Result, dftToResult
Parameters
resPointer to RES structure
iftPointer to initiated IFT structure
verboseVerbose level; if zero, then nothing is printed into stdout or stderr

Definition at line 14 of file resift.c.

21 {
22 int ri, pi, ret;
23 char tmp[1024], tmp2[1024], tmp3[1024];
24 struct tm st;
25
26 if(verbose>0) printf("res2ift()\n");
27
28 /* Check the input */
29 if(res==NULL || ift==NULL) {
30 if(verbose>0) fprintf(stderr, "Error: invalid input\n");
31 return(1);
32 }
33
34 /* Delete any previous content */
35 iftEmpty(ift);
36
37 /* Set header info */
38 if(strlen(res->program)>0) {
39 ret=iftPut(ift, "program", res->program, NULL, 0);
40 if(ret!=0) {
41 if(verbose>0) fprintf(stderr, "Error: cannot set IFT content\n");
42 return(3);
43 }
44 }
45 if(gmtime_r(&res->time, &st)!=NULL) {
46 strftime(tmp, 256, "%Y-%m-%d %H:%M:%S", &st);
47 iftPut(ift, "date", tmp, NULL, 0);
48 }
49 if(res->studynr[0]) iftPut(ift, "studynr", res->studynr, NULL, 0);
50 if(res->datafile[0]) iftPut(ift, "datafile", res->datafile, NULL, 0);
51 if(res->plasmafile[0]) iftPut(ift, "plasmafile", res->plasmafile, NULL, 0);
52 if(res->plasmafile2[0]) iftPut(ift, "plasmafile2", res->plasmafile2, NULL, 0);
53 if(res->bloodfile[0]) iftPut(ift, "bloodfile", res->bloodfile, NULL, 0);
54 if(res->reffile[0]) iftPut(ift, "reffile", res->reffile, NULL, 0);
55 if(res->refroi[0]) iftPut(ift, "refroi", res->refroi, NULL, 0);
56
57 if(res->datarange[0]) iftPut(ift, "datarange", res->datarange, NULL, 0);
58 if(res->datanr>0) {
59 snprintf(tmp, 1024, "%d", res->datanr); iftPut(ift, "datanr", tmp, NULL, 0);}
60 if(res->fitmethod[0]) iftPut(ift, "fitmethod", res->fitmethod, NULL, 0);
61
62 if(res->density>0) {
63 snprintf(tmp, 1024, "%g", res->density); iftPut(ift, "density", tmp, NULL, 0);}
64 if(res->lc>0) {
65 snprintf(tmp, 1024, "%g", res->lc); iftPut(ift, "lc", tmp, NULL, 0);}
66 if(res->concentration>0) {
67 snprintf(tmp, 1024, "%g", res->concentration);
68 iftPut(ift, "concentration", tmp, NULL, 0);
69 }
70 if(res->beta>0) {
71 snprintf(tmp, 1024, "%g", res->beta); iftPut(ift, "beta", tmp, NULL, 0);}
72 if(res->Vb>0) {
73 snprintf(tmp, 1024, "%g", res->Vb); iftPut(ift, "Vb", tmp, NULL, 0);}
74 if(res->fA>0) {
75 snprintf(tmp, 1024, "%g", res->fA); iftPut(ift, "fA", tmp, NULL, 0);}
76 if(res->E>0) {
77 snprintf(tmp, 1024, "%g", res->E); iftPut(ift, "E", tmp, NULL, 0);}
78 if(res->isweight>0) strcpy(tmp, "yes");
79 else if(res->isweight==0) strcpy(tmp, "no");
80 else strcpy(tmp, "unknown");
81 iftPut(ift, "weighting", tmp, NULL, 0);
82
83 /* Set each ROI and parameter value */
84 for(ri=0; ri<res->voiNr; ri++) {
85 if(res->voiNr>1) {
86 strcpy(tmp, res->voi[ri].name); rnameRmDots(tmp, NULL);
87 strcat(tmp, "_");
88 } else {
89 strcpy(tmp, "");
90 }
91 for(pi=0; pi<res->parNr; pi++) {
92 snprintf(tmp2, 1024, "%s%s", tmp, res->parname[pi]);
93 if(isnan(res->voi[ri].parameter[pi])) strcpy(tmp3, "");
94 else sprintf(tmp3, "%g", res->voi[ri].parameter[pi]);
95 if(strlen(res->parunit[pi])) {
96 strcat(tmp3, " "); strcat(tmp3, res->parunit[pi]);}
97 iftPut(ift, tmp2, tmp3, NULL, 0);
98 if(!isnan(res->voi[ri].sd[pi])) {
99 snprintf(tmp2, 1024, "%s%s_%s", tmp, res->parname[pi], "SD");
100 snprintf(tmp3, 1024, "%g", res->voi[ri].sd[pi]);
101 if(strlen(res->parunit[pi])) {
102 strcat(tmp3, " "); strcat(tmp3, res->parunit[pi]);}
103 iftPut(ift, tmp2, tmp3, NULL, 0);
104 }
105 if(!isnan(res->voi[ri].cl1[pi])) {
106 snprintf(tmp2, 1024, "%s%s_%s", tmp, res->parname[pi], "CL1");
107 snprintf(tmp3, 1024, "%g", res->voi[ri].cl1[pi]);
108 if(strlen(res->parunit[pi])) {
109 strcat(tmp3, " "); strcat(tmp3, res->parunit[pi]);}
110 iftPut(ift, tmp2, tmp3, NULL, 0);
111 }
112 if(!isnan(res->voi[ri].cl2[pi])) {
113 snprintf(tmp2, 1024, "%s%s_%s", tmp, res->parname[pi], "CL2");
114 snprintf(tmp3, 1024, "%g", res->voi[ri].cl2[pi]);
115 if(strlen(res->parunit[pi])) {
116 strcat(tmp3, " "); strcat(tmp3, res->parunit[pi]);}
117 iftPut(ift, tmp2, tmp3, NULL, 0);
118 }
119 }
120 }
121
122 return(0);
123}
struct tm * gmtime_r(const time_t *t, struct tm *tm)
Convert time_t to GMT struct tm.
Definition datetime.c:22
int iftPut(IFT *ift, char *key, char *value, char *cmt_type, int verbose)
Definition ift.c:82
int rnameRmDots(char *rname1, char *rname2)
Definition rname.c:99
double E
double density
char plasmafile2[FILENAME_MAX]
double concentration
double fA
double beta
double Vb
char plasmafile[FILENAME_MAX]
char datarange[128]
int isweight
double lc
char reffile[FILENAME_MAX]
char fitmethod[128]
char refroi[64]
char bloodfile[FILENAME_MAX]
double cl2[MAX_RESPARAMS]
double cl1[MAX_RESPARAMS]
double sd[MAX_RESPARAMS]

◆ res_allocate_with_dft()

int res_allocate_with_dft ( RES * res,
DFT * dft )
extern

Allocate memory for regional results based on information in DFT.

See also
fit_allocate_with_dft, dftToResult
Returns
Returns 0 if successful, otherwise <>0.
Parameters
resPointer to initiated RES struct which will be allocated here and filled with ROI names etc.
dftRegional data from where necessary information is read.

Definition at line 14 of file dftres.c.

19 {
20 int ri;
21
22 //printf("res_allocate_with_dft()\n"); fflush(stdout);
23 // Check the input data
24 if(res==NULL || dft==NULL || dft->voiNr<1) return 1;
25 // Allocate memory
26 if(resSetmem(res, dft->voiNr)!=0) return 2;
27 res->voiNr=dft->voiNr;
28 // Copy header information
29 strcpy(res->studynr, dft->studynr);
30 res->Vb=-1.0;
31 res->fA=-1.0;
32 res->E=-1.0;
33 res->time=time(NULL); // Set current time to results
34 res->isweight=dft->isweight;
35 /* Copy region names, etc */
36 for(ri=0; ri<dft->voiNr; ri++) {
37 strcpy(res->voi[ri].name, dft->voi[ri].name);
38 strcpy(res->voi[ri].voiname, dft->voi[ri].voiname);
39 strcpy(res->voi[ri].hemisphere, dft->voi[ri].hemisphere);
40 strcpy(res->voi[ri].place, dft->voi[ri].place);
41 }
42 /* Set data range */
44 sprintf(res->datarange, "%g - %g %s",
45 dft->x1[0], dft->x2[dft->frameNr-1], petTunit(dft->timeunit) );
46 else
47 sprintf(res->datarange, "%g - %g %s",
48 dft->x[0], dft->x[dft->frameNr-1], petTunit(dft->timeunit) );
49 res->datanr=dft->frameNr;
50
51 return 0;
52}

Referenced by dftToResult().

◆ resCopyMHeader()

int resCopyMHeader ( RES * res1,
RES * res2 )
extern

Copy result main header information to another result structure.

Returns
Returns 0 if successful.
See also
resRead, resInit

Definition at line 1297 of file result.c.

1302 {
1303 int i;
1304
1305 if(res1==NULL || res2==NULL) return(1);
1306 strcpy(res2->program, res1->program);
1307 res2->time=res1->time;
1308 res2->parNr=res1->parNr;
1309 strcpy(res2->studynr, res1->studynr);
1310 strcpy(res2->datafile, res1->datafile);
1311 strcpy(res2->reffile, res1->reffile);
1312 strcpy(res2->plasmafile, res1->plasmafile);
1313 strcpy(res2->plasmafile2, res1->plasmafile2);
1314 strcpy(res2->bloodfile, res1->bloodfile);
1315 strcpy(res2->refroi, res1->refroi);
1316 strcpy(res2->datarange, res1->datarange);
1317 res2->datanr=res1->datanr;
1318 strcpy(res2->fitmethod, res1->fitmethod);
1319 res2->density=res1->density;
1320 res2->lc=res1->lc;
1321 res2->concentration=res1->concentration;
1322 res2->beta=res1->beta;
1323 res2->Vb=res1->Vb;
1324 res2->fA=res1->fA;
1325 res2->E=res1->E;
1326 res2->isweight=res1->isweight;
1327 for(i=0; i<res1->parNr; i++) {
1328 strcpy(res2->parname[i], res1->parname[i]);
1329 strcpy(res2->parunit[i], res1->parunit[i]);
1330 }
1331 strcpy(res2->titleline, res1->titleline);
1332 strcpy(res2->unitline, res1->unitline);
1333 return(0);
1334}
char titleline[1024]
char unitline[1024]

◆ resDelete()

int resDelete ( RES * res,
int voi )
extern

Delete specified region (0..voiNr-1) from the structure.

Returns
Returns 0 if ok.
See also
resSelectRegions, resRead, resSortByName, resIsDuplicateNames
Parameters
resPointer to the result data.
voiTAC index (0..voiNr-1).

Definition at line 1342 of file result.c.

1347 {
1348 int i;
1349
1350 /* Check that region exists */
1351 if(res==NULL || voi>res->voiNr-1 || voi<0) return(1);
1352 /* If it is the last one, then just decrease the voiNr */
1353 if(voi==res->voiNr) {res->voiNr--; return(0);}
1354 /* Otherwise we have to move the following regions in its place */
1355 for(i=voi+1; i<res->voiNr; i++)
1356 memcpy(&res->voi[i-1], &res->voi[i], sizeof(ResVOI));
1357 res->voiNr--;
1358 return(0);
1359}

◆ resEmpty()

void resEmpty ( RES * res)
extern

Free memory allocated for results. All data are cleared.

See also
resInit, resSetmem
Parameters
resPointer to RES structure.

Definition at line 22 of file result.c.

25 {
26 if(res==NULL) return;
27 if(res->_voidataNr>0) {
28 free((char*)(res->voi));
29 res->_voidataNr=0;
30 }
31 res->voiNr=0;
32 res->parNr=0;
33 res->studynr[0]=(char)0;
34 for(int pi=0; pi<MAX_RESPARAMS; pi++) {
35 strcpy(res->parname[pi], ""); strcpy(res->parunit[pi], "");}
36 res->titleline[0]=res->unitline[0]=(char)0;
37 res->program[0]=(char)0; res->refroi[0]=(char)0; res->datarange[0]=(char)0;
38 res->datanr=0; res->fitmethod[0]=(char)0;
39 res->datafile[0]=res->reffile[0]=(char)0;
40 res->plasmafile[0]=res->plasmafile2[0]=res->bloodfile[0]=(char)0;
41 res->density=res->lc=res->concentration=res->beta=0.0;
42 res->Vb=-1.0;
43 res->fA=-1.0;
44 res->E=-1.0;
45}
int _voidataNr

Referenced by fitToResult(), resInit(), resRead(), and resSetmem().

◆ resFixParnames()

void resFixParnames ( RES * res)
extern

Fix result parameter names and units, so that both representations are filled correctly, that is, the new string lists *parname[] and *parunit[], and the deprecated titleline[] and unitline[].

New representation, if filled, always overwrites the deprecated one. Units are assumed to follow parameter name representation.

See also
resRNameSubfieldExists
Parameters
resPointer to RES struct.

Definition at line 107 of file result.c.

110 {
111 int i, len, n;
112 char *cptr, tmp[1024], *lptr;
113
114 if(RESULT_TEST>0) printf("resFixParnames(*res)\n");
115 if(res==NULL) return;
116 if(res->parNr<1) return;
118
119 /* If new string lists are filled, then copy those to old representation */
120 for(i=n=0; i<res->parNr; i++) {
121 len=strlen(res->parname[i]); if(len<1) continue;
122 if(strcmp(res->parname[i], ".")==0) continue;
123 n++;
124 }
125 if(n>0) { // copy names and units
126 strcpy(res->titleline, "");
127 for(i=0; i<res->parNr; i++) {
128 if(1023<(1+strlen(res->titleline)+strlen(res->parname[i]))) break;
129 if(i>0) strcat(res->titleline, " ");
130 len=strlen(res->parname[i]);
131 if(len<1) strcat(res->titleline, ".");
132 else strcat(res->titleline, res->parname[i]);
133 }
134 strcpy(res->unitline, "");
135 for(i=0; i<res->parNr; i++) {
136 if(1023<(1+strlen(res->unitline)+strlen(res->parunit[i]))) break;
137 if(i>0) strcat(res->unitline, " ");
138 len=strlen(res->parunit[i]);
139 if(len<1) strcat(res->unitline, ".");
140 else strcat(res->unitline, res->parunit[i]);
141 }
142 if(RESULT_TEST>1) {
143 printf("Parameter names and units:\n");
144 for(i=0; i<res->parNr; i++)
145 printf(" %d: '%s' '%s'\n", i+1, res->parname[i], res->parunit[i]);
146 printf("Created titleline: %s\n", res->titleline);
147 printf("Created unitline: %s\n", res->unitline);
148 }
149 return;
150 }
151
152 /* If new string lists are not filled, then get them from deprecated strings */
153 for(i=0; i<res->parNr; i++) {
154 strcpy(res->parname[i], "");
155 strcpy(res->parunit[i], "");
156 }
157 strcpy(tmp, res->titleline); lptr=tmp; cptr=strtok(lptr, " \t\n\r");
158 i=0; while(cptr!=NULL && i<res->parNr) {
159 if(strcmp(cptr, ".")==0) {i++; continue;}
160 strncpy(res->parname[i], cptr, MAX_RESPARNAME_LEN);
161 res->parname[i][MAX_RESPARNAME_LEN]=(char)0;
162 cptr=strtok(NULL, " \t\n\r"); i++;
163 }
164 strcpy(tmp, res->unitline); lptr=tmp; cptr=strtok(lptr, " \t\n\r");
165 i=0; while(cptr!=NULL && i<res->parNr) {
166 if(strcmp(cptr, ".")==0) {i++; continue;}
167 strncpy(res->parunit[i], cptr, MAX_RESPARNAME_LEN);
168 res->parunit[i][MAX_RESPARNAME_LEN]=(char)0;
169 cptr=strtok(NULL, " \t\n\r"); i++;
170 }
171 if(RESULT_TEST>1) {
172 printf("Original titleline: %s\n", res->titleline);
173 printf("Original unitline: %s\n", res->unitline);
174 printf("Resolved parameter names and units:\n");
175 for(i=0; i<res->parNr; i++)
176 printf(" %d: '%s' '%s'\n", i+1, res->parname[i], res->parunit[i]);
177 }
178 return;
179}
#define MAX_RESPARNAME_LEN
int RESULT_TEST
Definition result.c:5

Referenced by dftToResult(), fitToResult(), resMatchParameternames(), resRead(), resWrite(), and resWriteHTML().

◆ resFName2study()

int resFName2study ( char * fname,
char * studyNumber )
extern

Set study number based on file name.

See also
studynr_from_fname
Returns
Non-zero in case of an error.

Definition at line 1169 of file result.c.

1172 {
1173 return(studynr_from_fname(fname, studyNumber));
1174}

◆ resInit()

void resInit ( RES * res)
extern

Initiate RES structure. This should be called once before first use.

See also
resSetmem, resEmpty
Parameters
resPointer to RES structure.

Definition at line 52 of file result.c.

55 {
56 if(res==NULL) return;
57 memset(res, 0, sizeof(RES));
58 res->_voidataNr=0; res->voiNr=0; res->parNr=0;
59 //res->Vb=-1.0;
60 //res->fA=-1.0;
61 //res->E=-1.0;
62 resEmpty(res);
63}
void resEmpty(RES *res)
Definition result.c:22

◆ resIsDuplicateNames()

int resIsDuplicateNames ( RES * res)
extern

Check if result structure contains duplicate region names.

Returns
Returns 0 if not, 1 if duplicates are found, and <0 in case of an error.
See also
resSortByName, resDelete, resRNameSubfieldExists
Parameters
resPointer to the result data.

Definition at line 1473 of file result.c.

1476 {
1477 int ri, rj;
1478
1479 if(res==NULL) return(-1);
1480 if(res->voiNr<2) return(0);
1481 for(ri=0; ri<res->voiNr-1; ri++) for(rj=ri+1; rj<res->voiNr; rj++)
1482 if(strcasecmp(res->voi[ri].name, res->voi[rj].name)==0) return(1);
1483 return(0);
1484}

◆ resMatchHeader()

int resMatchHeader ( RES * res1,
RES * res2 )
extern

Check whether result header field values are the same.

Fields that are not checked: program, time, titleline.

Returns
Returns 0 in case of match, and <>0 if not matching.
See also
resRead, resMatchRegions, resMatchParameternames
Parameters
res1Pointers to the result data that are tested
res2Pointers to the result data that are tested

Definition at line 1494 of file result.c.

1499 {
1500 if(res1==NULL || res2==NULL) return(1);
1501 if(res1->voiNr!=res2->voiNr) return(3);
1502 if(res1->parNr!=res2->parNr) return(4);
1503 if(strcasecmp(res1->datafile, res2->datafile)!=0) return(6);
1504 if(strcasecmp(res1->reffile, res2->reffile)!=0) return(7);
1505 if(strcasecmp(res1->plasmafile, res2->plasmafile)!=0) return(8);
1506 if(strcasecmp(res1->plasmafile2, res2->plasmafile2)!=0) return(9);
1507 if(strcasecmp(res1->bloodfile, res2->bloodfile)!=0) return(10);
1508 if(strcasecmp(res1->refroi, res2->refroi)!=0) return(11);
1509 if(strcasecmp(res1->datarange, res2->datarange)!=0) return(12);
1510 if(res1->isweight!=res2->isweight) return(13);
1511 if(res1->density!=res2->density) return(14);
1512 if(res1->lc!=res2->lc) return(15);
1513 if(res1->beta!=res2->beta) return(16);
1514 if(res1->concentration!=res2->concentration) return(17);
1515 if(res1->Vb!=res2->Vb) return(18);
1516 if(res1->datanr!=res2->datanr) return(19);
1517 if(strcasecmp(res1->fitmethod, res2->fitmethod)!=0) return(20);
1518 if(res1->fA!=res2->fA) return(21);
1519 if(res1->E!=res2->E) return(22);
1520 /* Less important */
1521 if(strcasecmp(res1->studynr, res2->studynr)!=0) return(5);
1522 return(0);
1523}

◆ resMatchParameternames()

int resMatchParameternames ( RES * res1,
RES * res2 )
extern

Check whether result parameter names are the same.

Returns
Returns 0 in case of match, and 1 if not matching.
See also
resMatchHeader, resMatchHeader, resMatchParameters
Parameters
res1Pointers to the result data that are tested.
res2Pointers to the result data that are tested.

Definition at line 1564 of file result.c.

1569 {
1570 int i;
1571
1572 if(res1==NULL || res2==NULL || res1->parNr!=res2->parNr) return(1);
1573
1574 resFixParnames(res1);
1575 resFixParnames(res2);
1576
1577 for(i=0; i<res1->parNr; i++) {
1578 if(strcasecmp(res1->parname[i], res2->parname[i])!=0) {
1579 if(RESULT_TEST>1)
1580 printf(" Parameter names '%s' and '%s' do not match\n",
1581 res1->parname[i], res2->parname[i]);
1582 return(1);
1583 }
1584 if(strcasecmp(res1->parunit[i], res2->parunit[i])!=0) {
1585 if(RESULT_TEST>1)
1586 printf(" Parameter units '%s' and '%s' do not match\n",
1587 res1->parunit[i], res2->parunit[i]);
1588 return(1);
1589 }
1590 }
1591 return(0);
1592}
void resFixParnames(RES *res)
Definition result.c:107

◆ resMatchParameters()

int resMatchParameters ( RES * res1,
RES * res2,
int test_par,
double test_limit,
int test_sd )
extern

Check whether result parameter values are the same.

Returns
Returns 0 in case of match, and <>0 if not matching.
See also
resMatchParametersAbs, resMatchHeader, resMatchHeader, resMatchParameternames
Parameters
res1Pointers to the result data that are tested.
res2Pointers to the result data that are tested.
test_parParameter index (0..parNr-1) that is verified; <0, if all.
test_limitTest limit (how exact match is required).
test_sdTest (1) or do not test (0) SD and Confidence limits.

Definition at line 1600 of file result.c.

1611 {
1612 int ri, pi;
1613 double s, v1, v2;
1614
1615 if(res1==NULL || res2==NULL || res1->voiNr!=res2->voiNr) return(1);
1616 if(res1->parNr!=res2->parNr) {
1617 if(test_par<0) return(1);
1618 if(test_par+1>res1->parNr || test_par+1>res2->parNr) return(1);
1619 }
1620 for(ri=0; ri<res1->voiNr; ri++) {
1621 for(pi=0; pi<res1->parNr; pi++) {
1622 if(test_par>=0 && test_par!=pi) continue;
1623 v1=res1->voi[ri].parameter[pi]; v2=res2->voi[ri].parameter[pi];
1624 if(isnan(v1) && isnan(v2)) continue; // ok if both are NaN
1625 /* Parameter values */
1626 if(RESULT_TEST>5) printf("pi=%d ri=%d\n", pi, ri);
1627 if(RESULT_TEST>5) printf(" %g vs %g\n", v1, v2);
1628 s=fabs(v1+v2); if(isnan(s)) return(2); // Either one is NaN
1629 if(test_limit<=0.0) { // values are requested to match exactly
1630 if(v1!=v2) return(2);
1631 } if(s==0.0 || v1==0.0 || v2==0.0) { // relative matching cant be done
1632 if(fabs(v1-v2)>test_limit) return(2);
1633 } else { // test relative difference against given limit
1634 if(fabs((v1-v2)/s)>test_limit) return(2);
1635 }
1636 if(test_sd!=0) {
1637 /* SD */
1638 v1=res1->voi[ri].sd[pi]; v2=res2->voi[ri].sd[pi];
1639 if(RESULT_TEST>5) printf(" SD: %g vs %g\n", v1, v2);
1640 if(isnan(v1) && isnan(v2)) {
1641 // both are NA, that is ok
1642 } else if(isnan(v1) || isnan(v2)) {
1643 // one is NA, that is not ok
1644 return(3);
1645 } else if(test_limit<=0.0) { // values are requested to match exactly
1646 if(v1!=v2) return(3);
1647 } if(s==0.0) { // relative matching cant be done
1648 if(fabs(v1-v2)>test_limit) return(3);
1649 } else { // test relative difference against given limit
1650 if(fabs((v1-v2)/s)>test_limit) return(3);
1651 }
1652 /* CL1 */
1653 v1=res1->voi[ri].cl1[pi]; v2=res2->voi[ri].cl1[pi];
1654 if(RESULT_TEST>5) printf(" CL1: %g vs %g\n", v1, v2);
1655 if(isnan(v1) && isnan(v2)) {
1656 // both are NA, that is ok
1657 } else if(isnan(v1) || isnan(v2)) {
1658 // one is NA, that is not ok
1659 return(4);
1660 } else if(test_limit<=0.0) { // values are requested to match exactly
1661 if(v1!=v2) return(4);
1662 } if(s==0.0) { // relative matching cant be done
1663 if(fabs(v1-v2)>test_limit) return(4);
1664 } else { // test relative difference against given limit
1665 if(fabs((v1-v2)/s)>test_limit) return(4);
1666 }
1667 /* CL2 */
1668 v1=res1->voi[ri].cl2[pi]; v2=res2->voi[ri].cl2[pi];
1669 if(RESULT_TEST>5) printf(" CL2: %g vs %g\n", v1, v2);
1670 if(isnan(v1) && isnan(v2)) {
1671 // both are NA, that is ok
1672 } else if(isnan(v1) || isnan(v2)) {
1673 // one is NA, that is not ok
1674 return(5);
1675 } else if(test_limit<=0.0) { // values are requested to match exactly
1676 if(v1!=v2) return(5);
1677 } if(s==0.0) { // relative matching cant be done
1678 if(fabs(v1-v2)>test_limit) return(5);
1679 } else { // test relative difference against given limit
1680 if(fabs((v1-v2)/s)>test_limit) return(5);
1681 }
1682 }
1683 }
1684 }
1685 return(0);
1686}

◆ resMatchParametersAbs()

int resMatchParametersAbs ( RES * res1,
RES * res2,
int test_par,
double test_limit,
int test_sd )
extern

Check whether the two sets of result parameter values are similar within a given absolute range.

Returns
Returns 0 in case of match, and <>0 if not matching.
See also
resMatchParameters
Parameters
res1Pointers to the result data that are tested.
res2Pointers to the result data that are tested.
test_parParameter index (0..parNr-1) that is verified; <0, if all.
test_limitTest limit; positive value, below which the absolute difference must be.
test_sdTest (1) or do not test (0) SD and Confidence limits.

Definition at line 1694 of file result.c.

1705 {
1706 int ri, pi;
1707 double s, v1, v2;
1708
1709 if(res1==NULL || res2==NULL || res1->voiNr!=res2->voiNr) return(1);
1710 if(res1->parNr!=res2->parNr) {
1711 if(test_par<0) return(1);
1712 if(test_par+1>res1->parNr || test_par+1>res2->parNr) return(1);
1713 }
1714 if(test_limit<0.0) return(1);
1715 for(ri=0; ri<res1->voiNr; ri++) {
1716 for(pi=0; pi<res1->parNr; pi++) {
1717 if(test_par>=0 && test_par!=pi) continue;
1718 v1=res1->voi[ri].parameter[pi]; v2=res2->voi[ri].parameter[pi];
1719 if(isnan(v1) && isnan(v2)) continue;
1720 /* Parameter values */
1721 if(RESULT_TEST>5) printf("pi=%d ri=%d\n", pi, ri);
1722 if(RESULT_TEST>5) printf(" %g vs %g\n", v1, v2);
1723 s=fabs(v1-v2);
1724 if(isnan(s) || s>test_limit) return(2);
1725 if(test_sd!=0) {
1726 /* SD */
1727 v1=res1->voi[ri].sd[pi]; v2=res2->voi[ri].sd[pi];
1728 if(isnan(v1) && !isnan(v2)) return(3);
1729 if(!isnan(v1) && isnan(v2)) return(3);
1730 if(!isnan(v1) && !isnan(v2)) {
1731 if(RESULT_TEST>8) printf(" SD: %g vs %g\n", v1, v2);
1732 s=fabs(v1-v2); if(s>test_limit) return(3);
1733 }
1734 /* CL1 */
1735 v1=res1->voi[ri].cl1[pi]; v2=res2->voi[ri].cl1[pi];
1736 if(isnan(v1) && !isnan(v2)) return(4);
1737 if(!isnan(v1) && isnan(v2)) return(4);
1738 if(!isnan(v1) && !isnan(v2)) {
1739 if(RESULT_TEST>8) printf(" CL1: %g vs %g\n", v1, v2);
1740 s=fabs(v1-v2); if(s>test_limit) return(4);
1741 }
1742 /* CL2 */
1743 v1=res1->voi[ri].cl2[pi]; v2=res2->voi[ri].cl2[pi];
1744 if(isnan(v1) && !isnan(v2)) return(5);
1745 if(!isnan(v1) && isnan(v2)) return(5);
1746 if(!isnan(v1) && !isnan(v2)) {
1747 if(RESULT_TEST>8) printf(" CL2: %g vs %g\n", v1, v2);
1748 s=fabs(v1-v2); if(s>test_limit) return(5);
1749 }
1750 }
1751 }
1752 }
1753 return(0);
1754}

◆ resMatchRegions()

int resMatchRegions ( RES * res1,
RES * res2 )
extern

Check whether result region names are the same.

Returns
Returns 0 in case of match, and 1 if not matching.
See also
resRNameSubfieldExists, resMatchHeader, resMatchParameternames
Parameters
res1Pointers to the result data that are tested.
res2Pointers to the result data that are tested.

Definition at line 1531 of file result.c.

1536 {
1537 int ri, m=0;
1538
1539 if(res1==NULL || res2==NULL || res1->voiNr!=res2->voiNr) return(1);
1540 for(ri=0; ri<res1->voiNr; ri++) {
1541 m=0;
1542// if(strcmp(res1->voi[ri].name, res2->voi[ri].name)!=0) return(1);
1543 if(strcmp(res1->voi[ri].voiname, res2->voi[ri].voiname)!=0) m++;
1544 if(strcmp(res1->voi[ri].hemisphere, res2->voi[ri].hemisphere)!=0) m++;;
1545 if(strcmp(res1->voi[ri].place, res2->voi[ri].place)!=0) m++;
1546 if(m>0) {
1547 if(RESULT_TEST>5) {
1548 printf(" '%s' vs '%s'\n", res1->voi[ri].voiname, res2->voi[ri].voiname);
1549 printf(" '%s' vs '%s'\n", res1->voi[ri].hemisphere, res2->voi[ri].hemisphere);
1550 printf(" '%s' vs '%s'\n", res1->voi[ri].place, res2->voi[ri].place);
1551 }
1552 return(1);
1553 }
1554 }
1555 return(0);
1556}

◆ resMean()

int resMean ( double * data,
int nr,
double * mean,
double * sd )
extern

Calculate the mean and sd in the specified double array data of length nr.

NULL pointer may be specified to function in place of an unwanted return parameter.

Returns
Returns 0 if successful.
See also
resMedian, doubleMean
Parameters
dataArray of data.
nrLength of data array.
meanPointer where mean is written.
sdPointer where S.D. is written.

Definition at line 1222 of file result.c.

1231 {
1232 int i;
1233 double sum, ssum, v;
1234
1235 /* Check the arguments */
1236 if(data==NULL) return(1);
1237 if(nr<1) return(2);
1238 /* Calculate avg and sd */
1239 for(i=0, sum=ssum=0.0; i<nr; i++) {
1240 sum+=data[i]; ssum+=data[i]*data[i];
1241 }
1242 if(mean!=NULL) *mean=sum/(double)nr;
1243 if(sd!=NULL) {
1244 if(nr>1) v=(ssum-sum*sum/(double)nr)/(double)(nr-1); else v=0.0;
1245 if(v>0.0) *sd=sqrt(v); else *sd=0.0;
1246 }
1247 return(0);
1248}

Referenced by rescoll_tabulate().

◆ resMedian()

int resMedian ( double * data,
int nr,
double * median,
double * min,
double * max )
extern

Calculate the median and the lowest and highest value in the specified double array data of length nr.

Note that array is sorted in this function. NULL pointer may be specified to function in place of an unwanted return parameter.

Returns
Returns 0 if successful.
See also
resMean, doubleMean
Parameters
dataArray of data.
nrLength of data array.
medianPointer where median is written.
minPointer where min is written.
maxPointer where max is written.

Definition at line 1186 of file result.c.

1197 {
1198 /* Check the arguments */
1199 if(data==NULL) return(1);
1200 if(nr<1) return(2);
1201 /* Sort data in increasing order */
1202 qsort(data, nr, sizeof(double), resQSortComp);
1203 /* Get minimum and maximum */
1204 if(min!=NULL) *min=data[0];
1205 if(max!=NULL) *max=data[nr-1];
1206 /* Calculate median */
1207 if(median!=NULL) {
1208 if(nr%2) *median=data[(nr-1)/2];
1209 else *median=0.5*(data[(nr/2)-1]+data[nr/2]);
1210 }
1211 return(0);
1212}

Referenced by rescoll_tabulate().

◆ resParameterPrintType()

int resParameterPrintType ( RES * res,
int parIndex )
extern

Determine whether the result parameter should be printed as integer (0), float (1), or exponential (2).

Returns
Returns the code, or <0 in case of an error.
See also
resWrite
Parameters
resPointer to the result struct.
parIndexIndex of the parameter to test.

Definition at line 1447 of file result.c.

1452 {
1453 int vi, partype=0;
1454 double x, m=0.0, pint;
1455
1456 if(res==NULL || res->voiNr<1 || parIndex<0 || parIndex>=res->parNr)
1457 return(-1);
1458 for(vi=0; vi<res->voiNr; vi++) {
1459 x=res->voi[vi].parameter[parIndex];
1460 if(modf(x, &pint)!=0.0) partype=1;
1461 x=fabs(x); if(x>m) m=x;
1462 }
1463 if(partype==1 && (m>=10.0 || m<0.1)) partype=2;
1464 return(partype);
1465}

Referenced by rescoll_tabulate(), resWrite(), and resWriteHTML_table().

◆ resPrint()

void resPrint ( RES * res)
extern

Print to stdout the contents of RES data structure.

See also
resWrite, resInit, resRead
Parameters
resPointer to result data.

Definition at line 186 of file result.c.

189 {
190 resWrite(res, "stdout", 0);
191}
int resWrite(RES *res, char *filename, int verbose)
Definition result.c:565

◆ resRead()

int resRead ( char * filename,
RES * res,
int verbose )
extern

Read RES file contents to the specified data structure.

Returns
In case of an error, >0 is returned, and a description is written in reserrmsg.
See also
resWrite, resInit, resPrint, resFixParnames
Parameters
filenameResult file name.
resPointer to initiated RES structure; any previous contents are deleted.
verboseVerbose level; if <=0, then nothing is printed into stdout.

Definition at line 199 of file result.c.

206 {
207 FILE *fp;
208 char *cptr, line[1024], *lptr, tmp[1024];
209 int i, n;
210 fpos_t file_loc;
211
212
213 if(verbose>0) printf("resRead(%s, *res);\n", filename);
214 if(res==NULL) return(1);
215 /* Empty data */
216 resEmpty(res);
217 res->isweight=-1; /* unknown */
218
219 /* Open file; note that 'b' is required for fgetpos() and fsetpos() to work
220 correctly */
221 fp=fopen(filename, "rb");
222 if(fp==NULL) {strcpy(reserrmsg, "cannot open file"); return(1);}
223
224 /*
225 * Read data, each result set separately, saving only the first one
226 */
227 strcpy(reserrmsg, "wrong format");
228
229 /* Read program name */
230 if(verbose>1) printf("reading program name\n");
231 while(fgets(line, 1024, fp)!=NULL) {
232 /* Ignore empty and comment lines */
233 if(strlen(line)<4 || line[0]=='#') continue; else break;
234 }
235 /* Check for string (c) or (C) */
236 if(strstr(line, "(c)") || strstr(line, "(C)")) {
237 i=strlen(line)-1; while(i>0 && isspace(line[i])) i--; line[i+1]=(char)0;
238 if(i<4) {fclose(fp); return(2);}
239 strcpy(res->program, line);
240 } else {fclose(fp); return(2);}
241
242 /* Read calculation date and time */
243 if(verbose>1) printf("reading date and time\n");
244 while(fgets(line, 1024, fp)!=NULL) if(strlen(line)>2 && line[0]!='#') break;
245 if(strncasecmp(line, "Date:", 5)) {fclose(fp); return(4);}
246 cptr=&line[5]; while(isblank(cptr[0])) cptr++;
247 if(cptr!=NULL) {
248 if(verbose>3) printf("date_str := %s", cptr);
249 struct tm st;
250 if(get_datetime(cptr, &st, verbose-3)==0) res->time=timegm(&st);
251 else if(get_date(cptr, &st)==0) res->time=timegm(&st);
252 else res->time=(time_t)0;
253 }
254
255 /* Read studynr, datafiles, ref region, data range, etc */
256 if(verbose>1) printf("reading headers\n");
257 do {
258 /* Omit comment and too short lines */
259 while((lptr=fgets(line, 1024, fp))!=NULL) {
260 if(strlen(line)>2 && line[0]!='#') break;
261 if(lptr!=NULL && verbose>6)
262 printf("omitted line[%d] := %s", (int)strlen(line), line);
263 }
264 if(lptr==NULL) break;
265 strcpy(tmp, line);
266 n=0; if(verbose>3) printf("line[%d] := %s", (int)strlen(line), line);
267 if(strncasecmp(line, "Study", 5)==0) {
268 lptr=&tmp[6]; cptr=strtok(lptr, " \t\n\r"); n=1;
269 if(cptr!=NULL && strlen(cptr)<1024) {
270 strlcpy(res->studynr, cptr, MAX_STUDYNR_LEN+1);
271 }
272 } else if(strncasecmp(line, "Data file", 9)==0) {
273 lptr=&tmp[10]; cptr=strtok(lptr, " \t\n\r"); n=1;
274 if(cptr!=NULL && strlen(cptr)<1024) strcpy(res->datafile, cptr);
275 } else if(strncasecmp(line, "ROI file", 8)==0) {
276 lptr=&tmp[9]; cptr=strtok(lptr, " \t\n\r"); n=1;
277 if(cptr!=NULL && strlen(cptr)<1024) strcpy(res->datafile, cptr);
278 } else if(strncasecmp(line, "Plasma file", 11)==0) {
279 cptr=strchr(tmp, ':')+1; while(isspace((int)*cptr)) cptr++; n=1;
280 if(cptr!=NULL && strlen(cptr)<1024) strcpy(res->plasmafile, cptr);
281 cptr=res->plasmafile+strlen(res->plasmafile)-1;
282 while(isspace((int)*cptr)) {*cptr=(char)0; cptr--;}
283 } else if(strncasecmp(line, "2nd Plasma file", 15)==0) {
284 cptr=strchr(tmp, ':')+1; while(isspace((int)*cptr)) cptr++; n=1;
285 if(cptr!=NULL && strlen(cptr)<1024) strcpy(res->plasmafile2, cptr);
286 cptr=res->plasmafile2+strlen(res->plasmafile2)-1;
287 while(isspace((int)*cptr)) {*cptr=(char)0; cptr--;}
288 } else if(strncasecmp(line, "Blood file", 10)==0) {
289 lptr=&tmp[11]; cptr=strtok(lptr, " \t\n\r"); n=1;
290 if(cptr!=NULL && strlen(cptr)<1024) strcpy(res->bloodfile, cptr);
291 } else if(strncasecmp(line, "Reference file", 14)==0) {
292 lptr=&tmp[15]; cptr=strtok(lptr, " \t\n\r"); n=1;
293 if(cptr!=NULL && strlen(cptr)<1024) strcpy(res->reffile, cptr);
294 } else if(strncasecmp(line, "Reference region", 16)==0) {
295 cptr=strchr(tmp, ':')+1; while(isspace((int)*cptr)) cptr++; n=1;
296 if(cptr!=NULL && strlen(cptr)<64) strcpy(res->refroi, cptr);
297 cptr=res->refroi+strlen(res->refroi)-1;
298 while(isspace((int)*cptr)) {*cptr=(char)0; cptr--;}
299 } else if(strncasecmp(line, "Fit time", 8)==0 || strncasecmp(line, "Data range", 10)==0) {
300 cptr=strchr(tmp, ':')+1; while(isspace((int)*cptr)) cptr++; n=1;
301 if(cptr!=NULL && strlen(cptr)<128) strcpy(res->datarange, cptr);
302 cptr=res->datarange+strlen(res->datarange)-1;
303 while(isspace((int)*cptr)) {*cptr=(char)0; cptr--;}
304 } else if(strncasecmp(line, "Data nr", 7)==0) {
305 cptr=strchr(tmp, ':')+1; while(isspace((int)*cptr)) cptr++; n=1;
306 if(cptr!=NULL) res->datanr=atoi(cptr);
307 } else if(strncasecmp(line, "Fit method", 10)==0) {
308 cptr=strchr(tmp, ':')+1; while(isspace((int)*cptr)) cptr++; n=1;
309 if(cptr!=NULL && strlen(cptr)<128) strcpy(res->fitmethod, cptr);
310 cptr=res->fitmethod+strlen(res->fitmethod)-1;
311 while(isspace((int)*cptr)) {*cptr=(char)0; cptr--;}
312 } else if(strncasecmp(line, "Tissue density", 14)==0) {
313 cptr=strchr(tmp, ':')+1; while(isspace((int)*cptr)) cptr++; n=1;
314 if(cptr!=NULL) res->density=atof_dpi(cptr);
315 } else if(strncasecmp(line, "Lumped constant", 15)==0) {
316 cptr=strchr(tmp, ':')+1; while(isspace((int)*cptr)) cptr++; n=1;
317 if(cptr!=NULL) res->lc=atof_dpi(cptr);
318 } else if(strncasecmp(line, "Concentration", 13)==0) {
319 cptr=strchr(tmp, ':')+1; while(isspace((int)*cptr)) cptr++; n=1;
320 if(cptr!=NULL) res->concentration=atof_dpi(cptr);
321 } else if(strncasecmp(line, "Beta", 4)==0) {
322 cptr=strchr(tmp, ':')+1; while(isspace((int)*cptr)) cptr++; n=1;
323 if(cptr!=NULL) res->beta=atof_dpi(cptr);
324 } else if(strncasecmp(line, "Vb", 2)==0) {
325 cptr=strchr(tmp, ':')+1; while(isspace((int)*cptr)) cptr++; n=1;
326 if(cptr!=NULL) res->Vb=atof_dpi(cptr);
327 } else if(strncasecmp(line, "fA", 2)==0) {
328 cptr=strchr(tmp, ':')+1; while(isspace((int)*cptr)) cptr++; n=1;
329 if(cptr!=NULL) res->fA=atof_dpi(cptr);
330 } else if(strncasecmp(line, "Extraction", 10)==0) {
331 cptr=strchr(tmp, ':')+1; while(isspace((int)*cptr)) cptr++; n=1;
332 if(cptr!=NULL) res->E=atof_dpi(cptr);
333 } else if(strncasecmp(line, "Weighting", 9)==0) {
334 cptr=strchr(tmp, ':')+1; while(isspace((int)*cptr)) cptr++; n=1;
335 if(strncasecmp(cptr, "yes", 1)==0) res->isweight=1;
336 else if(strncasecmp(cptr, "no", 1)==0) res->isweight=0;
337 else res->isweight=-1;
338 } else if(strncasecmp(line, "Data was weighted", 17)==0) {
339 res->isweight=1; n=1;
340 } else if(strncasecmp(line, "Data was not weighted", 21)==0) {
341 res->isweight=0; n=1;
342 } else if(strncasecmp(line, "Region", 6)==0) {
343 /* Header end, stop here */
344 n=0;
345 } else { /* Ignore all other header lines */
346 n=1;
347 }
348 } while(n);
349 if(verbose>6) printf("quit reading headers\n");
350
351 /* Read the result parameter title line */
352 if(verbose>1) printf("reading parameter titles\n");
353 if(verbose>6) printf("using previously read line[%d] := %s", (int)strlen(line), line);
354 if(strncasecmp(line, "Region", 6)) {fclose(fp); return(10);}
355 strcpy(tmp, line);
356 lptr=strpbrk(tmp+6, " \n\r\t"); if(lptr==NULL) {fclose(fp); return(10);}
357 cptr=strtok(lptr, " \n\r\t");
358 n=0;
359 if(cptr!=NULL) {
360 if(strcmp(cptr, ".")!=0) {
361 strncpy(res->parname[n], cptr, MAX_RESPARNAME_LEN);
362 res->parname[n][MAX_RESPARNAME_LEN]=(char)0;
363 } else {strcpy(res->parname[n], "");}
364 if(verbose>5) printf(" parname[%d] := '%s'\n", n, res->parname[n]);
365 n++;
366 } else {strcpy(res->parname[n], "");}
367 while(cptr!=NULL) {
368 cptr=strtok(NULL, " \n\r\t");
369 if(cptr!=NULL && n<MAX_RESPARAMS) {
370 if(strcmp(cptr, ".")!=0) {
371 strncpy(res->parname[n], cptr, MAX_RESPARNAME_LEN);
372 res->parname[n][MAX_RESPARNAME_LEN]=(char)0;
373 } else {strcpy(res->parname[n], "");}
374 if(verbose>5) printf(" parname[%d] := '%s'\n", n, res->parname[n]);
375 n++;
376 }
377 }
378 res->parNr=n; if(verbose>1) printf("parNr := %d\n", res->parNr);
379
380 /* Read the result parameter unit line */
381 if(verbose>2) printf("seeking unit line...\n");
382 if(fgetpos(fp, &file_loc)!=0) {fclose(fp); return(20);}
383 while(fgets(line, 1024, fp)!=NULL && strlen(line)<3) {
384 if(verbose>6) printf("omitted line[%d] := %s", (int)strlen(line), line);
385 /* save the file position where unit line or results really start */
386 if(fgetpos(fp, &file_loc)!=0) {fclose(fp); return(20);}
387 }
388 if(verbose>5) printf("possible unit line[%d]: %s", (int)strlen(line), line);
389 if(strncasecmp(line, "# Units :", 7)==0 ||
390 strncasecmp(line, "Units : ", 7)==0 ||
391 strncasecmp(line, "# Units: ", 7)==0 ||
392 strncasecmp(line, "Units: ", 6)==0)
393 {
394 if(verbose>1) printf("reading parameter units\n");
395 strcpy(tmp, line); lptr=strchr(tmp+5, ':');
396 if(lptr!=NULL) lptr++; else lptr=strpbrk(tmp+6, " \n\r\t");
397 cptr=strtok(lptr, " \n\r\t"); n=0;
398 if(cptr!=NULL) {
399 if(strcmp(cptr, ".")!=0) {
400 strncpy(res->parunit[n], cptr, MAX_RESPARNAME_LEN);
401 res->parunit[n][MAX_RESPARNAME_LEN]=(char)0;
402 } else {strcpy(res->parunit[n], "");}
403 if(verbose>5) printf(" parunit[%d] := '%s'\n", n, res->parunit[n]);
404 n++;
405 } else {strcpy(res->parunit[n], "");}
406 while(cptr!=NULL) {
407 cptr=strtok(NULL, " \n\r\t");
408 if(cptr!=NULL && n<MAX_RESPARAMS) {
409 if(strcmp(cptr, ".")!=0) {
410 strncpy(res->parunit[n], cptr, MAX_RESPARNAME_LEN);
411 res->parunit[n][MAX_RESPARNAME_LEN]=(char)0;
412 } else strcpy(res->parunit[n], "");
413 if(verbose>5) printf(" parunit[%d] := '%s'\n", n, res->parunit[n]);
414 n++;
415 }
416 }
417 } else {
418 if(verbose>5) printf(" ... not identified as unit line.\n");
419 /* move file pointer to the previous place */
420 if(fsetpos(fp, &file_loc)!=0) {fclose(fp); return(20);}
421 }
422
423 /* Read the nr of result lines */
424 if(verbose>1) printf("reading nr of results\n");
425 /* Set bookmark to the start of result lines */
426 if(fgetpos(fp, &file_loc)!=0) {fclose(fp); return(21);}
427 n=0;
428 while(fgets(line, 1024, fp)!=NULL) {
429 if(verbose>6) printf("line[%d] := %s", (int)strlen(line), line);
430 if(line[0]=='#' || line[0]==';') continue;
431 i=strlen(line); if(i<2) continue; if(i<3) break;
432 n++;
433 }
434 /* Return file pointer to the start of result lines */
435 if(fsetpos(fp, &file_loc)!=0) {fclose(fp); return(22);}
436 if(verbose>1) printf("nr of result lines is %d\n", n);
437 if(n<1) {
438 strcpy(reserrmsg, "invalid result lines");
439 fclose(fp); return(23);
440 }
441
442 /* Allocate memory for regional results */
443 if(verbose>2) printf("allocating memory\n");
444 if(resSetmem(res, n)) {
445 strcpy(reserrmsg, "cannot allocate memory");
446 fclose(fp); return(25);
447 }
448
449 /* Read regional results */
450 if(verbose>1) printf("reading results to memory\n");
451 int separtab=0; // 0=space as separator, 1=tab as separator
452 char separstr[12];
453 res->voiNr=0;
454 while(fgets(line, 1024, fp)!=NULL) {
455 if(verbose>6) printf("line[%d] := %s", (int)strlen(line), line);
456 if(line[0]=='#' || line[0]==';') continue;
457 i=strlen(line); if(i<2) continue; if(i<3) break;
458 strcpy(tmp, line);
459 if(verbose>2) printf("reading result %d\n", 1+res->voiNr);
460
461 /* Read region names */
462 if(strchr(tmp, '\t')==NULL) separtab=0; else separtab=1;
463 if(separtab) strcpy(separstr, "\t\n\r"); else strcpy(separstr, " \t\n\r");
464 int tokenNr=strTokenNr(tmp, separstr);
465 if(verbose>20) printf(" tokenNr := %d\n", tokenNr);
466 if(!separtab) { // old format with space as separator
467 if(verbose>20) printf("separator: space\n");
468 n=strTokenNCpy(tmp, separstr, 1, res->voi[res->voiNr].voiname, MAX_REGIONSUBNAME_LEN+1);
469 if(n==0) {fclose(fp); return(31);}
470 n=strTokenNCpy(tmp, separstr, 2, res->voi[res->voiNr].hemisphere, MAX_REGIONSUBNAME_LEN+1);
471 if(n==0) {fclose(fp); return(31);}
472 n=strTokenNCpy(tmp, separstr, 3, res->voi[res->voiNr].place, MAX_REGIONSUBNAME_LEN+1);
473 if(n==0) {fclose(fp); return(31);}
475 res->voi[res->voiNr].hemisphere, res->voi[res->voiNr].place, ' ');
476 } else { // space can exist only in TAC name
477 if(verbose>20) printf("separator: tab\n");
478 n=strTokenNCpy(tmp, separstr, 1, res->voi[res->voiNr].name, MAX_REGIONNAME_LEN+1);
479 if(n==0) {fclose(fp); return(31);}
480 rnameSplit(res->voi[res->voiNr].name, res->voi[res->voiNr].voiname,
481 res->voi[res->voiNr].hemisphere, res->voi[res->voiNr].place, MAX_REGIONSUBNAME_LEN);
482 }
483 if(strcmp(res->voi[res->voiNr].voiname, ".")==0) res->voi[res->voiNr].voiname[0]=(char)0;
484 if(strcmp(res->voi[res->voiNr].hemisphere, ".")==0) res->voi[res->voiNr].hemisphere[0]=(char)0;
485 if(strcmp(res->voi[res->voiNr].place, ".")==0) res->voi[res->voiNr].place[0]=(char)0;
486 if(verbose>18) {
487 printf(" voiname := '%s'\n", res->voi[res->voiNr].voiname);
488 printf(" hemisphere := '%s'\n", res->voi[res->voiNr].hemisphere);
489 printf(" place := '%s'\n", res->voi[res->voiNr].place);
490 }
491
492 /* Read results, continuing from the pointer after region names */
493 int tokeni=2; if(!separtab) tokeni=4;
494 char buf[128];
495 for(i=0; i<MAX_RESPARAMS && tokeni<=tokenNr; i++, tokeni++) {
496 n=strTokenNCpy(tmp, separstr, tokeni, buf, 128);
497 if(n==0) {fclose(fp); return(32);}
498 if(strlen(buf)==1 && buf[0]=='.') res->voi[res->voiNr].parameter[i]=nan("");
499 else res->voi[res->voiNr].parameter[i]=atof_dpi(buf);
500 }
501 if(verbose>5) printf(" for '%s' parNr:=%d\n", res->voi[res->voiNr].name, i);
502 //if(res->voiNr==0) {res->parNr=i;} else if(i<res->parNr) res->parNr=i;
503 if(i<res->parNr) {
504 if(verbose>0)
505 printf("Warning: smaller parNr %d on region '%s'\n", i, res->voi[res->voiNr].name);
506 res->parNr=i;
507 }
508
509 /* If 'region' name implies that this was confidence limit or sd, then */
510 /* move the values into correct places, and do not increase the voiNr */
511 if(res->voiNr==0) {res->voiNr++; continue;}
512 if(strcasecmp(res->voi[res->voiNr].voiname, "CL")==0) {
513 if(strcmp(res->voi[res->voiNr].hemisphere, "95%")==0) {
514 if(strcasecmp(res->voi[res->voiNr].place, "Lower")==0)
515 for(i=0; i<res->parNr; i++)
516 res->voi[res->voiNr-1].cl1[i]=res->voi[res->voiNr].parameter[i];
517 else if(strcasecmp(res->voi[res->voiNr].place, "Upper")==0)
518 for(i=0; i<res->parNr; i++)
519 res->voi[res->voiNr-1].cl2[i]=res->voi[res->voiNr].parameter[i];
520 continue;
521 }
522 } else if(strcasecmp(res->voi[res->voiNr].voiname, "SD")==0) {
523 for(i=0; i<res->parNr; i++)
524 res->voi[res->voiNr-1].sd[i]=res->voi[res->voiNr].parameter[i];
525 continue;
526 }
527 res->voiNr++;
528 }
529 if(res->parNr==0) {fclose(fp); return(33);}
530 if(verbose>0) printf("nr of results: %d ; nr of parameters: %d\n", res->voiNr, res->parNr);
531
532 /* Seek for other results in the same file */
533 while(fgets(line, 1024, fp)!=NULL) {
534 /* Ignore empty and comment lines */
535 if(strlen(line)<3 || line[0]=='#') continue; else break;
536 }
537 /* Check again for string (c) or (C) */
538 if(strstr(line, "(c)") || strstr(line, "(C)")) {
539 fprintf(stderr,
540 "Warning: %s contains more than one set of results; only the 1st one is used.\n", filename);
541 }
542
543 /* Close file */
544 fclose(fp);
545 strcpy(reserrmsg, "");
546
547 /* Fill studynr if it was not found in file */
548 if(!res->studynr[0]) studynr_from_fname(filename, res->studynr);
549 /* Set also deprecated parameter name and unit representations, for now */
550 resFixParnames(res);
551
552 return(0);
553}
int get_date(char *str, struct tm *date)
Definition datetime.c:377
char reserrmsg[64]
Definition result.c:6
int resSetmem(RES *res, int voiNr)
Definition result.c:70

◆ resRNameSubfieldExists()

int resRNameSubfieldExists ( RES * res)
extern

Check whether region name sub-fields exist in any region.

Returns
Returns 1 if hemisphere exists, 2 if place exists, 3 if both exist, and 0 if neither exists, and <0 in case of an error.
See also
resFixParnames, resSortByName, resIsDuplicateNames
Parameters
resPointer to RES struct.

Definition at line 1763 of file result.c.

1766 {
1767 int ri, m=0, n=0;
1768
1769 if(res==NULL) return(-1);
1770 if(res->voiNr<1) return(-1);
1771 for(ri=0; ri<res->voiNr; ri++) {
1772 if(strlen(res->voi[ri].hemisphere)>0 &&
1773 strcmp(res->voi[ri].hemisphere, ".")!=0)
1774 m++;
1775 if(strlen(res->voi[ri].place)>0 &&
1776 strcmp(res->voi[ri].place, ".")!=0)
1777 n++;
1778 }
1779 ri=0; if(m>0) ri+=1; if(n>0) ri+=2;
1780 return(ri);
1781}

◆ resSelect()

int resSelect ( RES * data,
char * name )
extern

Select VOIs (sets sw=1), whose names are matching specified string.

If no string is specified, then all VOIs are selected.

Returns
Returns the number of matches, or <0, if an error occurred.
See also
resDelete, resSelectRegions
Parameters
dataPointer to the result data.
nameRegion name string.

Definition at line 1369 of file result.c.

1374 {
1375 unsigned int i, j, n;
1376 char *p, n1[128], n2[128], n3[128], tmp[128], sname[1024], *lptr;
1377
1378 if(data==NULL) return(-1);
1379 /* Select all, if no string was specified */
1380 if(name==NULL || strlen(name)==0) {
1381 for(i=0; i<(unsigned int)data->voiNr; i++) data->voi[i].sw=1;
1382 return(data->voiNr);
1383 }
1384 /* Make a copy of 'name' and use it */
1385 strcpy(sname, name); lptr=sname;
1386 /* Check if string contains several substrings (hemisphere and place) */
1387 n1[0]=n2[0]=n3[0]=(char)0;
1388 p=strtok(lptr, " ,;\n\t|"); if(p!=NULL) strcpy(n1, p); else return(-1);
1389 p=strtok(NULL, " ,;\n\t|"); if(p!=NULL) {
1390 strcpy(n2, p); p=strtok(NULL, " ,;\n\t|"); if(p!=NULL) strcpy(n3, p);}
1391 /* Convert strings to lowercase */
1392 for(i=0; i<strlen(n1); i++) n1[i]=tolower(n1[i]);
1393 for(i=0; i<strlen(n2); i++) n2[i]=tolower(n2[i]);
1394 for(i=0; i<strlen(n3); i++) n3[i]=tolower(n3[i]);
1395 /* Search through the data */
1396 for(i=0, n=0; i<(unsigned int)data->voiNr; i++) {
1397 data->voi[i].sw=0;
1398 snprintf(tmp, 128, "%s%s%s", data->voi[i].voiname, data->voi[i].hemisphere,
1399 data->voi[i].place);
1400 for(j=0; j<strlen(tmp); j++) tmp[j]=tolower(tmp[j]);
1401 if(strstr(tmp, n1)==NULL) continue;
1402 if(n2[0] && strstr(tmp, n2)==NULL) continue;
1403 if(n3[0] && strstr(tmp, n3)==NULL) continue;
1404 data->voi[i].sw=1; n++;
1405 }
1406 return(n);
1407}

◆ resSelectRegions()

int resSelectRegions ( RES * res,
char * region_name,
int reset )
extern

Select the VOIs that have matching region name or number.

Sets sw=1 or sw=0. This will replace resSelect().

Returns
Returns the number of selected VOIs, or <0 in case of an error.
See also
resRead, resDelete, resIsDuplicateNames
Parameters
resPointer to RES data where VOIs are selected
region_nameName or VOI number which is searched
reset1=Non-matching VOIs are deselected, 0=Old selections are preserved

Definition at line 1417 of file result.c.

1424 {
1425 int ri, match_nr=0;
1426
1427 /* Check the input */
1428 if(res==NULL || res->voiNr<1 || strlen(region_name)<1) return(-1);
1429 /* Reset all selections if required */
1430 if(reset!=0) for(ri=0; ri<res->voiNr; ri++) res->voi[ri].sw=0;
1431 /* Check each VOI */
1432 for(ri=0; ri<res->voiNr; ri++) {
1433 if(rnameMatch(res->voi[ri].name, ri+1, region_name)!=0) {
1434 res->voi[ri].sw=1; match_nr++;
1435 }
1436 }
1437 return(match_nr);
1438}

◆ resSetmem()

int resSetmem ( RES * res,
int voiNr )
extern

Allocate memory for result data. Old data is destroyed.

See also
resInit, resEmpty
Parameters
resPointer to initiated and possibly allocated result data.
voiNrNr of regional results.

Definition at line 70 of file result.c.

75 {
76 int ri, pi;
77
78 /* Check that there is something to do */
79 if(res==NULL || voiNr<1) return(1);
80
81 /* Clear previous data, but only if necessary */
82 if(res->_voidataNr>0 || res->voiNr>0) resEmpty(res);
83
84 /* Allocate memory for regional curves */
85 res->voi=(ResVOI*)calloc(voiNr, sizeof(ResVOI));
86 if(res->voi==NULL) return(2);
87 res->_voidataNr=voiNr;
88
89 /* Set SDs and CLs to NA */
90 for(ri=0; ri<res->_voidataNr; ri++) for(pi=0; pi<MAX_RESPARAMS; pi++)
91 res->voi[ri].sd[pi]=res->voi[ri].cl1[pi]=res->voi[ri].cl2[pi]=nan("");
92
93 return(0);
94}

Referenced by fitToResult(), res_allocate_with_dft(), and resRead().

◆ resSortByName()

void resSortByName ( RES * res)
extern

Sort RES regions by region name.

See also
resIsDuplicateNames, resRead, resWrite, resCopyMHeader

Definition at line 1266 of file result.c.

1269 {
1270 if(res==NULL || res->voiNr<=1) return;
1271 qsort(res->voi, res->voiNr, sizeof(ResVOI), resQSortName);
1272 return;
1273}

◆ resWrite()

int resWrite ( RES * res,
char * filename,
int verbose )
extern

Write calculation results into specified file.

If file exists, a backup file (+BACKUP_EXTENSION) is written also. If "stdout" is given as filename, output is directed to stdout. If filename extension is *.htm(l), file is saved in HTML format.

Returns
In case of an error, >0 is returned, and a description is written in reserrmsg.
See also
resInit, resRead, resEmpty, resPrint, resWriteHTML
Parameters
resPointer to result data.
filenameOutput file name.
verboseVerbose level; if <=0, then nothing is printed into stdout.

Definition at line 565 of file result.c.

572 {
573 int i, j, n;
574 char tmp[1024], is_stdout=0, *cptr;
575 FILE *fp;
576 int partype[MAX_RESPARAMS]; /* 0=int, 1=double, 2=exp */
577 int colwidth[MAX_RESPARAMS];
578 double *p;
579
580
581 if(verbose>1) printf("resWrite(*res, %s, %d)\n", filename, verbose);
582 /* Check that there is some data to write */
583 if(res==NULL) {strcpy(reserrmsg, "error in result data"); return(1);}
584 if(res->voiNr<1) {strcpy(reserrmsg, "no result data"); return(1);}
585
586 /* Write results in HTML format, if necessary */
587 cptr=strrchr(filename, '.');
588 if(cptr!=NULL && (!strncasecmp(cptr, ".htm", 4)))
589 return(resWriteHTML(res, filename, verbose));
590
591 /* Check if writing to stdout */
592 if(!strcasecmp(filename, "stdout")) is_stdout=1;
593
594 /* Check if file exists; backup, if necessary */
595 if(!is_stdout) (void)backupExistingFile(filename, NULL, NULL);
596
597 resFixParnames(res);
598
599 /* Open output file */
600 if(is_stdout) fp=(FILE*)stdout;
601 else if((fp = fopen(filename, "w")) == NULL) {
602 strcpy(reserrmsg, "cannot open file"); return(2);}
603
604 /* Program name */
605 n=fprintf(fp, "%s\n\n", res->program);
606 if(n==0) {
607 strcpy(reserrmsg, "disk full");
608 if(!is_stdout) fclose(fp);
609 return(3);
610 }
611
612 /* Write calculation date and time */
613 if(!ctime_r_int(&res->time, tmp)) strcpy(tmp, "1900-01-01 00:00:00");
614 fprintf(fp, "Date:\t%s\n", tmp);
615
616 /* Write the studynr */
617 if(res->studynr[0]) fprintf(fp, "Study:\t%s\n", res->studynr);
618
619 /* Write the names of the original datafiles */
620 if(res->datafile[0]) fprintf(fp, "Data file:\t%s\n", res->datafile);
621 if(res->plasmafile[0]) fprintf(fp, "Plasma file:\t%s\n", res->plasmafile);
622 if(res->plasmafile2[0]) fprintf(fp, "2nd Plasma file:\t%s\n", res->plasmafile2);
623 if(res->bloodfile[0]) fprintf(fp, "Blood file:\t%s\n", res->bloodfile);
624 if(res->reffile[0]) fprintf(fp, "Reference file:\t%s\n", res->reffile);
625 if(res->refroi[0]) fprintf(fp, "Reference region:\t%s\n", res->refroi);
626
627 /* Write data range etc */
628 if(res->datarange[0]) fprintf(fp, "Data range:\t%s\n", res->datarange);
629 if(res->datanr>0) fprintf(fp, "Data nr:\t%d\n", res->datanr);
630 if(res->fitmethod[0]) fprintf(fp, "Fit method:\t%s\n", res->fitmethod);
631
632 /* Write constants */
633 if(res->density>0.0) fprintf(fp, "Tissue density:\t%g\n", res->density);
634 if(res->lc>0.0) fprintf(fp, "Lumped constant:\t%g\n", res->lc);
635 if(res->concentration>0.0)
636 fprintf(fp, "Concentration:\t%g\n", res->concentration);
637 if(res->beta>0.0) fprintf(fp, "Beta:\t%g\n", res->beta);
638 if(res->Vb>=0.0) fprintf(fp, "Vb:\t%g %%\n", res->Vb);
639 if(res->fA>=0.0) fprintf(fp, "fA:\t%g %%\n", res->fA);
640 if(res->E>=0.0) fprintf(fp, "Extraction:\t%g\n", res->E);
641
642 /* Weighting */
643 if(res->isweight>0) strcpy(tmp, "yes");
644 else if(res->isweight==0) strcpy(tmp, "no");
645 else strcpy(tmp, "unknown");
646 fprintf(fp, "Weighting:\t%s\n", tmp);
647
648 /* Determine column widths: */
649 for(j=0; j<res->parNr; j++) colwidth[j]=1;
650 /* should column be printed as integers (0), floats (1) or exponentials (2)? */
651 for(j=0; j<res->parNr; j++) {
652 partype[j]=resParameterPrintType(res, j);
653 }
654 /* min width required by titles */
655 for(j=0; j<res->parNr; j++) colwidth[j]=strlen(res->parname[j]);
656 if(verbose>2) {
657 printf("col widths after titles were checked:\n");
658 for(i=0; i<res->parNr; i++)
659 printf(" par%d : partype=%d colwidth=%d\n", i+1, partype[i], colwidth[i]);
660 }
661 /* min width required by units */
662 for(j=0; j<res->parNr; j++) {
663 n=strlen(res->parunit[j]); if(n>colwidth[j]) colwidth[j]=n;
664 }
665 if(verbose>2) {
666 printf("col widths after units were checked:\n");
667 for(i=0; i<res->parNr; i++)
668 printf(" par%d : partype=%d colwidth=%d\n", i+1, partype[i], colwidth[i]);
669 }
670 /* widths required by result values */
671 for(i=0; i<res->voiNr; i++) {
672 p=res->voi[i].parameter;
673 for(j=0; j<res->parNr; j++) {
674 if(isnan(p[j])) continue;
675 if(p[j]>=0) n=4; else n=3;
676 switch(partype[j]) {
677 case 0: sprintf(tmp, "%.0f", p[j]); break;
678 case 1: sprintf(tmp, "%.*f", n, p[j]); break;
679 case 2:
680 default: sprintf(tmp, "%.*e", n, p[j]); break;
681 }
682 n=strlen(tmp); if(n>colwidth[j]) colwidth[j]=n;
683 }
684 }
685 if(verbose>2) {
686 printf("col widths after result values were checked:\n");
687 for(i=0; i<res->parNr; i++)
688 printf(" par%d : partype=%d colwidth=%d\n", i+1, partype[i], colwidth[i]);
689 }
690
691 /* Title line */
692 if(verbose>4) {
693 printf(" writing title line with %d parameter(s)\n", res->parNr);
694 fflush(stdout);
695 }
696 fprintf(fp, "\n%s\t", "Region");
697 for(i=0; i<res->parNr; i++) {
698 if(strlen(res->parname[i])<1) strcpy(tmp, ".");
699 else strcpy(tmp, res->parname[i]);
700 fprintf(fp, "\t%s", tmp);
701 }
702 fprintf(fp, "\n");
703
704 /* Write units, if they exist, currently as comment line */
705 for(i=j=0; i<res->parNr; i++) if(strlen(res->parunit[i])>0) j++;
706 if(j>0) {
707 if(verbose>4) {
708 printf(" writing units line with %d parameter(s)\n", j);
709 fflush(stdout);
710 }
711 fprintf(fp, "%s", "# Units:");
712 //fprintf(fp, "%s ", "# Units :");
713 for(i=0; i<res->parNr; i++) {
714 if(strlen(res->parunit[i])<1) strcpy(tmp, ".");
715 else strcpy(tmp, res->parunit[i]);
716 fprintf(fp, "\t%s", tmp);
717 }
718 fprintf(fp, "\n");
719 }
720 fflush(fp);
721
722 /* Write regional results */
723 if(verbose>4) {
724 printf(" writing %d regional results\n", res->voiNr); fflush(stdout);
725 }
726 for(i=0; i<res->voiNr; i++) {
727 if(verbose>6) {printf(" writing region %d\n", 1+i); fflush(stdout);}
728#if(1) // new version
729 if(res->voi[i].name[0]) {
730 fprintf(fp, "%s", res->voi[i].name);
731 } else {
732 if(res->voi[i].voiname[0]) strcpy(tmp, res->voi[i].voiname); else strcpy(tmp, ".");
733 fprintf(fp, "%.*s ", MAX_REGIONSUBNAME_LEN, tmp);
734 if(res->voi[i].hemisphere[0]) strcpy(tmp, res->voi[i].hemisphere); else strcpy(tmp, ".");
735 fprintf(fp, "%.*s ", MAX_REGIONSUBNAME_LEN, tmp);
736 if(res->voi[i].place[0]) strcpy(tmp, res->voi[i].place); else strcpy(tmp, ".");
737 fprintf(fp, "%.*s", MAX_REGIONSUBNAME_LEN, tmp);
738 }
739#else // previous version
740 if(res->voi[i].voiname[0])
741 strcpy(tmp, res->voi[i].voiname); else strcpy(tmp, ".");
742 fprintf(fp, "%.*s ", MAX_REGIONSUBNAME_LEN, tmp);
743 if(res->voi[i].hemisphere[0])
744 strcpy(tmp, res->voi[i].hemisphere); else strcpy(tmp, ".");
745 fprintf(fp, "%.*s ", MAX_REGIONSUBNAME_LEN, tmp);
746 if(res->voi[i].place[0])
747 strcpy(tmp, res->voi[i].place); else strcpy(tmp, ".");
748 fprintf(fp, "%.*s", MAX_REGIONSUBNAME_LEN, tmp);
749#endif
750 p=res->voi[i].parameter;
751 for(j=0; j<res->parNr; j++) {
752 if(verbose>15) {printf(" writing par %d\n", 1+j); fflush(stdout);}
753 if(isnan(p[j])) {fprintf(fp, "\t."); continue;}
754 switch(partype[j]) {
755 case 0: fprintf(fp, "\t%.0f", p[j]); break;
756 case 1:
757 if(p[j]>=0) n=4; else n=3;
758 fprintf(fp, "\t%.*f", n, p[j]);
759 break;
760 default:
761 if(p[j]>=0) n=4; else n=3;
762 fprintf(fp, "\t%.*e", n, p[j]);
763 break;
764 }
765 }
766 fprintf(fp, "\n"); fflush(fp);
767 /* Write SD's, if they exist */
768 if(verbose>25) {printf(" sd?\n"); fflush(stdout);}
769 //if(res->voi[i].sd==NULL) {printf("NULL\n"); fflush(stdout);}
770 if(verbose>25) {printf(" parNr=%d\n", res->parNr); fflush(stdout);}
771 n=0; for(int j=0; j<res->parNr; j++) {if(!isnan(res->voi[i].sd[j])) n++;}
772 if(verbose>25) {printf(" n=%d\n", n); fflush(stdout);}
773 if(n>0) {
774 fprintf(fp, "SD . .");
775 for(j=0; j<res->parNr; j++) {
776 if(verbose>15) {printf(" writing sd %d\n", 1+j); fflush(stdout);}
777 if(!isnan(res->voi[i].sd[j])) {
778 switch(partype[j]) {
779 case 0: fprintf(fp, "\t%.0f", res->voi[i].sd[j]); break;
780 case 1:
781 if(res->voi[i].sd[j]>=0) n=4; else n=3;
782 fprintf(fp, "\t%.*f", n, res->voi[i].sd[j]);
783 break;
784 default:
785 if(res->voi[i].sd[j]>=0) n=4; else n=3;
786 fprintf(fp, "\t%.*e", n, res->voi[i].sd[j]);
787 break;
788 }
789 } else {
790 fprintf(fp, "\t.");
791 }
792 }
793 fprintf(fp, "\n"); fflush(fp);
794 }
795 /* Write lower confidence limits, if they exist */
796 if(verbose>25) {printf(" cl1?\n"); fflush(stdout);}
797 n=0; for(int j=0; j<res->parNr; j++) if(!isnan(res->voi[i].cl1[j])) n++;
798 if(verbose>25) {printf(" n=%d\n", n); fflush(stdout);}
799 if(n>0) {
800 fprintf(fp, "CL 95%% Lower");
801 for(j=0; j<res->parNr; j++) {
802 if(verbose>15) {printf(" writing CL1 %d\n", 1+j); fflush(stdout);}
803 if(!isnan(res->voi[i].cl1[j])) {
804 switch(partype[j]) {
805 case 0: fprintf(fp, "\t%.0f", res->voi[i].cl1[j]); break;
806 case 1:
807 if(res->voi[i].cl1[j]>=0) n=4; else n=3;
808 fprintf(fp, "\t%.*f", n, res->voi[i].cl1[j]);
809 break;
810 default:
811 if(res->voi[i].cl1[j]>=0) n=4; else n=3;
812 fprintf(fp, "\t%.*e", n, res->voi[i].cl1[j]);
813 break;
814 }
815 } else {
816 fprintf(fp, "\t.");
817 }
818 }
819 fprintf(fp, "\n");
820 }
821 /* Write upper confidence limits, if they exist */
822 if(verbose>25) {printf(" cl2?\n"); fflush(stdout);}
823 n=0; for(int j=0; j<res->parNr; j++) if(!isnan(res->voi[i].cl2[j])) n++;
824 if(verbose>25) {printf(" n=%d\n", n); fflush(stdout);}
825 if(n>0) {
826 fprintf(fp, "CL 95%% Upper");
827 for(j=0; j<res->parNr; j++) {
828 if(verbose>15) {printf(" writing CL2 %d\n", 1+j); fflush(stdout);}
829 if(!isnan(res->voi[i].cl2[j])) {
830 switch(partype[j]) {
831 case 0: fprintf(fp, "\t%.0f", res->voi[i].cl2[j]); break;
832 case 1:
833 if(res->voi[i].cl2[j]>=0) n=4; else n=3;
834 fprintf(fp, "\t%.*f", n, res->voi[i].cl2[j]);
835 break;
836 default:
837 if(res->voi[i].cl2[j]>=0) n=4; else n=3;
838 fprintf(fp, "\t%.*e", n, res->voi[i].cl2[j]);
839 break;
840 }
841 } else {
842 fprintf(fp, "\t.");
843 }
844 }
845 fprintf(fp, "\n"); fflush(fp);
846 }
847 } /* next region */
848
849 /* Close file */
850 if(!is_stdout) {fflush(fp); fclose(fp);}
851 strcpy(reserrmsg, "");
852 if(verbose>1) {printf("resWrite() done.\n"); fflush(stdout);}
853
854 return(0);
855}
int resParameterPrintType(RES *res, int parIndex)
Definition result.c:1447
int resWriteHTML(RES *res, char *fname, int verbose)
Definition result.c:865

Referenced by resPrint().

◆ resWriteHTML()

int resWriteHTML ( RES * res,
char * fname,
int verbose )
extern

Write calculation results into specied XHTML 1.1 file. If file exists, a backup file (+BACKUP_EXTENSION) is written also. If "stdout" is given as filename, output is directed to stdout.

Returns
In case of an error, >0 is returned, and a description is written in reserrmsg.
See also
resWrite
Parameters
resPointer to result data
fnameOutput file name
verboseVerbose level; if <=0, then nothing is printed into stdout

Definition at line 865 of file result.c.

872 {
873 int n, is_stdout=0;
874 char tmp[1024];
875 FILE *fp;
876
877
878 if(verbose>0) printf("resWriteHTML(*res, %s, %d)\n", fname, verbose);
879 /* Check that there is some data to write */
880 if(res==NULL) {strcpy(reserrmsg, "error in result data"); return(1);}
881 if(res->voiNr<1) {strcpy(reserrmsg, "no result data"); return(1);}
882 /* Check if writing to stdout */
883 if(!strcasecmp(fname, "stdout")) is_stdout=1;
884
885 resFixParnames(res);
886
887 /* Check if file exists; backup, if necessary */
888 if(!is_stdout && access(fname, 0) != -1) {
889 strcpy(tmp, fname); strcat(tmp, BACKUP_EXTENSION);
890 if(access(tmp, 0)!=-1) remove(tmp);
891 rename(fname, tmp);
892 }
893 strcpy(reserrmsg, "cannot write file");
894
895 /* Open output file */
896 if(is_stdout) fp=(FILE*)stdout;
897 else if((fp=fopen(fname, "w"))==NULL) {
898 strcpy(reserrmsg, "cannot open file"); return(2);}
899
900 /* Write XHTML 1.1 doctype and head */
902 strcpy(reserrmsg, "disk full");
903 if(!is_stdout) fclose(fp);
904 return(3);
905 }
906
907 /* Start writing the body of the HTML file */
908 fprintf(fp, "\n<body>\n");
909
910 /* Start the div for tables */
911 fprintf(fp, "\n<div id=\"tables\">\n");
912
913 /* Write results into a table */
914 if(resWriteHTML_table(res, fp)!=0) {
915 strcpy(reserrmsg, "disk full");
916 if(!is_stdout) fclose(fp);
917 return(3);
918 }
919
920 /* Stop writing the body of the HTML file, and end the file */
921 fprintf(fp, "</div>\n");
922 n=fprintf(fp, "</body></html>\n\n");
923 if(n==0) {
924 strcpy(reserrmsg, "disk full");
925 if(!is_stdout) fclose(fp);
926 return(3);
927 }
928
929 /* Close file */
930 if(!is_stdout) {fflush(fp); fclose(fp);}
931 strcpy(reserrmsg, "");
932
933 return(0);
934}
int resWriteXHTML11_head(FILE *fp, char *author_name)
Definition result.c:960
int resWriteXHTML11_doctype(FILE *fp)
Definition result.c:941
int resWriteHTML_table(RES *res, FILE *fp)
Definition result.c:1013

Referenced by resWrite().

◆ resWriteHTML_table()

int resWriteHTML_table ( RES * res,
FILE * fp )
extern

Write calculation results as one HTML table into an opened (X)HTML file.

Returns
Returns 0 if successful, non-zero in case of a failure.
Parameters
resPointer to result data.
fpOutput file pointer.

Definition at line 1013 of file result.c.

1018 {
1019 int i, j, n;
1020 char *cptr, tmp[1024];
1021 int partype[MAX_RESPARAMS]; /* 0=int, 1=double, 2=exp */
1022 double *p;
1023
1024 if(RESULT_TEST>0) printf("resWriteHTML_table(*res, fp)\n");
1025 if(fp==NULL || res==NULL) return(1);
1026
1027 /* Write the title lines to the head of table */
1028 fprintf(fp, "<table>\n");
1029 fprintf(fp, "<thead>\n");
1030 /* Program name */
1031 strcpy(tmp, res->program);
1032 cptr=strcasestr(tmp, "(c)");
1033 if(cptr!=NULL) {
1034 *cptr=(char)0;
1035 i=strlen(tmp)-1; while(i>0 && isspace(tmp[i])) i--; tmp[i+1]=(char)0;
1036 }
1037 if(tmp[0])
1038 fprintf(fp, "<tr align=left><th>Program:</th><td>%s</td></tr>\n", tmp);
1039 /* Write calculation date and time */
1040 if(!ctime_r_int(&res->time, tmp)) strcpy(tmp, "1900-01-01 00:00:00");
1041 fprintf(fp, "<tr align=left><th>Date:</th><td>%s</td></tr>\n", tmp);
1042 /* Write the studynr */
1043 if(res->studynr[0])
1044 fprintf(fp, "<tr align=left><th>Study:</th><td>%s</td></tr>\n", res->studynr);
1045 /* Write the names of the original datafiles */
1046 if(res->datafile[0])
1047 fprintf(fp, "<tr align=left><th>Data file:</th><td>%s</td></tr>\n", res->datafile);
1048 if(res->plasmafile[0])
1049 fprintf(fp, "<tr align=left><th>Plasma file:</th><td>%s</td></tr>\n", res->plasmafile);
1050 if(res->plasmafile2[0])
1051 fprintf(fp, "<tr align=left><th>2nd Plasma file:</th><td>%s</td></tr>\n", res->plasmafile2);
1052 if(res->bloodfile[0])
1053 fprintf(fp, "<tr align=left><th>Blood file:</th><td>%s</td></tr>\n", res->bloodfile);
1054 if(res->reffile[0])
1055 fprintf(fp, "<tr align=left><th>Reference file:</th><td>%s</td></tr>\n", res->reffile);
1056 if(res->refroi[0])
1057 fprintf(fp, "<tr align=left><th>Reference region:</th><td>%s</td></tr>\n", res->refroi);
1058 /* Write data range etc */
1059 if(res->datarange[0])
1060 fprintf(fp, "<tr align=left><th>Data range:</th><td>%s</td></tr>\n", res->datarange);
1061 if(res->datanr>0)
1062 fprintf(fp, "<tr align=left><th>Data nr:</th><td>%d</td></tr>\n", res->datanr);
1063 if(res->fitmethod[0])
1064 fprintf(fp, "<tr align=left><th>Fit method:</th><td>%s</td></tr>\n", res->fitmethod);
1065 /* Write constants */
1066 if(res->density>0.0)
1067 fprintf(fp, "<tr align=left><th>Tissue density:</th><td>%g</td></tr>\n", res->density);
1068 if(res->lc>0.0)
1069 fprintf(fp, "<tr align=left><th>Lumped constant:</th><td>%g</td></tr>\n", res->lc);
1070 if(res->concentration>0.0)
1071 fprintf(fp, "<tr align=left><th>Concentration:</th><td>%g</td></tr>\n", res->concentration);
1072 if(res->beta>0.0)
1073 fprintf(fp, "<tr align=left><th>Beta:</th><td>%g</td></tr>\n", res->beta);
1074 if(res->Vb>=0.0)
1075 fprintf(fp, "<tr align=left><th>Vb:</th><td>%g %%</td></tr>\n", res->Vb);
1076 if(res->fA>=0.0)
1077 fprintf(fp, "<tr align=left><th>fA:</th><td>%g %%</td></tr>\n", res->fA);
1078 if(res->E>0.0)
1079 fprintf(fp, "<tr align=left><th>Extraction:</th><td>%g</td></tr>\n", res->E);
1080 /* Weighting */
1081 if(res->isweight>0) strcpy(tmp, "yes");
1082 else if(res->isweight==0) strcpy(tmp, "no");
1083 else strcpy(tmp, "unknown");
1084 fprintf(fp, "<tr align=left><th>Weighting:</th><td>%s</td></tr>\n", tmp);
1085 /* End the head of table */
1086 fprintf(fp, "</thead>\n");
1087
1088 /* Collect info on column types */
1089 for(j=0; j<res->parNr; j++) {
1090 /* should column be printed as integers, floats or exponentials? */
1091 partype[j]=resParameterPrintType(res, j);
1092 }
1093
1094 /* Write the result data to the table body */
1095 fprintf(fp, "<tbody>\n");
1096 /* Write the result title line */
1097 fprintf(fp,"<tr align=left><th>Region</th>\n");
1098 for(i=0; i<res->parNr; i++) fprintf(fp, "<th>%s</th>", res->parname[i]);
1099 fprintf(fp, "</tr>\n");
1100 /* Write regional results */
1101 for(i=0; i<res->voiNr; i++) {
1102 if(i%2) strcpy(tmp, "evenroi"); else strcpy(tmp, "oddroi");
1103 fprintf(fp, "<tr class=\"%s\">", tmp);
1104 char *senc=strEncodeForXML(res->voi[i].name);
1105 if(senc==NULL) fprintf(fp, "<th>%s</th>", res->voi[i].name);
1106 else {fprintf(fp, "<th>%s</th>", senc); free(senc);}
1107 p=res->voi[i].parameter;
1108 for(j=0; j<res->parNr; j++) switch(partype[j]) {
1109 case 0: fprintf(fp, "<td>%.0f</td>", p[j]); break;
1110 case 1: fprintf(fp, "<td>%.4f</td>", p[j]); break;
1111 default: fprintf(fp, "<td>%.4E</td>", p[j]); break;
1112 }
1113 fprintf(fp, "</tr>\n");
1114 /* Write SD's, if they exist */
1115 p=res->voi[i].sd; for(j=n=0; j<res->parNr; j++) if(!isnan(p[j])) n++;
1116 if(n>0) {
1117 fprintf(fp, "<tr class=\"sd\">");
1118 fprintf(fp, "<th>%s</th>", "SD");
1119 for(j=0; j<res->parNr; j++) {
1120 if(!isnan(p[j])) switch(partype[j]) {
1121 case 0: fprintf(fp, "<td>%.0f</td>", p[j]); break;
1122 case 1: fprintf(fp, "<td>%.4f</td>", p[j]); break;
1123 default: fprintf(fp, "<td>%.4E</td>", p[j]); break;
1124 } else fprintf(fp, "<td></td>");
1125 }
1126 fprintf(fp, "</tr>\n");
1127 }
1128 /* Write lower confidence limits, if they exist */
1129 p=res->voi[i].cl1; for(j=n=0; j<res->parNr; j++) if(!isnan(p[j])) n++;
1130 if(n>0) {
1131 fprintf(fp, "<tr class=\"cl1\">");
1132 fprintf(fp, "<th>CL95%%L</th>");
1133 for(j=0; j<res->parNr; j++) {
1134 if(!isnan(p[j])) switch(partype[j]) {
1135 case 0: fprintf(fp, "<td>%.0f</td>", p[j]); break;
1136 case 1: fprintf(fp, "<td>%.4f</td>", p[j]); break;
1137 default: fprintf(fp, "<td>%.4E</td>", p[j]); break;
1138 } else fprintf(fp, "<td></td>");
1139 }
1140 fprintf(fp, "</tr>\n");
1141 }
1142 /* Write upper confidence limits, if they exist */
1143 p=res->voi[i].cl2; for(j=n=0; j<res->parNr; j++) if(!isnan(p[j])) n++;
1144 if(n>0) {
1145 fprintf(fp, "<tr class=\"cl2\">");
1146 fprintf(fp, "<th>CL95%%U</th>");
1147 for(j=0; j<res->parNr; j++) {
1148 if(!isnan(p[j])) switch(partype[j]) {
1149 case 0: fprintf(fp, "<td>%.0f</td>", p[j]); break;
1150 case 1: fprintf(fp, "<td>%.4f</td>", p[j]); break;
1151 default: fprintf(fp, "<td>%.4E</td>", p[j]); break;
1152 } else fprintf(fp, "<td></td>");
1153 }
1154 fprintf(fp, "</tr>\n");
1155 }
1156 }
1157 /* End the body of the table and table */
1158 fprintf(fp, "</tbody></table>\n");
1159
1160 return(0);
1161}

Referenced by resWriteHTML().

◆ resWriteXHTML11_doctype()

int resWriteXHTML11_doctype ( FILE * fp)
extern

Write XHTML 1.1 doctype into an opened file pointer.

Returns
Returns 0 if successful, non-zero in case of a failure.
Parameters
fpOutput file pointer.

Definition at line 941 of file result.c.

944 {
945 int n;
946 if(fp==NULL) return(1);
947 n=fprintf(fp, "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" ");
948 n+=fprintf(fp, "\"https://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n");
949 if(n<20) return(2);
950 n=fprintf(fp,"<html xmlns=\"https://www.w3.org/1999/xhtml\" xml:lang=\"en\">\n\n");
951 if(n<20) return(2);
952 return(0);
953}

Referenced by resWriteHTML().

◆ resWriteXHTML11_head()

int resWriteXHTML11_head ( FILE * fp,
char * author_name )
extern

Write XHTML 1.1 head for PET results file into an opened file pointer.

Returns
Returns 0 if successful, non-zero in case of a failure.
Parameters
fpFile pointer where to write.
author_nameAuthor name, for example software name.

Definition at line 960 of file result.c.

965 {
966 int n;
967 if(fp==NULL) return(1);
968
969 n=fprintf(fp, "<head>\n"); if(n<6) return(2);
970 fprintf(fp, " <title>Tabulated PET results</title>\n");
971 fprintf(fp, " <meta http-equiv=\"content-type\" content=\"text/html; charset=iso-8859-1\" />\n");
972 fprintf(fp, " <meta http-equiv=\"content-language\" content=\"en-gb\" />\n");
973 fprintf(fp, " <meta name=\"description\" content=\"Regional PET results\" />\n");
974 fprintf(fp, " <meta name=\"author\" content=\"%s\" />\n", author_name);
975 fprintf(fp, " <meta name=\"ProgId\" content=\"Excel.Sheet\" />\n");
976 fprintf(fp, " <link rel=\"icon\" href=\"https://www.turkupetcentre.net/favicon.ico\" type=\"image/x-icon\" />\n");
977 fprintf(fp, " <link rel=\"shortcut icon\" href=\"https://www.turkupetcentre.net/favicon.ico\" type=\"image/x-icon\" />\n");
978 /* write local CSS with basic settings in case external CSS is not available */
979 fprintf(fp, " <style type=\"text/css\">\n");
980 fprintf(fp, " thead {background-color:#999999; color:black;}\n");
981//fprintf(fp, " table {text-align:left; width:100%%; border-collapse:colla");
982 fprintf(fp, " table {text-align:left; border-collapse:collapse; empty-cells:show;}\n");
983//fprintf(fp, " td {border:1px solid black;}\n");
984 fprintf(fp, " .oddroi {background-color:#FFFFFF; color:black;}\n");
985 fprintf(fp, " .evenroi {background-color:#CCCCCC; color:black;}\n");
986 fprintf(fp, " .sd {background-color:#999999; color:blue;}\n");
987 fprintf(fp, " .cl1 {background-color:#999999; color:green;}\n");
988 fprintf(fp, " .cl2 {background-color:#999999; color:green;}\n");
989 fprintf(fp, " .oddstudy {background-color:#FFFFFF; color:black;}\n");
990 fprintf(fp, " .evenstudy {background-color:#CCCCCC; color:black;}\n");
991 fprintf(fp, " .oddsum {background-color:#999999; color:black;}\n");
992 fprintf(fp, " .evensum {background-color:#CCCCCC; color:black;}\n");
993 fprintf(fp, " #regcontainer ul {margin-left:0; padding-left:0;}\n");
994 fprintf(fp, " #regcontainer ul li {display:inline; list-style-type:none;}\n");
995 fprintf(fp, " #regcontainer a {padding:2px 4px;}\n");
996 fprintf(fp, " <!--table\n");
997 fprintf(fp, " {mso-displayed-decimal-separator:\"\\.\";\n");
998 fprintf(fp, " mso-displayed-thousand-separator:\" \";}\n");
999 fprintf(fp, " -->\n");
1000 fprintf(fp, " </style>\n");
1001 /* load external CSS with more fancy settings */
1002 fprintf(fp, " <link rel=\"stylesheet\" type=\"text/css\" href=\"https://www.turkupetcentre.net/result.css\" />\n");
1003 fprintf(fp, "</head>\n");
1004 if(n<7) return(2);
1005 return(0);
1006}

Referenced by resWriteHTML().

◆ roikbqRead()

int roikbqRead ( char * fname,
DFT * dft )
extern

Read an old TAC file in *.roi.kbq / *.roi.nci format.

Returns
Returns 0 if ok.
Parameters
fnamePointer to filename
dftPointer to an empty but initiated DFT structure where data is written

Definition at line 95 of file ncifile.c.

100 {
101 FILE *fp;
102 int i, j, k, l, roi_nr=0, frame_nr=0, ret, nr=0;
103 char c, line[ROIKBQ_MAX_LINE_LEN], tmp[25], s1[25], s2[25];
104 double a, b;
105
106
107 /* Check the arguments */
108 if(dft==NULL || fname==NULL) {
109 strcpy(dfterrmsg, "program fault"); return(1);}
110 /* Empty data */
111 dftEmpty(dft);
112
113 /* Open file */
114 fp=fopen(fname, "r");
115 if(fp==NULL) {strcpy(dfterrmsg, "cannot open file"); return(2);}
116
117 /* Check file type */
118 rewind(fp); i=0;
119 while(fgets(line, ROIKBQ_MAX_LINE_LEN-1, fp) != NULL) {
120 roikbq_strip_spaces(line); if(!strlen(line) || line[0]=='#') continue;
121 if(!isalpha((int)line[0])) continue;
122 if(strncasecmp(line, "cpt2nci 3", 9)==0) {i=1; break;}
123 }
124 if(i==0) {strcpy(dfterrmsg, "unsupported file format"); fclose(fp); return(3);}
125
126 /* Get data size */
127 rewind(fp); roi_nr=frame_nr=0;
128 /* read first title line */
129 c=fgetc(fp);
130 if(c=='#') roikbq_move_to_next_line(fp); else ungetc(c, fp);
131 i=roikbq_fgets(fp, 16, tmp);
132 if(i<16) {strcpy(dfterrmsg, "unsupported file format"); fclose(fp); return(3);}
133 while(i>13) {
134 i=roikbq_fgets(fp, 14, tmp); if(i>11 && isalnum((int)tmp[0])) roi_nr++;
135 }
136 /* read two title lines more */
137 roikbq_move_to_next_line(fp); roikbq_move_to_next_line(fp);
138 /* now start reading data lines */
139 do {
140 c=fgetc(fp); if(c==EOF) break; if(c!='\n') frame_nr++;
141 roikbq_move_to_next_line(fp);
142 } while(c!=EOF);
143 if(roi_nr<1 || frame_nr<1) {
144 strcpy(dfterrmsg, "unsupported file format"); fclose(fp); return(3);}
145
146 /* Allocate memory for DFT */
147 ret=dftSetmem(dft, frame_nr, roi_nr);
148 if(ret) {strcpy(dfterrmsg, "out of memory"); fclose(fp); return(4);}
149 dft->_type=1;
150
151 /* Read data */
152 /* Set file pointer to the beginning of first title line */
153 rewind(fp); c=fgetc(fp);
154 if(c=='#') roikbq_move_to_next_line(fp); else ungetc(c, fp);
155 /* Read the names of ROIs and Hemispheres */
156 j=roikbq_fgets(fp, 16, tmp);
157 if(j<16) {strcpy(dfterrmsg, "unsupported file format"); fclose(fp); return(3);}
158 i=0; while (j>13) {
159 j=roikbq_fgets(fp, 14, tmp); if(i>=roi_nr) continue;
160 k=sscanf(tmp, "%s %s", s1, s2); if(k<1) continue;
161 if(k==1) s2[0]='\0';
162 strcpy(dft->voi[dft->voiNr+i].voiname, s1);
163 strcpy(dft->voi[dft->voiNr+i].hemisphere, s2);
164 if(s2[0]!='\0')
165 snprintf(dft->voi[dft->voiNr+i].name, MAX_REGIONNAME_LEN, "%s %s", s1, s2);
166 else
167 snprintf(dft->voi[dft->voiNr+i].name, MAX_REGIONNAME_LEN, "%s .", s1);
168 i++;
169 }
170 nr=i;
171 /* Read the name of place (planes) in 2nd title line */
172 c=fgetc(fp); if(c=='#') roikbq_move_to_next_line(fp); else ungetc(c, fp);
173 j=roikbq_fgets(fp, 16, tmp);
174 if(j<16) {strcpy(dfterrmsg, "unsupported file format"); fclose(fp); return(3);}
175 strncpy(dft->studynr, tmp, 6); dft->studynr[6]=(char)0;
176 roikbq_strip_spaces(dft->studynr);
177 i=0; while(j>13) {
178 j=roikbq_fgets(fp, 14, tmp); if(i>=nr) continue;
179 k=sscanf(tmp, "%s", s1); if(k<1) s1[0]='\0';
180 strcpy(dft->voi[dft->voiNr+i].place, s1);
181 if(s1[0]!='\0') {
182 strcat(dft->voi[dft->voiNr+i].name, " ");
183 strcat(dft->voi[dft->voiNr+i].name, s1);
184 } else strcat(dft->voi[dft->voiNr+i].name, " .");
185 i++;
186 }
187 for(j=i; j<nr; j++) strcpy(dft->voi[dft->voiNr+j].place, "");
188 /* Read the ROI volumes in 3rd title line */
189 c=fgetc(fp); if(c=='#') roikbq_move_to_next_line(fp); else ungetc(c, fp);
190 j=roikbq_fgets(fp, 16, tmp);
191 if(j<16) {strcpy(dfterrmsg, "unsupported file format"); fclose(fp); return(3);}
192 if(strstr(tmp, "Times")) dft->timetype=3;
193 else if(strstr(tmp, "Start")) dft->timetype=1;
194 else if(strstr(tmp, "End")) dft->timetype=2;
195 else dft->timetype=0;
196 if(strstr(tmp, "sec")) dft->timeunit=TUNIT_SEC; else dft->timeunit=TUNIT_MIN;
197 i=0; while(j>13) {
198 j=roikbq_fgets(fp, 14, tmp); if(i>=nr) continue;
199 if(sscanf(tmp, "%lf", &dft->voi[dft->voiNr+i].size)<1)
200 dft->voi[dft->voiNr+i].size=0.;
201 i++;
202 }
203 for(j=i; j<nr; j++) dft->voi[dft->voiNr+j].size=0.;
204 /* Read frame data */
205 k=0; c=fgetc(fp); if(c=='#') roikbq_move_to_next_line(fp); else ungetc(c, fp);
206 while((j=roikbq_fgets(fp, 16, tmp))>15) {
207 if(k>=frame_nr) break;
208 roikbq_strip_spaces(tmp); if(strlen(tmp)==0) continue;
209 if(dft->timetype==0) {
210 dft->x[k]=atof(tmp);
211 dft->x1[k]=dft->x2[k]=nan("");
212 } else if(dft->timetype==3) {
213 sscanf(tmp, "%lf %lf", &a, &b); dft->x1[k]=a; dft->x2[k]=b;
214 dft->x[k]=0.5*(dft->x1[k] + dft->x2[k]);
215 } else if(dft->timetype==1) {
216 dft->x1[k]=dft->x[k]=dft->x2[k]=atof(tmp);
217 } else if(dft->timetype==2) {
218 dft->x2[k]=dft->x[k]=dft->x1[k]=atof(tmp);
219 }
220 if(dft->x[k]<-3.e38) dft->x[k]=nan("");
221 i=0; while(j>13) {
222 j=roikbq_fgets(fp, 14, tmp); if(i>=nr || j<13) continue;
223 roikbq_strip_spaces(tmp);
224 if(!strlen(tmp) || !strcmp(tmp, ".")) dft->voi[dft->voiNr+i].y[k]=nan("");
225 else {
226 dft->voi[dft->voiNr+i].y[k]=atof(tmp);
227 if(dft->voi[dft->voiNr+i].y[k]<-3.e38)
228 dft->voi[dft->voiNr+i].y[k]=nan("");
229 }
230 i++;
231 }
232 for(l=i; l<nr; l++) dft->voi[dft->voiNr+l].y[k]=nan("");
233 k++;
234 c=fgetc(fp); if(c=='#') roikbq_move_to_next_line(fp); else ungetc(c, fp);
235 }
236 for(i=k; i<frame_nr; i++) {
237 dft->x[i]=0.;
238 for(j=dft->voiNr; j<dft->voiNr+nr; j++) dft->voi[j].y[i]=nan("");
239 }
240 /* Set voiNr and frameNr and close the file */
241 dft->voiNr=nr; dft->frameNr=frame_nr; fclose(fp);
242 /* Set data unit based on filename */
243 if(strstr(fname, ".nci")==NULL && strstr(fname, ".NCI")==NULL)
244 strcpy(dft->unit, "kBq/ml");
245 else strcpy(dft->unit, "nCi/ml");
246 /* Set weights in DFT to 1.0 */
247 dft->isweight=0;
248 for(i=0; i<dft->frameNr; i++) dft->w[i]=1.0;
249 /* quit */
250 return(0);
251}
#define ROIKBQ_MAX_LINE_LEN
Definition ncifile.c:12

Referenced by dftRead().

◆ roikbqWrite()

int roikbqWrite ( DFT * dft,
char * fname )
extern

Write DFT contents in *.roi.kbq format.

Returns
Returns 0 if ok.
Parameters
dftPointer to DFT
fnameFilename

Definition at line 26 of file ncifile.c.

31 {
32 int ri, fi;
33 char tmp[FILENAME_MAX];
34 FILE *fp;
35
36 /* Check that there is some data to write */
37 if(dft->voiNr<1 || dft->frameNr<1) {
38 strcpy(dfterrmsg, "no data"); return(1);}
39
40 /* Check if file exists; backup, if necessary */
41 if(access(fname, 0) != -1) {
42 strcpy(tmp, fname); strcat(tmp, BACKUP_EXTENSION);
43 if(access(tmp, 0) != -1) remove(tmp);
44 rename(fname, tmp);
45 }
46
47 /* Open output file */
48 if((fp = fopen(fname, "w")) == NULL) {strcpy(dfterrmsg, "cannot open file"); return(2);}
49
50 /* Write title lines */
51
52 /* Write 1st title line (Program name and ROI names) */
53 fprintf(fp, "%-15.15s", "cpt2nci 3");
54 for(ri=0; ri<dft->voiNr; ri++) {
55 fprintf(fp, " %-6.6s", dft->voi[ri].voiname);
56 if(strcmp(dft->voi[ri].hemisphere, ".")==0) fprintf(fp, " %-6.6s", " ");
57 else fprintf(fp, " %-6.6s", dft->voi[ri].hemisphere);
58 }
59 fprintf(fp, "\n");
60
61 /* Write 2nd title line (Study nr and Planes) */
62 fprintf(fp, "%-15.15s", dft->studynr);
63 for(ri=0; ri<dft->voiNr; ri++)
64 fprintf(fp, " %-13.13s", dft->voi[ri].place);
65 fprintf(fp, "\n");
66
67 /* Write 3rd title line (ROI volumes) */
68 fprintf(fp, "%-15.15s", "Time (min)");
69 for(ri=0; ri<dft->voiNr; ri++)
70 fprintf(fp, " %-13.1f", dft->voi[ri].size);
71 fprintf(fp, "\n");
72
73 /* Write times and data of each frame */
74 for(fi=0; fi<dft->frameNr; fi++) {
75 fprintf(fp, "%8.3f ", dft->x[fi]);
76 for(ri=0; ri<dft->voiNr; ri++)
77 if(!isnan(dft->voi[ri].y[fi]))
78 fprintf(fp, " %-13.6e", dft->voi[ri].y[fi]);
79 else
80 fprintf(fp, " . ");
81 fprintf(fp, "\n");
82 }
83
84 /* Close file */
85 fclose(fp);
86
87 return(0);
88}

◆ tsvRead()

int tsvRead ( char * filename,
DFT * dft )
extern

Read Amide TAC file (*.tsv) into DFT data structure. Any previous content of DFT is deleted.

Returns
Returns nonzero in case an error is encountered and sets dfterrmsg.
See also
dftRead
Parameters
filenameName of Amide TAC file (*.tsv) to be read
dftPointer to DFT data where to regional TAC data is read

Definition at line 15 of file tsv.c.

20 {
21 int ii, si, ri, fi, n, ret;
22 char tmp[1024], tmp2[512], *cptr;
23 IFT ift;
24 float f[13];
25
26
27 /* Check the arguments */
28 if(filename==NULL || dft==NULL || strlen(filename)<1) {
29 strcpy(dfterrmsg, "program error"); return(1);
30 }
31
32 /* Read the file contents */
33 iftInit(&ift); ret=iftRead(&ift, filename, 0, 0);
34 if(ret) {strcpy(dfterrmsg, ift.status); iftEmpty(&ift); return(2);}
35
36 /* Check that this actually is a Amide TAC file */
37 strcpy(tmp, "amide"); ii=iftGet(&ift, tmp, 0);
38 if(ii<0) {strcpy(dfterrmsg, "wrong format"); iftEmpty(&ift); return(3);}
39 if(strncasecmp(ift.item[ii].value, "ROI Analysis File - ", 16)!=0) {
40 strcpy(dfterrmsg, "wrong format"); iftEmpty(&ift); return(3);}
41 sprintf(dft->comments, "# Amide %s\n# original_filename := %s\n",
42 ift.item[ii].value, filename);
43
44 /* Get the number of ROIs */
45 strcpy(tmp, "ROI");
46 ri=0; while((ii=iftGetNth(&ift, tmp, ri+1, 0))>=0) ri++;
47 //printf("ri=%d\n", ri);
48 if(ri<1) {strcpy(dfterrmsg, "wrong format"); iftEmpty(&ift); return(4);}
49
50 /* Get the max frame number */
51 for(ii=0, fi=0; ii<ift.keyNr; ii++) {
52 if(ift.item[ii].type=='#') continue;
53 n=sscanf(ift.item[ii].value, "%f %f %f %f %f %f %f %f %f %f %f %f %f",
54 f, f+1, f+2, f+3, f+4, f+5, f+6, f+7, f+8, f+9, f+10, f+11, f+12);
55 if(n<13) continue;
56 n=temp_roundf(f[0])+1; // Amide frames start from 0
57 if(n>fi) fi=n;
58 }
59 //printf("fi=%d\n", fi);
60 if(fi<1) {strcpy(dfterrmsg, "wrong format"); iftEmpty(&ift); return(5);}
61
62 /* Allocate memory for DFT data */
63 if(dftSetmem(dft, fi, ri)) {
64 strcpy(dfterrmsg, "out of memory"); iftEmpty(&ift); return(7);}
65 dft->frameNr=fi; dft->voiNr=ri;
66
67 /*
68 * Read one ROI at a time
69 */
70 strcpy(tmp, "ROI"); ri=0;
71 while((ii=iftGetNth(&ift, tmp, ri+1, 0))>=0) {
72 /* Get ROI name */
73 strcpy(tmp2, ift.item[ii].value); cptr=strtok(tmp2, " \t\n\r");
74 if(cptr!=NULL) {
75 strncpy(dft->voi[ri].voiname, cptr, MAX_REGIONSUBNAME_LEN);
76 dft->voi[ri].voiname[MAX_REGIONSUBNAME_LEN]='\0';
77 } else {
78 char buf[128]; snprintf(buf, 128, "%03d", ri+1);
79 char *p=buf+strlen(buf)-3;
80 snprintf(dft->voi[ri].voiname, MAX_REGIONSUBNAME_LEN, "VOI%s", p);
81 }
82 /* Get the next data set (output filename will be based on this) */
83 for(si=ii+1; si<ift.keyNr; si++) {
84 if(ift.item[si].type!='#') continue;
85 if(strcasecmp(ift.item[si].key, "Data Set")==0) break;
86 }
87 if(si<0) {strcpy(dfterrmsg, "wrong format"); iftEmpty(&ift); return(8);}
88 strcpy(tmp2, ift.item[si].value); cptr=strtok(tmp2, " \t\n\r");
89 if(cptr!=NULL) {
90 strncpy(dft->voi[ri].name, cptr, MAX_REGIONNAME_LEN);
91 dft->voi[ri].name[MAX_REGIONNAME_LEN]='\0';
92 }
93 /* Read the frame data until the next data set */
94 for(ii=si+1, fi=0; ii<ift.keyNr; ii++)
95 if(ift.item[ii].type!='#') break;
96 for(; ii<ift.keyNr; ii++) {
97 if(ift.item[ii].type=='#') break;
98 n=sscanf(ift.item[ii].value, "%f %f %f %f %f %f %f %f %f %f %f %f %f",
99 f, f+1, f+2, f+3, f+4, f+5, f+6, f+7, f+8, f+9, f+10, f+11, f+12);
100 if(n<13) continue;
101 /* Get mean activity concentration */
102 dft->voi[ri].y[fi]=f[5];
103 /* Get VOI size */
104 if(fi==0)
105 dft->voi[ri].size=f[10];
106 /* Get frame times, if this is the first ROI */
107 if(ri==0) {
108 dft->x[fi]=f[2];
109 dft->x1[fi]=f[2]-0.5*f[1];
110 dft->x2[fi]=f[2]+0.5*f[1];
111 }
112 fi++;
113 } // next frame
114 ri++;
115 }
116 iftEmpty(&ift);
117
118 /* Set the study number based on Data Set */
119 (void)studynr_from_fname(dft->voi[0].name, dft->studynr);
120
121 /* Set the rest of DFT "header" */
122 dft->_type=1;
123 dft->isweight=0;
124 dftTimeunitToDFT(dft, petTunit(TUNIT_SEC)); // time units are in sec
125 dftUnitToDFT(dft, CUNIT_UNKNOWN); // conc units are not known
126
127 return(0);
128}
int dftTimeunitToDFT(DFT *dft, const char *timeunit)
Definition dftunit.c:103
int temp_roundf(float e)
Definition petc99.c:20

◆ xelRead()

int xelRead ( char * filename,
DFT * dft )
extern

Read Xeleris TAC file into DFT data structure. Any previous content of DFT is deleted.

Returns
Returns nonzero in case an error is encountered and sets dfterrmsg.
Parameters
filenameName of Xeleris TAC file to be read
dftPointer to DFT data where to regional TAC data is read

Definition at line 14 of file xeleris.c.

19 {
20 int ii, si, ri, fi, n, ret;
21 char tmp[1024], tmp2[512], *cptr;
22 IFT ift;
23 float f[6];
24
25
26 /* Check the arguments */
27 if(filename==NULL || dft==NULL || strlen(filename)<1) {
28 strcpy(dfterrmsg, "program error"); return(1);
29 }
30
31 /* Read the file contents */
32 iftInit(&ift); ret=iftRead(&ift, filename, 0, 0);
33 if(ret) {strcpy(dfterrmsg, ift.status); iftEmpty(&ift); return(2);}
34
35 /* Check that this actually is a Xeleris TAC file */
36 strcpy(tmp, "Image Position"); ii=iftGet(&ift, tmp, 0);
37 if(ii<0) {strcpy(dfterrmsg, "wrong format"); iftEmpty(&ift); return(3);}
38 strcpy(tmp, "XAxis"); ii=iftGet(&ift, tmp, 0);
39 if(ii<0) {strcpy(dfterrmsg, "wrong format"); iftEmpty(&ift); return(3);}
40 strcpy(tmp, "YAxis"); ii=iftGet(&ift, tmp, 0);
41 if(ii<0) {strcpy(dfterrmsg, "wrong format"); iftEmpty(&ift); return(3);}
42
43 /* Find the data title, and assume that lines after that contain the TACs */
44 strcpy(tmp, "Curve X Dur Max Min Mean StdDev");
45 ii=iftFindNthValue(&ift, tmp, 1, 0);
46 if(ii<0) {strcpy(dfterrmsg, "wrong format"); iftEmpty(&ift); return(4);}
47 si=ii+1;
48
49 /* Determine the number of TACs and time frames */
50 ri=fi=0; strcpy(tmp2, ""); n=1;
51 for(ii=si; ii<ift.keyNr; ii++) {
52 if(sscanf(ift.item[ii].value, "%s", tmp)!=1) {
53 strcpy(dfterrmsg, "wrong format"); iftEmpty(&ift); return(5);}
54 if(strcmp(tmp, tmp2)==0) {
55 n++; if(n>fi) fi=n;
56 } else {
57 ri++; strcpy(tmp2, tmp); if(n>fi) fi=n; n=1;
58 }
59 //printf("tmp=%s tmp2=%s n=%d, ri=%d fi=%d\n", tmp, tmp2, n, ri, fi);
60 }
61 if(ri<1 || fi<1) {strcpy(dfterrmsg, "wrong format"); iftEmpty(&ift); return(6);}
62
63 /* Allocate memory for DFT data */
64 if(dftSetmem(dft, fi, ri)) {
65 strcpy(dfterrmsg, "out of memory"); iftEmpty(&ift); return(7);}
66 dft->frameNr=fi; dft->voiNr=ri;
67
68 /* Read TAC data and fill DFT */
69 ri=fi=0; strcpy(tmp2, ""); n=1;
70 for(ii=si; ii<ift.keyNr; ii++) {
71 if(sscanf(ift.item[ii].value, "%s %f %f %f %f %f %f",
72 tmp, f, f+1, f+2, f+3, f+4, f+5)!=7) {
73 strcpy(dfterrmsg, "wrong format"); iftEmpty(&ift); return(5);}
74 if(strcmp(tmp, tmp2)==0) n++;
75 else {ri++; strcpy(tmp2, tmp); if(n>fi) fi=n; n=1;}
76 //printf("tmp=%s tmp2=%s n=%d, ri=%d fi=%d\n", tmp, tmp2, n, ri, fi);
77 /* TAC name */
78 strlcpy(dft->voi[ri-1].voiname, tmp, MAX_REGIONSUBNAME_LEN+1);
79 //dft->voi[ri-1].voiname[MAX_REGIONSUBNAME_LEN]='\0';
80 /* Frame time */
81 if(ri==1) {
82 dft->x1[n-1]=f[0]; dft->x2[n-1]=f[0]+f[1];
83 dft->x[n-1]=0.5*(dft->x1[n-1]+dft->x2[n-1]);
84 } else {
85 if(fabs(dft->x1[n-1]-f[0])>1.0E-12 || fabs(dft->x2[n-1]-f[0]-f[1])>1.0E-12) {
86 strcpy(dfterrmsg, "wrong format"); iftEmpty(&ift); return(8);}
87 }
88 /* Concentrations */
89 dft->voi[ri-1].y[n-1]=f[4];
90 }
91
92 /* Add image position to the TAC name, if possible */
93 strcpy(tmp, "Image Position"); ii=iftGet(&ift, tmp, 0);
94 if(ii>=0) {
95 f[0]=atof(ift.item[ii].value); sprintf(tmp, "%-6.0f", f[0]); tmp[6]='\0';
96 for(ri=0; ri<dft->voiNr; ri++) {
97 strcpy(dft->voi[ri].place, tmp);
98 sprintf(dft->voi[ri].name, "%s . %s", dft->voi[ri].voiname, dft->voi[ri].place);
99 }
100 }
101
102 /* Determine the concentration (y axis) unit */
103 strcpy(tmp, "YAxis"); ii=iftGet(&ift, tmp, 0);
104 if(ii>=0 && strncasecmp(ift.item[ii].value, "Uptake (Bqml)", 8)==0) {
105 cptr=ift.item[ii].value+8;
106 if( strncasecmp(cptr, "Bqml", 4)==0) strcpy(dft->unit, "Bq/ml");
107 else if(strncasecmp(cptr, "kBqml", 5)==0) strcpy(dft->unit, "kBq/ml");
108 else if(strncasecmp(cptr, "MBqml", 5)==0) strcpy(dft->unit, "MBq/ml");
109 else if(strncasecmp(cptr, "Bqcc", 4)==0) strcpy(dft->unit, "Bq/ml");
110 else if(strncasecmp(cptr, "kBqcc", 5)==0) strcpy(dft->unit, "kBq/ml");
111 else if(strncasecmp(cptr, "MBqcc", 5)==0) strcpy(dft->unit, "MBq/ml");
112 }
113
114 /* Determine the time (x axis) unit */
115 dft->timeunit=TUNIT_UNKNOWN;
116 strcpy(tmp, "XAxis"); ii=iftGet(&ift, tmp, 0);
117 if(ii>=0) {
118 if(strcasecmp(ift.item[ii].value, "sec")==0) dft->timeunit=TUNIT_SEC;
119 else if(strcasecmp(ift.item[ii].value, "min")==0) dft->timeunit=TUNIT_MIN;
120 }
121
122 iftEmpty(&ift);
123
124 /* Set the study number based on filename */
125 (void)studynr_from_fname(filename, dft->studynr);
126
127 /* Set the rest of DFT "header" */
128 dft->_type=1;
129 dft->timetype=3;
130 dft->isweight=0;
131
132 return(0);
133}

Variable Documentation

◆ cpterrmsg

char cpterrmsg[128]
extern

Error message from CPT functions.

Definition at line 6 of file cpt.c.

Referenced by cptReadOne(), and cptWrite().

◆ CSV_TEST

int CSV_TEST
extern

Verbose prints from CSV functions.

Definition at line 6 of file csv.c.

Referenced by csv2dft(), csv2dft_a(), csv2dft_b(), csv2dft_linkset(), csv2dft_mat(), csvRead(), dftFormat(), and dftRead().

◆ DFT_NR_OF_DECIMALS

int DFT_NR_OF_DECIMALS
extern

Nr of decimals for concentration values.

Nr of decimals for concentration values

Definition at line 13 of file dftio.c.

Referenced by dftRead(), and dftWrite().

◆ dfterrmsg

char dfterrmsg[64]
extern

◆ fiterrmsg

char fiterrmsg[64]
extern

Error message from FIT functions

Definition at line 6 of file mathfunc.c.

Referenced by fitRead(), and fitWrite().

◆ MATHFUNC_TEST

int MATHFUNC_TEST
extern

Verbose prints from FIT functions

Definition at line 5 of file mathfunc.c.

Referenced by fitEval(), fitPrint(), and fitWrite().

◆ reserrmsg

char reserrmsg[64]
extern

Error message from RES functions

Definition at line 6 of file result.c.

Referenced by resRead(), resWrite(), and resWriteHTML().

◆ RESULT_TEST

int RESULT_TEST
extern

Verbose prints from RES functions

Definition at line 5 of file result.c.

Referenced by resFixParnames(), resMatchParameternames(), resMatchParameters(), resMatchParametersAbs(), resMatchRegions(), and resWriteHTML_table().