C*******************************************************************************
C
C GOA_LST_SQR generates the Least Squares Best Fit line through a series of
C (x,y) pairs read from a file.
C
C Technique
C =========
C The program reads data pairs (x,y) from a file specified by the user,
C computes the gradient and intercept of the least squares best-fit line
C through the dataset from various statistical quantities described below.
C
C The line is described by it's gradient and intercept as follows:
C y=mx+c; Where: m = gradient; c = intercept;
C x = independent variable; y = dependent variable
C
C It then outputs this least best fit line in form of a plot in the x-y plane
C using the plotting program 'gnuplot'
C
C It also outputs various statistical data such as:
C + Mean of X data, Mean of Y Data
C + Variance of X data, Variance of Y Data
C + Covariance and Correlation Coefficient for the dataset
C + Mean Square Deviation
C + Gradient and Intercept of Least Square Best-Fit Line
C + Uncertainties in the Gradient and Intercept of the Best-Fit Line
C + Equation of the Least-Squares Best Fit line
C
C ALL results are displayed on the screen and saved to file.
C
C
C Options
C =======
C Other options available in the program include:
C + Re-plotting of the Least-Squares Plot
C + Saving the results/plot to a file
C + Printing the results and plot
C + Restarting the program (running more than one analysis without
C having to exit the program)
C
C Various Tests were conducted to ensure that the right file, indices and data
C were used in the analyses.
C
C Error checks were inserted to transfer control to specific locations whenever
C errors are encountered.
C
C
C NOTES
C =====
C - The GNUPLOT program must be available for the graphical output to be displayed.
C - Data entries are in the form x: Column 1
C y: Column 2
C - Columns are separated by a tab or a space.
C
C***********************************************************************************
C
C User Defined Parameters:
C InputFile: Name of file containing the (x,y) data
C X: X Data stored in the 1st column of the file
C Y: Y Dtat stored in the 2nd column of the file
C X_Label: Unit/Label of the X Data (Displayed on plot)
C Y_Label: Unit/Label of the Y Data (Displayed on plot)
C Title: Title of the Dataset (Displayed on plot)
C N_Lower: Index of 1st pair used in the least squares calculation
C N_Upper: Index of last pair used in the least squares calculation
C
C Computed Variables:
C N: Number of Data pairs used in the least squares calculation
C X_Mean: Mean of the X Data
C Y_Mean: Mean of the Y Data
C X_Variance: Variance in the X-Data
C Y_Variance: Variance in the Y-Data
C Cov: Covariance of the dataset
C CorCoeff: Correlation coefficient between the X & Y-Data
C MnSqDev: Mean Square Deviation of the Dataset
C Gradient: Gradient of the computed least squares best-fit line
C Intercept: Intercept of the computed least squares best-fit line
C Uncert_Grad: The uncertainty in the Gradient
C Uncert_Intrcpt: The uncertainty in the Intercept
C
C Other Variables:
C N_Max: Maximum Number of dataset (1000)
C Err1: Variable to determine if Error exists in the Input file
C NDATA: Actual Number of data pairs in the file
C OutputFile: Name of the output File
C RUN: Variable to check if user wants to run another analysis
C
C*******************************************************************************
C
C Last Modified: 28 January 2006
C
C Author: AYENI GBOYEGA
C
C***********************************************************************************
C
C Disclaimer:
C ==========
C This program may be used for simple scientific operations involving least squares.
C But the author would take no liability whatsoever for damages incured from the
C use of the program
C
C Copyright:
C ==========
C All parts of this program may be copied and modified in part or whole for academic
C and research purpose.
C Use of the program for any commercial purpose must be done with a written permission
C from the author.
C
C
C Comments/Enquiries: [email protected]
C
C**********************************************************************************
C

C Program Definition
PROGRAM GOA_LST_SQR

C Implicit Statement
IMPLICIT NONE

C Declaration of variables
CHARACTER InputFile*30,X_Label*30,Y_Label*30,Title*30,
* OutputFile*30,RUN*1
INTEGER N_Max,N,N_Lower,N_Upper,Err1,NDATA
PARAMETER(N_Max=1000)
REAL Gradient,Intercept,MnSqDev,Uncert_Grad,Uncert_Intrcpt,Cov,
* CorCoeff,X(N_Max),Y(N_Max),X_Mean,Y_Mean,X_Variance,Y_Variance

C Common block indicating variables accessible to other subroutines
COMMON/VAL1/N_Lower,N_Upper,Title,X_Label,Y_Label
COMMON/VAL3/N,Gradient,Intercept
COMMON/VAL4/Err1,NDATA
COMMON/VAL5/MnSqDev,Uncert_Grad,Uncert_Intrcpt,Cov,CorCoeff,X,Y,
* X_Mean,Y_Mean,X_Variance,Y_Variance,InputFile,OutputFile

C Welcome Statement/Instructions
WRITE(*,*)'WELCOME TO GOA_LST_SQR'
WRITE(*,*)'AUTHOR: AYENI GBOYEGA'
WRITE(*,*)'JANUARY 2006'
WRITE(*,*)
WRITE(*,*)'-----------------------------------------------------'
WRITE(*,*)'THIS PROGRAM COMPUTES THE LEAST SQUARES BEST FIT LINE'
WRITE(*,*)'THROUGH A SERIES OF (X,Y) PAIRS READ FROM A FILE'
WRITE(*,*)
WRITE(*,*)'TO USE THE PROGRAM, FOLLOW INSTRUCTIONS ON THE SCREEN'
WRITE(*,*)
WRITE(*,*)'Comments/Enquiries: [email protected]'
WRITE(*,*)'======================================================'

C Call Subroutine USERINPUT to get all the user defined Variables
1 CALL USERINPUT(InputFile,X_Label,Y_Label,Title,N_Lower,N_Upper)

C Set variable Run to 'N', i.e. No.
C (This would be used later to determine whether to run the program after each operation)
RUN='N'

C Call Subroutine GETDATA to read (x,y) data from the specified Input file
CALL GETDATA(X,Y,N_Lower,N_Upper,N,InputFile)

C If there was an error in the specified Input file, then return to beginning of file
C and start program again (Err1=1 when there was an error in reading the file)
IF(Err1.EQ.1) then
REWIND(1)
GOTO 1
END IF

C Call Subroutine Mean() to compute the mean of the x-data "X_Mean"
CALL MEAN(X,N,X_Mean)

C Call Subroutine Mean() to compute the mean of the y-data "Y_Mean"
CALL MEAN(Y,N,Y_Mean)

C Call Subroutine VAR() to compute the variance of the x-data "X_Variance"
CALL VAR(X,N,X_Mean,X_Variance)

C Call Subroutine VAR() to compute the variance of the y-data "Y_Variance"
CALL VAR(Y,N,Y_Mean,Y_Variance)

C Call Subroutine COVAR() to compute the covariance "Cov" between the x- & y- data
CALL COVAR(X,Y,N,X_Mean,Y_Mean,Cov)

C Call Subroutine CORRCOEF() to compute the correlation coefficient "CorCoeff"
C between the x- & y- data
CALL CORRCOEF(X_Variance,Y_Variance,Cov,CorCoeff)

C Call Subroutine GRAD() to compute the gradient "Gradient" of the least squares
C best-fit line
CALL GRAD(Cov,X_Variance,Gradient)

C Call Subroutine INTRCPT() to compute the intercept "Intercept" of the least squares
C best-fit line
CALL INTRCPT(X_Mean,Y_Mean,Gradient,Intercept)

C Call Subroutine MSQDEV() to compute the Mean Squared Deviation "MnSqDev" of the
C least squares best-fit line
CALL MSQDEV(X,Y,Gradient,Intercept,N,MnSqDev)

C Call Subroutine UNCTGRAD() to compute the uncertainty in the gradient of the
C least squares best-fit line "Uncert_Grad"
CALL UNCTGRAD(MnSqDev,N,X_Variance,Uncert_Grad)

C Call Subroutine UNCTINT() to compute the uncertainty in the intercept of the
C least squares best-fit line "Uncert_Intrcpt"
CALL UNCTINT(Uncert_Grad,X_Variance,N,X_Mean,Uncert_Intrcpt)

C Call Subroutine GNUFILE() to save the x- & y-data used in the analysis (i.e.
C from 1st to last indices specified by user); y-values for the best fit line
C and the equation of the best fit line into appropriate files.
CALL GNUFILE(X,Y)

C Call Subroutine RESULT_OUT() to screen and to file "OutputFile"
CALL RESULT_OUT()

C Call Subroutine GNU_PLOT() to plot the (x.y) pairs and the least squares best
C fit line through the data pairs
CALL GNU_PLOT()

C Close all open files
CLOSE (1)
CLOSE (7)
CLOSE (8)
CLOSE (9)
CLOSE(11)

C Ask the user whether to run the program again. Exit program except when Run='Y'
C Recall default was Run = 'N' at beginning of the program
WRITE(*,*)
WRITE(*,*)'======================================='
WRITE(*,*)'Would You like to run another Analysis?'
WRITE(*,*)'Y=Yes'
WRITE(*,*)'Any other key to exit'
WRITE(*,*)'======================================='
WRITE(*,*)

C Get the user's response
READ(*,'(A1)')RUN

C Transfer control to Statement labelled 1 if Run='Y'
IF(RUN.EQ.'Y'.OR.RUN.EQ.'y') GOTO 1

C Quit program
STOP
END


C END OF MAIN PROGRAM




C*******************************************************************************
C Subroutine USERINPUT
C This subroutine is used to acquire all the necessary User-defined variables
C including InputFile, X_Label, Y_Label, Title, N_Lower, N_Upper (all defined
C at the beginning of main program).
C
C Local Variables
C =================
C EXIST: Logical variable used to check if the Input File Exists

SUBROUTINE USERINPUT(InputFile,X_Label,Y_Label,Title,
* N_Lower,N_Upper)

C Implicit Statement
IMPLICIT NONE

C Variable Declaration
CHARACTER InputFile*30,X_Label*30,Y_Label*30,Title*30
INTEGER N_Lower,N_Upper
LOGICAL EXIST

C Write instructions
WRITE(*,*)
WRITE(*,*)'Please Enter the following parameters'

C Get the Input Filename
2 WRITE(*,*)'Input Filename (+ extension):'
READ(*,'(A30)')InputFile

C Check if File Exists
INQUIRE(FILE=InputFile, EXIST=EXIST)

C If Input File does not exist in the current directory, output
C an error message and go back to read the input Filename again
IF(.NOT. EXIST) THEN
WRITE(*,*)'Input file does not exist. Please try again.'
WRITE(*,*)'Ensure that File is saved in your current path'
WRITE(*,*)
GOTO 2
ELSE
C Else if the Input File exists, then Open the File
OPEN(1,STATUS='OLD',FILE=InputFile)
ENDIF

C Get the Label for the X-axis
WRITE(*,*)
WRITE(*,*)'X LABEL: (Maximum 30 Characters)'
READ(*,'(A30)')X_Label

C Get the Label for the Y-axis
WRITE(*,*)
WRITE(*,*)'Y LABEL: (Maximum 30 Characters)'
READ(*,'(A30)')Y_Label

C Get the Title of the Analysis
WRITE(*,*)
WRITE(*,*)'TITLE: (Maximum 30 Characters)'
READ(*,'(A30)')Title

C Get the Index of the First (x,y) pair to use in the analysis
C If there is an error while reading the Index, go to statement labelled 3
WRITE(*,*)
4 WRITE(*,*)'Index of First pair to read'
READ(*,'(I3)',ERR=3)N_Lower

C Get the Index of the Last (x,y) pair to use in the analysis
C If there is an error while reading the Index, go to statement labelled 3
WRITE(*,*)
WRITE(*,*)'Index of Last pair to read'
READ(*,'(I3)',ERR=3)N_Upper

C****Check the indices
C If the Index of the first (x,y) pair is greater than or equal
C to the index of the last (x,y) pair then there is an error!!
C Go to Statement 3.
IF(N_Lower.GT.N_Upper.OR.N_Lower.EQ.N_Upper) then
WRITE(*,*)'Fisrt Index:',N_Lower,'Last Index:',N_Upper
WRITE (*,*)
GOTO 3
ELSE

C Else, everything is OK......transfer control to statement labelled 5.
GOTO 5
END IF


C Output reason(s) for error and give probable solutions.
3 WRITE(*,*)
WRITE(*,*)'Error: Invalid Index(ices)!!!'
WRITE(*,*)'Indices MUST be an Integer AND'
WRITE(*,*)'Index of Last pair MUST be greater than Index
*of the 1st pair'
WRITE(*,*)

C then go back to read the indices.
GOTO 4

C Return to main program.
5 RETURN
END




C*******************************************************************************
C Subroutine GETDATA is used is used to acquire all (x,y) data pairs from
C the specified Input file

SUBROUTINE GETDATA(X,Y,N_Lower,N_Upper,N,InputFile)

C Variable Declaration
INTEGER N,NDATA,Err1
CHARACTER InputFile*30
PARAMETER (N_Max=100)
REAL X(N_Max),Y(N_Max)

C Common Block
COMMON/VAL4/Err1,NDATA

C Set Err1 to zero (Err1 remains zero except if an error is encountered
C while reading the file)
Err1=0

C Set N (Number of Data points) to zero
N=0

C Read all the (x,y) data pairs in the input file until the end of file.
C Increment number of data points after reading each (x,y) pair in the file
C Transfer control to Statement 12 If Error is encountered
C Transfer control to Statement 11 If end of file is encountered
DO I=1,N_Max
READ(1,*, END=11, ERR=12)X(I),Y(I)
N=N+1
END DO

C Store actual number of data pairs in the file in the variable NDATA
C This is important because the number to be used for the Least Squares
C computation might differ

11 NDATA=N

C If 1st Index is not equal to 1, or Last Index is not equal to the total
C number of data pairs, then the user would not be using the whole dataset
IF(N_Lower.NE.1.OR.N_Upper.NE.N)THEN
C
C Therefore a new data range must be defined.
C
C Set a new counter to zero
L=0
C Set the data pairs from 1st to last indices as the new set of data.
C Count the new number of data pairs to be used in the analysis
DO J=N_Lower,N_Upper
L=L+1
X(L)=X(J)
Y(L)=Y(J)
END DO

C Replace the old number of data pairs with the new.
N=L

END IF

C If the IF statement is FALSE, the block above is not executed because
C the whole dataset in file would be used in the computations
C (so return to to main program)
C
C Jump to Statement Label 13 (ie return to main program)
GOTO 13

C Error block (Only Executed if there is an error while reading the input file
C Give advice on probable cause(s) of the error
12 WRITE(*,*)'---------------------------------------------------'
WRITE(*,*)'An Error occurred while trying to read the data'
WRITE(*,*)'HINTS:'
WRITE(*,*)'Make sure Input file exists and data properly saved'
WRITE(*,*)'Save the x and y-values in columns'
WRITE(*,*)'Separate each x-y pair with a TAB'
WRITE(*,*)'No Heading should be present at the top'
WRITE(*,*)'---------------------------------------------------'

C Set Err1 to 1 (this sends a message to the main program that an error was
C encountered while reading the input file). Only executed if there is an error.
Err1=1

C Return to Main program
13 RETURN

END




C*******************************************************************************
C Subroutine MEAN() returns the means for each of the two data columns x- & y-
C The subroutine computes the mean of the dataset 'A' ("A" corresponds to either
C the x- or y- data depending on the entry into the call statement)

SUBROUTINE MEAN(A,NA,A_MEAN)

C Variable declaration
INTEGER NA
REAL A(NA),A_MEAN, A_SUM

C Set sum of entries "A_SUM" to zero
A_SUM=0.

C Add up all the entries in the data column
DO I=1,NA
A_SUM=A_SUM+A(I)
END DO

C Mean of the data is equal to the Sum of the data divided by number of data points
A_MEAN=A_SUM/NA

C Return to the main program
RETURN
END




C*******************************************************************************
C Subroutine VAR() returns the variance for each of the two data columns x- & y-
C The subroutine computes the variance of the dataset 'A' ("A" corresponds to either
C the x- or y- data depending on the entry into the call statement)

SUBROUTINE VAR(A,NA,A_MEAN,A_VAR)

C Variable declaration
INTEGER NA
REAL A(NA),A_MEAN,A_VAR,VAR_SUM

C Set the Numerator (Summation) in the variance equation to zero
VAR_SUM=0.

C Set the Variance to zero (Not important...used as a control while
C building the program)
A_VAR=0.

C Compute the Numerator (Summation) in the variance equation
DO I=1,NA
VAR_SUM=(VAR_SUM+((A(I)-A_MEAN)**2))
END DO

C Compute the variance of the data column
A_VAR=(VAR_SUM/(NA-1))

C Return to main program
RETURN
END


C******************************************************************************
C Subroutine COVAR() returns the covariance between the two data columns x- & y-
C The subroutine computes the covariance of the dataset 'A' and 'B' ("A" & "B"
C correspond to x- & y- data resp.)

SUBROUTINE COVAR(A,B,N,A_MEAN,B_MEAN,Cov)

C Variable declaration
INTEGER N
REAL A(N),B(N),A_MEAN,A_VAR,B_MEAN,Cov,COV_SUM

C Set the Numerator (Summation) in the covariance equation to zero
COV_SUM=0.

C Compute the Numerator (Summation) in the covariance equation
DO I=1,N
COV_SUM=COV_SUM+((A(I)-A_MEAN)*(B(I)-B_MEAN))
END DO

C Compute the covariance between the two data columns

Cov=COV_SUM/(N-1)

C Return to the main program
RETURN
END


C*******************************************************************************
C Subroutine CORRCOEF() returns the correlation coefficient between the two data
C columns x- & y- .

SUBROUTINE CORRCOEF(A_VAR,B_VAR,Cov,CorCoeff)

C Variable declaration
REAL A_VAR,B_VAR,Cov,CorCoeff

C Compute the correlation coefficient between the two data columns
C A_VAR & B_VAR correspond to the variances in A nad B respectively
CorCoeff=Cov/((A_VAR*B_VAR)**0.5)

C Return to the main program
RETURN
END


C*******************************************************************************
C Subroutine GRAD() returns the gradient of the least squares best fit line through
C the (x,y) pairs

SUBROUTINE GRAD(Cov,A_VAR,Gradient)

C Variable declaration
REAL Cov,A_VAR,Gradient

C Compute the gradient of the least squares best fit line
Gradient=Cov/A_VAR

C Return to the main program
RETURN
END

C*******************************************************************************
C Subroutine INTRCPT() returns the intercept of the least squares best fit line through
C the (x,y) pairs
SUBROUTINE INTRCPT(A_MEAN,B_MEAN,Gradient,Intercept)
REAL A_MEAN,B_MEAN,Gradient,Intercept

C Compute the Intercept of the least squares best fit line
Intercept=B_MEAN-Gradient*A_MEAN

C Return to the main program
RETURN
END


C*******************************************************************************
C Subroutine MSQDEV() returns the mean squared deviation of the the best fit line through
C the (x,y) pairs
SUBROUTINE MSQDEV(A,B,Gradient,Intercept,N,MnSqDev)

C Variable declaration
INTEGER N
REAL A(N),B(N),Gradient,Intercept,MnSqDev,MnSqDev_Sum

C Set the Numerator (Summation) in the mean squared deviation equation to zero
MnSqDev_Sum=0.

C Compute the Numerator (Summation) in the mean squared deviation equation
DO I=1,N
MnSqDev_Sum=MnSqDev_Sum+((B(I)-Gradient*A(I)-Intercept)**2)
END DO

C Compute the mean squared deviation of the best fit line
MnSqDev=MnSqDev_Sum/(N-2)

C Return to the main program
RETURN
END

C*******************************************************************************
C Subroutine UNCTGRAD() returns the uncertainty in the gradient "Uncert_Grad" of
C the best fit line through the (x,y) pairs

SUBROUTINE UNCTGRAD(MnSqDev,N,A_VAR,Uncert_Grad)

C Variable declaration
INTEGER N
REAL Uncert_Grad,MnSqDev,A_VAR,UASQ

C Compute the uncertainty in the gradient of the best fit line
Uncert_Grad=(MnSqDev/((N-1)*A_VAR))**0.5

C Return to the main program
RETURN
END

C*******************************************************************************
C Subroutine UNCTINT() returns the uncertainty in the intercept "Uncert_Intrcpt" of
C the best fit line through the (x,y) pairs

SUBROUTINE UNCTINT(Uncert_Grad,A_VAR,N,A_MEAN,Uncert_Intrcpt)

C Variable declaration
INTEGER N
REAL Uncert_Intrcpt,MnSqDev,A_VAR,UBSQ

C Compute the uncertainty in the intercept of the best fit line
Uncert_Intrcpt=(Uncert_Grad*(A_VAR*(1-(1/N))+A_MEAN**2))**0.5

C Return to the main program
RETURN
END


C*******************************************************************************
C Subroutine UNCTINT() writes the (x,y) pairs used in the analysis, the (x,y2) values
C for the best fit line, and the equation of the best fit line into appropriate files
C
C
C Variable(s) not yet defined
C =================
C EQ: character variable used to store the equation of the best fit line
C Y2: data column used to store the y- values for the best fit line
C
SUBROUTINE GNUFILE(X,Y)

C Variable declaration
INTEGER N
CHARACTER EQ*17
REAL Gradient, Intercept, Y2(N), X(N), Y(N)


C Common Block
COMMON/VAL2/EQ
COMMON/VAL3/N,Gradient,Intercept

C Open output files "RawData", "BestFit", "EQN", & "DATA"
OPEN (UNIT=7, FILE='RawData', STATUS='UNKNOWN')
OPEN (UNIT=8, FILE='BestFit', STATUS='UNKNOWN')
OPEN (UNIT=9, FILE='EQN', STATUS='UNKNOWN')
OPEN (UNIT=11, FILE='DATA', STATUS='UNKNOWN')

DO I=1,N

C Compute the Y2 values for the best fit line using the same X values
C y=mx+c (already defined in main program)
Y2(I)=Gradient*X(I)+Intercept

C Write the (x,y) pairs to file: "RawData"
WRITE(7,*)X(I),Y(I)

C Write the (x,y2) pairs to file: "BestFit"
WRITE(8,*)X(I),Y2(I)

C Write the y2 values to file: "DATA"
WRITE(11,*)Y2(I)
END DO


C Write the equation of the best fit line to file: "EQN"
WRITE(9,'(A2,F6.2,A1,A1,F6.2)')'Y=',Gradient,'X','+',Intercept
REWIND (9)

C Read equation from file "EQN" and store in variable "EQ"
READ(9,'(A17)')EQ

C Return to the main program
RETURN
END

C*******************************************************************************
C Subroutine RESULT_OUT() outputs the results and variables to the screen and to a file.
C
SUBROUTINE RESULT_OUT()

C Variable declaration
CHARACTER File1*30,XLab*30,YLab*30,Title*30,OutputFile*30,EQ*17
INTEGER NMax,N,NLow,NUpp
PARAMETER(NMax=1000)
REAL Grad,Inter,MSDev,UnGrad,UnInter,Cov,CorCoeff,X(NMax),
* Y(NMax),Y2(NMax),XMean,YMean,XVar,YVar

C Common Block
COMMON/VAL1/NLow,NUpp
COMMON/VAL2/EQ
COMMON/VAL3/N,Grad,Inter
COMMON/VAL4/Err1,NDATA
COMMON/VAL5/MSDev,UnGrad,UnInter,Cov,CorCoeff,X,Y,
* XMean,YMean,XVar,YVar,File1,OutputFile


C Go to beginning of file "DATA" and read off data column "Y2"
REWIND (11)
DO I=1,N
READ(11,*,END=41)Y2(I)
END DO

C Open the Output file
OPEN(UNIT=12, FILE='OutputFile',Status='UNKNOWN')

C Call the Subroutine DTIME() to output the date and time to screen and output file
CALL DTIME()

C Output all the results to the screen
WRITE(*,*)
41 WRITE(*,*) '+++++++++++++++++++++++++++++++++++++++++++'
WRITE(*,*) 'SUMMARY OF RESULTS'
WRITE(*,*) '+++++++++++++++++++++++++++++++++++++++++++'
WRITE(*,*) 'Input Filename: ',File1
WRITE(*,*) 'Total Number of data in File: ', NDATA
WRITE(*,*) 'Index of 1st pair of x-y used: ', NLow
WRITE(*,*) 'Index of Last pair of x-y used:', NUpp
WRITE(*,*) 'Number of data pairs used : ', N
WRITE(*,*) '+++++++++++++++++++++++++++++++++++++++++++'
WRITE(*,*) '+++++++++++++++++++++++++++++++++++++++++++'
WRITE(*,*)
WRITE(*,*) 'S/N INDEX X-DATA Y-DATA Y-LSQR'

NL=NLow

DO I=1,N
WRITE(*,'(I3,3x,I3,2x,3(F7.2,3x))')I,NL,X(I),Y(I),Y2(I)
NL=NL+1
END DO

WRITE(*,*)
WRITE(*,*) '++++++++++++++++++++++++++++++++'
WRITE(*,'(A13,F9.2)') ' Mean X: ',XMean
WRITE(*,'(A13,F9.2)') ' Mean Y: ',YMean
WRITE(*,'(A13,F9.2)') ' Variance X: ',XVar
WRITE(*,'(A13,F9.2)') ' Variance Y: ',YVar
WRITE(*,'(A13,F9.2)') ' Covariance: ',Cov
WRITE(*,'(A13,F9.2)') ' Corr. Coeff: ',CorCoeff
WRITE(*,'(A13,F9.2)') ' Gradient: ',Grad
WRITE(*,'(A13,F9.2)') ' Intercept: ',Inter
WRITE(*,'(A13,F9.2)') ' Mean Sq. Dev:',MSDev
WRITE(*,'(A25,F6.2)') ' Uncertainty in Gradient :',UnGrad
WRITE(*,'(A25,F6.2)') ' Uncertainty in Intercept:',UnInter
WRITE(*,*) '++++++++++++++++++++++++++++++++'
WRITE(*,*) 'Equation of Least Square Line:'
WRITE(*,'(2x,A17)')EQ
WRITE(*,*) '==============================='
WRITE(*,*)


C Save a summary of the results in the file OutputFile

WRITE(12,*) '+++++++++++++++++++++++++++++++++++++++++++'
WRITE(12,*) 'SUMMARY OF RESULTS'
WRITE(12,*) '+++++++++++++++++++++++++++++++++++++++++++'
WRITE(12,*) 'Input Filename: ',File1
WRITE(12,*) 'Total Number of data in File: ', NDATA
WRITE(12,*) 'Index of 1st pair of x-y used: ', NLow
WRITE(12,*) 'Index of Last pair of x-y used:', NUpp
WRITE(12,*) 'Number of data pairs used : ', N
WRITE(12,*) '+++++++++++++++++++++++++++++++++++++++++++'
WRITE(12,*)
WRITE(12,*) 'S/N INDEX X-DATA Y-DATA Y-LSQR'

NL=NLow

DO I=1,N
WRITE(12,'(I3,3x,I3,2x,3(F7.2,3x))')I,NL,X(I),Y(I),Y2(I)
NL=NL+1
END DO

WRITE(12,*)
WRITE(12,*) '===================================='
WRITE(12,'(A13,F9.2)') ' Mean X: ',XMean
WRITE(12,'(A13,F9.2)') ' Mean Y: ',YMean
WRITE(12,'(A13,F9.2)') ' Variance X: ',XVar
WRITE(12,'(A13,F9.2)') ' Variance Y: ',YVar
WRITE(12,'(A13,F9.2)') ' Covariance: ',Cov
WRITE(12,'(A13,F9.2)') ' Corr. Coeff: ',CorCoeff
WRITE(12,'(A13,F9.2)') ' Gradient: ',Grad
WRITE(12,'(A13,F9.2)') ' Intercept: ',Inter
WRITE(12,'(A13,F9.2)') ' Mean Sq. Dev:',MSDev
WRITE(12,'(A25,F6.2)') ' Uncertainty in Gradient :',UnGrad
WRITE(12,'(A25,F6.2)') ' Uncertainty in Intercept:',UnInter
WRITE(12,*) '==============================='
WRITE(12,*) 'Equation of Least Square Line:'
WRITE(12,'(2x,A17)')EQ
WRITE(12,*) '==============================='

WRITE(12,*)
WRITE(*,*) 'NOTE: Summary of Results saved in File "OutputFile"'
WRITE(12,*)
CLOSE(12)

C Return to the main program
RETURN
END


C+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
SUBROUTINE GNU_PLOT()
C+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
C This Subroutine outputs a plot of the original data and the computed Least
C Squares Best Fit line.
C It also displays the equation of the line, indices of the data used in the
C Analyses (i.e. the part of the data used) and other useful parameters

C Discussion:
C This subroutine reads and plots the data from files "RawData" and
C "BestFit" for the original data and the Least Squares Best Fit
C Line respectively.

C The subroutine write the necessary commands for the graph into the file "CMD"
C and the invokes GNUPLOT to display your picture.

C Once this routine invokes GNUPLOT, a graphics window opens up,
C and the FORTRAN program pauses. Hitting RETURN allows the
C FORTRAN routine to proceed.
C
C The subroutine also gives an option to save a postscript version of the plot,
C re-plot the last graph, or to print a hardcopy of the graph. Control is
C transferred to the appropriate point depending on the user's choice
C

C Modified: 2 January 2006
C Author: Ayeni Gboyega
C Parameters:
C Title,X_Label,Y_Label,N_Lower,N_Upper (Same meanings as described in Main Program)
C EQ (Same meaning as described in subroutine GNUFILE)
C OPN: OPTION (P-PRINT,R-REPEAT,S-SAVE OR X-EXIT)
C STAT: Integer used to check if Gnuplot returns error when called with "SYSTEM"
C+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

IMPLICIT NONE

C Variable Declaration
CHARACTER X_Label*30,Y_Label*30,Title*30
CHARACTER EQ*17,OPN*1
INTEGER N_Lower,N_Upper,SYSTEM,STAT

C Common block indicating variables common to other subroutines
COMMON/VAL1/N_Lower,N_Upper,Title,X_Label,Y_Label
COMMON/VAL2/EQ

C Open the File "CMD" to write in the gnuplot commands for plotting the graph
21 OPEN(UNIT=10,FILE='CMD',STATUS='UNKNOWN')

C Write the gnuplot commands to set the title, labels for x- & y-axes, equation
C of the least squares fit line and indices of the data used in the analyses
WRITE(10,*)'set title ','"',Title,'"'
WRITE(10,*)'set xlabel ','"',X_Label,'"'
WRITE(10,*)'set ylabel ','"',Y_Label,'"'
WRITE(10,*)'set label 1 ','"EQN OF BESTFIT LINE: ',EQ,'"',' at
* graph .01,.97 left'
WRITE(10,*)'set label 2 ','"NLOWER:',N_Lower,'"',' at
* graph .01,.93 left'
WRITE(10,*)'set label 3 ','"NUPPER:',N_Upper,'"',' at
* graph .01,.89 left'

C Write the gnuplot command to plot the Raw Data and Best-Fit line
WRITE ( 10,'(A)')'plot "RawData" using 1:2,"BestFit"
* using 1:2 with lines'

C Write the gnuplot command to pause while the graph is displayed
WRITE ( 10, '(A)' ) 'pause -1 "Hit return to continue"'

C Write the gnuplot command to quit after return is hit by the user
WRITE ( 10, '(A)' ) 'q'

C Call program GNUPLOT to display plot using the commands in file "CMD"
STAT = SYSTEM ('gnuplot CMD')

C If an Error was generated while the gnuplot command is issued,
C the output an Error message and exit. If No error occurs here
C then there would not be need to check in subsequent sections"
IF(STAT /= 0 ) THEN
WRITE(*,*)'********************NOTE*************************'
WRITE(*,*)'FATAL ERROR!'
WRITE(*,*)' AN ERROR CODE WAS GENERATED WHEN THE GNUPLOT '
WRITE(*,*)' COMMAND WAS ISSUED. MAYBE "GNUPLOT" IS NOT INSTALLED!! '
WRITE(*,*)' CHECK TO ENSURE THAT THE PROGRAM IS IN YOUR PATH.'
WRITE(*,*)'*************************************************'
WRITE(*,*)' '
STOP
END IF

CLOSE (10)

C Ask User for what to do next: (P)rint, (S)ave, (R)epeat Plot or E(x)it
30 WRITE(*,*)
WRITE(*,*)'OPTIONS:'
WRITE(*,*)'---------'
WRITE(*,*)'R: Repeat Plot'
WRITE(*,*)'S: Save Plot'
WRITE(*,*)'P: Print Plot'
WRITE(*,*)'X: Exit'

C Read User's response. If Error occurs while reading, show options again.
READ(*,'(A1)',ERR=30)OPN

C If User would like to see plot again, transfer control to statement label 21.
IF (OPN.EQ.'R'.OR.OPN.EQ.'r') GOTO 21


C If User would like to save the plot then follow the same procedure
C used to display the plot but with the terminal set to postscript and
C output set to a the file "LSQFile.ps"
IF (OPN.EQ.'S'.OR.OPN.EQ.'s') then
OPEN(UNIT=10,FILE='CMD',STATUS='OLD')
WRITE(10,*)'set output "LSQFile.ps"'
WRITE(10,*)'set term postscript'
WRITE(10,*)'set title ','"',Title,'"'
WRITE(10,*)'set xlabel ','"',X_Label,'"'
WRITE(10,*)'set ylabel ','"',Y_Label,'"'
WRITE(10,*)'set label 1 ','"EQN OF BESTFIT LINE: ',EQ,'"',' at
* graph .01,.97 left'
WRITE(10,*)'set label 2 ','"NLOWER:',N_Lower,'"',' at
* graph .01,.93 left'
WRITE(10,*)'set label 3 ','"NUPPER:',N_Upper,'"',' at
* graph .01,.89 left'

WRITE ( 10,'(A)')'plot "RawData" using 1:2,"BestFit"
* using 1:2 with lines'


C Write Message for Fortran to pause and inform user that the file was saved
WRITE ( 10, '(A)' ) 'pause -1 "File Saved"'
WRITE ( 10, '(A)' ) 'q'

C Call GNUPLOT to output the plot to file "LSQFile.ps"
STAT = SYSTEM ('gnuplot CMD')
CLOSE (10)

C Inform User that the file was saved
WRITE(*,*)'The graph has been saved as "LSQFile.ps" in your
* present working directory'

WRITE(*,*) 'Summary of Results saved in File "OutputFile"'

WRITE(*,*)

C Return to Options Statement
GOTO 30

ENDIF


C If User would like to print the plot then follow the same procedure
C used to save the plot and inform user to open the file
C LSQFile.ps and print
IF (OPN.EQ.'P'.OR.OPN.EQ.'p') then


C Open the file "CMD" to write the gnuplot commands
OPEN(UNIT=10,FILE='CMD',STATUS='OLD')

WRITE(10,*)'set output "LSQFile.ps"'
WRITE(10,*)'set term postscript'
WRITE(10,*)'set title ','"',Title,'"'
WRITE(10,*)'set xlabel ','"',X_Label,'"'
WRITE(10,*)'set ylabel ','"',Y_Label,'"'
WRITE(10,*)'set label 1 ','"EQN OF BESTFIT LINE: ',EQ,'"',' at
* graph .01,.97 left'
WRITE(10,*)'set label 2 ','"NLOWER:',N_Lower,'"',' at
* graph .01,.93 left'
WRITE(10,*)'set label 3 ','"NUPPER:',N_Upper,'"',' at
* graph .01,.89 left'
WRITE ( 10,'(A)')'plot "RawData" using 1:2,"BestFit"
* using 1:2 with lines'
WRITE(10,'(A)')'!lpr -Pps49 LSQFile.ps'
WRITE(10,'(A)')'pause -1 "To Print, open the file LSQFile.ps"'
WRITE(10,'(A)')'q'
STAT = SYSTEM ('gnuplot CMD')
CLOSE (10)
WRITE(*,*)
WRITE(*,*)'To Print, open the file LSQFile.ps and print'
WRITE(*,*)

C Return to Options Statement
GOTO 30

ENDIF

C If User wishes to exit, the return to main program
IF (OPN.EQ.'X'.OR.OPN.EQ.'x') GOTO 24

C If User's Option is invalid, then Inform User and return to Options
IF(OPN.NE.'P'.AND.OPN.NE.'p') then
IF(OPN.NE.'S'.AND.OPN.NE.'s') then
IF(OPN.NE.'R'.AND.OPN.NE.'r') then
IF(OPN.NE.'X'.AND.OPN.NE.'x') then
WRITE(*,*)
WRITE(*,*) 'INVALID ENTRY'
WRITE(*,*) 'SELECT P,S,R OR X'
WRITE(*,*)
GOTO 30
END IF
END IF
END IF
END IF

C Return to the main program
24 RETURN
END


C*******************************************************************************
C Subroutine DTIME() outputs the current time in the Screen and Output File
SUBROUTINE DTIME()

C Implicit Statement
IMPLICIT NONE

C Variable declaration
CHARACTER DATE*8,TIME*10,ZONE*5
INTEGER D,H,M,MM,N,S,Y,VALUES(8)
CHARACTER(4), PARAMETER, DIMENSION(12) :: MONTH = (/
* 'JAN. ','FEB. ','MAR. ','APR. ','MAY ','JUN. ',
* 'JUL. ','AUG. ','SEP. ','OCT. ','NOV. ','DEC. ' /)

C Call function DATE_AND_TIME() to get the date, time ,etc
CALL DATE_AND_TIME (DATE,TIME,ZONE,VALUES)
Y=VALUES(1)
M=VALUES(2)
D=VALUES(3)
H=VALUES(5)
N=VALUES(6)
S=VALUES(7)
C Output the date and time to the screen and file
WRITE(*,*)
WRITE(*,'(1X,A,I2,1X,I4,I2,A1,I2,A1,I2)' )
* MONTH(M), D, Y, H,':',N,':',S
WRITE(12,*)
WRITE(12,'(1X,A,I2,1X,I4,I2,A1,I2,A1,I2)' )
* MONTH(M), D, Y, H,':',N,':',S

C Return to the main program
RETURN
END
 

Hosted by www.Geocities.ws

1