Глядя на двоичный вывод из Фортрана на gnuplot - PullRequest
6 голосов
/ 06 января 2012

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

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

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

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

Спасибо

Ответы [ 3 ]

8 голосов
/ 24 февраля 2012

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

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

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

в фортране:

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» на «% double».

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

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

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

6 голосов
/ 11 января 2012

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

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

или по строкам:

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
4 голосов
/ 27 марта 2015

Тестирование с использованием gnuplot 5.0, следующая запись в неформатированный формат данных из двойного массива 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"

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

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

...