SciPy - FortranFile() Function



scipy.io.FortranFile function is used to handle unformatted binary files generated by Fortran applications. It is an efficient technique to read and write data in the Fortran binary file format, which employs specific markers to split and identify data blocks.

This method is useful for integrating Python with legacy Fortran applications or performing scientific computations that require binary data storage. It enables operations such as reading and writing integers, floating-point numbers, and complex data types, making it suitable for a variety of numerical jobs.

Errors can happen when the file structure doesn't meet expectations. This includes using the wrong header_dtype trying to read files that aren't Fortran, or working with incomplete data or mismatched types.

Using the right header_dtype makes sure Fortran binary records are handled. Using the same data types for writing and reading (like np.int32 or np.float64) helps avoid issues and ensures Fortran-style files are processed.

Syntax

The syntax for the SciPy FortranFile() method is as follows −

.FortranFile(filename, mode='r', header_dtype=numpy.int32)

Parameters

This method accepts the following parameters −

  • filename (str or file-like object) − The name of the file to open or a file-like object.

  • mode (str, default='r') − The file mode: 'r' for reading, 'w' for writing, or 'a' for appending.

  • header_dtype (dtype, default=numpy.int32) − The data type for record markers. Commonly used types are numpy.int32 and numpy.int64.

Return Value

FortranFile object − Provides methods to read and write Fortran binary data.

Example 1

Fortran binary files can hold structured data, including integers, floating-point numbers, and complex values.

This is the basic example of fortanfile() method where we have wrote integers, floats, complex numbers to fortan binary file and read back using read_ints, read_reals, and read_record. The program retrieves the data in the original structure.

from scipy.io import FortranFile
import numpy as np

# Step 1: Write data to a Fortran binary file
with FortranFile('example.dat', 'w') as f:
    f.write_record(np.array([10, 20, 30, 40], dtype=np.int32))
    f.write_record(np.array([1.1, 2.2, 3.3, 4.4], dtype=np.float64))
    f.write_record(np.array([1+2j, 3+4j], dtype=np.complex128))
print("Data written to 'example.dat'.")
with FortranFile('example.dat', 'r') as f:
    
    ints = f.read_ints(np.int32)
    print("Integers read from file:", ints)
    floats = f.read_reals(np.float64)
    print("Floats read from file:", floats)
    complex_nums = f.read_record(np.complex128)
    print("Complex numbers read from file:", complex_nums)

When we run above program, it produces following result −

Data written to 'example.dat'.
Integers read from file: [10 20 30 40]
Floats read from file: [1.1 2.2 3.3 4.4]
Complex numbers read from file: [1.+2.j 3.+4.j]

Example 2

Fortran binary files can also contain multi-dimensional arrays. When read back, the data can be reconfigured to return into its original dimensions.

In this example we will create a 2D array with the help of write_record to a Fortran binary file and read it back with read_record. The reshape function was used to restore its original dimensions, demonstrating smooth handling of multidimensional data.

from scipy.io import FortranFile
import numpy as np

# Write a 2D array to a Fortran binary file
with FortranFile('example_2d_array.dat', 'w') as f:
    f.write_record(np.array([[1, 2, 3], [4, 5, 6]], dtype=np.int32))

# Read the 2D array from the file
with FortranFile('example_2d_array.dat', 'r') as f:
    data = f.read_record(np.int32)
    print("2D array read from file:")
    print(data.reshape(2, 3))  # Reshape as needed

Following is an output of the above code −

2D array read from file:
[[1 2 3]
 [4 5 6]]

Example 3

If you give the method an incorrect header_dtype, it may read the structure of the file incorrectly and hence cause runtime problems or read invalid data.

In the following code, we intentionally used an incorrect header_dtype (np.float64) while reading a file that had np.int32 headers using fortanfile(). This mismatch causes a runtime error, which shows why the right header type should be used.

from scipy.io import FortranFile
import numpy as np

with FortranFile('example.dat', 'w', header_dtype=np.int32) as f:
    f.write_record(np.array([10, 20, 30, 40], dtype=np.int32))

try:
    with FortranFile('example.dat', 'r', header_dtype=np.float64) as f:
        data = f.read_ints(np.int32)
        print("Data read:", data)
except Exception as e:
    print("Error:", e)

Output of the above code is as follows −

Data read: []UserWarning: Given a dtype which is not unsigned.
with FortranFile('example.dat', 'w', header_dtype=np.int32) as f:

Example 4

A Fortran file is an ordered binary file, using Fortran's specific format, which adds record markers to indicate the start and end of data blocks. If one tries to read a file that is not a Fortran binary using FortranFile, then the process will fail since it depends on these record markers. Runtime problems occur if a mismatch in size or structures is used rather than the appropriate Fortran file.

In the below code, we created a non-Fortran binary file with arbitrary content and then tried to read it using FortranFile() method. The code is raising a ValueError with the message, "Size obtained (.) is not a multiple of the dtypes given (.)". This makes sure that a proper Fortran binary file format has to be used with FortranFile.

# Create a non-Fortran binary file with arbitrary content
with open('non_fortran.dat', 'wb') as f:
    f.write(b'RANDOM_BINARY_DATA')

# Try reading the non-Fortran file
from scipy.io import FortranFile

try:
    with FortranFile('non_fortran.dat', 'r') as f:
        data = f.read_ints(np.int32)
        print("Data read:", data)
except Exception as e:
    print("Error:", e)

Output of the above code is as follows −

Error: Size obtained (1145979218) is not a multiple of the data types given (4).
scipy_input_output.htm
Advertisements