
/* C program to take raw data from Finnigan MAT252 mass spec and reformat*/
/*originally written by Skip Little, modified Aug1996 by DRO & RG*/


/*to recompile type cc curry19.c which makes a file called "a.out"*/
/*which can be moved to "curry19" for regular running of the program*/



#include <ctype.h>
#include <stdio.h>
#include <string.h>


#define MAXLINE 1000
#define MAXOUT 2000
#define MAXWORD 500
#define IN 1
#define OUT 0
#define NO 0
#define YES 1


static char sa44[8]={'S','A','4','4','[','V',']','\0'};
static char st44[8]={'S','T','4','4','[','V',']','\0'};
static char c1312[8]={'1','3','/','1','2','-','C','\0'};
static char o1816[8]={'1','8','/','1','6','-','O','\0'};
static char sd45[6]={'4','5','/','4','4','\0'};
static char sd46[6]={'4','6','/','4','4','\0'};
static char temp[10]={'[','C','e','l','s','i','u','s',']','\0'};
static char micr[11]={'[','m','i','c','r','o','B','A','R',']','\0'};
static char expa[10]={'E','x','p','a','n','s','i','o','n','\0'};
static char pstn[9]={'P','o','s','i','t','i','o','n','\0'};


static char stA[6]={'i','d','e','n','t','\0'};
static char stB[8]={'P','r','o','c','e','s','s','\0'};
static char stC[5]={'A','c','i','d','\0'};
static char stD[10]={'[','C','e','l','s','i','u','s',']','\0'};
static char stE[9]={'s','t','d','.','d','e','v','.','\0'};


static char std45[15]={'s','t','d','.','d','e','v','.','-','4','5','/','4','4', '\0'};
static char std46[15]={'s','t','d','.','d','e','v','.','-','4','6','/','4','4', '\0'};
        
main()
{
        int len,max,header;
        int i,j,k,l,m,n,ll;
        char line[MAXLINE];
        int pos[MAXWORD];
        int lng[MAXWORD];
        int nw;
        int cnt;
        int posn;
        int state;
        int nlast=0,nfirst=0,ncol=0,nend=0,nstart=0;
        char c;
        float fnumb;
        int kD;
        /*int kA,kT,kC,kO,k45,k46,kTemp,kPres,kExpn,kPstn;*/
        int ksa44,kst44,kc1312,ko1816,kstd45,kstd46,ktemp,kmicr,kexpa,kpstn;
        int ksa44p,kst44p,kc1312p,ko1816p,kstd45p,kstd46p;
        int intout;
        int icnt,i1,i2,i3,i4,io,iolen,iomax=15;
        char blnk,obuf[100];
/*added the next line to deal with the need to add a constant number*/
/*to the reset spec numbers resulting from bad Finnigan Programming*/
        int specin,specout;
        
max = 0;
header = 1;


while ((len = getline(line, MAXLINE)) > 0) {
        cnt = 0;
        nw = 0;
        posn = 0;
        state = OUT;


  /* fill in leading zero in date:    */
        if (header==0 && line[8]==' ') line[8] = '0';
                
        for (i=0;i<len;++i) {


                
        /* special case: change "ncm " to  "n cm", where n is a decimal digit*/
                /*c = line[i];
                if( (header==0&&c=='c'&&isdigit(line[i-1])&&line[i+1]=='m') ) {
                        line[i+2] = line[i+1];
                        line[i+1] = line[i];
                        line[i  ] = ' ';
                        }*/
                
        /* special case: change "nug " to  "n ug", where n is a decimal digit*/
                /*c = line[i];
                if( (header==0&&c=='u'&&isdigit(line[i-1])&&line[i+1]=='g') ) {
                        line[i+2] = line[i+1];
                        line[i+1] = line[i];
                        line[i  ] = ' ';
                        }*/


        /* special case:  put "-" in 'std.dev.-45/44" and "std.dev.-46/44":   */


                c = line[i];
                if( header==1 && c=='s') {
                        if(strncmp(line+i,stE,8)==0)  {
                                line[i+8] = '-';
                        }
                }
                
                c = line[i];
                if( ((header==1) && (c==' '||c=='\t'||c=='\n')) ||
                    ((header==0) && (c==' '||c=='\t'||c=='\n'||c=='/'))  )  { 
                        state = OUT;
                        pos[nw] = posn;
                        lng[nw] = cnt;
                        }
                else if (state == OUT) {
                        state = IN;
                        ++nw;
                        posn = i+1;
                        cnt = 1;
                        }
                else
                        ++cnt;
                }
        
        if (header==1) {


                for (k=1;k<=nw;++k) {
                        ll = lng[k];
                        if(strncmp(line+pos[k]-1,stA,ll)==0)nfirst=k;
                        if(strncmp(line+pos[k]-1,stB,ll)==0)nlast=k;
                        
                        if(ll==7 && strncmp(line+pos[k]-1,sa44,ll)==0)ksa44=k;
                        if(ll==7 && strncmp(line+pos[k]-1,st44,ll)==0)kst44=k;
                        if(ll==7 && strncmp(line+pos[k]-1,c1312,ll)==0)kc1312=k;
                        if(ll==7 && strncmp(line+pos[k]-1,o1816,ll)==0)ko1816=k;
                        if(ll==14&& strncmp(line+pos[k]-1,std45,ll)==0)kstd45=k;
                        if(ll==14&& strncmp(line+pos[k]-1,std46,ll)==0)kstd46=k;
                        }


                if (nfirst!=0 && nlast!=0) {
                        header = 0;
                        ncol = nlast - nfirst - 1;
                        }
                }


/*      else if (header==0 && line[15]=='/') {    */
        else if (header==0) { 


                nstart = 0;
                nend = 0;


                for (k=1;k<=nw;++k) {
                        ll = lng[k];    
                        if(ll==4 && strncmp(line+pos[k]-1,stC,ll)==0) {
                                nend = k;
                                nstart = nend - ncol;
                                ksa44p = ksa44 - nlast + nend;
                                kst44p = kst44 - nlast + nend;
                                kc1312p = kc1312 - nlast + nend;
                                ko1816p = ko1816 - nlast + nend;
                                kstd45p = kstd45 - nlast + nend;
                                kstd46p = kstd46 - nlast + nend;   }


                        if(ll==9 && strncmp(line+pos[k]-1,temp,ll)==0)ktemp=k+2;
                        if(ll==10&& strncmp(line+pos[k]-1,micr,ll)==0)kmicr=k+2;
                        if(ll==9 && strncmp(line+pos[k]-1,expa,ll)==0)kexpa=k+2;
                        if(ll==8 && strncmp(line+pos[k]-1,pstn,ll)==0)kpstn=k+2;
                        if(ll==9 && strncmp(line+pos[k]-1,stD,ll)==0) kD=k+2; 
                        }


                if(nstart!=0 && nend!=0) {


/* locate "/"s */


                        icnt = 1;
                        i1 = 0;  i2 = 0;  i3 = 0;
                        for (i=0;i<len;++i) {
                                if (line[i]=='/') {
                                        if (icnt==1) {
                                                i1 = i;
                                                ++icnt;
                                                }
                                        else if (icnt==2) {
                                                i2 = i;
                                                ++icnt;
                                                }
                                        else if (icnt==3) {
                                                i3 = i;
                                                ++icnt;
                                                }
                                        }
                                }


/* print date, time, spec no */


                        for (i=0;i<15;++i) printf("%c",line[i]);
                        printf (" ");
                        for (i=16;i<24;++i) printf("%c",line[i]);
                        printf (" ");
/*added by DRO and RG 07 August 1996 to deal with reset database*/
/*will add a constant to new spec numbers and add reset spec number*/
/*to the end of the database for reference to datasheets*/
/*original reset number was 33138*/
/*AFTER 29 AUG 1999, has to reset database again to 1*/
/*so now we add 66000 to all spec numbers, DRO*/
                        sscanf (line+30, "%d", &specin);
                        specout=specin+66000;
                        printf("%6d",specout);                  
                        printf (" ");


/* print 1st sample ident field */
                
                        for (i=37;i<56;++i) {
                                if (i < i2) printf("%c",line[i]);
                                else                printf(" "); 
                                }
                
/* reformat and print 2nd sample ident field */


                        for (io=0;io<=iomax;++io) obuf[io]=' '; 
                        
                        iolen  = i3-i2-1;
                        io = iomax-1;
                        blnk = YES;


                        for (i=i3-1;i>i2;--i) {


                                if (line[i] != ' ') {
                                        blnk = NO;
                                        obuf[io] = line[i];
                                        --io;
                        
                                        /* special case:
                                        put space before "cm" or "ug" */
                        
                                        if (((line[i]=='c'&&line[i+1]=='m')
                                                        ||
                                             (line[i]=='u'&&line[i+1]=='g'))


                                                        &&


                                                   isdigit(line[i-1])


                                                        &&


                                                ((line[i+2]=='/')
                                                        ||
                                                 (line[i+2]==' '))       ) {


                                                blnk = YES;
                                                obuf[io] = ' ';
                                                --io;
                                                }
                
                                        }
                                else if (line[i] == ' ' && blnk == NO) {
                                        blnk = YES;
                                        obuf[io] = line[i];
                                        --io;
                                        }
                                }


                        for (io=0;io<iomax;++io) printf("%c",obuf[io]);
                        printf ("  ");


/* print 3rd sample ident field */


                        c = line[pos[nstart-1]+8];      
                        if (c == 'E') i4 = pos[nstart-1]-1;
                        else          i4 = pos[nstart]-1;


                        for (i=i3+1;i<i3+17;++i) {
                                if (i < i4) printf("%c",line[i]);
                                else                 printf(" "); 
                                }
                        printf(" ");


/* decode and print selected float. pt. data */


                        k=kc1312p;
                        sscanf( (line+pos[k]-1), "%f", &fnumb);
                        printf("%9.3f",fnumb);
                        printf(" ");
                        
                        k=kstd45p;
                        sscanf( (line+pos[k]-1), "%f", &fnumb);
                        printf("%9.3f",fnumb);
                        printf(" ");
                
                        k=ko1816p;
                        sscanf( (line+pos[k]-1), "%f", &fnumb);
                        printf("%9.3f",fnumb);
                        printf(" ");
                        
                        k=kstd46p;
                        sscanf( (line+pos[k]-1), "%f", &fnumb);
                        printf("%9.3f",fnumb);
                        printf(" ");


                        k=ksa44p;
                        sscanf( (line+pos[k]-1), "%f", &fnumb);
                        printf("%5.2f",fnumb);
                        printf(" ");
                        
                        k=kst44p;
                        sscanf( (line+pos[k]-1), "%f", &fnumb);
                        printf("%5.2f",fnumb);
                        printf(" ");
                                
                        k = ktemp;
                        ll = lng[k];
                        for(l=0;l<ll;++l) printf("%c",line[pos[k]-1+l]);
                        for(l=0;l<(5-ll);++l) printf(" ");
                        printf(" ");


                        k = kmicr;
                        ll = lng[k];
                        for(l=0;l<ll;++l) printf("%c",line[pos[k]-1+l]);
                        for(l=0;l<(5-ll);++l) printf(" ");
                        printf(" ");


                        k = kexpa;
                        ll = 1;
                        for(l=0;l<ll;++l) printf("%c",line[pos[k]-1+l]);
                        printf (" ");
        
                        k = kpstn + 1;
                        ll = 1;
                        for(l=0;l<ll;++l) printf("%c",line[pos[k]-1+l]);
                        printf(" ");


                        k = kpstn + 2;
                        ll = 2;
                        for(l=0;l<ll;++l) printf("%c",line[pos[k]-1+l]);
                        printf(" ");
/*added the following line to print out the reset spec number at the*/
/*end of the database to cross reference with the datasheet numbers*/
                        printf("%6d",specin);
                        printf ("\n");  


                        }
                }
        }
        return 0;       
}
int getline(s, lim)
char s[];
int lim;
{
        int c, i; 


        for (i=0; i<lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
                s[i] = c;
        if (c == '\n') {
            s[i] = c;
            ++i;
        }
        s[i] = '\0';
        return i;
} 

