Lire la sortie Fortran avec python

Lire la sortie du fichier binaire par Fortran avec python

Les calculs numériques sont effectués dans Fortran, et les diagrammes et analyses sont destinés aux personnes appelées python. On suppose que la sortie du calcul numérique est un fichier binaire. De plus, en python, on suppose que numpy est utilisé pour l'analyse. Dans cet article, je vais d'abord expliquer le format de sortie binaire de Fortran, puis décrire comment le lire en python.

À propos du format de sortie Fortran

Il existe trois types de formats de sortie binaires Fortran: séquentiel (recherche d'ordre), direct (recherche directe) et flux. Regardons chacun. Notez que la sortie binaire fait ici référence à form = "non formaté". Pas de forme = "binaire". (Je ne connais pas grand chose à form = "binary")

séquentiel

Un format qui écrit depuis le début du fichier. Chaque fois que vous écrivez, un marqueur de 4 octets (qui peut être de 8 octets s'il est ancien) est ajouté au début et à la fin de la sortie. Le nombre d'octets de sortie est entré au début. Il est nécessaire de lire depuis le début (même s'il n'est pas impossible de lire avec stream si vous spécifiez le nombre d'octets ...)

real(4) :: a=1,b=2
open(10,file="test.seq", form="unformatted", action="write",access="sequential")
write(10) a
write(10) b

direct

Sortie en spécifiant la longueur de l'enregistrement (nombre d'octets; recl). Lors de la sortie, spécifiez rec et spécifiez la position de sortie. Par conséquent, il n'est pas toujours nécessaire d'écrire depuis le début (bien qu'il soit généralement généré depuis le début). Il est pratique de ne pas avoir à lire depuis le début lors de la lecture. Dans le cas du compilateur d'Intel (ifort), la valeur par défaut de recl est de 4 octets (par exemple, si recl = 4, 16 octets sont générés). Il est prudent de corriger -assume byte recl en unités d'octets en option.

real(4) :: a=1,b=2
open(10,file="test.dir", form="unformatted", action="write",access="direct",recl=4)
write(10,rec=1) a
write(10,rec=2) b

stream L'entrée / sortie de flux a été ajoutée dans Fortran 2003 et versions ultérieures. Similaire à séquentiel, sauf qu'il n'y a pas de marqueurs au début et à la fin du fichier.

open(10,file="test.stm", form="unformatted", action="write",access="stream")
write(10) a
write(10) b !Pos est automatiquement spécifié.

La position de sortie peut également être spécifiée (nombre d'octets) à l'aide de pos. Si vous spécifiez pos lors de la saisie, il n'est pas toujours nécessaire de lire depuis le début.

À propos d'Endian

Il y a des big endians et des petits endians. S'il n'est pas spécifié, la valeur par défaut de la machine sera utilisée. L'un ou l'autre convient, mais il est prudent de les utiliser de manière unifiée afin que vous puissiez les comprendre. La méthode à spécifier au moment de la compilation est la suivante

$ gfortran -fconvert=big-endian test.f90
$ ifort -convert=big_endian -assume byterecl test.f90

Il peut également être spécifié avec l'instruction open. Spécifiez avec convert (probablement défini comme une extension dans la plupart des compilateurs).

open(10, file="test.dat", form="unformatted", action="write, access="stream" , &
& convert="big_endian" )

Lire avec python

Il peut être lu avec la bibliothèque standard de python. Lisez le binaire et convertissez-le avec np.frombuffer. Si vous créez la classe suivante, vous pouvez la gérer pour Fortran. Puisque la sortie est un tableau unidimensionnel, convertissez-le avec un remodelage si nécessaire. L'explication de dtype n'est que typique. Pour plus de détails [https://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html#] Et

symbole sens
> Big endian
< Petit indien
i4 Entier de 4 octets
f4 Fraction flottante de 4 octets
f8 Fraction flottante de 8 octets

Exemples ci-dessous. Je vais lire un exemple de lecture d'un nombre réel de 4 octets avec 200 éléments.

séquentiel

import numpy as np
import struct
class seq_read :
    def __init__(self,filename, endian=">") :
        self.f = open(filename, "rb")
        self.endian = endian
        
    def read(self, dtype) :
        num, = struct.unpack(self.endian+"i",self.f.read(4))    
        data = np.frombuffer(self.f.read(num), dtype )
        num, = struct.unpack(self.endian+"i",self.f.read(4))            
        return data
    
    def rewind(self) :
        self.f.seek(0) 
        
    def __del__(self) :
        self.f.close()
### example ### 
f = seq_read("test.seq", endian=">" ) 
data = f.read(">i") #entier de 4 octets big endian
f.rewind() #Vers le haut du fichier

direct

L'accès direct ne modifie pas le type et la longueur de l'enregistrement est constante, définissez-la lors de la création d'une instance.

import numpy as np
import struct
class dir_read :
    def __init__(self, filename, recl, dtype) : 
        self.f = open(filename, "rb")
        self.recl = recl
        self.dtype = dtype        
        
    def read(self, rec) : #rec commence à partir de 1(À la Fortran)
        self.f.seek((rec-1)*self.recl)
        data = np.frombuffer(self.f.read(self.recl), self.dtype)
        return data
    
    def __del__(self) :
        self.f.close()
### example ### 
f2 = dir_read("test.dir",4*200,">f")
print(f2.read(2))

Vous pouvez également le lire en utilisant numpy.fromfile. Spécifiez le nombre d'octets à lire avec offset et spécifiez le nombre d'éléments à lire avec dtype.

numpy 1.7 ou version ultérieure

import numpy as np
recl = 200
data = np.fromfile("test.dir",dtype=">"+str(recl)+"f4",count=1,offset=4*recl)[0]

stream

Vous pouvez le lire avec seek et np.frombuffer utilisés ci-dessus. seek est le même que pos, donc quiconque peut utiliser la sortie de flux dans Fortran devrait pouvoir le faire tout de suite.

Recommended Posts

Lire la sortie Fortran avec python
Lire DXF avec python
Sortie japonaise avec Python
Lire la formule d'Euler en Python
Lire du XML avec un espace de noms spécifié en Python
Sortie de la liste du vendredi Premium 2017 en Python
Lire des morceaux PNG en Python (édition de classe)
Rendre la sortie standard non bloquante en Python
Demandez à python de lire la sortie de la commande
Lire des fichiers en parallèle avec Python
Exporter et exporter des fichiers en Python
Créer et lire des paquets de messages en Python
Python en optimisation
CURL en Python
Métaprogrammation avec Python
Python 3.3 avec Anaconda
Géocodage en python
Méta-analyse en Python
Unittest en Python
Arborescence de sortie des fichiers en Python
sortie d'apprentissage python
Époque en Python
Discord en Python
Lire la sortie standard d'un sous-processus ligne par ligne en Python
Allemand en Python
DCI en Python
tri rapide en python
nCr en python
N-Gram en Python
Programmation avec Python
Lisez le fichier ligne par ligne avec Python
Plink en Python
Constante en Python
Lire et écrire des fichiers JSON avec Python
FizzBuzz en Python
Étape AIC en Python
Ecrire un module python dans fortran en utilisant f2py
CSV en Python
Assemblage inversé avec Python
Réflexion en Python
Constante en Python
nCr en Python.
format en python
Scons en Python 3
Puyopuyo en python
python dans virtualenv
PPAP en Python
Quad-tree en Python
Chimie avec Python
[Python] Lire la ligne spécifiée dans le fichier
Hashable en Python
DirectLiNGAM en Python
LiNGAM en Python
Aplatir en Python
[python] Lecture de données
Aplatir en python
Utilisez Python pour une sortie formatée telle que C / C ++ printf
Sortie du nombre de cœurs de processeur en Python
3.14 π jour, alors essayez de sortir en Python