/*******************************************************************************
*                                                                              *
*                                   Viewmol                                    *
*                                                                              *
*                           R E A D G A M E S S . C                            *
*                                                                              *
*                 Copyright (c) Joerg-R. Hill, October 2003                    *
*                                                                              *
********************************************************************************
*
* $Id: readgamess.c,v 1.2 2003/11/07 11:13:26 jrh Exp $
* $Log: readgamess.c,v $
* Revision 1.2  2003/11/07 11:13:26  jrh
* Release 2.4
*
* Revision 1.1  2000/12/10 15:15:13  jrh
* Initial revision
*
*
*/
#include<ctype.h>
#include<math.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "isotopes.h"

#define RHF 1
#define UHF 2
#define ROHF 3
#define MCSCF 4
#define GVB 5

#define TRUE  1
#define FALSE 0

#define MAXLENLINE 134

int  main(int, char **);
void readBasis(FILE *, char *, char *, int *, int);
void readMOs(int, int, FILE *, int);
void readFrq(FILE *, int);
int  readOpg(FILE *, int);
void printCoord(double **, char **, int, int);
void makeLower(char *);
void changeDs(char *);

extern void *getmem(size_t, size_t);
extern void *expmem(void *, size_t, size_t);
extern void fremem(void **);
extern void eof(char *, char *, int);

int main(int argc, char **argv)
{
  FILE *file;
  double atomicCharge;
  int found, na, mna=50, mnn=80, cycle=0, atomNumber;
  int freq=FALSE, opt=FALSE, scftype=RHF, *done;
  char line[MAXLENLINE], pgroup[8], *atomNames, *currentName, *word=NULL, *p, *symbol;
  register int i, k;

  if ((file=fopen(argv[1], "r")) == NULL) eof("noFile", argv[1], 1);

  /* Check whether it really is a GAMESS output file */

  do
  {
    if (fgets(line, MAXLENLINE, file) == NULL) eof("wrongFiletype", argv[1], 1);
    makeLower(line);
  } while (!strstr(line, "gamess"));

  /* Load Title */

  found=TRUE;
  do
  {
    if (fgets(line, MAXLENLINE, file) == NULL)
    {
      found=FALSE;
      rewind(file);
      break;
    }
  } while (!strstr(line, "RUN TITLE"));
  if (found)
  {
    fgets(line, MAXLENLINE, file);
    fgets(line, MAXLENLINE, file);
    word=line;
    while (*word == ' ') word++;
    printf("$title\n%s", word);
  }

  /* Load symmetry */

  found=TRUE;
  do
  {
    if (fgets(line, MAXLENLINE, file) == NULL)
    {
      found=FALSE;
      rewind(file);
      break;
    }
  } while (!strstr(line, "THE POINT GROUP OF THE MOLECULE IS"));
  if (found)
  {
    word=strtok(line, " ");
    for (i=0; i<7; i++)
      word=strtok(NULL, " ");
    strcpy(pgroup, word);
    fgets(line, MAXLENLINE, file);
    if (strstr(line, "THE ORDER OF THE PRINCIPAL AXIS IS"))
    {
      word=strtok(line, " ");
      for (i=0; i<7; i++)
        word=strtok(NULL, " \n");
      if (*word != '0' && (p=strchr(pgroup, 'N')) != NULL) *p=*word;
    }
    printf("$symmetry %s\n", pgroup);
    if (strcmp(pgroup, "C1")) printf("$error onlySymmetricBasis 0\n");
  }

  /* Check SCF and run type */
  do
  {
    if (fgets(line, MAXLENLINE, file) == NULL) break;
  } while (!(word=strstr(line, "RUNTYP=")));
  if (!strncmp(word+7, "OPTIMIZE", 8)) opt=TRUE;
  if (!strncmp(word+7, "HESSIAN", 7)) freq=TRUE;
  word=strstr(line, "SCFTYP=");
  if (word)
  {
    if (!strncmp(word+7, "RHF", 3)) scftype=RHF;
    if (!strncmp(word+7, "UHF", 3)) scftype=UHF;
    if (!strncmp(word+7, "ROHF", 4)) scftype=ROHF;
    if (!strncmp(word+7, "MCSCF", 5)) scftype=MCSCF;
    if (!strncmp(word+7, "GVB", 3)) scftype=GVB;
  }

  /* Load coordinates */

  rewind(file);
  do
  {
    if (fgets(line, MAXLENLINE, file) == NULL) eof("noCoordinates", argv[1], 1);
  } while (!strstr(line, "ATOM      ATOMIC                      COORDINATES (BOHR)"));
  fgets(line, MAXLENLINE, file);
  fgets(line, MAXLENLINE, file);
  na=0;
  symbol=(char *)getmem((size_t)mna, (size_t)(3*sizeof(char)));
  atomNames=(char *)getmem((size_t)mnn, sizeof(char));
  currentName=atomNames;
  if (!opt) printf("$coord 0.52917706\n");
  while (line[0] != '\n' && !strstr(line, "INTERNUCLEAR DISTANCES"))
  {
    word=strtok(line, " \t");
    if (strlen(word)+(int)(currentName-atomNames) > mnn-1)
    {
      mnn+=80;
      p=atomNames;
      atomNames=(char *)expmem((void *)atomNames, mnn, sizeof(char));
      if (p != atomNames) currentName+=atomNames-p;
    }
    strcpy(currentName, word);
    currentName+=strlen(word)+1;
    atomicCharge=atof(strtok(NULL, " \t"));
    atomNumber=(int)floor(atomicCharge);
    if (fabs((double)atomNumber-atomicCharge) < 1.0e-6)
    {
      atomNumber--;
      symbol[3*na]=pse[atomNumber][0];
      symbol[3*na+1]=pse[atomNumber][1];
      symbol[3*na+2]='\0';
      if (!opt)
      {
        p=strtok(NULL, " \t");
        printf("%s ", p);
        p=strtok(NULL, " \t");
        printf("%s ", p);
        p=strtok(NULL, " \t\n");
        printf("%s %s\n", p, &symbol[3*na]);
      }
      na++;
      if (na >= mna)
      {
        mna+=50;
        symbol=(char *)expmem((void *)symbol, (size_t)mna, (size_t)(3*sizeof(char)));
      }
    }
    if (fgets(line, MAXLENLINE, file) == NULL) break;
  }

/* Load optimization history */

  if (opt) cycle=readOpg(file, na);

/* Load basis functions */

  rewind(file);
  found=TRUE;
  do
  {
    if (fgets(line, MAXLENLINE, file) == NULL)
    {
	found=FALSE;
      break;
    }
  } while (!strstr(line, "ATOMIC BASIS SET"));
  if (found)
  {
    do
    {
      if (fgets(line, MAXLENLINE, file) == NULL) break;
    } while (!strstr(line, "SHELL TYPE PRIM"));
    printf("$atoms\n");
    done=(int *)getmem((size_t)na, sizeof(int));
    for (i=0; i<na; i++)
    {
      if (!done[i])
      {
        printf("%s %d", &symbol[3*i], i+1);
        for (k=i+1; k<na; k++)
        {
          if (!strncmp(&symbol[3*k], &symbol[3*i], 2))
          {
            done[k]=TRUE;
            printf(",%d", k+1);
          }
        }
        printf(" \\\n");
        printf("   basis =%s basis%d\n", &symbol[3*i], i+1);
/*      done[i]=TRUE; */
      }
    }
    if (strstr(line, "SHELL TYPE PRIM")) readBasis(file, atomNames, symbol, done, na);
    fremem((void **)&done);
  }
  fremem((void **)&atomNames);

/* Load orbital energies and symmetries */

  readMOs(scftype, cycle, file, opt);

/* Load frequencies and normal modes vectors */

  if (na <= 1) freq=FALSE;
  if (freq) readFrq(file, na);

  printf("$end\n");
  fclose(file);
  return(0);
}

void readBasis(FILE *file, char *atomNames, char *symbol, int *done, int na)
{
  double *ex, *scoeff, *pcoeff, *dcoeff, *fcoeff;
  int maxpri=20, atom, ishell;
  char line[MAXLENLINE], shell[3], previous[MAXLENLINE]="";
  char *currentName, *word, *p;
  register int i, j;

  ex=(double *)getmem(maxpri, sizeof(double));
  scoeff=(double *)getmem(maxpri, sizeof(double));
  pcoeff=(double *)getmem(maxpri, sizeof(double));
  dcoeff=(double *)getmem(maxpri, sizeof(double));
  fcoeff=(double *)getmem(maxpri, sizeof(double));

  printf("$basis\n");
  atom=1;
  fgets(line, MAXLENLINE, file);
  if (line[0] == '\n')
    fgets(line, MAXLENLINE, file);
  while (!strstr(line, "TOTAL NUMBER OF"))
  {
    word=strtok(line, " \t\n");
    if (isalpha(*word))
    {
      currentName=atomNames;
      for (i=0; i<na; i++)
      {
        if (strstr(currentName, word) && !done[i]) break;
        currentName+=strlen(currentName)+1;
      }
      printf("*\n%s basis%d\n*\n", &symbol[3*i], i+1);
      strcat(previous, word);
      strcat(previous, ",");
    }
    fgets(line, MAXLENLINE, file);
    if (line[0] == '\n')
      fgets(line, MAXLENLINE, file);
    word=strtok(line, " \t");
    do
    {
      i=0;
      ishell=atoi(word);
      while (ishell == atoi(word))
      {
        strncpy(shell, strtok(NULL, " \t"), 2);
        shell[2]='\0';
        (void)strtok(NULL, " \t");
        ex[i]=atof(strtok(NULL, " \t"));
        switch (shell[0])
        {
          case 'S': scoeff[i]=atof(strtok(NULL, " \t"));
                    break;
          case 'P': pcoeff[i]=atof(strtok(NULL, " \t"));
                    break;
          case 'L': scoeff[i]=atof(strtok(NULL, " \t"));
                    strcpy(shell, "SP");
                    p=strtok(NULL, " \t");
                    if (*p == '(')
                    {
                      (void)strtok(NULL, " \t");
                      p=strtok(NULL, " \t");
                    }
                    pcoeff[i]=atof(p);
                    break;
          case 'D': dcoeff[i]=atof(strtok(NULL, " \t"));
                    break;
          case 'F': fcoeff[i]=atof(strtok(NULL, " \t"));
                    break;

        }
        i++;
        if (i > maxpri)
        {
          maxpri+=20;
          ex=(double *)expmem((void *)ex, maxpri, sizeof(double));
          scoeff=(double *)expmem((void *)scoeff, maxpri, sizeof(double));
          pcoeff=(double *)expmem((void *)pcoeff, maxpri, sizeof(double));
          dcoeff=(double *)expmem((void *)dcoeff, maxpri, sizeof(double));
          fcoeff=(double *)expmem((void *)fcoeff, maxpri, sizeof(double));
        }
        fgets(line, MAXLENLINE, file);
        if (line[0] == '\n')
          fgets(line, MAXLENLINE, file);
        if (strstr(line, "TOTAL NUMBER OF")) break;
        word=strtok(line, " \t");
        if (isalpha(*word)) break;
      } /* end of while (ishell == atoi(word)) */
      for (p=&shell[0]; *p; p++)
      {
        printf("%4d  %c\n", i, tolower(*p));
        for (j=0; j<i; j++)
        {
          switch (*p)
          {
            case 'S': printf("%15.6f %10.6f\n", ex[j], scoeff[j]);
                      break;
            case 'P': printf("%15.6f %10.6f\n", ex[j], pcoeff[j]);
                      break;
            case 'D': printf("%15.6f %10.6f\n", ex[j], dcoeff[j]);
                      break;
            case 'F': printf("%15.6f %10.6f\n", ex[j], fcoeff[j]);
                      break;
          }
        }
      }
      if (strstr(line, "TOTAL NUMBER OF")) break;
    } while (!isalpha(*word));  /* end of do */
  }

/* To use Spherical Harmonics, i.e. 5d functions, you need
   to include ISPHER=1 in the $CONTRL Section. */

  printf("*\n$pople 6d 10f 15g\n");
  fremem((void **)&ex);
  fremem((void **)&scoeff);
  fremem((void **)&pcoeff);
  fremem((void **)&dcoeff);
  fremem((void **)&fcoeff);
}

void readMOs(int scftype, int cycle, FILE *file, int opt)
{
  double *eorb, *cmo;
  int mno=20, mnc=200, norbital=0, nbasfu=0, nocc[2]={0, 0}, offset, found, icol;
  int spin;
  char line[MAXLENLINE], keyword[24], *word, *symorb;
  register int i, j, k;

  if (scftype != RHF && scftype != UHF) return;
  spin=0;
  rewind(file);
  do
  {
    if (fgets(line, MAXLENLINE, file) == NULL) return;
  } while (!strstr(line, "ORBITALS ARE OCCUPIED"));
  nocc[0]=atoi(strtok(line, " \t"));
  if (scftype == UHF)
  {
    do
    {
      if (fgets(line, MAXLENLINE, file) == NULL) return;
    } while (!strstr(line, "ORBITALS ARE OCCUPIED"));
    nocc[1]=atoi(strtok(line, " \t"));
  }

  if (opt)
    strcpy(keyword, "MOLECULAR ORBITALS");
  else
    strcpy(keyword, "EIGENVECTORS");

  while (spin < scftype)
  {
    found=TRUE;
    eorb=(double *)getmem((size_t)mno, sizeof(double));
    symorb=(char *)getmem((size_t)mno, 4*sizeof(char));
    cmo=(double *)getmem((size_t)mnc, sizeof(double));

    do
    {
      if (fgets(line, MAXLENLINE, file) == NULL) return;
    } while (!strstr(line, keyword));

    i=j=k=0;
    icol=0;
    fgets(line, MAXLENLINE, file);
    fgets(line, MAXLENLINE, file);
    while (TRUE)
    {
      if (line[0] == '\n')
        fgets(line, MAXLENLINE, file);
      if (strstr(line, "------------") || strstr(line, "- BETA SET -")) break;
      fgets(line, MAXLENLINE, file);

      word=strtok(line, " \t\n");
      while (word)
      {
        eorb[i++]=atof(word);
        if (found) icol++;
        if (i >= mno)
        {
          mno+=20;
          eorb=(double *)expmem((void *)eorb, (size_t)mno, sizeof(double));
          symorb=(char *)expmem((void *)symorb, (size_t)mno, 4*sizeof(char));
        }
        word=strtok(NULL, " \t\n");
      }
      found=FALSE;
      fgets(line, MAXLENLINE, file);
      word=strtok(line, " \t\n");
      while (word)
      {
        strncpy(&symorb[j], word, 4);
        j+=4*sizeof(char);
        word=strtok(NULL, " \t\n");
      }
      fgets(line, MAXLENLINE, file);
      while (line[0] != '\n' && (line[14] != ' ' || line[15] != ' '))
      {
        (void)strtok(line, " \t\n");
        (void)strtok(NULL, " \t\n");
        word=strtok(NULL, " \t\n");
        if (word[0] >= '0' && word[0] <= '9') (void)strtok(NULL, " \t\n");
        while ((word=strtok(NULL, " \t")))
        {
          cmo[k]=atof(word);
          if (++k >= mnc)
          {
            mnc+=200;
            cmo=(double *)expmem((void *)cmo, (size_t)mnc, sizeof(double));
          }
        }
        fgets(line, MAXLENLINE, file);
        if (strstr(line, "...... END OF") || strstr(line, "- BETA SET -")) break;
      }
      if (strstr(line, "...... END OF") || strstr(line, "- BETA SET -")) break;
    }
    norbital=i;
    nbasfu=k/i;
 
    if (scftype == RHF)
      printf("$scfmo gaussian\n");
    else
    {
      if (spin == 0)
        printf("$uhfmo_alpha gaussian\n");
      else
        printf("$uhfmo_beta gaussian\n");
    }
    k=0;
    for (i=0; i<norbital; i++)
    {
      word=&symorb[4*i];
      printf("%6d  %s     eigenvalue=%20.14e   nsaos=%d\n", i+1, word, eorb[i], nbasfu);
      if (norbital-i <= norbital % icol)
        offset=norbital % icol;
      else
        offset=icol;
      for (j=0; j<nbasfu; j++)
      {
        printf(" %19.14e", cmo[k+j*offset]);
        if ((j+1) % 4 == 0) printf("\n");
      }
      if (j % 4 != 0) printf("\n");
      if ((k+1) % icol == 0)
        k+=icol*(nbasfu-1)+1;
      else
        k++;
    }
    fremem((void **)&eorb);
    fremem((void **)&cmo);

    if (scftype == RHF)
      printf("$closed shells\n");
    else
    {
      if (spin == 0)
        printf("$alpha shells\n");
      else
        printf("$beta shells\n");
    }
    for (i=0; i<nocc[spin]; i++)
    {
      found=FALSE;
      for (j=0; j<nocc[spin]; j++)
      {
        if (symorb[4*j] != '\0')
        {
          strcpy(line, &symorb[4*j]);
          found=TRUE;
          break;
        }
      }
      if (found)
      {
        k=0;
        for (j=0; j<nocc[spin]; j++)
        {
          if (!strcmp(&symorb[4*j], line))
          {
            k++;
            symorb[4*j]='\0';
            }
        }
        printf(" %s 1-%d\n", line, k);
      }
      else
        break;
    }
    fremem((void **)&symorb);
    spin++;
  }
}

void readFrq(FILE *file, int na)
{
  double *freq, *ir, *nmo;
  int nstart, nend, nout, ncart, nfrq, accepted, all, i, j;
  char line[MAXLENLINE], *word;

  rewind(file);
  do
  {
    if (fgets(line, MAXLENLINE, file) == NULL) return;
  } while (!strstr(line, "ARE TAKEN AS ROTATIONS AND TRANSLATIONS"));
  (void)strtok(line, " \t");
  nstart=atoi(strtok(NULL, " \t"))-1;
  (void)strtok(NULL, " \t");
  nend=atoi(strtok(NULL, " \t"))-1;
  nout=nend-nstart+1;

  ncart=3*na-nout;
  freq=(double *)getmem(ncart, sizeof(double));
  ir=(double *)getmem(ncart, sizeof(double));
  nmo=(double *)getmem(ncart*(ncart+nout), sizeof(double));

  nfrq=0;
  i=0;
  while (i < 3*na)
  {
    do
    {
      if (fgets(line, MAXLENLINE, file) == NULL) break;
    } while (!strstr(line, "FREQUENCY:"));
    (void)strtok(line, " \t\n");
    accepted=all=0;
    /* Read frequencies, check for imaginary frequencies marked by 'I' */
    while ((word=strtok(NULL, " \t\n")))
    {
      if (*word == 'I')
      {
        freq[nfrq-1]*=-1.0;
      }
      else
      {
        if (i+all < nstart || i+all > nend)
	{
	  freq[nfrq++]=atof(word);
	  accepted++;
	}
        all++;
      }
    }
    nfrq-=accepted;
    /* Read IR intensities */
    fgets(line, MAXLENLINE, file);
    (void)strtok(line, " \t\n");
    (void)strtok(NULL, " \t\n");
    accepted=all=0;
    while ((word=strtok(NULL, " \t\n")))
    {
      if (i+all < nstart || i+all > nend)
      {
        ir[nfrq++]=atof(word);
	accepted++;
      }
      all++;
    }
    nfrq-=accepted;
    fgets(line, MAXLENLINE, file);

    /* Read normal modes */
    for (j=0; j<3*na; j++)
    {
      accepted=all=0;
      fgets(line, MAXLENLINE, file);
      word=strtok(line, " \t\n");
      if (isdigit(*word))
      {
        (void)strtok(NULL, " \t\n");
        (void)strtok(NULL, " \t\n");
      }
      while ((word=strtok(NULL, " \t\n")))
      {
        if (i+all < nstart || i+all > nend)
	{
	  nmo[j*ncart+nfrq]=atof(word);
	  accepted++;
	  nfrq++;
        }
	all++;
      }
      if (j != 3*na-1) nfrq-=accepted;
    }
    i+=all;
  }

  printf("$vibrational spectrum\n");
  for (i=0; i<ncart; i++)
  {
    printf("n/a %f %f 100.0\n", freq[i], ir[i]);
  }

  printf("$vibrational normal modes\n");
  for (i=0; i<ncart+nout; i++)
  {
    for (j=0; j<ncart; j++)
    {
      if (j % 5 == 0)
      {
        if (j == 0)
          printf("%2d %2d ", i+1, j/5+1);
        else
          printf("\n%2d %2d ", i+1, j/5+1);
      }
      printf("%15.10f", nmo[i*ncart+j]);
    }
    printf("\n");
  }
  fremem((void **)&freq);
  fremem((void **)&ir);
  fremem((void **)&nmo);
}

int readOpg(FILE *file, int na)
{
  double *x, *y, *z, *gx, *gy, *gz;
  double energy, gnorm=0.0, atomicCharge;
  int cycle=0, version=1, atomNumber;
  char line[MAXLENLINE], *symbol, *word;
  register int i;

  x=(double *)getmem(na, 6*sizeof(double));
  y=x+na;
  z=y+na;
  gx=z+na;
  gy=gx+na;
  gz=gy+na;
  symbol=(char *)getmem(na, 3*sizeof(char));

  rewind(file);
  word=fgets(line, MAXLENLINE, file);
  while (word)
  {
    do
    {
      if (fgets(line, MAXLENLINE, file) == NULL)
      {
        printCoord(&x, &symbol, na, version);
        return(cycle);
      }
    } while (!strstr(line, "  ENERGY="));
    energy=atof(&line[33]);

    while (TRUE)
    {
      if (fgets(line, MAXLENLINE, file) == NULL) return(0);
      if (strstr(line, "ATOM     ZNUC       X             Y             Z"))
      {
        version=1;
        break;
      }
      if (strstr(line, "ATOM     ZNUC       DE/DX         DE/DY         DE/DZ"))
      {
        version=2;
        break;
      }
    }
    if (version == 1)
    {
      do
      {
        fgets(line, MAXLENLINE, file);
	word=line;
	while (*word == ' ') word++;
      } while (*word != '1');
/*    fgets(line, MAXLENLINE, file);
      fgets(line, MAXLENLINE, file); */
      i=0;
      while (line[0] != '\n')
      {
        (void)strtok(line, " \t");
        (void)strtok(NULL, " \t");
        atomicCharge=atof(strtok(NULL, " \t"));
        atomNumber=(int)floor(atomicCharge);
        if (fabs((double)atomNumber-atomicCharge) < 1.0e-6)
        {
          atomNumber--;
          symbol[3*i]=pse[atomNumber][0];
          symbol[3*i+1]=pse[atomNumber][1];
          symbol[3*i+2]='\0';
          x[i]=atof(strtok(NULL, " \t\n"));
          y[i]=atof(strtok(NULL, " \t\n"));
          z[i]=atof(strtok(NULL, " \t\n"));
          gx[i]=atof(strtok(NULL, " \t\n"));
          gy[i]=atof(strtok(NULL, " \t\n"));
          gz[i]=atof(strtok(NULL, " \t\n"));
          i++;
        }
        if (fgets(line, MAXLENLINE, file) == NULL) break;
      }
      word=fgets(line, MAXLENLINE, file);
      (void)strtok(line, " \t");
      (void)strtok(NULL, " \t");
      (void)strtok(NULL, " \t");
      (void)strtok(NULL, " \t");
      (void)strtok(NULL, " \t");
      (void)strtok(NULL, " \t");
      (void)strtok(NULL, " \t");
      gnorm=atof(strtok(NULL, " \t"));
    }
    if (version == 2)
    {
      fgets(line, MAXLENLINE, file);
      fgets(line, MAXLENLINE, file);
      i=0;
      while (line[0] != '\n')
      {
        (void)strtok(line, " \t");
        (void)strtok(NULL, " \t");
        atomicCharge=atof(strtok(NULL, " \t"));
        atomNumber=(int)floor(atomicCharge);
        if (fabs((double)atomNumber-atomicCharge) < 1.0e-6)
        {
          atomNumber--;
          symbol[3*i]=pse[atomNumber][0];
          symbol[3*i+1]=pse[atomNumber][1];
          symbol[3*i+2]='\0';
          gx[i]=atof(strtok(NULL, " \t\n"));
          gy[i]=atof(strtok(NULL, " \t\n"));
          gz[i]=atof(strtok(NULL, " \t\n"));
          i++;
        }
        if (fgets(line, MAXLENLINE, file) == NULL) break;
      }
      do
      {
        if (fgets(line, MAXLENLINE, file) == NULL) break;
      } while (!strstr(line, "RMS GRADIENT"));
      (void)strtok(line, " \t");
      (void)strtok(NULL, " \t");
      (void)strtok(NULL, " \t");
      (void)strtok(NULL, " \t");
      (void)strtok(NULL, " \t");
      (void)strtok(NULL, " \t");
      (void)strtok(NULL, " \t");
      gnorm=atof(strtok(NULL, " \t"));
      do
      {
        if (fgets(line, MAXLENLINE, file) == NULL) break;
      } while (!strstr(line, "COORDINATES OF ALL ATOMS ARE (ANGS)"));
      fgets(line, MAXLENLINE, file);
      fgets(line, MAXLENLINE, file);
      fgets(line, MAXLENLINE, file);
      i=0;
      while (line[0] != '\n')
      {
        (void)strtok(line, " \t");
        (void)strtok(NULL, " \t");
        x[i]=atof(strtok(NULL, " \t\n"));
        y[i]=atof(strtok(NULL, " \t\n"));
        z[i]=atof(strtok(NULL, " \t\n"));
        i++;
        if (fgets(line, MAXLENLINE, file) == NULL) break;
      }
    }
    if (!cycle++)
    {
      if (version == 1) printf("$grad 0.52917706\n");
      else              printf("$grad 1.0\n");
    }
    printf("  cycle = %3d    SCF energy = %17.10f   |dE/xyz| = %9.6f\n", cycle, energy, gnorm);
    for (i=0; i<na; i++)
      printf("%22.14f%22.14f%22.14f  %s\n", x[i], y[i], z[i], &symbol[3*i]);
    for (i=0; i<na; i++)
      printf("%22.14e%22.14e%22.14e\n", gx[i], gy[i], gz[i]);
  }
  return(cycle);
}

void printCoord(double **coord, char **symbol, int na, int version)
{
  double *x, *y, *z;
  char *s;
  register int i;

  x=*coord;
  y=x+na;
  z=y+na;
  s=*symbol;
  if (version == 1)
    printf("$coord 0.52917706\n");
  else
    printf("$coord 1.0\n");
  for (i=0; i<na; i++)
    printf("%22.14f%22.14f%22.14f  %s\n", x[i], y[i], z[i], &s[3*i]);

  fremem((void **)coord);
  fremem((void **)symbol);
}

void makeLower(char *line)
{
  char *p=line;

  while (*p)
  {
    *p=tolower(*p);
    p++;
  }
}

void changeDs(char *line)
{
  char *p;

  p=line;
  while (*p)
  {
    if (*p == 'D') *p='e';
    if (*p == '\n') *p='\0';
    p++;
  }
}
