Глядя на двоичный вывод из fortran на gnuplot

Итак, я создал двоичный файл с fortran, используя что-то похожее на это:

open (3,file=filename,form="unformatted",access="sequential")
write(3) matrix(i,:)

Как я понимаю, fortran помещает файл с 4 байтами на любом конце файла, а остальное-это только данные, которые я хочу (в этом случае список из 1000 двойников).

Я хочу прочитать это с помощью gnuplot, однако я не знаю, как заставить gnuplot пропустить первые и последние 4 байта, а остальные прочитать как двойные. Документация не очень полезна в этом рассматривать.

спасибо

3 ответов


тестирование с gnuplot 5.0, следующая fortran неформатированная запись данных двойного массива x в размере N,

open(FID,file='binaryfile')
do k = 1, N
  write(FID) x(k)
end do 
close(FID)

можно понять gnuplot со следующим:

plot 'binaryfile' binary format="%*1int%double%*1int"

The %*1int означает, пропустить один раз четырехбайтовое целое число, эффективно пропуская данные верхнего и нижнего колонтитулов fortran обертывания вокруг вывода.

для получения дополнительной информации и экстраполяции для более сложных данных см. документы gnuplot 5.0 на двоичном файле и см. Размер форматы с, show datafile binary datasizes. Обратите внимание, однако, что данные с несколькими столбцами (т. е. N двойников на запись) могут быть доступны в том же формате, что и выше, но как %Ndoubles где N-целое число. Тогда с using 1:3 например, можно построить первый столбец против 3-го.


Andrew: я не вижу причин заставлять gnuplot обрабатывать эти дополнительные байты до/после ваших данных. Либо Fortran не делает эту прокладку, либо делает, и gnuplot обрабатывает ее без хлопот.

у меня была аналогичная проблема, и поиск Google всегда возвращал меня сюда. Я решил, что лучше опубликовать свое решение, если то же самое произойдет с другими людьми.

Я пытался сделать 2D-цветной график, используя файл "plot" gnuplot.dat 'matrix with image" команда. Мой код ASCII выходные файлы были слишком большими,поэтому я хотел использовать двоичные файлы. Я сделал примерно следующее:--3-->

в fortran:

implicit none
real, dimension(128,128) :: array
integer :: irec

! ... initialize array ...

inquire( iolength=irec ) array
open( 36, 'out.dat', form='unformatted', access='direct', recl=irec )
write( 36, rec=1 ) array
close( 36, status='keep' )

в gnuplot:

plot 'out.dat' binary array=128x128 format="%float" with image

Примечания:

  • по умолчанию gnuplot предполагает единую точность в двоичных файлах. Если ваш выходы программы fortran в двойной точности, просто изменяют " % float" удваивать."

  • моя программа использовала данные двойной точности в массиве, но исходящие файлы быть слишком большой. Поскольку изображения, основанные на двойной или одиночной точности неразличимы для глаз, и файлы данных двойной точности большой, я преобразовал данные двойной точности в данные с одной точностью перед записью в файл.

  • возможно, вам придется адаптировать команду gnuplot в зависимости от того, что вы хотите сделать с Матрицей, но это загружает ее и строит ее что ж. Это сделало то, что мне было нужно, и я надеюсь, что это поможет кому-нибудь
    еще кто подобная проблема.

  • Как вы можете видеть, если Fortran добавляет дополнительные байты до / после ваших данных, gnuplot, похоже, читает данные, не заставляя вас принимать эти дополнительные байты в счет.


может быть проще использовать прямой ввод-вывод вместо последовательного:

inquire (iolength = irec) matrix(1,:) !total record length for a row
open (3, file=filename, form="unformatted", access="direct", recl=irec)
write(3, rec=1) matrix(i,:)

на inquire оператор дает вам длину выходного списка в единицах "recl". Таким образом, весь список помещается в одну запись длины irec.

для записи матрицы в файл по столбцу вы можете сделать:

inquire (iolength = irec) matrix(:,1)
open (3, file=filename, form="unformatted", access="direct", recl=irec)
do i=1,ncol
    write(3, rec=i) matrix(:,i)
end do

или row-wise:

inquire (iolength = irec) matrix(1,:)
open (3, file=filename, form="unformatted", access="direct", recl=irec)
do i=1,nrow
    write(3, rec=i) matrix(i,:)
end do

или поэлементного:

inquire (iolength = irec) matrix(1,1)
open (3, file=filename, form="unformatted", access="direct", recl=irec)
do j=1,ncol
    do i=1,nrow
        write(3, rec=j+(ncol-1)*i) matrix(i,j)
    end do
end do

или сбросить всю матрицу:

inquire (iolength = irec) matrix
open (3, file=filename, form="unformatted", access="direct", recl=irec)
write(3, rec=1) matrix