/* $Id$ */

/*****************************************************************************
** 
**      Date: 22th June 2002
**
**	Author: Scott A. Belmonte
**
******************************************************************************
******************************************************************************
*     PATE is                                                                
*           a program that extracts the observed and calculated powder       
*           patterns and tick marks from the GSAS files                      
*           *.P## for use with graph plotting software.
* 
*           Requires the *.EXP file and the *.P## file for each 
*           histogram in the experiment. 
*
*     Program Web-site at:                                                   
*            http://www.ccp14.ac.uk/ccp/web-mirrors/scott-belmonte-software/ 
*                                                                            
*                            Scott A. Belmonte - September 1999             
*                            s.a.belmonte@dl.ac.uk                           
*                            Department of Physics and Astronomy             
*                            University of Edinburgh                         
*                            UK.                                   
*                                                                            
******************************************************************************
******************************************************************************
*
*    Copyright (C) 1998 - 2002 Scott Belmonte
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 
* 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*
*
***********************************************************************/


/*
 * $Log$
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stddef.h>
#include <ctype.h>
#include <math.h>

#define PI 3.14159265
#define MAX_HISTS 99

struct patternData {
  int icode;
  float t, yo, yc, yi, yb, yw, cw;
  int iovlp;
};

void get_gsas_line(char *line, FILE *file);

int main(int argv, char *argc[])
{
  
  FILE *exp_file, *pattern_file;
  FILE *patout, *refout;
  char *locate, expnam[1024], exp_filename[1024];
  char pattern_filename[1024];
  char patout_filename[1024], refout_filename[1024];
  int length, i, j, k, nhsts, end, icode, power;
  char hst_type[MAX_HISTS][5], line[81], suffix[5];
  struct patternData pattern_data[14];
  float dummy, x;
  
  printf("\n");
  printf("********************************************\n");
  printf("*                PATE V1.2.1               *\n");
  printf("*      GSAS Powder Pattern Extractor.      *\n");
  printf("*                                          *\n");
  printf("*    (c) 1998 - 2002 Scott A. Belmonte     *\n");
  printf("********************************************\n");
  printf("\n");
  
  printf("Given EXPNAM.EXP and the EXPNAM.P## files\n");
  printf("(one for each histogram). PATE extracts\n");
  printf("the observed, calculated and difference\n");
  printf("plots for each histogram in the experiment\n");
  printf("in ascii format suitable for reading into\n");
  printf("plotting programs such as Origin.\n\n\n");
  
  printf("Enter EXPNAM: ");
  scanf("%s", expnam);
  
  
  /* Check to see if the filename ends in .EXP. If not
  add it to the end. */
  if ((locate = strstr(expnam, ".")) != NULL) {
    *locate = '\0';
  } 
  
  strcpy(exp_filename, expnam);
  strcat(exp_filename, ".exp");
  
  /* Try to open the *.EXP file. */
  if ((exp_file = fopen(exp_filename, "r")) == NULL) {
    
    /* Can't open with lower case filename so try all upper case. */ 
    length = strlen(exp_filename);
    for (i = 0; i < length; i++) exp_filename[i] =
      toupper(exp_filename[i]);  
    if ((exp_file = fopen(exp_filename, "r")) == NULL) {
      printf("Error opening %s\n", exp_filename);
      exit(1);
    }
  }
  
  /* Parse the *.EXP file to get the number of histograms and 
  their type. */
  nhsts = 0;
  end = 0;
  get_gsas_line(line, exp_file);
  while (!feof(exp_file) && end == 0 && nhsts < MAX_HISTS) {
    if ((strncmp(line, " EXPR  HTYP", 11)) == 0) {
      for (i = 0; i < 12; i++) {
        strncpy(hst_type[nhsts], &line[14 + i*5], 4);
        hst_type[nhsts][4] = '\0';
        if (hst_type[nhsts][0] != ' ') 
          nhsts++;
        else
          end = 1;
      }
    }
    get_gsas_line(line, exp_file);
  }
  
  /*
  printf("Num histograms: %d\n", nhsts);
  for (i = 0; i < nhsts; i++) 
  printf("%d: %s\n", i, hst_type[i]);
  */
  
  /* Now, for every powder histogram open the correponding *.P##
  file and extract the powder pattern and tick marks. */
  for (i = 0; i < nhsts; i++) {
    if (hst_type[i][0] == 'P') {
      strcpy(pattern_filename, expnam);
      sprintf(suffix, ".p%.2d", i + 1);
      strcat(pattern_filename, suffix);
      
      if ((pattern_file = fopen(pattern_filename, "rb")) == NULL) {      
        length = strlen(pattern_filename);
        for (j = 0; j < length; j++) pattern_filename[j] =
          toupper(pattern_filename[j]); 
        if ((pattern_file = fopen(pattern_filename, "rb")) == NULL) {
          printf("Error opening %s\n", pattern_filename);
          exit(1);
        }
      }
      
      strcpy(patout_filename, expnam);
      sprintf(suffix, ".a%.2d", i + 1);
      strcat(patout_filename, suffix);
      
      strcpy(refout_filename, expnam);
      sprintf(suffix, ".b%.2d", i + 1);
      strcat(refout_filename, suffix);
      
      if ((patout = fopen(patout_filename, "w")) == NULL) {
        printf("Error opening %s\n", patout_filename);
        exit(1);
      }
      
      if ((refout = fopen(refout_filename, "w")) == NULL) {
        printf("Error opening %s\n", refout_filename);
        exit(1);
      }
      
      /* Read in blocks of 14 because of the way the *.P## file
      is formatted. */
      fread(pattern_data, sizeof(struct patternData), 14, pattern_file);
      while (!feof(pattern_file)) {    
        for (j = 0; j < 14; j++) {
            if (hst_type[i][2] == 'C')
                x = pattern_data[j].t/100;
            else 
                x = pattern_data[j].t;
            
            fprintf(patout, "%7.3f %8.1f %8.1f %8.1f %11.4f %11.4f\n", 
                x, pattern_data[j].yo*pattern_data[j].yi,
                pattern_data[j].yc*pattern_data[j].yi,
                (pattern_data[j].yo - pattern_data[j].yc)*pattern_data[j].yi,
                pattern_data[j].yi, pattern_data[j].yb);
            
            icode = pattern_data[j].icode/4; 
            for (k = 10; k >= 0; k--) {
                power = (int) pow((double) 2, (double) k);
                if (icode/power == 1) {
                    fprintf(refout, "%7.3f %2d\n", x, k + 1);
                    icode = icode % power;
                }
            }
        }
        
        /* Read the dummy pad bytes. */
        fread(&dummy, sizeof(dummy), 1, pattern_file);
        fread(&dummy, sizeof(dummy), 1, pattern_file);
        fread(pattern_data, sizeof(struct patternData), 14, pattern_file);
      }
      
      fclose(patout);
      fclose(refout);
      fclose(pattern_file);
    }
  }
  
  fclose(exp_file);
  return 0;
}


void get_gsas_line(char *line, FILE *file) {

  char ch;
  int nRead;
    
  /* The line parameter must point to a character array
   * of at least 81 bytes, enough for 80 characters 
   * followed by a NULL.
   *
   *
   * Routine that reads lines from all types of GSAS 
   * ASCII files (UNIX and PC). 
   */
  nRead = fread(line, 1, 80, file);
  if (nRead == 80) {
    fread(&ch, 1, 1, file);
    switch (ch) {
    case '\n':
      /* Don't do anything. */
      break;
    case '\r':
      /* Jump forward one char because this is 
       * probably a PC format text file with \r\n
       * pairs terminating the lines. 
       */
      fseek(file, 1, SEEK_CUR);
      break;
    default:
      /* If there is no \n or \r after 80 chars then
       * this is probably a UNIX format GSAS file.
       */
      fseek(file, -1, SEEK_CUR);
      break;
    }
  }

  line[nRead] = '\0';
}
