A basic data analysis toolkit for Fortran.
Install the source code by cloning this repository:
git clone https://github.com/koseiohara/EDAT.git
cd EDATThis library can be built by Makefile.
Rewrite the Makefile for your environment:
cd src
vim MakefileYou can change the definitions of DIR, FC, CC, FFLAG, and CFLAGS.
${DIR}/lib and ${DIR}/include are needed.
After making these settings, execute the makefile
make
make installlibedat.a and *.mod will be made and copied to ${DIR}/lib and ${DIR}/include, respectively.
edat_math provides useful parameters and tools for mathematical analysis.
real(rk), parameter :: M_E = 2.718281828459045235360287471352662498_rk ! e
real(rk), parameter :: M_LOG2E = 1.442695040888963407359924681001892137_rk ! log_2 e
real(rk), parameter :: M_LOG10E = 0.434294481903251827651128918916605082_rk ! log_10 e
real(rk), parameter :: M_LN2 = 0.693147180559945309417232121458176568_rk ! log_e 2
real(rk), parameter :: M_LN10 = 2.302585092994045684017991454684364208_rk ! log_e 10
real(rk), parameter :: M_PI = 3.141592653589793238462643383279502884_rk ! pi
real(rk), parameter :: M_PI_2 = 1.570796326794896619231321691639751442_rk ! pi/2
real(rk), parameter :: M_PI_4 = 0.785398163397448309615660845819875721_rk ! pi/4
real(rk), parameter :: M_1_PI = 0.318309886183790671537767526745028724_rk ! 1/pi
real(rk), parameter :: M_2_PI = 0.636619772367581343075535053490057448_rk ! 2/pi
real(rk), parameter :: M_2_SQRTPI = 1.128379167095512573896158903121545172_rk ! 2/sqrt(pi)
real(rk), parameter :: M_SQRT2 = 1.414213562373095048801688724209698079_rk ! sqrt(2)
real(rk), parameter :: M_SQRT1_2 = 0.707106781186547524400844362104849039_rk ! 1/sqrt(2)rk is the local kind parameter, specifies quadruple precision.
The variable names and their values are identical to those defined in the math.h header of the C language.
In addition to these parameters, qnorm is defined.
qnorm is a 99-element array.
qnorm(i) is the value
real(rk), parameter :: qnorm(99)=[0.01253346951_rk, & !! 01
& 0.02506890826_rk, & !! 02
& 0.03760828766_rk, & !! 03
.
.
.
& 1.95996398454_rk, & !! 95
& 2.05374891063_rk, & !! 96
& 2.17009037758_rk, & !! 97
& 2.32634787404_rk, & !! 98
& 2.57582930355_rk ] !! 99pure function corrcoef(n, array1, array2) result(output)
integer, intent(in) :: n
real, intent(in) :: array1(n)
real, intent(in) :: array2(n)Returns the correlation coefficient between array1 and array2.
Both arrays must be the same type, real32, real64, or real128.
pure function covariance(n, array1, array2, sample) result(output)
integer, intent(in) :: n
real , intent(in) :: array1(n)
real , intent(in) :: array2(n)
logical, intent(in), optional :: sampleReturns the covariance between array1 and array2.
Both arrays must be the same type, real32, real64, or real128.
If sample is provided and sample=.TRUE., the return value is the sample covariance. Otherwise, the return value is the population covariance.
pure function variance(n, array, sample) result(output)
integer, intent(in) :: n
real , intent(in) :: array(n)
logical, intent(in), optional :: sampleReturns the variance of array.
array must be real32, real64, or real128.
This routine can compute the variance of data very precisely because sum_hp is used.
If sample is provided and sample=.TRUE., the return value is the sample variance. Otherwise, the return value is the population variance.
pure function mean(n, array) result(output)
integer, intent(in) :: n
real , intent(in) :: array(n)Returns the mean of array.
array must be real32, real64, or real128.
This routine can compute the average of data very precisely because sum_hp is used.
pure function sum_hp(n, array) result(output)
integer, intent(in) :: n
real , intent(in) :: array(n)Returns the sum of array.
array must be real32, real64, or real128.
This function can compute the sum of data more precisely than the built-in function sum() because the pairwise-sum algorithm is used.
edat_sort provides sorting subroutine.
subroutine quick_sort(n, array)
integer, intent(in) :: n
real , intent(inout) :: array(n) !! integer array is also acceptableReturns sorted array of array.
array must be real32, real64, or int32.
This subroutine is a wrapper of qsort defined in the stdlib.h header of the C language.
edat_string provides some routines for manipulating strings.
pure elemental function to_upper(input) result(output)
character(*), intent(in) :: input
character(len(input)) :: outputConverts lowercase letters to uppercase, leaving all other characters unchanged.
pure elemental function to_lower(input) result(output)
character(*), intent(in) :: input
character(len(input)) :: outputConverts uppercase letters to lowercase, leaving all other characters unchanged.
edat_met is a module for meteorology.
real(rk), parameter :: GRAV = 9.80665_rk ! Gravitational Acceleration [m/s^2]
real(rk), parameter :: EarthRadius = 6.3710E+6_rk ! Radius of the Earth [m]
real(rk), parameter :: GasConstant = 287.04_rk ! Gas Constant for Dry Air [J/K/kg] #used for p=rhoRT
real(rk), parameter :: Cp = 1004._rk ! Specific Heat for Dry Air at Constant Pressure [J/K/kg]
real(rk), parameter :: Cv = Cp-GasConstant ! Specific Heat for Dry Air at Constant Volume [J/K/kg]
real(rk), parameter :: Lq = 2.507E+6_rk ! Latent Heat of vaporication [J/kg]rk is the local kind parameter, specifies quadruple precision.
pure elemental function potential_temperature(T, P) result(output)
real, intent(in) :: T
real, intent(in) :: PReturns potential temperature.
T and P are temperature[K] and pressure[Pa], respectively.
Both of them must be the same type, real32, real64, or real128.
pure subroutine meridionalIntegral(lat, field, south, north, output, status, valid_south, valid_north)
real , intent(in) :: lat(:) ! Latitude [rad]. shape must be [ny]
real , intent(in) :: field(:,:,:) ! Target. shape must be [nx,ny,nz]
real , intent(in) :: south ! Southern limit of the integral [rad]
real , intent(in) :: north ! Northern limit of the integral [rad]
real , intent(out) :: output(:,:) ! Result of meridional integral. shape must be [nx,nz]
integer, intent(out) :: status ! Positive if successfully computed
real , intent(out), optional :: valid_south ! Actual southern limit of the integral [rad]
real , intent(out), optional :: valid_north ! Actual northern limit of the integral [rad]Returns mridionally integrated field.
If south and north are exist in lat, valid_south and valid_north are equal to south and north.
Otherwise, the most close latitudes will be choosen as valid_south and valid_north and the interval of integration.
subroutine verticalIntegral(lev, field, psfc, output, status)
real , intent(in), contiguous :: lev(:) ! Vertical Levels [Pa] or [hPa]. shape must be [nz]
real , intent(in), contiguous :: field(:,:,:) ! Target. shape must be [nx,ny,nz]
real , intent(in), contiguous :: psfc(:,:) ! Surface Pressure [Pa] or [hPa]. shape must be [nx,ny]
real , intent(out) :: output(:,:) ! Result of vertical integral. shape must be [nx,ny]
integer, intent(out) :: status ! Positive if successfully computedReturns vertically integrated field.
pure subroutine zonalDerivative(lon, input, output, periodic, status)
real , intent(in) :: lon(:) ! Longitude [rad]. shape must be [nx]
real , intent(in) :: input(:,:,:) ! Target. shape must be [nx,ny,nz]
real , intent(out) :: output(:,:,:) ! Result of zonal derivative. shape must be [nx,ny,nz]
logical, intent(in) , optional :: periodic ! Whether the boundary condition of the input is periodic
integer, intent(out), optional :: status ! Positive if successfully computedReturns zonal derivative.
Both west-to-east and east-to-west longitude are acceptable.
Derivative is computed with central difference method at most grid points.
If periodic=.FALSE., eastern and western boundaries are computed with one-sided difference method.
| Status | Cause |
|---|---|
| -1 | Inconsistency of input array shapes |
| -2 | Array size is too small to compute derivative |
| -3 | Derivative axis is not a monotone sequence |
pure subroutine meridionalDerivative(lat, input, output, status)
real , intent(in) :: lat(:) ! Latitude [rad]. shape must be [ny]
real , intent(in) :: input(:,:,:) ! Target. shape must be [nx,ny,nz]
real , intent(out) :: output(:,:,:) ! Result of meridional derivative. shape must be [nx,ny,nz]
integer, intent(out), optional :: status ! Positive if successfully computedReturns meridional derivative.
Both north-to-south and south-to-north latitude are acceptable.
Derivative is computed with central difference method at most grid points, except the northern and southern boundaries.
Northern and southern boundaries are computed with one-sided difference method.
| Status | Cause |
|---|---|
| -1 | Inconsistency of input array shapes |
| -2 | Array size is too small to compute derivative |
| -3 | Derivative axis is not a monotone sequence |
pure subroutine verticalDerivative(lev, input, psfc, output, undef, status)
real , intent(in) :: lev(:) ! Vertical Levels [hPa] or [Pa]. shape must be [nz]
real , intent(in) :: input(:,:,:) ! Target. shape must be [nx,ny,nz]
real , intent(in) :: psfc(:,:) ! Surface Pressure [Pa] or [hPa]. shape must be [nx,ny]
real , intent(out) :: output(:,:,:) ! Result of vertical derivative. shape must be [nx,ny,nz]
real , intent(in) , optional :: undef ! Any value filling under ground with. Default: -999.E+30_rk
integer, intent(out), optional :: status ! Positive if successfully computedReturns Vertical derivative.
Both upper-to-lower and lower-to-upper levels are acceptable.
Derivative is computed with central difference method at most grid points, except the lower and upper boundaries.
Lower and upper boundaries are computed with one-sided difference method.
| Status | Cause |
|---|---|
| -1 | Inconsistency of input array shapes |
| -2 | Array size is too small to compute derivative |
| -3 | Derivative axis is not a monotone sequence |
edat_binio is a module for performing input and output of no-header binary files.
type finfo
private
integer :: unit
character(128) :: file
character(16) :: action
integer :: record
integer :: recl
integer :: recstep
contains
procedure, pass, public :: fclose
procedure, pass, public :: get_record
procedure, pass, public :: reset_record
generic, public :: fread => fread_s, fread_1, fread_2, fread_3, fread_4, fread_5
generic, public :: fwrite => fwrite_ss, fwrite_sd, fwrite_sq, &
...
& fwrite_5s, fwrite_5d, fwrite_5q
...
end type finfoUnit number for a file.
File name for reading or writing.
READ, WRITE, or READWRITE.
The initial record for reading or writing.
Record length (byte).
Increment to record at every reading or writing.
record will be automatically updated with this value.
function fopen(unit, file, action, record, recl, recstep) result(self)
type(finfo) :: self
integer , intent(in), optional :: unit
character(*), intent(in) :: file
character(*), intent(in) :: action
integer , intent(in) :: record
integer , intent(in) :: recl
integer , intent(in) :: recstepConstructor.
You can call this routine as name finfo.
This subroutine initializes this class with the provided arguments.
It is strongly recommended not to provide unit.
If you provide unit as an argument, its value will be used for the unit number.
Otherwise, the unit number will be automatically decided.
subroutine fclose(self)
class(finfo), intent(inout) :: selfClose a file.
subroutine fread(self, input_data)
class(finfo), intent(inout) :: self
real(4) , intent(out) :: input_dataRead data from a record in a file.
Scalar and 1-5 dimension arrays are acceptable for input_data.
input_data must be a real32 type.
subroutine fwrite(self, output_data)
class(finfo), intent(inout) :: self
real , intent(in) :: output_dataWrite data to a record in a file.
Scalar and 1-5 dimension arrays are acceptable for output_data.
output_data must be real32, real64, or real128.
Regardless of the precision of output_data, the output is in single precision.
subroutine get_record(self, record)
class(finfo), intent(in) :: self
integer , intent(out) :: recordReturn the next record you read or write.
subroutine reset_record(self, increment, newrecord)
class(finfo), intent(inout) :: self
integer , intent(in) , optional :: increment
integer , intent(in) , optional :: newrecordReset the next record you read or write.
If increment is provided, its value will be added to the present record.
If newrecord is provided, the record will be changed to the value.
If both are provided, only increment will be used.
pure elemental subroutine endian_converter(rawOre)
real(4), intent(inout) :: rawOreConvert the endian of rawOre.
This subroutine accepts a floating-point value and returns the same value with its byte order reversed.
This conversion enables correct interpretation of the value when it is stored in an endianness different from that of the running system independent of environment.