Skip to content

Instantly share code, notes, and snippets.

@DSCF-1224
Created December 27, 2020 12:35
Show Gist options
  • Save DSCF-1224/e616fa0e58203ef7258ba682a5b35f5a to your computer and use it in GitHub Desktop.
Save DSCF-1224/e616fa0e58203ef7258ba682a5b35f5a to your computer and use it in GitHub Desktop.
python で fortran の unformatted で出力した INT32 と REAL64 型のデータを読み出す

gist.20201227.02

目的

fortran から unformatted で出力した INT32 と REAL64 型のデータを python で読み出す方法の確認。

実行方法

make
python3 ./main.py

実行結果


order:  C
major:  col
<__main__.TestData object at 0x7f0e685964a8>
<class '__main__.TestData'>
[[ 1.  5.  9.]
 [ 2.  6. 10.]
 [ 3.  7. 11.]
 [ 4.  8. 12.]]

order:  C
major:  row
<__main__.TestData object at 0x7f0e68483550>
<class '__main__.TestData'>
[[ 1.  4.  7. 10.]
 [ 2.  5.  8. 11.]
 [ 3.  6.  9. 12.]]

order:  F
major:  col
<__main__.TestData object at 0x7f0e4f6c6e48>
<class '__main__.TestData'>
[[ 1.  5.  9.]
 [ 2.  6. 10.]
 [ 3.  7. 11.]
 [ 4.  8. 12.]]

order:  F
major:  row
<__main__.TestData object at 0x7f0e68483550>
<class '__main__.TestData'>
[[ 1.  4.  7. 10.]
 [ 2.  5.  8. 11.]
 [ 3.  6.  9. 12.]]

program main
! <module>s to import
use, intrinsic :: iso_fortran_env
! require all variables to be explicitly declared
implicit none
! constant(s) for this <program>
integer(INT32), parameter :: num_col = 4_INT32
integer(INT32), parameter :: num_row = 3_INT32
integer(INT32), parameter :: len_data = num_col * num_row
! variable(s) for this <program>
integer :: save_unit_ascii
integer :: save_unit_binary
integer(INT32) :: itr
real(REAL64) :: test_data(len_data)
! STEP.01
! generate test data
test_data(:) = (/ (itr * 1.0_REAL64, itr = 1_INT32, len_data, 1_INT32) /)
! STEP.02
! open a file to save test data
open(&!
action = 'write' , &!
file = 'ascii.dat' , &!
form = 'formatted' , &!
newunit = save_unit_ascii , &!
status = 'replace' &!
)
open(&!
access = 'stream' , &!
action = 'write' , &!
file = 'binary.dat' , &!
form = 'unformatted' , &!
newunit = save_unit_binary , &!
status = 'replace' &!
)
! STEP.03.01
! write the test data (ascii)
write(unit= save_unit_ascii, fmt='(I0)') num_row
write(unit= save_unit_ascii, fmt='(I0)') num_col
write(unit= save_unit_ascii, fmt='(ES24.16E3)') test_data(:)
! STEP.03.02
! write the test data (binary)
write(unit= save_unit_binary) num_row
write(unit= save_unit_binary) num_col
write(unit= save_unit_binary) test_data(:)
! STEP.04
! close the file written the test data
close( unit= save_unit_ascii , status= 'keep' )
close( unit= save_unit_binary , status= 'keep' )
end program main
# -*- coding: utf-8 -*-
# modules to import
import numpy
# local functions
def read_int32(file_stream):
return numpy.fromfile(file= file_stream, dtype= numpy.int32, count=1)[0]
def read_real64(file_stream):
return numpy.fromfile(file= file_stream, dtype= numpy.float64, count=1)[0]
class TestData:
class Shape:
def __init__(self, file_stream, order, major):
self.row = read_int32(file_stream= file_stream)
self.col = read_int32(file_stream= file_stream)
self.order = order
self.major = major
pass
def get_shape(self):
if self.major == 'col':
return self.get_shape_major_col()
elif self.major == 'row':
return self.get_shape_major_row()
else:
pass
def get_shape_major_col(self):
return (self.col, self.row)
def get_shape_major_row(self):
return (self.row, self.col)
def __init__(self, file_path, order, major):
with open(file_path, 'rb') as self.file_stream:
# STEP.01
# get the test data shape
self.shape = TestData.Shape(file_stream= self.file_stream, order= order, major= major)
# STEP.02
# prepare the numpy.array object to store the test data
self.array = numpy.zeros( shape= self.shape.get_shape() , dtype= numpy.float64, order= order )
# STEP.03
# read out the test data
if major == 'col':
for itr_row in range(self.shape.row):
for itr_col in range(self.shape.col):
self.array[itr_col, itr_row] = read_real64(file_stream= self.file_stream)
elif major == 'row':
for itr_col in range(self.shape.col):
for itr_row in range(self.shape.row):
self.array[itr_row, itr_col] = read_real64(file_stream= self.file_stream)
else:
pass
# STEP.END
pass
def show(self):
print()
print( 'order: ', self.shape.order )
print( 'major: ', self.shape.major )
print( test_data )
print( type(test_data) )
print( test_data.array )
pass
# main process is as follows
if __name__ == "__main__":
test_data = TestData(file_path= './binary.dat', order= 'C', major= 'col'); test_data.show()
test_data = TestData(file_path= './binary.dat', order= 'C', major= 'row'); test_data.show()
test_data = TestData(file_path= './binary.dat', order= 'F', major= 'col'); test_data.show()
test_data = TestData(file_path= './binary.dat', order= 'F', major= 'row'); test_data.show()
pass
# EOF
FCFLAGS= -fbacktrace -fbounds-check -ffree-line-length-none -O2 -pedantic -std=f2008 -Wall -Wextra
main.exe: ./main.f08
gfortran $(FCFLAGS) -o ./main.exe $<
clean:
rm ./*.mod ./*.o ./*.dat
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment