/*************************************************************************************
 * Program: XRDCALC1.2                                                               *
 * Purpose: Calculate ferrite and austenite lattice parameters and phase fractions   *                                             
 * from peak positions. Program also attempts to calculate size and strain from      *
 * the broadness of the peaks (this feature experimental and should be used with     * 
 * extra caution.                                                                    *
 * Author:  Dr Marimuthu Murugananth and Mr Mathew J Peet                            *
 * Version: 1.2                                                                      *
 * Date:    14-December-09                                                           *
 * Location: http://mathewpeet.org/thesis/programs/                                  *
 * License: GPL, Gnu Public License, you are free to modify and use this program     *
 * if you distribute the program you must also distribute the code, along with any   *
 * changes you make. Do not modify this header.                                      *
 *                                                                                   *
 ************************************************************************************/




#include<stdio.h>
#include<math.h>
#include<stdlib.h>
#define PI 3.141592654
int no_fer_peaks,fer_h[20],fer_k[20],fer_l[20],fer_hkl2[20];
int no_aus_peaks,aus_h[20],aus_k[20],aus_l[20], aus_hkl2[20];
float wavelength;
float aus_peak_theta_rad[20],fer_peak_theta_rad[20];
float aus_breadth[20],fer_breadth[20];
FILE *fres, *fentry;
float gradient, intercept;
float aus_a[20],fer_a[20],LPF_aus[20],LPF_fer[20];
int i,system_choice,option_alloy;
char iptchoice;
int MF_aus[20],MF_fer[20];
float value;
float aus_peak_2theta[20],fer_peak_2theta[20],aus_peak_theta[20],fer_peak_theta[20];
float sine_by_lambda_fer[20],sine_by_lambda_aus[20],fer_d[20],aus_d[20];
float F_aus[20],F_fer[20],F_aus2[20],F_fer2[20];
float asc;
/*float atom_scatter();*/
float e2m_aus[20],e2m_fer[20],aus_Iint[20],fer_Iint[20];
float inten_err_aus[20],R_fer[20],R_aus[20],inten_err_fer[20],IbyR_aus[20],IbyR_fer[20];
float ave_aus,ave_fer,Afer,Aaus,Aus_frac,Fer_frac,inten_err_aus_total;
float inten_err_fer_total,pre_total_error,total_error;
char name[50],filename[61],inputfname[58]; 

int main(void)
{
  title();  
  printf("Type the Identification name of the material : \t");
  scanf("%s",name);
  sprintf(filename,"%s_XRD_result",name);
  sprintf(inputfname,".%s_inputs",name);
  printf("\n%s\n",inputfname);
  getchar();
  
  if((fentry=fopen(inputfname,"r"))!=NULL)
    {
      printf("\n\nYour input file \"%s\" for the identification name \"%s\" exists\n Do you want to use that (Y/N)? \t",inputfname,name);
      scanf("%c",&iptchoice);
      printf("%c",iptchoice);
      iptchoice = toupper(iptchoice);
      printf("%c",iptchoice);
      if(iptchoice=='Y')
	{
	  get_values_from_file();
        }   
      else
	{
	  printf("\n\nExiting XRDCALC...");
	  exit(0);
	}
    }
  else
    {
      get_values_from_stdio();
      print_to_entry_file();
    }  
  
  printf ("here");
  getchar();

  if((fres=fopen(filename,"w"))!=NULL)
    {
      calculate_stuff();
      calculate_d_spacings();
      calculate_lattice_param();
      calculte_lorentz_polarization_factor();
      regression(LPF_aus,aus_a,no_aus_peaks); 
      print_lp();
      regression(LPF_fer,fer_a,no_fer_peaks);
      print_lp();
      calculate_multiplicity_factor();	  
      calculate_structure_factor();
      calculate_temperature_factor();
      calculate_R_factor();
      result_to_stdio();
      average_lattice_param();
      print_to_file();
    }        
  else
    {
      printf("%s already exists\n\nPlease rename it and then run this program\n\n", filename);
      printf("\n\nExiting XRDCALC...");
      exit(0);
    }
}

float atom_scatter(lambda,opt,sin_by_lambda)     
     int opt;
     float sin_by_lambda,lambda;     
{  
  float ffe,fni,fcr,f,f_err,ratio_lambda;  
  ffe=298.541*pow(sin_by_lambda,7)-1416.84*pow(sin_by_lambda,6)+2708.46*pow(sin_by_lambda,5)-2647.53*pow(sin_by_lambda,4)+1369.02*pow(sin_by_lambda,3)-323.115*pow(sin_by_lambda,2)-8.21796*sin_by_lambda+26.0038; 
  fni=164.627*pow(sin_by_lambda,7)-881.92*pow(sin_by_lambda,6)+1866.91*pow(sin_by_lambda,5)-1994.09*pow(sin_by_lambda,4)+1115.99*pow(sin_by_lambda,3)-281.002*pow(sin_by_lambda,2)-11.5068*sin_by_lambda+28.0041;  
  fcr=255.541*pow(sin_by_lambda,7)-1208.95*pow(sin_by_lambda,6)+2301.11*pow(sin_by_lambda,5)-2237.69*pow(sin_by_lambda,4)+1149.36*pow(sin_by_lambda,3)-266.194*pow(sin_by_lambda,2)-11.4846*sin_by_lambda+23.9948;
  switch(opt)
    {
    case 1: f=ffe;break;
    case 2: f=(ffe+fni)/2;printf("\n[ %f ]Selected Fe and Ni \tffe=%f fni=%f f = %f",sin_by_lambda,ffe,fni,f);break;
    case 3: f=(ffe+fcr)/2;break;
    case 4: f=(ffe+fcr+fni)/3;break;
    }
  ratio_lambda=lambda/1.74346;
  if (ratio_lambda <= 1)
    {
      f_err=-33745.3*pow(ratio_lambda,10) + 158121*pow(ratio_lambda,9) - 314972*pow(ratio_lambda,8) + 347441*pow(ratio_lambda,7) - 231665*pow(ratio_lambda,6) + 95617.5*pow(ratio_lambda,5) - 24013.6*pow(ratio_lambda,4) + 3450.3*pow(ratio_lambda,3) - 248.253*pow(ratio_lambda,2) + 7.56109*ratio_lambda + 0.0341823;
      printf("\nError Associated [ratio_lambda = %f ]\t ratio <= 1:\t%f\n",ratio_lambda ,f_err);
    }
  else if (ratio_lambda > 1 && ratio_lambda <= 1.13)
    {
      f_err=327.877*pow(ratio_lambda,7)-3700.62*pow(ratio_lambda,6)+17745.5*pow(ratio_lambda,5)-46856.2*pow(ratio_lambda,4)+73564.1*pow(ratio_lambda,3)-68668*pow(ratio_lambda,2)+35288.7*ratio_lambda-7705.91 ;
      printf("\nError Associated [Ratio_lambda = %f ]\t:\t%f\n",ratio_lambda ,f_err);
    }
  else /*if(ratio_lambda > 1.13) */
    {
      f_err=2.31485*pow(ratio_lambda,6)-19.2679*pow(ratio_lambda,5)+61.2172*pow(ratio_lambda,4)-87.0473*pow(ratio_lambda,3)+38.6116*pow(ratio_lambda,2)+28.3705*ratio_lambda-27.3772;
      printf("\nError Associated [ratio_lambda = %f ]\t:\t%f\n",ratio_lambda,f_err);
    }
  return(f+f_err);
}

int title()
{
  printf("----------------------------------------------------------------------\n");
  printf("\n");
  printf("\t   CALCULATION OF PHASE FRACTIONS USING XRD DATA\n\n");
  printf("----------------------------------------------------------------------\n\n\n\n");
  printf("\n\n\n\t\t\t    By\n\t\t\tMurugananth M\n\t\tPhase Transformation Group\n\t\t  University of Cambridge\n\n\n\n");
}


/*CALCULATE CRYSTALLITE SIZE AND STRAIN */
int size_strain()
{ 
  int i,j; 
  float fer_four_sin_theta[20],fer_breadth_2theta_radians[20],fer_beta_cos_theta[20];
  float aus_four_sin_theta[20],aus_breadth_2theta_radians[20],aus_beta_cos_theta[20];
  float slope, constant;
  
  for(i=1;i<=no_fer_peaks;i++)
    {
      fer_four_sin_theta[i]=4*sin(fer_peak_theta_rad[i]);
      fer_breadth_2theta_radians[i]=fer_breadth[i]*(PI/180);
      fer_beta_cos_theta[i]=fer_breadth_2theta_radians[i]*cos(fer_peak_theta_rad[i]);
      printf("theta_rad = %f  breadth= %f  breadth_rad= %f ",fer_peak_theta_rad[i],fer_breadth[i],fer_breadth_2theta_radians[i]);
      printf("4sin(theta) = %f",fer_four_sin_theta[i]);
      printf("beta_cos(theta) = %f\n",fer_beta_cos_theta[i]);
    }
  
  printf("Searching peaks \n", i, j);
  for(i=1;i<=no_fer_peaks;i++)
    for(j=1;j<=no_fer_peaks;j++)
      {
	if((2*fer_h[i])==fer_h[j] && (2*fer_l[i])==fer_l[j] && (2*fer_k[i])==fer_k[j] || (3*fer_h[i])==fer_h[j] && (3*fer_l[i])==fer_l[j] && (3*fer_k[i])==fer_k[j])
	  {
	    printf("\nPeak %d (%d %d %d) and peak %d (%d %d %d) of ferrite are of the same direction\n", i,fer_h[i],fer_l[i],fer_k[i],j,fer_h[j],fer_l[j],fer_k[j]);
	    constant = (fer_beta_cos_theta[j]-fer_beta_cos_theta[i])/(fer_four_sin_theta[j]-fer_four_sin_theta[i]);
	    printf("\nGradient = strain = %f",slope);
	    fprintf(fres,"\nGradient = strain = %f",slope);
	    slope = fer_beta_cos_theta[i] - slope*fer_four_sin_theta[i];
	    printf("\nIntercept = %f",constant);
	    printf("\nSize = %f nanometers\n",wavelength*0.1*0.9/constant);
	    fprintf(fres,"\nSize = %f nanometers\n",wavelength*0.1*0.9/constant);
	  }
	else printf(".");
      }
  printf("\nRegression on ferrite peaks");
  fprintf(fres,"\nRegression on ferrite peaks");
  regression(fer_four_sin_theta,fer_beta_cos_theta,no_fer_peaks);
  print_regression();
  
  for(i=1;i<=no_aus_peaks;i++)
    {
      aus_four_sin_theta[i]=4*sin(aus_peak_theta_rad[i]);
      aus_breadth_2theta_radians[i]=aus_breadth[i]*(PI/180);
      aus_beta_cos_theta[i]=aus_breadth_2theta_radians[i]*cos(aus_peak_theta_rad[i]);
      printf("theta_rad = %f  breadth= %f  breadth_rad= %f ",aus_peak_theta_rad[i],aus_breadth[i],aus_breadth_2theta_radians[i]);
      printf("4sin(theta) = %f",aus_four_sin_theta[i]);
      printf("beta_cos(theta) = %f\n",aus_beta_cos_theta[i]);
    }
  printf("Searching peaks \n", i, j);
  for(i=1;i<=no_aus_peaks;i++)
    for(j=1;j<=no_aus_peaks;j++)
      {
	if((2*aus_h[i])==aus_h[j] && (2*aus_l[i])==aus_l[j] && (2*aus_k[i])==aus_k[j] || (3*aus_h[i])==aus_h[j] && (3*aus_l[i])==aus_l[j] && (3*aus_k[i])==aus_k[j])
	  {
	    printf("\nPeak %d (%d %d %d) and peak %d (%d %d %d) of austenite are of the same direction\n", i,aus_h[i],aus_l[i],aus_k[i],j,aus_h[j],aus_l[j],aus_k[j]);
	    slope = (aus_beta_cos_theta[j]-aus_beta_cos_theta[i])/(aus_four_sin_theta[j]-aus_four_sin_theta[i]);
	    printf("\nGradient = strain = %f",slope);
	    fprintf(fres,"\nGradient = strain = %f",slope);
	    constant = aus_beta_cos_theta[i] - slope*aus_four_sin_theta[i];
	    printf("\nIntercept = %f",constant);
	    printf("\nSize = %f nanometers\n",wavelength*0.1*0.9/constant);
	    fprintf(fres,"\nSize = %f nanometers\n",wavelength*0.1*0.9/constant);
	  }	
	else printf(".");
      }
  printf("\nRegression on austenite peaks");
  fprintf(fres,"\nRegression on austenite peaks");
  regression(aus_four_sin_theta,aus_beta_cos_theta,no_aus_peaks);
  print_regression();
}

int regression(float x[20], float y[20], int N)
{
  int i;
  float Ex, Ey, Ex2, Ey2, Exy;	
  float corr;
  float sxx,syy,sxy;
  Ex = 0.0;
  Ey = 0.0;
  Ex2 = 0.0;
  Ey2 = 0.0;
  Exy = 0.0;
  for(i=1;i<=N;i++)
    {
      Ex=Ex+x[i];
      Ey=Ey+y[i];
      Exy=Exy+x[i]*y[i];
      Ey2=Ey2+y[i]*y[i];
      Ex2=Ex2+x[i]*x[i];
      /* printf("\ni = %d",i);*/ /*for testing */
    }
  sxx = Ex2 - Ex * Ex / N;
  syy = Ey2 - Ey * Ey / N;
  sxy = Exy - Ex * Ey / N;
  gradient = sxy / sxx;
  intercept = Ey/N-gradient*Ex/N;
  corr = sxy / sqrt(sxx * syy);
  printf("\nsxx= %lf, syy = %lf, sxy = %lf, gradient = %lf, intercept = %lf, corr= %lf \n",sxx,syy,sxy,gradient,intercept,corr);
  fprintf(fres,"\nsxx= %lf, syy = %lf, sxy = %lf, gradient = %lf, intercept = %lf, corr= %lf \n",sxx,syy,sxy,gradient,intercept,corr);
}

int print_regression(void)
{
  printf("\n-----------REGRESSION-----------\n");
  printf("\nGradient = strain = %f",gradient);
  printf("\nSize = %f nanometers",wavelength*0.1*0.9/intercept);
  fprintf(fres,"\nGradient = strain = %f",gradient);
  fprintf(fres,"\nSize = %f nanometers\n",wavelength*0.1*0.9/intercept);  
}

int print_lp(void)
{
  printf("\nLattice Parameter = %f",intercept);
  fprintf(fres,"\nLattice Parameter = %f ",intercept);  
}

int get_values_from_file(void)
{
  printf("\nReading from file %s\n", name);
  fscanf(fentry,"%s",name);
  fscanf(fentry,"%f",&wavelength);
  fscanf(fentry,"%d",&no_aus_peaks);
  fscanf(fentry,"%d",&no_fer_peaks);
  for(i=1;i<=no_aus_peaks;i++)
    fscanf(fentry,"%d %d %d %f %f %f",&aus_h[i],&aus_k[i],&aus_l[i],&aus_peak_2theta[i],&aus_Iint[i],&aus_breadth[i]);
  for(i=1;i<=no_fer_peaks;i++)
    fscanf(fentry,"%d %d %d %f %f %f",&fer_h[i],&fer_k[i],&fer_l[i],&fer_peak_2theta[i],&fer_Iint[i],&fer_breadth[i]);
  fscanf(fentry,"%d",&system_choice);
  fscanf(fentry,"%d",&option_alloy);
  fclose(fentry);
}



int get_values_from_stdio()
{
  printf("Input entries will be logged to \t : %s\n\n", inputfname);
  printf("Enter the wavelength of the X-radiation used in Angroms:\t");
  scanf("%f",&wavelength);
  printf("\n\nHow many austenite peaks have you got\t:\t");
  scanf("%d",&no_aus_peaks);
  printf("How many ferrite peaks have you got\t:\t");
  scanf("%d",&no_fer_peaks);
  for(i=1;i<=no_aus_peaks;i++)
    {
      printf("\nEnter {hkl} for AUSTENITE peak %d (h k l seperated by spaces):\t", i);
      scanf("%d %d %d",&aus_h[i],&aus_k[i],&aus_l[i]);
      printf("Enter the TWO THETA value:\t",i);
      scanf("%f",&aus_peak_2theta[i]);
      printf("Enter Integrated Intensity:\t",i,aus_peak_2theta[i]);
      scanf("%f",&aus_Iint[i]);
      printf("Enter Breadth:\t",i);
      scanf("%f",&aus_breadth[i]);
      printf("\nPeak %d of austenite, is {%d %d %d}, 2theta %f, Integrated intensity %f, breadth %f, do you accept (Y/N)?", i,aus_h[i],aus_k[i],aus_l[i],aus_peak_2theta[i],aus_Iint[i],aus_breadth[i]);
      getchar();
      scanf("%c",&iptchoice);
      iptchoice = toupper(iptchoice);
      if(iptchoice!='Y')
	i=i-1;
    }
  for(i=1;i<=no_fer_peaks;i++) 
    {
      printf("\nEnter {hkl} for FERRITE peak %d (h k l seperated by spaces):\t", i);
      scanf("%d %d %d",&fer_h[i],&fer_k[i],&fer_l[i]);
      printf("Enter the TWO THETA value for peak %d of FERRITE:\t",i);
      scanf("%f",&fer_peak_2theta[i]);
      printf("Integrated Intensity for peak %d with 2-Theta %f of FERRITE:\t",i,fer_peak_2theta[i]);
      scanf("%f",&fer_Iint[i]);
      printf("Enter Breadth of peak %d of FERRITE:\t",i);
      scanf("%f",&fer_breadth[i]);
      printf("\nPeak %d of ferrite, is {%d %d %d}, 2theta %f, Integrated intensity %f, breadth %f, do you accept (Y/N)?", i,fer_h[i],fer_k[i],fer_l[i],fer_peak_2theta[i],fer_Iint[i],fer_breadth[i]);
      getchar();
      scanf("%c",&system_choice);/*corrected from iptchoice?*/
      iptchoice = toupper(iptchoice);
      if(iptchoice!='Y')
	i=i-1;
    }    
  printf("\n\n\nWhich system_choice are you using\n");
  printf("\n\t1.\tCUBIC\n\t2.\tHEXAGONAL and RHOMBHOHEDRAL\n\t3.\tTETRAGONAL\n\t4.\tORTHORHOMBIC\n\t5.\tMONOCLINIC\n\t6.\tTRICLINIC\n\n");
  printf("Enter option:\t");
  /*scanf("%d",&system_choice);*/
  /* if(iptchoice!=1)scanf("%d",&system_choice);*/
  /* choice commented out because the other options are not yet available */
  
  if(system_choice!=1)
    {
      system_choice=1;
      printf("\nSorry forcing system choice to 1\n");
    }
  
  printf("\n\n--------------  STRUCTURE FACTOR --------------------\n\n");
  printf("\n\nThe major alloying elements in your steel are\t:\n\t1.\tFe only\n\t2.\tFe and Ni\n\t3.\tFe and Cr\n\t4.\tFe, Ni and Cr\n\n\tChoose option:\t");
  /*scanf("%d",&option_alloy); */
  printf("\nSorry forcing alloy option to 1  (feature not implimented)\n");
}



int print_to_entry_file()
{
  fentry=fopen(inputfname,"w");
  fprintf(fentry, "%s\n%f\n%d\n%d\n", name,wavelength,no_aus_peaks,no_fer_peaks);
  for(i=1;i<=no_aus_peaks;i++)
   {
      fprintf(fentry,"%d %d %d \t %f %f %f\n",aus_h[i],aus_k[i],aus_l[i],aus_peak_2theta[i],aus_Iint[i],aus_breadth[i]);
    }
 for(i=1;i<=no_fer_peaks;i++)
    {
      fprintf(fentry,"%d %d %d \t%f %f %f\n",fer_h[i],fer_k[i],fer_l[i],fer_peak_2theta[i],fer_Iint[i],aus_breadth[i]);
    }
 fprintf(fentry,"%d\n",system_choice);
 fprintf(fentry,"%d\n",option_alloy);
 fclose(fentry);  
}



int print_to_file()
{ 
  fprintf(fres,"\n----------------------------------------------------------------------\n");
  fprintf(fres,"\n");
  fprintf(fres,"\t\tCALCULATION OF PHASE FRACTIONS USING XRD DATA\n");
  fprintf(fres,"\n");
  fprintf(fres,"----------------------------------------------------------------------\n");
  fprintf(fres, "Material Identification : \t %s", name);
  fprintf(fres, "\n\nWAVELENGTH USED : %f", wavelength);

  fprintf(fres,"\n\n--------------THETA VALUES--------------------\n\n");
  for(i=1;i<=no_aus_peaks;i++)
    {
      fprintf(fres,"2theta for AUSTENITE : %f\t sin(theta)_by_lambda : %f  \n", aus_peak_2theta[i],sine_by_lambda_aus[i]);
      fprintf(fres,"Integrated Intensity %d AUSTENITE: %f\n\n",i, aus_Iint[i]);
    }
  for(i=1;i<=no_fer_peaks;i++)
    {
      fprintf(fres,"2theta for FERRITE : %f\t sin(theta)_by_lambda : %f  \n", fer_peak_2theta[i],sine_by_lambda_fer[i]);
      fprintf(fres,"Integrated Intensity %d FERRITE: %f\n\n",i, fer_Iint[i]);
    }      

  fprintf(fres,"\n\n-------------- D-SPACING --------------------\n\n");
  for(i=1;i<=no_aus_peaks;i++)
    {
      fprintf(fres,"d-spacing for AUSTENITE : %f \n",aus_d[i]);
    }     
  for(i=1;i<=no_fer_peaks;i++)
    {
      fprintf(fres,"d-spacing for FERRITE : %f \n",fer_d[i]);
    }
  
  fprintf(fres,"\n\n--------------LATTICE PARAMETER RESULTS--------------------\n\n"); 
  
  for(i=1;i<=no_aus_peaks;i++)
    {
      fprintf(fres, "\nAUSTENITE [ 2-Theta=%f ]: \t %f",aus_peak_2theta[i],aus_a[i]);
    }     
  for(i=1;i<=no_fer_peaks;i++)
    {
      fprintf(fres,"\nFERRITE [ 2-Theta=%f ] : \t %f",fer_peak_2theta[i], fer_a[i]);
    }
  
  fprintf(fres,"\n\n--------------   LORENTZ POLARIZATION FACTOR --------------------\n\n");  
  for(i=1;i<=no_aus_peaks;i++)
    {
      fprintf(fres, "AUSTENITE 2-Theta : %f\t LPF [ %d ] : %f \n", aus_peak_2theta[i], i, LPF_aus[i]); 
    }     
  for(i=1;i<=no_fer_peaks;i++)
    {
      fprintf(fres, "FERRITE 2-Theta : %f\t LPF [ %d ] : %f \n", fer_peak_2theta[i], i, LPF_fer[i]);
    }
  
  fprintf(fres,"\n\n--------------  MULTIPLICITY FACTOR --------------------\n\n");
  for(i=1;i<=no_aus_peaks;i++)
    {
      fprintf(fres, "Multipilicity factor [ 2-Theta = %f, {%d%d%d} ] : %d\n",aus_peak_2theta[i],aus_h[i], aus_k[i], aus_l[i], MF_aus[i]);
    }     
  for(i=1;i<=no_fer_peaks;i++)
    {
      fprintf(fres, "Multipilicity factor [ 2-Theta = %f, {%d%d%d} ] : %d\n",fer_peak_2theta[i],fer_h[i], fer_k[i], fer_l[i], MF_fer[i]);
    }

  fprintf(fres,"\n\n--------------  STRUCTURE FACTOR --------------------\n\n");
  if (option_alloy==1) 
    fprintf(fres, "Selected system Fe only\n\n");
  else if (option_alloy==2)
    fprintf(fres, "Selected system Fe & Ni only\n\n");
  else if (option_alloy==3)
    fprintf(fres, "Selected system Fe & Cr only\n\n");
  else if (option_alloy==4)
    fprintf(fres, "Selected system Fe, Cr & Ni only\n\n");  
  
  for(i=1;i<=no_fer_peaks;i++)
    { 
      fprintf(fres, "Fer [ sin(theta)_by_lambda=%f ]\tAtomic Scattering factor=%f \t F2=%f\n", sine_by_lambda_fer[i],asc, F_fer2[i]);
    }     
  for(i=1;i<=no_fer_peaks;i++)
    {
      fprintf(fres, "Aus [ sin(theta)_by_lambda=%f ]\tAtomic Scattering factor=%f \t F2=%f\n", sine_by_lambda_aus[i],asc, F_aus2[i]);
    }
  
  fprintf(fres,"\n\n--------------  TEMPERATURE FACTOR --------------------\n\n"); 
  
  for(i=1;i<=no_aus_peaks;i++)
    { 
      fprintf(fres,"Austenite e^-2m [ sin(theta)_by_lambda=%f ]: %f\n", sine_by_lambda_aus[i],e2m_aus[i]);
    }
  for(i=1;i<=no_fer_peaks;i++)
    {
      fprintf(fres,"Ferrite e^-2m [ sin(theta)_by_lambda=%f ]: %f\n", sine_by_lambda_fer[i],e2m_fer[i]);
    }
  fprintf(fres,"\n\n--------------  R FACTOR --------------------\n\n");
  
  for(i=1;i<=no_fer_peaks;i++)
    {    
      fprintf(fres,"Ferrite R : %f\n",R_fer[i]); 
    }
  for(i=1;i<=no_aus_peaks;i++)
    {
      fprintf(fres,"Austenite R : %f\n",R_aus[i]); 
    }
  
  fprintf(fres,"\n\n--------------  RESULT --------------------\n\n");
  
  fprintf(fres,"Fraction of Austenite : %f  Ferrite : %f \n",Aus_frac, Fer_frac);
  fprintf(fres,"\n\nPercentage of austenite :\t%.3f %%\tError : %.4f%%", Aus_frac*100,total_error*100);
  fprintf(fres,"\nPercentage of ferrite     :\t%.3f %%\tError : %.4f %%\n\n", Fer_frac*100, total_error*100);
  size_strain();      
  fprintf(fres, "-------------------------  END  --------------------------------------");
  fclose(fres);
  
}
	 

int calculate_stuff()
{
  inten_err_aus_total=0.0;
  inten_err_fer_total=0.0; /*these variables need to be initialised*/
  for(i=1;i<=no_aus_peaks;i++)
    {
      aus_hkl2[i]=aus_h[i]*aus_h[i]+aus_k[i]*aus_k[i]+aus_l[i]*aus_l[i];	  
      aus_peak_theta[i]=aus_peak_2theta[i]/2;
      aus_peak_theta_rad[i]=(PI/180)*aus_peak_theta[i];
      sine_by_lambda_aus[i]=sin(aus_peak_theta_rad[i])/wavelength;
      inten_err_aus[i]=1/sqrt(aus_Iint[i]);
      inten_err_aus_total=inten_err_aus_total+inten_err_aus[i];
    }
  
  for(i=1;i<=no_fer_peaks;i++)
    {
      fer_hkl2[i]=fer_h[i]*fer_h[i]+fer_k[i]*fer_k[i]+fer_l[i]*fer_l[i];
      fer_peak_theta[i]=fer_peak_2theta[i]/2;
      fer_peak_theta_rad[i]=(PI/180)*fer_peak_theta[i];
      sine_by_lambda_fer[i]=sin(fer_peak_theta_rad[i])/wavelength;
      inten_err_fer[i]=1/sqrt(fer_Iint[i]);
      inten_err_fer_total=inten_err_fer_total+inten_err_fer[i];
    }
}


int calculate_d_spacings()
{
  /*printf("\n-----------D SPACING------------\n");*/
  for(i=1;i<=no_aus_peaks;i++)
    {
      aus_d[i]=wavelength/(2*sin(aus_peak_theta_rad[i]));	     
    }
  for(i=1;i<=no_fer_peaks;i++)
    {
      fer_d[i]=wavelength/(2*sin(fer_peak_theta_rad[i]));
    }  
}


int calculate_lattice_param()
{
  /* printf("\n------LATTICE PARAMETER---------\n");*/
  for(i=1;i<=no_aus_peaks;i++)
    {
      aus_a[i]=sqrt(aus_d[i]*aus_d[i]*aus_hkl2[i]);
      /* printf("\nAUSTENITE [ 2-Theta=%f ]: \t %f",aus_peak_2theta[i],aus_a[i]);*/
    }
  printf("\n\n");
  for(i=1;i<=no_fer_peaks;i++)
    {
      fer_a[i]=sqrt(fer_d[i]*fer_d[i]*fer_hkl2[i]);
      /* printf("\nFERRITE [ 2-Theta=%f ] : \t %f",fer_peak_2theta[i], fer_a[i]);*/
    }
}  

int calculte_lorentz_polarization_factor()
{
  /* printf("\n------LORENTZ POLARIZATION FACTOR--------\n");*/
  for(i=1;i<=no_aus_peaks;i++)
    {
      LPF_aus[i]=(1+cos(2*aus_peak_theta_rad[i])*cos(2*aus_peak_theta_rad[i]))/(sin(aus_peak_theta_rad[i])*sin(aus_peak_theta_rad[i])*cos(aus_peak_theta_rad[i]));
    }
  for(i=1;i<=no_fer_peaks;i++)
    {
      LPF_fer[i]=(1+cos(2*fer_peak_theta_rad[i])*cos(2*fer_peak_theta_rad[i]))/(sin(fer_peak_theta_rad[i])*sin(fer_peak_theta_rad[i])*cos(fer_peak_theta_rad[i]));
    }
}

int calculate_multiplicity_factor()
{
  switch(system_choice)
    {  
    case 1: /*printf("\n\nSelected system : CUBIC\n\n"); fprintf(fres, "\n\nSelected system : CUBIC\n\n");*/
      for(i=1;i<=no_aus_peaks;i++)
	{
	  printf("\nAustenite: {%d%d%d}",aus_h[i],aus_k[i],aus_l[i]);
	  if(aus_h[i]!=aus_k[i] && aus_k[i] != aus_l[i]) MF_aus[i]=48;
	  if(aus_h[i]==aus_k[i] && aus_k[i] != aus_l[i]) MF_aus[i]=24;
	  if(aus_h[i]==0 && aus_k[i] != aus_l[i]) MF_aus[i]=24;
	  if(aus_h[i]==0 && aus_k[i] == aus_l[i]) MF_aus[i]=12;
	  if(aus_h[i]==aus_k[i] && aus_k[i] == aus_l[i]) MF_aus[i]=8;
	  if(aus_h[i]==0 && aus_k[i] ==0) MF_aus[i]=6;
	  /* printf("\nMultipilicity factor [ 2-Theta = %f ]:\t%d\t sin_lambda:\t%f",aus_peak_2theta[i],MF_aus[i],sine_by_lambda_aus[i]); */
	}      
      printf("\n\n\n");
      for(i=1;i<=no_fer_peaks;i++)
	{
	  /*	  printf("\nFerrite: {%d%d%d}",fer_h[i],fer_k[i],fer_l[i]);*/
	  if(fer_h[i]!=fer_k[i] && fer_k[i] != fer_l[i]) MF_fer[i]=48;
	  if(fer_h[i]==fer_k[i] && fer_k[i] != fer_l[i]) MF_fer[i]=24;
	  if(fer_h[i]==0 && fer_k[i] != fer_l[i]) MF_fer[i]=24;
	  if(fer_h[i]==0 && fer_k[i] == fer_l[i]) MF_fer[i]=12;
	  if(fer_h[i]==fer_k[i] && fer_k[i] == fer_l[i]) MF_fer[i]=8;
	  if(fer_h[i]==0 && fer_k[i] ==0) MF_fer[i]=6;
	  /*	  printf("\nMultipilicity factor [ 2-Theta = %f ]:\t%d\t sin_lambda:\t%f",fer_peak_2theta[i],MF_fer[i],sine_by_lambda_fer[i]);*/
	}     
      break;
    case 2: printf("\n\nSelected system : HEXAGONAL and RHOMBHOHEDRAL\n\n");
      break;
    case 3: printf("\n\nSelected system : TETRAGONAL\n\n");
      break;
    case 4: printf("\n\nSelected system : ORTHORHOMBIC\n\n");
      break;
    case 5: printf("\n\nSelected system : MONOCLINIC\n\n");
      break;
    case 6: printf("\n\nSelected system : TRICLINIC\n\n");
      break;
    }
}


int calculate_structure_factor()
{
  /* printf("\n------STRUCTURE FACTOR---------\n");*/
  for(i=1;i<=no_fer_peaks;i++)
    {
      if((fer_h[i]+fer_k[i]+fer_l[i])%2 == 0) 
	{
	  asc=atom_scatter(wavelength,option_alloy,sine_by_lambda_fer[i]);
	  F_fer[i]=2*asc;
	  F_fer2[i]=F_fer[i]*F_fer[i];
	  /*  printf("\nFer [ sin_by_lambda %f ] asc=%f \t F2=%f",sine_by_lambda_fer[i],asc, F_fer2[i]);*/
	}
      else
	F_fer[i]=0;
    }  
  for(i=1;i<=no_aus_peaks;i++)
    {
      if((aus_h[i]+aus_k[i])%2==0 && (aus_h[i]+aus_l[i])%2==0 && (aus_k[i]+aus_l[i])%2==0)
	{
	  asc=atom_scatter(wavelength,option_alloy,sine_by_lambda_aus[i]);
	  F_aus[i]=4*asc;
	  F_aus2[i]=F_aus[i]*F_aus[i];
	  /*printf("\nAus [ sin_by_lambda %f ] asc=%f \t F2=%f", sine_by_lambda_aus[i],asc, F_aus2[i]);*/
	}  
      else
	F_aus[i]=0;
    }
} 

int calculate_temperature_factor()
{
  /* printf("\n--------------TEMPERATURE FACTOR---------------------------------\n");*/
  double debeye = 470; // Debeye temperature of the material in Kelvin from Kittel C, Introduction to solid state physics 7th Ed (Wiliey) 1995.
  double T_K    = 23+273; // Temperature in Kelvin
  double A = 55; //Atomic weight 
  double m = 0; // 'factor'
  double sine_by_lambda =0;

  for(i=1;i<=no_aus_peaks;i++)
    {
      /* debeye temperature factor? */
      /*I assume this is for room temperature */
      e2m_aus[i]=0.150728*pow(sine_by_lambda_aus[i],3)-0.630945*pow(sine_by_lambda_aus[i],2)-0.0277821*sine_by_lambda_aus[i] + 1.00055;
      printf ("old e2m_aus[%d], %lf \n ",i,e2m_aus[i]);
      /* see elements of X-ray diffraction 3rd edition, Cullity and stock p156 */ 
      /* my solution is not exact and works with linear regression on the data from cullity good for 
	 when debeye/T < 2  its ok for steel in range 200 kelvin and above */
      sine_by_lambda = sine_by_lambda_aus[i]; // equation is same for below for ferrite
      m = (11500 * T_K / (A*debeye*debeye)) * (exp(-0.25102875*(debeye/T_K)) + debeye/(T_K*4)) * (sine_by_lambda*sine_by_lambda); // m is factor :)
      e2m_aus[i] = exp(-m);
      printf ("new e2m_aus[%d], %lf \n ",i,e2m_aus[i]);
    }
  for(i=1;i<=no_fer_peaks;i++)
    {
      e2m_fer[i]=0.150728*pow(sine_by_lambda_fer[i],3)-0.630945*pow(sine_by_lambda_fer[i],2)-0.0277821*sine_by_lambda_fer[i] + 1.00055;
      printf ("old e2m_fer[%d], %lf \n ",i,e2m_fer[i]);
      sine_by_lambda = sine_by_lambda_fer[i]; // equation is same below -- read comments above
      m = (11500 * T_K / (A*debeye*debeye)) * (exp(-0.25102875*(debeye/T_K)) + debeye/(T_K*4)) * (sine_by_lambda*sine_by_lambda);
      e2m_fer[i] = exp(-m);
      printf ("new e2m_fer[%d], %lf \n ",i,e2m_fer[i]);
    }
}

int calculate_R_factor()
{
  /* printf("\n---------------R FACTOR-----------------\n");*/
  for(i=1;i<=no_fer_peaks;i++)
    {
      R_fer[i]=(F_fer2[i]*MF_fer[i]*LPF_fer[i]*e2m_fer[i])/pow(fer_a[i],6);
      IbyR_fer[i]=fer_Iint[i]/R_fer[i];
      Afer=IbyR_fer[i]+Afer;
    }
  for(i=1;i<=no_aus_peaks;i++)
    {
      R_aus[i]=(F_aus2[i]*MF_aus[i]*LPF_aus[i]*e2m_aus[i])/pow(aus_a[i],6);
      IbyR_aus[i]=aus_Iint[i]/R_aus[i];
      Aaus=IbyR_aus[i]+Aaus;
    }
  ave_fer=Afer/no_fer_peaks;
  ave_aus=Aaus/no_aus_peaks;
  Aus_frac=1/(1+(ave_fer/ave_aus));
  Fer_frac=1-Aus_frac;
  pre_total_error=inten_err_aus_total*inten_err_fer_total;
  total_error=pre_total_error/(1+pre_total_error);
}
	
int result_to_stdio()
{
  printf("\n\n--------------  RESULT --------------------\n\n");
  printf("preT:%f Aus:%f fer:%f",pre_total_error, inten_err_aus_total,inten_err_fer_total);
  printf("\n\nPercentage of austenite :\t%.3f %%\t Error : %.4f %%", Aus_frac*100,total_error*100);
  printf("\nPercentage of ferrite :\t%.3f %%\t Error : %.4f %%\n\n", Fer_frac*100, total_error*100);
  printf("Look into the filename %s for your results\n\n\t\t\t Thank you for using xrdcalc- Ananth\n", filename);
}

int average_lattice_param()
{
  float austenite_lp=0.0;
  float ferrite_lp=0.0;
  float aus_err[20];
  //float aus_err_sum=0.0;
  float fer_err[20];
  //float fer_err_sum=0.0;
  printf("Regression of austenite peaks, Cohen method, error sources according to A.Wilson\n\n");
  printf("Apparant LP\t\tError\n");
  for(i=1;i<=no_aus_peaks;i++)
    {
      //form below is for errors in camera debeye-sherrer only
      //  aus_err[i]=0.5*(((cos(aus_a[i])*cos(aus_a[i]))/(sin(aus_a[i])*sin(aus_a[i])))+((cos(aus_a[i])*cos(aus_a[i]))/aus_a[i]));
      //
      // Major errors in Counter Diffractometry would be expected to be from 
      // specimen flatness, and displacement, both have the form cos(th)cot(th)
      aus_err[i]=(cos(aus_peak_theta_rad[i])*cos(aus_peak_theta_rad[i]))/sin(aus_peak_theta_rad[i]); //this is the form for d spacings
      //should use values for angles not d spacing (form is correct)
      //aus_peak_theta_rad[i]
      printf("%f\t\t%f\n",aus_a[i],aus_err[i]);
    }


  //  austenite_lp=(aus_a[1]+aus_a[2]+aus_a[3]+aus_a[4]);
  // austenite_lp=(aus_a[1]+aus_a[2]+aus_a[3]+aus_a[4]);
  // maybe not the best way? Check Cullity.


  regression(aus_err,aus_a,no_aus_peaks);
  printf("\n-----------REGRESSION-----------\n");
  printf("\nGradient = %f",gradient);
  printf("\nIntercept = %f\n",intercept); 
  austenite_lp = intercept + gradient*(cos(90*PI/180)*cos(90*PI/180))/sin(90*PI/180); // should be same as intecerpt!
  printf("Regression of ferrite peaks, Cohen method, error sources according to A.Wilson\n\n");
  printf("Apparant LP\t\tError\n");
  for(i=1;i<=no_fer_peaks;i++)
    {
      
      //form below is for errors in camera debeye-sherrer only
      //  fer_err[i]=0.5* (((cos(fer_a[i])*cos(fer_a[i]))/( sin(fer_a[i])*sin(fer_a[i])))+((cos(fer_a[i])*cos(fer_a[i]))/fer_a[i]));
      //
      // Major errors in Counter Diffractometry would be expected to be from
      // specimen flatness, and displacement, both have the form cos(th)cot(th)
      fer_err[i]=(cos(fer_peak_theta_rad[i])*cos(fer_peak_theta_rad[i]))/sin(fer_peak_theta_rad[i]);
      printf("%f\t\t%f\n",fer_a[i],fer_err[i]);
    } 
  regression(fer_err,fer_a,no_fer_peaks);
  printf("\n-----------REGRESSION-----------\n");
  printf("\nGradient = %f",gradient);
  printf("\nIntercept = %f\n",intercept); 
  ferrite_lp = intercept;
  // ferrite_lp=(fer_a[1]+fer_a[2]+fer_a[3]+fer_a[4]);
  // ferrite_lp=(fer_a[1]/fer_err[1]+fer_a[2]/fer_err[2]+fer_a[3]/fer_err[3]+fer_a[4]/fer_err[4])*fer_err_sum;
  printf("Lattice Parameter determined extrapolating (Cohen Method - Cullity p368)\n");
  printf("\n\n\taustenite_lp=\t %lf", austenite_lp);
  printf("\n\tferrite_lp=\t %lf\n\n", ferrite_lp);    
}


