home *** CD-ROM | disk | FTP | other *** search
- /*
- split one spectra file, containing 4 or 8 spectra, into
- single spectra, possibly reverse spectra, subtract Background
- Calculate PAC ratio function:
-
- 1/4
- 2 (product(Si(180) - BACKi))
- R(t) = - * --------------------------
- 3 (product(Sj(90) - BACKj))^(1/4)
-
- Input is read from the file specified.
- The peakpositions, phase and parity are read from *.def or global.def
- */
-
- #include <stdio.h>
- #include <spec.h>
- #define TMPFILE "global.def"
-
- char deffile[80];
- float *spc, *err, *tim, *usp1, *usp2, *uer1, *uer2;
- int range=1024,
- tri=0,
- flg_v=FALSE,
- flg_ba=0,
- lastn=10,
- dev=50;
-
- int *back;
-
- help()
- {
- printf("Splitting spectrum file into single spectra, possibly reversing\n");
- printf("them, subtracting Background\n");
- printf("Calculating PAC Ratio function:\n");
- printf(" 1/4 \n");
- printf(" 2 (product(Si(180,t) - BACKi)) \n");
- printf(" R(t) = - * --------------------------------- - 1 \n");
- printf(" 3 (product(Sj(90,t) - BACKj))^(1/4) \n");
- printf("\n");
- printf(" 1 2 [ 1 \n");
- printf(" Error(t) = ------ * - * [-- * sum(1/(Si(180,t)-BACKi)) + \n");
- printf(" R(t)+1 3 [16 \n");
- printf(" 1/2 \n");
- printf(" 1 ] \n");
- printf(" + -- * sum(1/(Sj(180,t)-BACKj)) ] \n");
- printf(" 16 ] \n");
- printf("\n");
- printf("RVT2 file [-o file] [-back n] [-last n]\n");
- printf("options:\n");
- printf(" -o file output spectrum instead of stdout\n");
- printf(" -back n1,n2,n3,.. background for all spectra\n");
- printf(" -last n takes arithmetic mean of last n channels as\n");
- printf(" background. Default is, to find the background\n");
- printf(" by fitting an exponential curve to the spectrum\n");
- printf(" -v verbose mode. Prints fitted background\n");
- printf(" -def file use spectra definition file different from %s\n",TMPFILE);
- printf("The definition of the spectrum is read from %s\n",deffile);
- printf("This file should be in a format as generated by the FPROMPT \n");
- printf("routine and is organized as follows:\n");
- printf("Each line consists of 4 integers.\n");
- printf("The first specifies the Time 0 position.\n");
- printf("The second can be +1 -1 +2 or -2 and specifies, if it is\n");
- printf(" to be mirrored (-) and if it is a 0 degree (1)\n");
- printf(" or 90 degree (2) spectrum\n");
- printf(" If any other number is given, the spectrum is ignored\n");
- printf("The last two numbers are used to specify the range\n");
- printf("of the usable data area. Up to now, these parameters\n");
- printf("are only significant in the last line !\n");
- printf("\n(C) Rainer Kowallik\n");
- exit(0);
- }
-
- float sd(x,y)
- float x,y;
- {
- if(y!=0.0) return((float)(x / y));
- return(0.0);
- }
-
- float root(n,x)
- float x;
- int n;
- {
- float y;
-
- y = fabs(exp((double)(log(fabs((double)x))/((double)n))));
- return(y);
- }
-
- main(argc,argv)
- int argc;
- char *argv[];
- {
- int xbeg,n,m,i,max,peakptr,pacmax,peaks[30],phase[30];
- int wurzel1,wurzel2,merk;
- char *z,*s,*comment,*defnam;
- FILE *fp;
-
- if(argc == 1) help();
-
- z = (char *) malloc(256);
- s = (char *) malloc(256);
- comment = (char *) malloc(256);
- defnam = (char *) malloc(256);
- back = (int *) calloc(32,sizeof(int));
-
- strcpy(deffile,TMPFILE);
- flg_ba=0; /* defaults to exponential fit */
- for(n = 0; n < 32; n++) back[n] = -1;
- flg_v=FALSE;
-
- if(checkopt(argc,argv,"-def",z)) strcpy(deffile,z);
- strcpy(defnam,deffile);
- if(checkopt(argc,argv,"-back",z)) {
- i = 0; n = 0; m = 0; flg_ba=1;
- while(z[n] != 0) {
- s[m++] = z[n++];
- if(z[n] == ',') {
- s[m] = 0; m = 0; n = n + 1;
- back[i++] = atoi(s);
- }
- }
- while(i < 32) back[i++] = atoi(s);
- }
- if(checkopt(argc,argv,"-last",z)) {
- flg_ba=2; lastn = atoi(z);
- }
- if(checkopt(argc,argv,"-v",z)) flg_v=TRUE;
-
-
- spc=(float *)calloc(_MAXSPCLEN+2,sizeof(float));
- err=(float *)calloc(_MAXSPCLEN+2,sizeof(float));
- tim=(float *)calloc(_MAXSPCLEN+2,sizeof(float));
- usp1=(float *)calloc(_MAXSPCLEN+2,sizeof(float));
- usp2=(float *)calloc(_MAXSPCLEN+2,sizeof(float));
- uer1=(float *)calloc(_MAXSPCLEN+2,sizeof(float));
- uer2=(float *)calloc(_MAXSPCLEN+2,sizeof(float));
-
- /* -----------------------------------------------
- reading spectrum
- ----------------------------------------------- */
-
- max=readspec(argv[1],spc,err,tim,comment);
-
- /* -----------------------------------------------
- generating error spectrum
- ----------------------------------------------- */
-
- for(n=0;n<max;n++) err[n] = sqrt(spc[n]);
-
- /* -----------------------------------------------
- reading spectra definition file
- ----------------------------------------------- */
-
- fp=fopen(defnam,"r");
- #ifdef UNIX
- if(fp==NULL) {
- home = (char *) getenv("HOME");
- if(home != NULL) {strcpy(defnam,home); strcat(defnam,"/"); }
- strcat(defnam,deffile);
- fp=fopen(defnam,"r");
- }
- if(fp==NULL) {
- home = (char *) getenv("LISEPRG");
- if(home != NULL) {strcpy(defnam,home); strcat(defnam,"/"); }
- strcat(defnam,deffile);
- fp=fopen(defnam,"r");
- }
- #endif
- #ifdef AMIGA
- if(fp==NULL) {
- strcpy(defnam,"LISE:"); strcat(defnam,deffile);
- fp=fopen(defnam,"r");
- }
- #endif
- if(fp == NULL) {
- printf("rvt2: could not open >%s<\n",deffile);
- exit(0);
- }
- peakptr=0;
- while(!feof(fp)) {
- fscanf(fp,"%d %d %d %d\n",&peaks[peakptr],&phase[peakptr],&i,&pacmax);
- peakptr=peakptr+1;
- }
- fclose(fp);
-
- /* -------------------------------------------------
- initializing usp1, usp2 ,uer1 and uer2
- ------------------------------------------------- */
-
- for(n=0;n<pacmax;n++) {
- usp1[n]=1.0;
- usp2[n]=1.0;
- uer1[n]=0.0;
- uer2[n]=0.0;
- }
-
- /* ----------------------------------------------
- here we start calculating the new sum spectra
- -----------------------------------------------*/
-
- wurzel1 = 0; wurzel2 = 0;
-
- for(n=0;n<peakptr;n++) {
- xbeg = peaks[n];
- m = phase[n];
- /* if negative, go and mirror spectrum */
- if(m < 0) {
- for(i=pacmax/2 ; i<pacmax ; i++) {
- merk = spc[xbeg - i];
- spc[xbeg - i] = spc[xbeg + i - pacmax];
- spc[xbeg + i - pacmax] = merk;
- err[xbeg - i] = sqrt(spc[xbeg - i]);
- err[xbeg + i - pacmax] = sqrt(spc[xbeg + i - pacmax]);
- }
- xbeg = xbeg - pacmax; m = 0 - m;
- }
-
- SubBackground(spc,err,xbeg,xbeg+pacmax,n);
-
- switch(m) { /* which spectrum to add ? */
- case 1: /* 180 degree spectrum */
- for(i=0;i<pacmax;i++) {
- usp1[i] = usp1[i] * spc[xbeg+i];
- uer1[i] = uer1[i] + sd(1.0,spc[xbeg+i]);
- }
- wurzel1 = wurzel1 + 1;
- break;
- case 2: /* 90 degree spectrum */
- for(i=0;i<pacmax;i++) {
- usp2[i] = usp2[i] * spc[xbeg+i];
- uer2[i] = uer2[i] + sd(1.0,spc[xbeg+i]);
- }
- wurzel2 = wurzel2 + 1;
- break;
- }
- }
-
- /* --------------------------------------------------------------
- calculate ratio function and error spectrum
- -------------------------------------------------------------- */
-
- for(i=0;i<pacmax;i++) {
- spc[i] = sd(2.0 * root(wurzel1,usp1[i]) , 3.0 * root(wurzel2,usp2[i]));
- spc[i] = spc[i] - 0.666667;
- err[i] = sd(1.0,1.0 + spc[i]) * (2.0 / 3.0);
- err[i] = err[i] *
- sqrt(sd(1.0,(float)(wurzel1 * wurzel1)) * uer1[i] +
- sd(1.0,(float)(wurzel2 * wurzel2)) * uer2[i]);
- }
-
-
- /* -------------------------------------------
- now we can go and save the new spectrum
- ------------------------------------------- */
-
- strcpy(z,comment);
- n=instr("|",comment);
- if(n>0) midstr(z,comment,0,n-1);
- strcat(z," | RVT(PAC)");
- writespec("",spc,err,pacmax,2,z);
- free(uer1); free(uer2); free(usp1); free(usp2);
- free(spc); free(err); free(tim);
- free(back); free(defnam); free(comment);
- free(s); free(z);
- exit(0);
- }
- /* --------------------------------------------
- finding and subtracting correct background
- -------------------------------------------- */
- SubBackground(spc,err,xbeg,xend,j)
- float *spc, *err;
- int xbeg, xend, j;
- {
- int n,ba;
-
- switch(flg_ba) {
- case 0:
- ba = expbafit(spc,err,xbeg,xend);
- break;
- case 1: /* allready done when parsing arguments */
- ba = back[j];
- break;
- case 2:
- ba = sumspc(spc,xend-lastn,xend) / lastn;
- break;
- }
- if(flg_v) printf("background=%d\n",ba);
-
- /* Subtracting background */
- for(n=xbeg ; n<xend ; n++) spc[n] = spc[n] - ba;
- return(0);
- }
-
- sumspc(spc,a,z)
- float spc[];
- int a,z;
- {
- int i,erg;
-
- erg=0;
- for(i=a;i<z;i++) erg=erg+spc[i];
- return(erg);
- }
-
- /* ---------------------------------------------------------
- Linear regression after logarithm of spectrum
- This is only to calculate the chi**2, all
- other values are lost.
- UP TO NOW, THE ERRORBARS ARE NOT INCLUDED !
- I HAVE FORGOTTEN MY OLD SUPERBASIC SOURCE AT HOME, SORRY.
- --------------------------------------------------------- */
-
- float linreg(spc,err,n,a,z)
- float spc[],err[];
- int n,a,z;
- {
- int i;
- float ysoll,x,y,sumx,sumxx,sumy,sumyy,sumxy,nges,
- steigung,offset,erg,
- *ylog;
-
- ylog=(float *)calloc(_MAXSPCLEN+2,sizeof(float));
-
- nges = (float) (z-a); /* this we know for shure */
- sumx = 0.0;
- sumxx = 0.0;
- sumy = 0.0;
- sumyy = 0.0;
- sumxy = 0.0;
-
- for(i=a;i<z;i++) {
- x = (float) i;
- y = spc[i];
- y = y - ((float) n);
- if(y<0.1) y=1.0; /* trap overflow on log */
- y = (float) log((double) y); /* linearization of exp function */
- ylog[i] = y; /* store for later use */
- sumx = sumx + x;
- sumxx = sumxx + (x*x);
- sumy = sumy + y;
- sumyy = sumyy + (y*y);
- sumxy = sumxy + (x*y);
- }
- sumx = sumx / nges;
- sumy = sumy / nges;
- sumxx = sumxx - (nges * sumx * sumx);
- sumxy = sumxy - (nges * sumx * sumy);
- sumyy = sumyy - (nges * sumy * sumy);
- steigung = sumxy / sumxx;
- offset = sumy - (steigung * sumx);
-
- /* calculating chi**2 */
-
- erg=0.0;
- for(i=a;i<z;i++) {
- x = (float) i;
- y = spc[i];
- y = ylog[i];
- ysoll = (steigung * x) + offset;
- y = y - ysoll;
- erg = erg + (y * y);
- }
- free(ylog);
- return(erg);
- }
-
-
- /* ---------------------------------------------------------
- Fitting background to exponential function.
- This is done, by calculating the chi**2 with
- linear regression for the logarithm of the spectrum.
- We than look for a minimum of chi**2 for different
- backgrounds.
- UP TO NOW, THE ERRORBARS ARE NOT INCLUDED !
- I HAVE FORGOTTEN MY OLD SUPERBASIC SOURCE AT HOME, SORRY.
- --------------------------------------------------------- */
- expbafit(spc,err,a,z)
- float spc[],err[];
- int a,z;
- {
- int i,n,bamin,bamax,babest,inc,xraster,xdepth;
- float chisq,chibest;
-
- xraster = 10;
- xdepth = 5;
- chibest = 1E10;
- bamax = sumspc(spc,z-10,z) / 10 ; /* get maximum background */
- bamin = bamax / 2; /* get minimum background */
- for(i=1;i<xdepth;i++) {
- inc = (bamax - bamin) / xraster;
- if(inc<1) break;
- n = bamin; while(n<=bamax) {
- chisq = linreg(spc,err,n,a,z); /* just calculate chi**2 */
- if(chisq < chibest) {
- chibest = chisq;
- babest = n;
- if(flg_v) {
- printf("new best: background = %d chi**2 = %f\n",babest,chibest);
- }
- }
- n = n + inc;
- }
- bamin = babest - inc;
- bamax = babest + inc;
- }
- return(babest);
- }
-