2012-01-05 22 views
6

Così, ho creato un file binario con FORTRAN, utilizzando qualcosa di simile a questo:Guardando uscita binario da FORTRAN su gnuplot

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

Il modo in cui ho capito, i rilievi FORTRAN il file con 4 byte su entrambi i lati del file, e il resto sono solo i dati che voglio (in questo caso, una lista di 1000 doppi).

Voglio leggere questo in con gnuplot, tuttavia, non so come ottenere gnuplot per saltare il primo e l'ultimo 4 byte e leggere il resto come doppio. La documentazione non è molto utile in questo senso.

Grazie

+3

Utilizzare Steam IO per ottenere i byte extra, come suggerito all'indirizzo http://stackoverflow.com/questions/8751185/fortran-binary-file-format –

+0

Non ho visto che questo era un duplicato dell'altra domanda , forse qualcuno può chiudere questo? – steabert

+2

Questo è piuttosto diverso dall'altra domanda ... fondamentalmente non sto chiedendo come modificare l'output di fortran (anche se questo risolve il mio problema), sto chiedendo come ottenere gnuplot per leggere nei dati. –

risposta

4

Test con gnuplot 5.0, il seguente FORTRAN dati formattati scrittura di un doppio array x di dimensioni N,

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

siano comprese dal gnuplot con il seguente:

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

Il %*1int significa, salta una volta un intero di quattro byte, saltando in modo efficace i dati di intestazione e piè di pagina che fortran avvolge l'output.

Per ulteriori informazioni e estrapolazioni per dati più complicati, consultare i documenti gnuplot 5.0 su binario e vedere la dimensione dei formati con, show datafile binary datasizes. Si noti tuttavia che è possibile accedere ai dati a più colonne (vale a dire N raddoppia per scrittura) con lo stesso formato sopra ma come %Ndoubles dove N è un numero intero. Quindi con using 1:3, ad esempio, si traccia la prima colonna rispetto alla terza.

+0

Questa è la risposta corretta alla domanda posta e certamente contribuisce alla conoscenza. Grazie per la pubblicazione! – jvriesem

6

potrebbe essere più facile da usare I/O diretto anziché sequenziale:

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,:) 

La dichiarazione inquire ti dà la lunghezza della lista di output in unità 'detraibile. In quanto tale, l'intera lista si inserisce in un record di lunghezza irec.

Per scrivere una matrice di file colonna-saggio è quindi possibile fare:

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 

o una riga-saggio:

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 

o elemento-saggio:

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 

o scaricare l'intera matrice:

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

Questa è una risposta fantastica e molto utile, ma sfortunatamente non penso che risponda alla domanda: "come faccio a leggere gnuplot in dati binari con padding" –

+0

Sarebbe più adatto per la domanda di altri OP http: // stackoverflow.com/questions/8751185/fortran-binary-file-format –

8

Andrew: Non vedo alcun motivo per far sì che gnuplot gestisca quei byte aggiuntivi prima/dopo i dati. O Fortran non esegue questo riempimento, o lo fa e gnuplot lo gestisce senza problemi.

Ho avuto un problema simile e le ricerche di Google mi hanno sempre riportato qui. Ho pensato che sarebbe meglio pubblicare la mia soluzione nel caso in cui lo stesso accadesse ad altre persone.

Ho cercato di creare un tracciato della mappa di colori 2D utilizzando il comando "trama" file.dat 'di matrice con immagine "di gnuplot. I miei file di output ASCII erano troppo grandi, quindi ho preferito utilizzare file binari. Quello che ho fatto è stato qualcosa di simile al seguente:

in 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') 

in gnuplot:

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

Note:

  • Per impostazione predefinita, gnuplot assume precisione singola in file binari. Se il tuo programma di fortran emette una doppia precisione, cambia semplicemente "% float" in "% double".

  • Il mio programma utilizzava dati di precisione doppia nell'array, ma i file di output erano troppo grandi.Poiché le immagini basate sulla precisione doppia o singola sono indistinguibili alla vista, e i file di dati a precisione doppia sono di grandi dimensioni, ho convertito i miei dati a precisione doppia in dati a precisione singola prima di scriverlo in un file.

  • Potrebbe essere necessario adattare il comando di gnuplot seconda di ciò che si vuole fare con la matrice, ma questo lo carica e trame che bene. Questo ha fatto ciò che avevo bisogno di fare, e spero che aiuti chiunque a trovare lo
    chi ha un problema simile.

  • Come si può vedere, se Fortran aggiunge byte in più prima/dopo i dati, gnuplot sembra leggere i dati senza che si prende quelli extra byte in considerazione.

+0

Vorrei sottolineare che questa risposta in realtà non risponde al post originale. Mentre Andrew voleva un modo per saltare i byte di informazione dell'intestazione, la mia risposta fornisce un modo migliore per emettere i dati di Fortran. Fortran DOES print header bytes (testato con ifort 15.0.1 20141022), ma di solito è una caratteristica molto indesiderabile di Fortran, rispetto ad altri linguaggi di programmazione e convenzioni di I/O. La mia risposta fornisce un modo per eseguire I/O in Fortran SENZA i byte di intestazione. In entrambi i codici @Andrew Spott e HAL 9001 sono inclusi i byte di intestazione. – jvriesem