Lesen Sie die Fortran-Ausgabe mit Python

Lesen Sie die von Fortran ausgegebene Binärdatei mit Python

In Fortran werden numerische Berechnungen durchgeführt, und Diagramme und Analysen gelten für Personen, die Python genannt werden. Es wird angenommen, dass die Ausgabe der numerischen Berechnung eine Binärdatei ist. In Python wird außerdem angenommen, dass Numpy für die Analyse verwendet wird. In diesem Artikel werde ich zuerst das binäre Ausgabeformat von Fortran erläutern und dann beschreiben, wie es in Python gelesen wird.

Informationen zum Fortran-Ausgabeformat

Es gibt drei Arten von Fortran-Binärausgabeformaten: sequentiell (Auftragssuche), direkt (direkte Suche) und Stream. Schauen wir uns jeden an. Beachten Sie, dass sich die Binärausgabe hier auf form = "unformatiert" bezieht. Nicht form = "binär". (Ich weiß nicht viel über form = "binary")

sequentiell

Ein Format, das vom Anfang der Datei an schreibt. Jedes Mal, wenn Sie schreiben, wird am Anfang und am Ende der Ausgabe ein 4-Byte-Marker hinzugefügt (der 8 Byte betragen kann, wenn er alt ist). Die Anzahl der ausgegebenen Bytes wird am Anfang eingegeben. Es ist notwendig, von Anfang an zu lesen (obwohl es nicht unmöglich ist, mit Stream zu lesen, wenn Sie die Anzahl der Bytes angeben ...)

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

Direkte

Ausgabe durch Angabe der Datensatzlänge (Anzahl der Bytes; recl). Geben Sie bei der Ausgabe rec und die Ausgabeposition an. Daher ist es nicht immer notwendig, von Anfang an zu schreiben (obwohl es normalerweise von Anfang an ausgegeben wird). Es ist praktisch, dass Sie beim Lesen nicht von Anfang an lesen müssen. Im Fall des Intel-Compilers (ifort) beträgt der Standardwert von recl 4 Byte (wenn beispielsweise recl = 4 ist, werden 16 Byte ausgegeben). Es ist sicher, die Annahme von Byte-Recl in Byte-Einheiten als Option zu korrigieren.

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 Stream-Eingabe / Ausgabe wurde in Fortran 2003 und höher hinzugefügt. Ähnlich wie sequentiell, außer dass am Anfang und Ende der Datei keine Markierungen vorhanden sind.

open(10,file="test.stm", form="unformatted", action="write",access="stream")
write(10) a
write(10) b !Pos wird automatisch angegeben.

Die Ausgabeposition kann auch mit pos angegeben werden (Anzahl der Bytes). Wenn Sie bei der Eingabe pos angeben, muss nicht immer von Anfang an gelesen werden.

Über Endian

Es gibt große und kleine Endianer. Wenn nicht angegeben, wird die Standardeinstellung des Computers verwendet. Beides ist in Ordnung, aber es ist sicher, sie einheitlich zu verwenden, damit Sie sie verstehen können. Die zur Kompilierungszeit anzugebende Methode lautet wie folgt

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

Sie kann auch mit der open-Anweisung angegeben werden. Geben Sie mit convert an (wahrscheinlich in den meisten Compilern als Erweiterung festgelegt).

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

Lesen Sie mit Python

Es kann mit der Standardbibliothek von Python gelesen werden. Lesen Sie die Binärdatei und konvertieren Sie sie mit np.frombuffer. Wenn Sie die folgende Klasse erstellen, können Sie sie für Fortran verarbeiten. Da es sich bei der Ausgabe um ein eindimensionales Array handelt, konvertieren Sie es bei Bedarf mit Umformung. Die Erklärung von dtype ist nur typisch. Für Details [https://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html#] Und

Symbol Bedeutung
> Big Endian
< Kleiner Inder
i4 4-Byte-Ganzzahl
f4
f8

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") #
f.rewind() #

Zum Beispiel 8-Byte-Floating-Fraktion oder weniger. Ich werde ein Beispiel für das Lesen einer 4-Byte-reellen Zahl mit 200 Elementen lesen. sequentielle (sequentielle Suche) Big-Endian-4-Byte-Ganzzahl Zum Anfang der Datei direkt (direkte Suche)

Der direkte Zugriff ändert den Typ nicht und die Datensatzlänge ist konstant. Legen Sie ihn daher beim Erstellen einer Instanz fest.

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 beginnt bei 1(Fortran-artig)
        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))

Sie können es auch mit numpy.fromfile lesen. Geben Sie die Anzahl der Bytes an, die mit dem Versatz mit dem Lesen beginnen sollen, und geben Sie die Anzahl der Elemente an, die mit dtype gelesen werden sollen.

numpy 1.7 oder höher

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

stream

Sie können es mit seek und np.frombuffer lesen, die oben verwendet wurden. seek ist dasselbe wie pos, daher sollte jeder, der die Stream-Ausgabe in Fortran verwenden kann, dies sofort tun können.

Recommended Posts

Lesen Sie die Fortran-Ausgabe mit Python
Lesen Sie DXF mit Python
Japanische Ausgabe mit Python
Lesen Sie Eulers Formel in Python
Lesen Sie XML mit dem in Python angegebenen Namespace
Ausgabe 2017 Premium Friday List in Python
Lesen Sie PNG-Chunks in Python (Klassenausgabe)
Machen Sie die Standardausgabe in Python nicht blockierend
Lassen Sie Python die Befehlsausgabe lesen
Lesen Sie Dateien parallel zu Python
Exportieren und Ausgeben von Dateien in Python
Erstellen und lesen Sie Messagepacks in Python
Python in der Optimierung
CURL in Python
Metaprogrammierung mit Python
Python 3.3 mit Anaconda
Geokodierung in Python
Metaanalyse in Python
Unittest in Python
Ausgabebaumstruktur von Dateien in Python
Python-Lernausgabe
Epoche in Python
Zwietracht in Python
Lesen Sie die Standardausgabe eines Unterprozesses zeilenweise in Python
Deutsch in Python
DCI in Python
Quicksort in Python
nCr in Python
N-Gramm in Python
Programmieren mit Python
Lesen Sie die Datei Zeile für Zeile mit Python
Plink in Python
Konstante in Python
Lesen und schreiben Sie JSON-Dateien mit Python
FizzBuzz in Python
Schritt AIC in Python
Schreiben Sie mit f2py ein Python-Modul in fortran
CSV in Python
Reverse Assembler mit Python
Reflexion in Python
Konstante in Python
nCr in Python.
Format in Python
Scons in Python 3
Puyopuyo in Python
Python in Virtualenv
PPAP in Python
Quad-Tree in Python
Chemie mit Python
[Python] Lesen Sie die angegebene Zeile in der Datei
Hashbar in Python
DirectLiNGAM in Python
LiNGAM in Python
In Python reduzieren
[Python] Daten lesen
In Python flach drücken
Verwenden Sie Python für formatierte Ausgaben wie C / C ++ printf
Geben Sie die Anzahl der CPU-Kerne in Python aus
3,14 π Tag, versuchen Sie also, in Python auszugeben