/* Steven Andrews, 9/98 */ /* Spectrum fitting program */ /* See documentation called SpectFit doc */ /* Copyright 2003 by Steven Andrews. Permission is granted for non-commercial use of and modifications to the code. */ #include #include #include #include #include #include "errors.h" #include "Rn.h" #include "Cn.h" #include "RnSort.h" #include "Spectra.h" #include "Plot.h" #include "Set.h" #include "BasisFn.h" #include "DiskIO.h" #include "Utility.h" #include "math2.h" #include "VoidComp.h" #include "string2.h" #include "SpectFit.h" #include "errors.h" struct result{ void *val; void **valptr; char type; int temp; int var; int er; }; int UpdateModels(modelptr m); void drawplot(); void mouse(); int tweak(modelptr m); void ClearSpect(sptr s,int fre); void ClearBasis(basisptr b); void ClearModel(modelptr m,int fre); void ClearString(char *name); int CreateSpect(sptr s); int CreateModel(modelptr m); int CreateNumber(char *name,float f); int CreateString(char *name,char *str); void ResultFree(struct result ans); int CheckArgs(struct result *ag,int arg,char *str); struct result dosymbol(char *expr,int i); struct result dodots(char *expr,int i); struct result doword(char *cmd,char *expr); struct result evalexpr(char *expr); struct result doassign(char *lhs,char *rhs); int docommand(char *cmd); int doline(char *cmd); void debug(); set Spectra,Plotlist,Models,Numbers,Strings; modelptr Model; int Logcmd; int Need2Plot,Need2Update; /* Routines available externally */ int UpdateModel(modelptr m) { void *x,*k; struct scell *trace; basisptr b; char str[STRCHAR]; int i,out; struct result ans; float f; if(!m) return 0; out=0; for(trace=SetNext(NULL,&k,&x,m->basis);trace;trace=SetNext(trace,&k,&x,m->basis)) { b=(basisptr) x; for(i=0;in;i++) if(b->freeze[i]&&strlen(b->eqn[i])) { strncpy(str,b->eqn[i],STRCHAR); ans=evalexpr(str); if(ans.type!='F') out=18; else if(!((f=*((float*)ans.val))>-FLT_MAX&&f17)?out:17; else if(b->param[i]!=f) { b->param[i]=f; out=out?out:-1; }}} return out; } int UpdateModels() { int er; void *x,*k; struct scell *trace; er=0; for(trace=SetNext(NULL,&k,&x,Models);trace;trace=SetNext(trace,&k,&x,Models)) if(er>0) UpdateModel((modelptr)x); else er=UpdateModel((modelptr)x); Need2Update=0; if(er<0) er=0; return er; } sptr Name2Spec(char *str) { return (sptr) SetItem((void*)str,Spectra); } /* Drawing routines */ void drawplot() { void *k,*x,*km,*xm; struct scell *trace,*tracem; PlotClear(); ShowLimits(); for(trace=SetNext(NULL,&k,&x,Plotlist);trace;trace=SetNext(trace,&k,&x,Plotlist)) { if(SetMember(k,x,Models)) PlotModel((modelptr) x); else if(SetMember(k,x,Spectra)) PlotSpect((sptr) x); else { for(tracem=SetNext(NULL,&km,&xm,Models);tracem;tracem=SetNext(tracem,&km,&xm,Models)) if(SetMember(k,x,((modelptr) xm)->basis)) PlotBasis((basisptr) x); }} Need2Plot=0; return; } void mouse() { int a,b; char c,dispstr[STRCHAR]; float x,y; fprintf(stderr,"Press any key to stop.\n"); c=0; while(!c) { c=Wait4Mouse(&a,&b); if(!c&&ToPoint(a,b,&x,&y)) { PlotPt(x,y); fprintf(stderr,"%f, %f\n",x,y); }} return; } int tweak(modelptr m) { char c,oldc,dispstr[2*STRCHAR],cmdstr[STRCHAR]; int i,j,np; struct scell *trace; void *k,*item; float **p,*rate,dispx,dispy; char **pname,**bname; int *freeze; basisptr b; if(!m) return 0; np=m->np; if(!np) return 42; p=(float **) calloc(np,sizeof(float *)); /* pointers to parameters */ pname=(char **) calloc(np,sizeof(char *)); /* pointers to pnames */ bname=(char **) calloc(np,sizeof(char *)); /* pointers to basis names */ freeze=(int *) calloc(np,sizeof(int)); /* pointers to frozeness */ rate=allocV(np); if(!p||!pname||!bname||!freeze||!rate) { if(p) free(p); if(pname) free(pname); if(bname) free(bname); if(freeze) free(freeze); if(rate) freeV(rate); return 1; } if(m->covar) { freeM(m->covar); m->covar=NULL; } j=0; for(trace=SetNext(NULL,&k,&item,m->basis);trace;trace=SetNext(trace,&k,&item,m->basis)) for(i=0;i<(b=(basisptr) item)->n;i++) { p[j]=&b->param[i]; pname[j]=b->pname[i]; bname[j]=b->name; freeze[j]=b->freeze[i]; rate[j]=0.01; j++; } j=0; oldc=0; fprintf(stderr,"Press escape to stop tweaking.\n"); while((c=inkey())!=27) { /* escape */ if(!c); /* nothing */ else if(c==28) { /* left arrow */ if(--j<0) j=np-1; oldc=28; } else if(c==29) { /* right arrow */ if(++j>=np) j=0; oldc=29; } else if(c==30) { /* up arrow */ if(*p[j]>0) *p[j]*=(1+rate[j]); else if(*p[j]<0) *p[j]/=(1+rate[j]); else *p[j]=0.001; if(oldc==30) rate[j]*=1.5; else if(oldc==31) rate[j]/=5; UpdateModel(m); oldc=30; } else if(c==31) { /* down arrow */ if(*p[j]>0) *p[j]/=(1+rate[j]); else if(*p[j]<0) *p[j]*=(1+rate[j]); else *p[j]=-0.001; if(oldc==31) rate[j]*=1.5; else if(oldc==30) rate[j]/=5; UpdateModel(m); oldc=31; } else if(c=='-') { /* - sign */ *p[j]=-*p[j]; UpdateModel(m); oldc='-'; } else if(c=='m'||c=='s'||c=='a') { if(c=='m') sprintf(cmdstr,"scale %s",m->name); else if(c=='s'&&m->spec) sprintf(cmdstr,"scale %s",m->spec->name); else if(c=='a') sprintf(cmdstr,"scale"); else cmdstr[0]='\0'; docommand(cmdstr); } if(c||!oldc) { drawplot(); sprintf(dispstr,"%s.%s: %f %s",bname[j],pname[j],*p[j],freeze[j]?"fix":""); ToPoint(10,10,&dispx,&dispy); PlotStr(dispx,dispy,dispstr); if(!oldc) oldc=1; }} Need2Plot=1; free(p); free(pname); free(bname); free(freeze); freeV(rate); return 0; } /* Set management routines */ void ClearSpect(sptr s,int fre) { void *k,*x,*kb,*xb; struct scell *trace,*traceb; modelptr m; if(!s) return; if(SetMember((void *) s->name,(void *) s,Plotlist)) { SetDelete((void *) s->name,(void *) s,Plotlist,0,0); Need2Plot=1; } for(trace=SetNext(NULL,&k,&x,Models);trace;trace=SetNext(trace,&k,&x,Models)) { m=(modelptr)x; if(m->spec==s) m->spec=NULL; else if(m->uncert==s) m->uncert=NULL; else for(traceb=SetNext(NULL,&kb,&xb,m->basis);traceb;traceb=SetNext(traceb,&kb,&xb,m->basis)) if(((basisptr) xb)->spec==s) ClearBasis((basisptr) xb); } if(SetMember((void *) s->name,(void *) s,Spectra)) SetDelete((void *) s->name,(void *) s,Spectra,0,0); if(fre) SpectFree(s); return; } void ClearBasis(basisptr b) { if(!b) return; if(SetDelete((void *) b->name,(void *) b,Plotlist,0,0)) Need2Plot=1; RemoveBasis(b); BasisFree(b); return; } void ClearModel(modelptr m,int fre) { void *k,*x; struct scell *trace; if(!m) return; if(SetMember((void *) m->name,(void *) m,Plotlist)) { SetDelete((void *) m->name,(void *) m,Plotlist,0,0); Need2Plot=1; } if(SetMember((void *) m->name,(void *) m,Models)) SetDelete((void *) m->name,(void *) m,Models,0,0); for(trace=SetNext(NULL,&k,&x,m->basis);trace;trace=SetNext(trace,&k,&x,m->basis)) ClearBasis((basisptr) x); if(Model==m) SetNext(NULL,&k,&((void *) Model),Models); if(fre) ModelFree(m); return; } void ClearString(char *name) { char *str; if(!name) return; str=(char*) SetItem((void*)name,Strings); if(str) SetDelete((void*) name,(void*) str,Strings,1,1); return; } int CreateSpect(sptr s) { sptr sold; void *k,*x,*kb,*xb; struct scell *trace,*traceb; modelptr m; basisptr b; int er; er=0; sold=(sptr) SetItem((void *)s->name,Spectra); if(sold) { strncpy(s->color,sold->color,STRCHAR); if(SetMember((void *) sold->name,(void *) sold,Plotlist)) { SetDelete((void *) sold->name,(void *) sold,Plotlist,0,0); if(SetInsert((void *) s->name,(void *) s,Plotlist)!=1) er=1; Need2Plot=1; } for(trace=SetNext(NULL,&k,&x,Models);trace;trace=SetNext(trace,&k,&x,Models)) { m=(modelptr)x; if(m->spec==sold) { m->spec=s; if(er=CheckMSpec(m)) m->spec=NULL; } if(m->uncert==sold) { m->uncert=s; if(er=CheckUncert(m)) m->uncert=NULL; } for(traceb=SetNext(NULL,&kb,&xb,m->basis);traceb;traceb=SetNext(traceb,&kb,&xb,m->basis)) if(((basisptr) xb)->spec==sold) { b=(basisptr)xb; b->spec=s; if(er=CheckBasis(b,NULL)) ClearBasis(b); }} SetDelete((void *) sold->name,(void *) sold,Spectra,0,0); SpectFree(sold); } if(SetInsert((void *) s->name,(void *) s,Spectra)!=1) er=1; if(er==1) ClearSpect(s,0); return er; } int CreateModel(modelptr m) { modelptr mold; int er; er=0; mold=(modelptr) SetItem((void *) m->name,Models); if(mold) { strncpy(m->color,mold->color,STRCHAR); if(SetMember((void *) mold->name,(void *) mold,Plotlist)) { SetDelete((void *) mold->name,(void *) mold,Plotlist,0,0); if(SetInsert((void *) m->name,(void *) m,Plotlist)!=1) er=1; Need2Plot=1; } ClearModel(mold,1); } if(SetInsert((void *) m->name,(void *) m,Models)!=1) er=1; if(!er) Model=m; if(er) ClearModel(m,0); return er; } int CreateNumber(char *name,float f) { int er; float *fptr; char *ncpy; er=0; fptr=(float *) SetItem((void*)name,Numbers); if(fptr) *fptr=f; else { ncpy=StringCopy(name); if(!ncpy) return 1; fptr=(float*) malloc(sizeof(float)); if(!fptr) {free(ncpy);return 1;} *fptr=f; if(SetInsert((void *)ncpy,(void*)fptr,Numbers)!=1) er=1; } return er; } int CreateString(char *name,char *str) { int er; char *str2,*name2; er=0; str2=(char*) SetItem((void*)name,Strings); if(str2&&strlen(str2)>=strlen(str)) strcpy(str2,str); else { str2=StringCopy(str); if(!str2) return 1; name2=StringCopy(name); if(!name2) {free(str2);return 1;} ClearString(name); if(SetInsert((void*)name2,(void*)str2,Strings)!=1) er=1; } return er; } void ResultFree(struct result ans) { if(ans.temp&&ans.val) { if(ans.type=='F') free(ans.val); else if(ans.type=='S') SpectFree((sptr) ans.val); else if(ans.type=='C') free(ans.val); else if(ans.type=='W') free(ans.val); else if(ans.type=='B') BasisFree((basisptr) ans.val); else if(ans.type=='M') ModelFree((modelptr) ans.val); } return; } int CheckArgs(struct result *ag,int arg,char *str) { int i,len; char a,s; len=strlen(str); for(i=0;is->n-1) i=s->n-1; } ResultFree(memres); if(ans.er) ans.type='?'; else if(!strcmp(mem2,"x")) { ans.temp=1; ans.val=malloc(sizeof(float)); if(!ans.val) ans.er=1; else *((float *) ans.val)=s->x[i]; } else if(!strcmp(mem2,"y")&&!s->cmplx) ans.val=ans.valptr=(void *) &(s->y[i]); else if(!strcmp(mem2,"yr")&&s->cmplx) ans.val=ans.valptr=(void *) &(s->y[2*i]); else if(!strcmp(mem2,"yi")&&s->cmplx) ans.val=ans.valptr=(void *) &(s->y[2*i+1]); else { ans.type='?'; ans.er=23; }} else if(root.type=='S') { // S.mem s=(sptr) root.val; ans.type='C'; if(!strcmp(mem,"name")) ans.val=(void *) s->name; else if(!strcmp(mem,"file")) ans.val=ans.valptr=(void *) s->file; else if(!strcmp(mem,"desc")) ans.val=ans.valptr=(void *) s->desc; else if(!strcmp(mem,"xunit")) ans.val=ans.valptr=(void *) s->xunit; else if(!strcmp(mem,"yunit")) ans.val=ans.valptr=(void *) s->yunit; else if(!strcmp(mem,"color")) ans.val=ans.valptr=(void *) s->color; else if(!strcmp(mem,"n")) { ans.type='F'; ans.temp=1; ans.val=malloc(sizeof(float)); if(!ans.val) {ans.type='?';ans.er=1;} else *((float *) ans.val)=s->n; } else if(!strcmp(mem,"cmplx")) { ans.type='F'; ans.temp=1; ans.val=malloc(sizeof(float)); if(!ans.val) {ans.type='?';ans.er=1;} else *((float *) ans.val)=s->cmplx; } else if(!strcmp(mem,"xmin")||!strcmp(mem,"xmax")||!strcmp(mem,"ymin")||!strcmp(mem,"ymax")) { SpectRange(s,&f1,&f2,&f3,&f4,0); ans.type='F'; ans.temp=1; ans.val=malloc(sizeof(float)); if(!ans.val) {ans.type='?';ans.er=1;} else if(!strcmp(mem,"xmin")) *((float *) ans.val)=f1; else if(!strcmp(mem,"xmax")) *((float *) ans.val)=f2; else if(!strcmp(mem,"ymin")) *((float *) ans.val)=f3; else *((float *) ans.val)=f4; } else { memres=evalexpr(mem); // S.F if(memres.type=='F'&&memres.val) { ans.type='F'; ans.temp=1; ans.val=malloc(sizeof(float)); if(!ans.val) {ans.type='?';ans.er=1;} else *((float *) ans.val)=interpolate1(s->x,s->y,s->n,&i,*((float *) memres.val)); } else {ans.type='?';ans.er=23;} ResultFree(memres); }} else if(root.type=='B'&&mem2||root.type=='F'&&root.valptr&&!mem2) { // B.mem2.mem or param.mem if(root.type=='B') { b=(basisptr) root.val; i=FindBasisParam(&b,NULL,mem2); } else { b=NULL; i=FindBasisParam2(&b,Model,(float*)root.valptr); } if(i<0) ans.er=24; else if(!strcmp(mem,"eqn")) { ans.type='C'; ans.val=ans.valptr=(void *) b->eqn[i]; } else if(!strcmp(mem,"pname")) { ans.type='C'; ans.val=ans.valptr=(void *) b->pname[i]; } else if(!strcmp(mem,"freeze")) { ans.val=malloc(sizeof(float)); if(!ans.val) ans.er=1; else { ans.type='F'; ans.temp=1; *((float *) ans.val)=b->freeze[i]; }} else if(!strcmp(mem,"min")) { ans.type='F'; ans.val=ans.valptr=(void *) &(b->paramlo[i]); } else if(!strcmp(mem,"max")) { ans.type='F'; ans.val=ans.valptr=(void *) &(b->paramhi[i]); } else ans.er=23; } else if(root.type=='B') { // B.mem b=(basisptr) root.val; if(!strcmp(mem,"name")) { ans.type='C'; ans.val=(void *) b->name; } else if(!strcmp(mem,"proc")) { ans.type='C'; ans.val=(void *) b->proc; } else if(!strcmp(mem,"color")) { ans.type='C'; ans.val=ans.valptr=(void *) b->color; } else if(!strcmp(mem,"desc")) { ans.type='C'; ans.val=ans.valptr=(void *) b->desc; } else if(!strcmp(mem,"model")) { ans.type='M'; ans.val=(void *) b->model; } else if(!strcmp(mem,"n")) { ans.temp=1; ans.val=malloc(sizeof(float)); if(!ans.val) ans.er=1; else { ans.type='F'; *((float *) ans.val)=b->n; }} else if(!strcmp(mem,"isspec")) { ans.temp=1; ans.val=malloc(sizeof(float)); if(!ans.val) ans.er=1; else { ans.type='F'; *((float *) ans.val)=b->isspec; }} else if(!strcmp(mem,"spec")) { ans.type='S'; ans.valptr=(void *) &(b->spec); ans.val=*ans.valptr; } else { i=FindBasisParam(&b,NULL,mem); if(i<0) ans.er=24; else { ans.type='F'; ans.val=ans.valptr=(void *) &(b->param[i]); }}} else if((root.type=='M'||root.type=='W'&&!strcmp((char*)root.val,"model"))&&!mem2) { if(root.type=='M') // M.mem or model.mem m=(modelptr) root.val; else if(Model) m=Model; else ans.er=32; if(ans.er); else if((ans.val=SetItem((void *) mem,m->basis))!=NULL) ans.type='B'; else if(!strcmp(mem,"name")) { ans.type='C'; ans.val=(void *) m->name; } else if(!strcmp(mem,"file")) { ans.type='C'; ans.val=ans.valptr=(void *) m->file; } else if(!strcmp(mem,"color")) { ans.type='C'; ans.val=ans.valptr=(void *) m->color; } else if(!strcmp(mem,"spec")) { ans.type='S'; ans.valptr=(void *) &(m->spec); ans.val=*ans.valptr; } else if(!strcmp(mem,"uncert")) { ans.type='S'; ans.valptr=(void *) &(m->uncert); ans.val=*ans.valptr; } else if(!strcmp(mem,"n")) { ans.temp=1; ans.val=malloc(sizeof(float)); if(!ans.val) ans.er=1; else { ans.type='F'; *((float *) ans.val)=m->np; }} else if(!strcmp(mem,"covar")) { ans.temp=1; i=(m->np*m->np+1)*12; ans.val=calloc(i,sizeof(char)); if(!ans.val) ans.er=1; else if(m->covar) { ans.type='C'; sprintM(m->covar,m->np,m->np,"%+1.4e ",(char*) ans.val,i); } else { free(ans.val); ans.er=33; }} else if(!strcmp(mem,"sigma")) { ans.type='F'; ans.val=ans.valptr=(void *) &(m->sigma); } else if(!strcmp(mem,"xmin")) { ans.type='F'; ans.val=ans.valptr=(void *) &(m->xmin); } else if(!strcmp(mem,"xmax")) { ans.type='F'; ans.val=ans.valptr=(void *) &(m->xmax); } else if(!strcmp(mem,"dx")) { ans.type='F'; ans.val=ans.valptr=(void *) &(m->dx); } else ans.er=23; } else ans.er=22; expr[at]='.'; ResultFree(root); return ans; } struct result doword(char *cmd,char *expr) { struct result ans,ag[MAXARG],rlt1; int prn,qte,i,j,len,arg; char s[STRCHAR],*cptr; float num[MAXARG],f1,f2,f3; sptr s1,s2; basisptr b; modelptr m; arg=prn=qte=0; s1=s2=NULL; b=NULL; m=NULL; ans.type='S'; ans.temp=1; ans.val=ans.valptr=NULL; ans.var=ans.er=0; for(i=0;ix[0]; num[1]=(ag[2].type=='F')?*((float*)ag[2].val):s1->x[s1->n-1]; num[2]=(ag[3].type=='F')?*((float*)ag[3].val):0; ans.er=SpectMath2(s1,&(sptr)ans.val,num,3,"copy",""); } else if(ag[0].type=='B') { b=(basisptr)ag[0].val; f1=b->model->xmin; f2=b->model->xmax; f3=b->model->dx; b->model->xmin=(ag[1].type=='F')?*((float*)ag[1].val):f1; b->model->xmax=(ag[2].type=='F')?*((float*)ag[2].val):f2; b->model->dx=(ag[3].type=='F')?*((float*)ag[3].val):f3; ans.er=BasisMath(b,NULL,&(sptr)ans.val,0,"b+k"); b->model->xmin=f1; b->model->xmax=f2; b->model->dx=f3; } else if(ag[0].type=='M') { m=(modelptr)ag[0].val; f1=m->xmin; f2=m->xmax; f3=m->dx; m->xmin=(ag[1].type=='F')?*((float*)ag[1].val):f1; m->xmax=(ag[2].type=='F')?*((float*)ag[2].val):f2; m->dx=(ag[3].type=='F')?*((float*)ag[3].val):f3; ans.er=ModelMath(m,NULL,&(sptr)ans.val,0,"m+k"); m->xmin=f1; m->xmax=f2; m->dx=f3; } else if(ag[0].type=='F') { f1=*((float*)ag[0].val); num[0]=(ag[1].type=='F')?*((float*)ag[1].val):0; num[1]=(ag[2].type=='F')?*((float*)ag[2].val):10; num[2]=(ag[3].type=='F')?*((float*)ag[3].val):0.1; ans.er=SpectMath2(NULL,&s1,num,3,"new","1"); if(!ans.er) ans.er=SpectMath(s1,NULL,&(sptr)ans.val,"s*k",f1); SpectFree(s1); s1=NULL; } else if(ag[0].type=='C') { num[0]=(ag[1].type=='F')?*((float*)ag[1].val):0; num[1]=(ag[2].type=='F')?*((float*)ag[2].val):10; num[2]=(ag[3].type=='F')?*((float*)ag[3].val):0.1; rlt1=evalexpr("x"); if(rlt1.er) ans.er=rlt1.er; else if(rlt1.type=='S'||rlt1.type=='F'||rlt1.type=='B'||rlt1.type=='M') { sprintf(s,"spec(%s,%f,%f,%f)",(char*) ag[0].val,num[0],num[1],num[2]); ans=evalexpr(s); } else if(rlt1.type=='W') { ans.er=SpectMath2(NULL,&s1,num,3,"new","x"); if(!ans.er) { strcpy(s1->name,"x"); CreateSpect(s1); sprintf(s,"spec(%s,%f,%f,%f)",(char*) ag[0].val,num[0],num[1],num[2]); ans=evalexpr(s); ClearSpect(s1,1); s1=NULL; }} else ans.er=18; ResultFree(rlt1); } else ans.er=27; else if(!strcmp(cmd,"merge")&&!(ans.er=CheckArgs(ag,arg,"SS"))) ans.er=SpectMath((sptr) ag[0].val,(sptr) ag[1].val,&(sptr)ans.val,"merge",0); else if(!strcmp(cmd,"exp")&&!(ans.er=CheckArgs(ag,arg,"X"))) if(ag[0].type=='F') { ans.type='F'; ans.val=malloc(sizeof(float)); if(ans.val) *((float *) ans.val)=exp(*((float *) ag[0].val)); else ans.er=1; } else if(ag[0].type=='S') ans.er=SpectMath((sptr) ag[0].val,NULL,&(sptr)ans.val,"exp",0); else if(ag[0].type=='B') ans.er=BasisMath((basisptr) ag[0].val,NULL,&(sptr)ans.val,0,"exp b"); else if(ag[0].type=='M') ans.er=ModelMath((modelptr) ag[0].val,NULL,&(sptr)ans.val,0,"exp m"); else ans.er=27; else if(!strcmp(cmd,"exp10")&&!(ans.er=CheckArgs(ag,arg,"X"))) if(ag[0].type=='F') { ans.type='F'; ans.val=malloc(sizeof(float)); if(ans.val) *((float *) ans.val)=pow(10,*((float *) ag[0].val)); else ans.er=1; } else if(ag[0].type=='S') ans.er=SpectMath((sptr) ag[0].val,NULL,&(sptr)ans.val,"10^s",0); else if(ag[0].type=='B') ans.er=BasisMath((basisptr) ag[0].val,NULL,&(sptr)ans.val,0,"10^b"); else if(ag[0].type=='M') ans.er=ModelMath((modelptr) ag[0].val,NULL,&(sptr)ans.val,0,"10^m"); else ans.er=27; else if(!strcmp(cmd,"ln")&&!(ans.er=CheckArgs(ag,arg,"X"))) if(ag[0].type=='F') { ans.type='F'; ans.val=malloc(sizeof(float)); if(ans.val) *((float *) ans.val)=log(*((float *) ag[0].val)); else ans.er=1; } else if(ag[0].type=='S') ans.er=SpectMath((sptr) ag[0].val,NULL,&(sptr)ans.val,"ln",0); else if(ag[0].type=='B') ans.er=BasisMath((basisptr) ag[0].val,NULL,&(sptr)ans.val,0,"ln b"); else if(ag[0].type=='M') ans.er=ModelMath((modelptr) ag[0].val,NULL,&(sptr)ans.val,0,"ln m"); else ans.er=27; else if(!strcmp(cmd,"log")&&!(ans.er=CheckArgs(ag,arg,"X"))) if(ag[0].type=='F') { ans.type='F'; ans.val=malloc(sizeof(float)); if(ans.val) *((float *) ans.val)=log10(*((float *) ag[0].val)); else ans.er=1; } else if(ag[0].type=='S') ans.er=SpectMath((sptr) ag[0].val,NULL,&(sptr)ans.val,"log",0); else if(ag[0].type=='B') ans.er=BasisMath((basisptr) ag[0].val,NULL,&(sptr)ans.val,0,"log b"); else if(ag[0].type=='M') ans.er=ModelMath((modelptr) ag[0].val,NULL,&(sptr)ans.val,0,"log m"); else ans.er=27; else if(!strcmp(cmd,"sqrt")&&!(ans.er=CheckArgs(ag,arg,"X"))) if(ag[0].type=='F') { ans.type='F'; ans.val=malloc(sizeof(float)); if(ans.val) *((float *) ans.val)=sqrt(*((float *) ag[0].val)); else ans.er=1; } else if(ag[0].type=='S') ans.er=SpectMath((sptr) ag[0].val,NULL,&(sptr)ans.val,"sqrt",0); else if(ag[0].type=='B') ans.er=BasisMath((basisptr) ag[0].val,NULL,&(sptr)ans.val,0,"sqrt b"); else if(ag[0].type=='M') ans.er=ModelMath((modelptr) ag[0].val,NULL,&(sptr)ans.val,0,"sqrt m"); else ans.er=27; else if(!strcmp(cmd,"timesx")&&!(ans.er=CheckArgs(ag,arg,"S"))) ans.er=SpectMath((sptr) ag[0].val,NULL,&(sptr)ans.val,"s*x",0); else if(!strcmp(cmd,"divx")&&!(ans.er=CheckArgs(ag,arg,"S"))) ans.er=SpectMath((sptr) ag[0].val,NULL,&(sptr)ans.val,"s/x",0); else if(!strcmp(cmd,"expx")&&!(ans.er=CheckArgs(ag,arg,"S"))) ans.er=SpectMath((sptr) ag[0].val,NULL,&(sptr)ans.val,"exp x",0); else if(!strcmp(cmd,"exp10x")&&!(ans.er=CheckArgs(ag,arg,"S"))) ans.er=SpectMath((sptr) ag[0].val,NULL,&(sptr)ans.val,"10^x",0); else if(!strcmp(cmd,"lnx")&&!(ans.er=CheckArgs(ag,arg,"S"))) ans.er=SpectMath((sptr) ag[0].val,NULL,&(sptr)ans.val,"ln x",0); else if(!strcmp(cmd,"logx")&&!(ans.er=CheckArgs(ag,arg,"S"))) ans.er=SpectMath((sptr) ag[0].val,NULL,&(sptr)ans.val,"log x",0); else if(!strcmp(cmd,"sqrtx")&&!(ans.er=CheckArgs(ag,arg,"S"))) ans.er=SpectMath((sptr) ag[0].val,NULL,&(sptr)ans.val,"sqrt x",0); else if(!strcmp(cmd,"shiftx")&&!(ans.er=CheckArgs(ag,arg,"SF"))) ans.er=SpectMath((sptr) ag[0].val,NULL,&(sptr)ans.val,"x+k",*((float *) ag[1].val)); else if(!strcmp(cmd,"scalex")&&!(ans.er=CheckArgs(ag,arg,"SF"))) ans.er=SpectMath((sptr) ag[0].val,NULL,&(sptr)ans.val,"x*k",*((float *) ag[1].val)); else if(!strcmp(cmd,"powx")&&!(ans.er=CheckArgs(ag,arg,"SF"))) ans.er=SpectMath((sptr) ag[0].val,NULL,&(sptr)ans.val,"x^k",*((float *) ag[1].val)); else if(!strcmp(cmd,"deriv1")&&!(ans.er=CheckArgs(ag,arg,"S"))) ans.er=SpectMath((sptr) ag[0].val,NULL,&(sptr)ans.val,"deriv",0); else if(!strcmp(cmd,"deriv")&&!(ans.er=CheckArgs(ag,arg,"S"))) ans.er=SpectMath((sptr) ag[0].val,NULL,&(sptr)ans.val,"deriv",0); else if(!strcmp(cmd,"deriv2")&&!(ans.er=CheckArgs(ag,arg,"S"))) ans.er=SpectMath((sptr) ag[0].val,NULL,&(sptr)ans.val,"deriv2",0); else if(!strcmp(cmd,"xderiv1")&&!(ans.er=CheckArgs(ag,arg,"S"))) ans.er=SpectMath((sptr) ag[0].val,NULL,&(sptr)ans.val,"xderiv1",0); else if(!strcmp(cmd,"xderiv")&&!(ans.er=CheckArgs(ag,arg,"S"))) ans.er=SpectMath((sptr) ag[0].val,NULL,&(sptr)ans.val,"xderiv1",0); else if(!strcmp(cmd,"xderiv2")&&!(ans.er=CheckArgs(ag,arg,"S"))) ans.er=SpectMath((sptr) ag[0].val,NULL,&(sptr)ans.val,"xderiv2",0); else if(!strcmp(cmd,"integral")&&!(ans.er=CheckArgs(ag,arg,"Sf"))) { s1=(sptr)ag[0].val; if(s1->x[0]<=0&&s1->x[s1->n-1]>=0) f1=0; else f1=s1->x[0]; f1=(ag[1].type=='F')?*((float*)ag[1].val):f1; ans.er=SpectMath((sptr) ag[0].val,NULL,&(sptr)ans.val,"integ",f1); } else if(!strcmp(cmd,"integrate")&&!(ans.er=CheckArgs(ag,arg,"Sff"))) { s1=(sptr)ag[0].val; f1=(ag[1].type=='F')?*((float*)ag[1].val):s1->x[0]; ans.er=SpectMath((sptr) ag[0].val,NULL,&s2,"integ",f1); f2=(ag[2].type=='F')?*((float*)ag[2].val):s2->x[s2->n-1]; j=-2; f3=interpolate1(s2->x,s2->y,s2->n,&j,f2); SpectFree(s2); s2=NULL; ans.type='F'; ans.val=(float*) malloc(sizeof(float)); if(!ans.val) ans.er=1; else *((float*)ans.val)=f3; } else if(!strcmp(cmd,"smooth")&&!(ans.er=CheckArgs(ag,arg,"SF"))) ans.er=SpectMath((sptr) ag[0].val,NULL,&(sptr)ans.val,"smooth",*((float *) ag[1].val)); else if(!strcmp(cmd,"complex")&&!(ans.er=CheckArgs(ag,arg,"Ss"))) { s1=(sptr)ag[0].val; s2=(ag[1].type=='S')?(sptr)ag[1].val:NULL; ans.er=SpectMath(s1,s2,&(sptr)ans.val,"complex",0); } else if(!strcmp(cmd,"real")&&!(ans.er=CheckArgs(ag,arg,"S"))) ans.er=SpectMath((sptr) ag[0].val,NULL,&(sptr)ans.val,"real",0); else if(!strcmp(cmd,"imag")&&!(ans.er=CheckArgs(ag,arg,"S"))) ans.er=SpectMath((sptr) ag[0].val,NULL,&(sptr)ans.val,"imag",0); else if(!strcmp(cmd,"fourier")&&!(ans.er=CheckArgs(ag,arg,"Sf"))) { s1=(sptr) ag[0].val; f1=(ag[1].type=='F')?*((float*) ag[1].val):FTStartDflt(s1->x,s1->n); ans.er=SpectMath((sptr) ag[0].val,NULL,&(sptr)ans.val,"fourier",f1); } else if(!strcmp(cmd,"invfourier")&&!(ans.er=CheckArgs(ag,arg,"Sf"))) { s1=(sptr) ag[0].val; f1=(ag[1].type=='F')?*((float*) ag[1].val):FTStartDflt(s1->x,s1->n); ans.er=SpectMath((sptr) ag[0].val,NULL,&(sptr)ans.val,"invfourier",f1); } else if(!strcmp(cmd,"ftpower")&&!(ans.er=CheckArgs(ag,arg,"S"))) ans.er=SpectMath((sptr) ag[0].val,NULL,&(sptr)ans.val,"ftpower",0); else if(!strcmp(cmd,"fft")&&!(ans.er=CheckArgs(ag,arg,"Sf"))) { s1=(sptr) ag[0].val; f1=(ag[1].type=='F')?*((float*) ag[1].val):FTStartDflt(s1->x,s1->n); ans.er=SpectMath((sptr) ag[0].val,NULL,&(sptr)ans.val,"fft",f1); } else if(!strcmp(cmd,"invfft")&&!(ans.er=CheckArgs(ag,arg,"Sf"))) { s1=(sptr) ag[0].val; f1=(ag[1].type=='F')?*((float*) ag[1].val):FTStartDflt(s1->x,s1->n); ans.er=SpectMath((sptr) ag[0].val,NULL,&(sptr)ans.val,"invfft",f1); } else if(!strcmp(cmd,"hankel")&&!(ans.er=CheckArgs(ag,arg,"Sf"))) { f1=(ag[1].type=='F')?*((float*) ag[1].val):10; ans.er=SpectMath((sptr) ag[0].val,NULL,&(sptr)ans.val,"hankel",f1); } else if(!strcmp(cmd,"noise")&&!(ans.er=CheckArgs(ag,arg,"Sf"))) { f1=(ag[1].type=='F')?*((float*) ag[1].val):1; ans.er=SpectMath((sptr) ag[0].val,NULL,&(sptr)ans.val,"noise",f1); } else if(!strcmp(cmd,"convolve")&&!(ans.er=CheckArgs(ag,arg,"SS"))) ans.er=SpectMath((sptr)ag[0].val,(sptr)ag[1].val,&(sptr)ans.val,"convolve",0); else if(!strcmp(cmd,"realft")&&!(ans.er=CheckArgs(ag,arg,"Sf"))) { ans.er=SpectMath((sptr) ag[0].val,NULL,&s1,"complex",0); if(ans.er); else f1=(ag[1].type=='F')?*((float*) ag[1].val):FTStartDflt(s1->x,s1->n); if(!ans.er) ans.er=SpectMath(s1,NULL,&s2,"fourier",f1); if(!ans.er) ans.er=SpectMath(s2,NULL,&(sptr)ans.val,"real",0); SpectFree(s1); SpectFree(s2); s1=s2=NULL; } else if(!strcmp(cmd,"realift")&&!(ans.er=CheckArgs(ag,arg,"Sf"))) { ans.er=SpectMath((sptr) ag[0].val,NULL,&s1,"complex",0); if(ans.er); else f1=(ag[1].type=='F')?*((float*) ag[1].val):FTStartDflt(s1->x,s1->n); if(!ans.er) ans.er=SpectMath(s1,NULL,&s2,"invfourier",f1); if(!ans.er) ans.er=SpectMath(s2,NULL,&(sptr)ans.val,"real",0); SpectFree(s1); SpectFree(s2); s1=s2=NULL; } else if(!strcmp(cmd,"input")&&!(ans.er=CheckArgs(ag,arg,"C"))) { fprintf(stderr,"%s?",(char *) ag[0].val); scanf("%s",s); ans=evalexpr(s); } else if(!strcmp(cmd,"write")&&!(ans.er=CheckArgs(ag,arg,"C."))) { ans.type='F'; ans.val=malloc(sizeof(float)); if(!ans.val) ans.er=1; s[0]='\0'; for(i=1;i=0) { expr[i]='\0'; ans=doassign(expr,expr+i+1); expr[i]='='; return ans; } i=StrrChrPQuote(expr,'+'); if(i>=0) return dosymbol(expr,i); i=StrrChrPQuote(expr,'-'); if(i>=0) return dosymbol(expr,i); i=StrrChrPQuote(expr,'*'); if(i>=0) return dosymbol(expr,i); i=StrrChrPQuote(expr,'/'); if(i>=0) return dosymbol(expr,i); i=StrrChrPQuote(expr,'^'); if(i>=0) return dosymbol(expr,i); i=StrrChrPQuote(expr,'.'); if(i>=0) return dodots(expr,i); if(expr[0]=='('&&expr[len-1]==')') { /* ( ) */ expr[0]=expr[len-1]='\0'; ans=evalexpr(expr+1); expr[0]='('; expr[len-1]=')'; return ans; } if(expr[0]=='"'&&expr[len-1]=='"') { /* " " */ expr[len-1]='\0'; if(strchr(expr+1,'"')) { expr[len-1]='"'; ans.er=30; return ans; } ans.type='C'; ans.temp=1; ans.val=(void*) StringCopy(expr+1); expr[len-1]='"'; if(!ans.val) {ans.type='?';ans.er=1;} return ans; } if(expr[len-1]==')') { /* word( ) */ i=strchr(expr,'(')-expr; expr[i]=expr[len-1]='\0'; ans=doword(expr,expr+i+1); expr[i]='('; expr[len-1]=')'; return ans; } if(strpbrk(expr," ()\"")) {ans.er=31;return ans;} /* spare delimiters */ ans.var=1; if((ans.val=SetItem((void *) expr,Spectra))!=NULL) ans.type='S'; else if((ans.val=SetItem((void *) expr,Models))!=NULL) ans.type='M'; else if((ans.val=SetItem((void *) expr,Numbers))!=NULL) ans.type='F'; else if((ans.val=SetItem((void *) expr,Strings))!=NULL) ans.type='C'; else if(Model&&(ans.val=SetItem((void *) expr,Model->basis))!=NULL) { ans.var=0; ans.type='B'; } else if ((i=FindBasisParam(&b,Model,expr))>=0) { ans.var=0; ans.type='F'; ans.val=ans.valptr=(void*) &(b->param[i]); } else { ans.type='W'; ans.temp=1; ans.var=0; ans.val=(void *) StringCopy(expr); if(!ans.val) {ans.er=1;ans.type='?';}} return ans; } struct result doassign(char *lhs,char *rhs) { struct result left,right; void *copy; int er; er=0; // printf("doassign: '%s' = '%s'\n",lhs,rhs); left=evalexpr(lhs); right=evalexpr(rhs); copy=NULL; if(right.er) er=right.er; else if(left.er) er=left.er; else if(right.type=='?') er=999; else if(left.type=='?') er=999; else if(left.type==' ') er=35; else if(right.type==' ') er=36; else if(!right.val) er=36; else if(left.type=='W'&&!left.val) er=35; else if(left.type=='W'&&!strcmp((char*)left.val,"model")) { // W= if(right.type=='M'&&!right.temp) Model=(modelptr) right.val; else if(right.type=='M') er=36; else er=37; } else if(left.type=='W'&&!strcmp((char*)left.val,"null")) er=35; else if(left.type=='W'&&okname((char*)left.val)) { if(right.type=='S'&&right.temp) { strncpy(((sptr)right.val)->name,(char*)left.val,STRCHAR); er=CreateSpect((sptr) right.val); if(!er) right.temp=0; } else if(right.type=='S') { er=SpectMath((sptr) right.val,NULL,&(sptr)copy,"copy",0); if(!er) { strncpy(((sptr) copy)->name,(char*)left.val,STRCHAR); er=CreateSpect((sptr) copy); }} else if(right.type=='F') er=CreateNumber((char*)left.val,*((float*)right.val)); else if(right.type=='C') er=CreateString((char*)left.val,(char*)right.val); else if(right.type=='M'&&right.temp) { strncpy(((modelptr) right.val)->name,(char*) left.val,STRCHAR); er=CreateModel((modelptr) right.val); if(!er) right.temp=0; } else if(right.type=='M') { copy=(void*) ModelCopy((modelptr) right.val); if(copy) { strncpy(((modelptr) copy)->name,(char*) left.val,STRCHAR); er=CreateModel((modelptr) copy); } else er=1; } else if(right.type=='W'&&!strcmp((char*)right.val,"model")) { if(!Model) er=32; else { copy=(void*) ModelCopy(Model); if(copy) { strncpy(((modelptr) copy)->name,(char*) left.val,STRCHAR); er=CreateModel((modelptr) copy); }}} else er=36; } else if(left.type=='W') er=35; else if(left.type=='S') { // S= if(left.temp) er=35; else if(left.var&&right.type=='S'&&right.temp) { strcpy(((sptr) right.val)->name,((sptr) left.val)->name); er=CreateSpect((sptr) right.val); if(!er) right.temp=0; } else if(left.var&&right.type=='S') { er=SpectMath((sptr) right.val,NULL,&(sptr)copy,"copy",0); if(!er) { strcpy(((sptr) copy)->name,((sptr) left.val)->name); er=CreateSpect((sptr) copy); }} else if(left.var) er=37; else if(left.valptr&&right.type=='S'&&!right.temp) *left.valptr=right.val; else if(left.valptr&&right.type=='S') er=36; else if(left.valptr&&right.type=='W'&&!strcmp((char*)right.val,"null")) *left.valptr=NULL; else er=37; } else if(left.type=='F') { // F= if(left.temp) er=35; else if(right.type!='F') er=37; else if(left.var&&left.val) *((float*) left.val)=*((float *) right.val); else if(left.var) er=999; else if(left.valptr) *((float*) left.valptr)=*((float*) right.val); else er=35; } else if(left.type=='C') { // C= if(left.temp) er=35; else if(right.type!='C') er=37; else if(left.var) { copy=SetKey(left.val,Strings); if(copy) er=CreateString((char*)copy,(char*)right.val); else er=999; } else if(left.valptr) { strncpy((char*)left.valptr,(char*)right.val,STRCHAR); } else er=35; } else if(left.type=='B') { // B= if(left.temp) er=35; else if(right.type=='B') { RemoveBasis((basisptr)left.val); copy=(void*) AddBasis((basisptr)right.val,NULL,((basisptr)right.val)->spec,((basisptr)left.val)->model); if(copy) strcpy((char*)copy,((basisptr)left.val)->name); else er=1; BasisFree((basisptr)left.val); } else er=37; } else if(left.type=='M') { // M= if(left.temp) er=35; else if(left.var&&right.type=='M'&&right.temp) { strcpy(((modelptr)right.val)->name,((modelptr)left.val)->name); er=CreateModel((modelptr) right.val); if(!er) right.temp=0; } else if(left.var&&right.type=='M') { copy=(void *) ModelCopy((modelptr) right.val); if(copy) { strcpy(((modelptr) copy)->name,((modelptr) left.val)->name); er=CreateModel((modelptr) copy); }} else if(left.var&&right.type=='W'&&!strcmp((char*)right.val,"model")) { copy=(void *) ModelCopy(Model); if(copy) { strcpy(((modelptr) copy)->name,((modelptr) left.val)->name); er=CreateModel((modelptr) copy); }} else if(left.var) er=37; else if(left.valptr&&right.type=='M'&&!right.temp) *left.valptr=right.val; else if(left.valptr&&right.type=='M') er=36; else if(left.valptr&&right.type=='W'&&!strcmp((char*)right.val,"null")) *left.valptr=NULL; else er=37; } else er=999; ResultFree(left); if(er) { ResultFree(right); right.type='?'; right.er=er; } else Need2Plot=Need2Update=1; return right; } int docommand(char *cmd) { void *k,*x,*k2,*x2; struct result ans; int items,i,j,er,ok,lett; char op[STRCHAR],*lhs; char str1[STRCHAR]; char *rhs,*cmd2; float f1,f2,f3,f4,f5,f6; basisptr base; struct scell *trace,*trace2; er=0; items=sscanf(cmd,"%s",&op); lett=strlen(op); ans=evalexpr(cmd+lett); if(ans.er) return ans.er; if(!items||!strlen(cmd)||!lett); else if(!strncmp(op,"help",lett)) /* OP: help */ printf("No.\n"); else if(!strcmp(op,"exit")) /* OP: exit */ er=-1; else if(!strcmp(op,"log")) /* OP: log */ Logcmd=1; else if(!strcmp(op,"unlog")) /* OP: unlog */ Logcmd=0; else if(op[0]=='/'); /* OP: / */ else if(!strcmp(op,"kill")) { /* OP: kill */ if(ans.type=='C'&&ans.val) { fprintf(stderr,"File %s will be killed from disk. Are you sure?",(char*)ans.val); items=scanf("%s",str1); if(items&&str1[0]=='y') er=KillData((char*)ans.val); else er=2; } else er=38; } else if(!strncmp(op,"exec",lett)) { /* OP: exec */ if(ans.type=='C'&&ans.val) er=docommand((char*)ans.val); else er=38; } else if(!strncmp(op,"eval",lett)) { /* op: eval */ printf("type: %c, val: %lx, valptr: %lx, temp: %i, var: %i\n",ans.type,ans.val,ans.valptr,ans.temp,ans.var); if(ans.type=='S') printf("spectrum name: %s\n",((sptr) ans.val)->name); else if(ans.type=='F') printf("float value: %f\n",*((float *) ans.val)); else if(ans.type=='W') printf("word: %s\n",((char *) ans.val)); else if(ans.type=='C') printf("string: #%s#\n",((char *) ans.val)); else if(ans.type=='B') printf("basis function name: %s\n",((basisptr) ans.val)->name); else if(ans.type=='M') printf("model name: %s\n",((modelptr) ans.val)->name); else er=38; } else if(!strncmp(op,"clear",lett)) { /* OP: clear */ if(!ans.val) er=39; else if(!ans.var&&(ans.type=='S'||ans.type=='M'||ans.type=='F'||ans.type=='C')) er=41; else if(ans.type=='S') ClearSpect((sptr) ans.val,1); else if(ans.type=='B') ClearBasis((basisptr) ans.val); else if(ans.type=='M') ClearModel((modelptr) ans.val,1); else if(ans.type=='F') SetDelete(SetKey(ans.val,Numbers),ans.val,Numbers,1,1); else if(ans.type=='C') SetDelete(SetKey(ans.val,Strings),ans.val,Strings,1,1); else if(ans.type=='W') { if(!strcmp((char *) ans.val,"model")&&Model) ClearModel(Model,1); else if(!strcmp((char *) ans.val,"model")) er=32; else if(!strcmp((char *) ans.val,"spectra")) for(trace=SetNext(NULL,&k,&x,Spectra);trace;trace=SetNext(trace,&k,&x,Spectra)) ClearSpect((sptr) x,1); else if(!strcmp((char *) ans.val,"models")) for(trace=SetNext(NULL,&k,&x,Models);trace;trace=SetNext(trace,&k,&x,Models)) ClearModel((modelptr) x,1); else if(!strcmp((char *) ans.val,"numbers")) SetNull(Numbers,1,1); else if(!strcmp((char *) ans.val,"strings")) SetNull(Strings,1,1); else if(!strcmp((char *) ans.val,"plot")) SetNull(Plotlist,0,0); else if(!strcmp((char *) ans.val,"all")) { for(trace=SetNext(NULL,&k,&x,Models);trace;trace=SetNext(trace,&k,&x,Models)) ClearModel((modelptr) x,1); for(trace=SetNext(NULL,&k,&x,Spectra);trace;trace=SetNext(trace,&k,&x,Spectra)) ClearSpect((sptr) x,1); SetNull(Numbers,1,1); SetNull(Strings,1,1); } else er=31; } else er=38; Need2Plot=Need2Update=1; } else if(!strncmp(op,"scale",lett)) { /* OP: scale */ GetScales(&f1,&f2,&f3,&f4); i=0; if(ans.type==' ') for(trace=SetNext(NULL,&k,&x,Plotlist);trace;trace=SetNext(trace,&k,&x,Plotlist)) { if(SetMember(k,x,Models)) ModelRange((modelptr) x,&f1,&f2,&f3,&f4,i++); else if(SetMember(k,x,Spectra)) SpectRange((sptr) x,&f1,&f2,&f3,&f4,i++); } else if(!ans.val) er=39; else if(ans.type=='S') SpectRange((sptr) ans.val,&f1,&f2,&f3,&f4,0); else if(ans.type=='M') ModelRange((modelptr) ans.val,&f1,&f2,&f3,&f4,0); else if(ans.type=='B') BasisRange((basisptr) ans.val,&f1,&f2,&f3,&f4,0); else if(ans.type=='F') { f5=f1-(f2-f1)*(*((float *) ans.val)-1)/2; f2=f2+(f2-f1)*(*((float *) ans.val)-1)/2; f1=f5; f5=f3-(f4-f3)*(*((float *) ans.val)-1)/2; f4=f4+(f4-f3)*(*((float *) ans.val)-1)/2; f3=f5; } else if(ans.type=='W') { if(!strcmp((char*) ans.val,"model")&&Model) ModelRange(Model,&f1,&f2,&f3,&f4,0); else if(!strcmp((char*) ans.val,"model")) er=32; else if(!strcmp((char*) ans.val,"models")&&Model) for(trace=SetNext(NULL,&k,&x,Plotlist);trace;trace=SetNext(trace,&k,&x,Plotlist)) { if(SetMember(k,x,Models)) ModelRange((modelptr) x,&f1,&f2,&f3,&f4,i++); } else if(!strcmp((char*) ans.val,"models")) er=32; else if(!strcmp((char*) ans.val,"spectra")) for(trace=SetNext(NULL,&k,&x,Plotlist);trace;trace=SetNext(trace,&k,&x,Plotlist)) { if(SetMember(k,x,Spectra)) SpectRange((sptr) x,&f1,&f2,&f3,&f4,i++); } else if(!strcmp((char*) ans.val,"all")) for(trace=SetNext(NULL,&k,&x,Plotlist);trace;trace=SetNext(trace,&k,&x,Plotlist)) { if(SetMember(k,x,Models)) ModelRange((modelptr) x,&f1,&f2,&f3,&f4,i++); else if(SetMember(k,x,Spectra)) SpectRange((sptr) x,&f1,&f2,&f3,&f4,i++); } else if(!strcmp((char*) ans.val,"y")) for(trace=SetNext(NULL,&k,&x,Plotlist);trace;trace=SetNext(trace,&k,&x,Plotlist)) { if(SetMember(k,x,Models)) ModelRange((modelptr) x,&f5,&f6,&f3,&f4,i++); else if(SetMember(k,x,Spectra)) SpectRange((sptr) x,&f5,&f6,&f3,&f4,i++); } else if(!strcmp((char*) ans.val,"x")) for(trace=SetNext(NULL,&k,&x,Plotlist);trace;trace=SetNext(trace,&k,&x,Plotlist)) { if(SetMember(k,x,Models)) ModelRange((modelptr) x,&f1,&f2,&f5,&f6,i++); else if(SetMember(k,x,Spectra)) SpectRange((sptr) x,&f1,&f2,&f5,&f6,i++); } else er=31; } else er=38; if(f1==f2) {f1-=0.0001;f2+=0.0001;} if(f3==f4) {f3-=0.0001;f4+=0.0001;} SetScales(f1,f2,f3,f4); Need2Plot=1; } else if(!strncmp(op,"save",lett)) { /* OP: save */ if(!ans.val) er=39; else if(ans.type=='S') SaveSpect((sptr) ans.val); else if(ans.type=='M') SaveModel((modelptr) ans.val); else if(ans.type=='W') { if(!strcmp((char*)ans.val,"model")&&Model) SaveModel(Model); else if(!strcmp((char*) ans.val,"model")) er=32; else if(!strcmp((char*) ans.val,"spectra")) for(trace=SetNext(NULL,&k,&x,Spectra);trace;trace=SetNext(trace,&k,&x,Spectra)) SaveSpect((sptr) x); else if(!strcmp((char*) ans.val,"models")) for(trace=SetNext(NULL,&k,&x,Models);trace;trace=SetNext(trace,&k,&x,Models)) SaveModel((modelptr) x); else if(!strcmp((char*) ans.val,"all")) { for(trace=SetNext(NULL,&k,&x,Spectra);trace;trace=SetNext(trace,&k,&x,Spectra)) SaveSpect((sptr) x); for(trace=SetNext(NULL,&k,&x,Models);trace;trace=SetNext(trace,&k,&x,Models)) SaveModel((modelptr) x); } else er=31; } else er=38; } else if(!strncmp(op,"plot",lett)) { /* OP: plot */ if(ans.type==' ') drawplot(); else if(!ans.val) er=39; else if(ans.type=='W') { if(!strcmp((char*)ans.val,"model")&&Model) SetInsert((void *) (Model)->name,(void *) Model,Plotlist); else if(!strcmp((char*)ans.val,"model")) er=32; else if(!strcmp((char *) ans.val,"all")) { for(trace=SetNext(NULL,&k,&x,Spectra);trace;trace=SetNext(trace,&k,&x,Spectra)) SetInsert(k,x,Plotlist); for(trace=SetNext(NULL,&k,&x,Models);trace;trace=SetNext(trace,&k,&x,Models)) SetInsert(k,x,Plotlist); } else er=31; } else if(ans.temp) er=41; else if(ans.type=='S') SetInsert((void *) ((sptr) ans.val)->name,ans.val,Plotlist); else if(ans.type=='B') SetInsert((void *) ((basisptr) ans.val)->name,ans.val,Plotlist); else if(ans.type=='M') SetInsert((void *) ((modelptr) ans.val)->name,ans.val,Plotlist); else er=38; Need2Plot=1; } else if(!strncmp(op,"unplot",lett)) { /* OP: unplot */ if(!ans.val) er=39; else if(ans.type=='W') { if(!strcmp((char*) ans.val,"model")&&Model) SetDelete((void*) (Model)->name,(void*) Model,Plotlist,0,0); else if(!strcmp((char *) ans.val,"model")) er=32; else if(!strcmp((char *) ans.val,"all")) SetNull(Plotlist,0,0); else er=31; } else if(ans.type=='S'&&!ans.temp) SetDelete((void *) ((sptr) ans.val)->name,ans.val,Plotlist,0,0); else if(ans.type=='B'&&!ans.temp) SetDelete((void *) ((basisptr) ans.val)->name,ans.val,Plotlist,0,0); else if(ans.type=='M'&&!ans.temp) SetDelete((void *) ((modelptr) ans.val)->name,ans.val,Plotlist,0,0); else er=38; Need2Plot=1; } else if(!strncmp(op,"print",lett)||!strcmp(op,"?")) { /* OP: print, ? */ if(ans.type==' ') printf("\n"); else if(!ans.val) er=39; else if(ans.type=='S') TypeSpect((sptr) ans.val); else if(ans.type=='M') TypeModel((modelptr) ans.val); else if(ans.type=='B') TypeBasis((basisptr) ans.val); else if(ans.type=='F') printf("%f\n",*((float *) ans.val)); else if(ans.type=='C') printf("%s\n",(char *) ans.val); else if(ans.type=='W') { if(!strcmp((char *) ans.val,"spectra")) { printf("%i spectra loaded.\n",SetCard(Spectra)); for(trace=SetNext(NULL,&k,&x,Spectra);trace;trace=SetNext(trace,&k,&x,Spectra)) printf("%s\t\t%s\n",(char*) k,((sptr) x)->desc); } else if(!strcmp((char *) ans.val,"basis")) TypeAllBasis(); else if(!strcmp((char *) ans.val,"models")) { printf("%i models defined.\n",SetCard(Models)); for(trace=SetNext(NULL,&k,&x,Models);trace;trace=SetNext(trace,&k,&x,Models)) printf("%s for %s\n",(char*) k,((modelptr)x)->spec?((modelptr)x)->spec->name:"NULL"); } else if(!strcmp((char*) ans.val,"numbers")) { printf("%i numbers defined.\n",SetCard(Numbers)); for(trace=SetNext(NULL,&k,&x,Numbers);trace;trace=SetNext(trace,&k,&x,Numbers)) printf("%s = %f\n",(char*) k,*((float*) x)); } else if(!strcmp((char *) ans.val,"strings")) { printf("%i strings defined.\n",SetCard(Strings)); for(trace=SetNext(NULL,&k,&x,Strings);trace;trace=SetNext(trace,&k,&x,Strings)) printf("%s = %s\n",(char *) k,(char *) x); } else if(!strcmp((char *) ans.val,"all")) { printf("%i spectra loaded.\n",SetCard(Spectra)); for(trace=SetNext(NULL,&k,&x,Spectra);trace;trace=SetNext(trace,&k,&x,Spectra)) printf("%s\t\t%s\n",(char *) k,((sptr) x)->desc); printf("%i models defined.\n",SetCard(Models)); for(trace=SetNext(NULL,&k,&x,Models);trace;trace=SetNext(trace,&k,&x,Models)) printf("%s for %s\n",(char*) k,((modelptr)x)->spec?((modelptr)x)->spec->name:"NULL"); printf("%i numbers defined.\n",SetCard(Numbers)); for(trace=SetNext(NULL,&k,&x,Numbers);trace;trace=SetNext(trace,&k,&x,Numbers)) printf("%s = %f\n",(char*) k,*((float*) x)); printf("%i strings defined.\n",SetCard(Strings)); for(trace=SetNext(NULL,&k,&x,Strings);trace;trace=SetNext(trace,&k,&x,Strings)) printf("%s = %s\n",(char*) k,(char*) x); } else if(!strcmp((char *) ans.val,"model")&&Model) TypeModel(Model); else if(!strcmp((char *) ans.val,"model")) er=32; else if(!strcmp((char *) ans.val,"params")&&Model) { for(trace=SetNext(NULL,&k,&x,Model->basis);trace;trace=SetNext(trace,&k,&x,Model->basis)) for(i=0;i<((basisptr) x)->n;i++) printf("%s.%s=%f\n",((basisptr)x)->name,((basisptr)x)->pname[i],((basisptr)x)->param[i]); } else if(!strcmp((char *) ans.val,"params")) er=32; else if(!strcmp((char *) ans.val,"plot")) { printf("%i things plotted.\n",SetCard(Plotlist)); for(trace=SetNext(NULL,&k,&x,Plotlist);trace;trace=SetNext(trace,&k,&x,Plotlist)) printf("%s\n",(char *) k); } else if(!strcmp((char *) ans.val,"scale")) { GetScales(&f1,&f2,&f3,&f4); printf("Scale limits: %f %f %f %f\n",f1,f2,f3,f4); } else er=31; } else er=38; } else if(!strncmp(op,"add",lett)) { /* OP: add */ base=NULL; if(!ans.val) er=39; else if(!Model) er=32; else if(ans.type=='B') base=AddBasis((basisptr)ans.val,((basisptr)ans.val)->proc,((basisptr)ans.val)->spec,Model); else if(ans.type=='S') { sprintf(str1,"%s:0",((sptr)ans.val)->name); if(SetItem((void*)str1,Model->basis)) er=43; else { base=AddBasis(NULL,"spectrum",(sptr)ans.val,Model); if(base) strncpy(base->name,str1,STRCHAR); else er=1; }} else if(ans.type=='W') { base=AddBasis(NULL,(char*)ans.val,NULL,Model); if(!base) er=40; } else if(ans.type=='M'&&(modelptr)ans.val!=Model) for(trace=SetNext(NULL,&k,&x,((modelptr)ans.val)->basis);trace;trace=SetNext(trace,&k,&x,((modelptr)ans.val)->basis)) base=AddBasis((basisptr)x,((basisptr)x)->proc,((basisptr)x)->spec,Model); else if(ans.type=='M') er=43; else er=38; if(!er&&!base) er=1; if(base&&Model&&Model->covar) { freeM(Model->covar); Model->covar=NULL; } Need2Plot=Need2Update=1; } else if(!strncmp(op,"remove",lett)) { /* OP: remove */ if(!Model) er=32; else if(!ans.val) er=39; else if(ans.type=='B') ClearBasis((basisptr)ans.val); else er=38; if(Model&&Model->covar) { freeM(Model->covar); Model->covar=NULL; } Need2Plot=Need2Update=1; } else if(!strncmp(op,"tweak",lett)) { /* OP: tweak */ if(!Model) er=32; else if(ans.type==' ') er=tweak(Model); else if(!ans.val) er=39; else if(ans.type=='M') er=tweak((modelptr)ans.val); else if(ans.type=='W') { if(!strcmp((char*)ans.val,"model")) er=tweak(Model); else er=31; } else er=38; Need2Plot=Need2Update=1; } else if(!strncmp(op,"mouse",lett)) { /* OP: mouse */ mouse(); } else if(!strncmp(op,"fit",lett)) { /* OP: fit */ if(!Model) er=32; else if(ans.type==' ') er=LMFit(Model); else if(!ans.val) er=39; else if(ans.type=='M') er=LMFit((modelptr)ans.val); else if(ans.type=='W'&&!strcmp((char*)ans.val,"model")) er=LMFit(Model); else if(ans.type=='W'&&!strcmp((char*)ans.val,"linear")) er=LinearFit(Model); else if(ans.type=='W'&&!strcmp((char*)ans.val,"random")) er=RandomFit(Model); else if(ans.type=='W'&&!strcmp((char*)ans.val,"LM")) er=LMFit(Model); else if(ans.type=='W'&&!strcmp((char*)ans.val,"all")) er=RandMultiFit(Models); else er=38; Need2Plot=Need2Update=1; } else if(!strncmp(op,"unfit",lett)) { /* OP: unfit */ if(!Model) er=32; else if(ans.type==' ') unfit(Model); else if(!ans.val) er=39; else if(ans.type=='M') unfit((modelptr)ans.val); else if(ans.type=='W'&&!strcmp((char*)ans.val,"model")) unfit(Model); else er=38; Need2Plot=Need2Update=1; } else if(!strncmp(op,"fix",lett)||!strncmp(op,"free",lett)) { /* OP: fix/free */ j=strncmp(op,"fix",lett)?0:1; if(!ans.val) er=39; if(ans.type=='B') { base=(basisptr) ans.val; for(i=0;in;i++) base->freeze[i]=j; } else if(ans.type=='M') { for(trace=SetNext(NULL,&k,&x,((modelptr)ans.val)->basis);trace;trace=SetNext(trace,&k,&x,((modelptr)ans.val)->basis)) for(i=0;i<((basisptr)x)->n;i++) ((basisptr)x)->freeze[i]=j; } else if(ans.type=='W'&&!strcmp((char*)ans.val,"model")&&Model) { for(trace=SetNext(NULL,&k,&x,Model->basis);trace;trace=SetNext(trace,&k,&x,Model->basis)) for(i=0;i<((basisptr) x)->n;i++) ((basisptr) x)->freeze[i]=j; } else if(ans.type=='W'&&(!strcmp((char*)ans.val,"models")||!strcmp((char*)ans.val,"all"))) { for(trace2=SetNext(NULL,&k2,&x2,Models);trace2;trace2=SetNext(trace2,&k2,&x2,Models)) for(trace=SetNext(NULL,&k,&x,((modelptr)x2)->basis);trace;trace=SetNext(trace,&k,&x,((modelptr)x2)->basis)) for(i=0;i<((basisptr)x)->n;i++) ((basisptr)x)->freeze[i]=j; } else if(ans.type=='F'&&ans.valptr) { ok=1; for(trace2=SetNext(NULL,&k2,&x2,Models);trace2&&ok;trace2=SetNext(trace2,&k2,&x2,Models)) for(trace=SetNext(NULL,&k,&x,((modelptr)x2)->basis);trace&&ok;trace=SetNext(trace,&k,&x,((modelptr)x2)->basis)) for(i=0;i<((basisptr)x)->n&&ok;i++) { base=(basisptr)x; if(&(base->param[i])==(float*)ans.valptr) { base->freeze[i]=j; ok=0; }} if(ok) er=24; } else er=38; Need2Plot=Need2Update=1; } else er=31; ResultFree(ans); return er; } int doline(char *cmd) { int er; char *cmd2,*rhs; // printf("doline: '%s'\n",cmd); cmd2=StrChrQuote(cmd,';'); if(cmd2) { *cmd2++='\0'; er=doline(cmd); if(!er) er=doline(cmd2); *(--cmd2)=';'; return er; } rhs=strchr(cmd,'='); cmd2=strnword(cmd,2); if(!rhs||cmd2&&rhs>cmd2) return docommand(cmd); *rhs++='\0'; er=(doassign(cmd,rhs)).er; *(--rhs)='='; return er; } /* main segment */ void debug() { return; } int main() { int er; char cmd[256]; SiouxWindow(0.1,0.1,70,50,0); printf("Welcome to SpectFit 2.0\n"); InitPlot(); MakeWindow(0.5,0.95,0.1,0.95); EndPlot(); Model=NULL; Logcmd=1; Need2Plot=Need2Update=1; Spectra=SetAlloc(&StringCmp,NULL); Plotlist=SetAlloc(&StringCmp,NULL); Models=SetAlloc(&StringCmp,NULL); Numbers=SetAlloc(&StringCmp,&PtrCmp); Strings=SetAlloc(&StringCmp,&PtrCmp); setupbasis(); debug(); printf("Ready\n"); er=0; while(er!=-1) { er=Need2Update?UpdateModels():0; if(er>0) displayerr(er); if(Need2Plot) drawplot(); printf(">"); gets(cmd); if(Logcmd) SaveString(cmd,"SFlog",1); er=doline(cmd); if(er>0) displayerr(er); } docommand("clear all"); SetFree(Spectra,0,0); SetFree(Plotlist,0,0); SetFree(Models,0,0); SetFree(Numbers,0,0); SetFree(Strings,0,0); endbasis(); printf("Bye.\n\n"); printf("Press command-q to quit.\n"); return 0; }