【问题标题】:Looking at binary output from fortran on gnuplot在 gnuplot 上查看 fortran 的二进制输出
【发布时间】:2012-02-03 18:54:53
【问题描述】:

所以,我用 fortran 创建了一个二进制文件,使用类似的东西:

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

按照我的理解,fortran 在文件的两端用 4 个字节填充文件,其余的只是我想要的数据(在这种情况下,是 1000 个双精度的列表)。

我想用 gnuplot 读这个,但是,我不知道如何让 gnuplot 跳过第一个和最后 4 个字节,并将其余的作为双精度读入。文档在这方面不是很有帮助。

谢谢

【问题讨论】:

  • stackoverflow.com/questions/8751185/fortran-binary-file-format 建议的那样,使用 Steam IO 获取额外字节数
  • 我没有看到这是另一个问题的重复,也许有人可以关闭这个?
  • 这与其他问题有很大不同......基本上我不是在问如何更改 fortran 输出(尽管这确实解决了我的问题),我在问如何让 gnuplot 阅读在数据中。

标签: fortran gnuplot binaryfiles binary-data


【解决方案1】:

使用直接 I/O 可能比顺序 I/O 更容易:

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

【讨论】:

【解决方案2】:

Andrew:我认为没有理由让 gnuplot 在您的数据之前/之后处理这些额外的字节。 Fortran 不执行此填充,或者它执行并且 gnuplot 轻松处理它。

我也遇到过类似的问题,Google 搜索总是让我回到这里。我想我最好发布我的解决方案,以防其他人发生同样的情况。

我一直在尝试使用 gnuplot 的“plot 'file.dat' matrix with image”命令绘制 2D 颜色图。我的 ASCII 输出文件太大,所以我想改用二进制文件。我所做的类似于以下内容:

在 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” 到 "%double"。

  • 我的程序在数组中使用了双精度数据,但输出文件 太大了。由于基于双精度或单精度的图像是 肉眼无法区分,双精度数据文件 大,我将我的双精度数据转换为单精度数据 在将其写入文件之前。

  • 您可能需要根据具体情况调整 gnuplot 命令 您想处理矩阵,但这会将其加载并绘制出来 好吧。这完成了我需要它做的事情,我希望它可以帮助任何人
    其他有类似问题的人。

  • 如您所见,如果 Fortran 在您的数据之前/之后添加额外的字节, gnuplot 似乎可以读取数据而不会让您采取额外的措施 字节考虑在内。

【讨论】:

  • 我想指出,这个答案实际上并没有回答原始帖子。尽管 Andrew 想要一种跳过标头信息字节的方法,但我的回答提供了一种更好的输出 Fortran 数据的方法。 Fortran 确实打印头字节(使用 ifort 15.0.1 20141022 测试),但与其他编程语言和 I/O 约定相比,这通常是 Fortran 非常不受欢迎的功能。我的回答提供了一种在没有头字节的情况下在 Fortran 中执行 I/O 的方法。在@Andrew Spott 和 HAL 9001 的代码中,都包含了标头字节。
  • 我现代的 Fortran 流访问,正如问题下的 cmets 所建议的那样,可能更方便。
【解决方案3】:

使用 gnuplot 5.0 进行测试,以下为大小为 N 的双精度数组 x 的 fortran 无格式数据写入,

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 意味着,跳过一次四字节整数,有效地跳过页眉和页脚数据 fortran 环绕输出。

有关更复杂数据的更多信息和推断,请参阅有关二进制的 gnuplot 5.0 文档并使用show datafile binary datasizes 查看格式的大小。但请注意,可以使用与上述相同的格式访问多列数据(即每次写入 N 个双精度数),但使用 %Ndoubles 其中 N 是整数。然后以using 1:3 为例,将第一列与第三列进行对比。

【讨论】:

  • 这是对所提出问题的正确答案,当然也有助于知识。感谢发帖!
猜你喜欢
  • 1970-01-01
  • 2020-12-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-14
  • 1970-01-01
  • 2017-12-21
  • 1970-01-01
相关资源
最近更新 更多