Problem with writing .dat files using Fortran - fortran

I am reading a .txt file and writing to a .dat file for use in GrADS.
The .txt file contains 1D data, and my program reads all 123 lines correctly as I checked by printing on screen. However, the result .dat file only contains the very first line of data, the rest are all zeros. How can I fix this? Did I set the dimensions in write incorrectly?
Here is my code:
program convert
integer,parameter::nlon=1,nlat=1,nz=123
real,dimension(nlat,nlon,nz)::pr
integer::ilon,ilat,iz
open(2,file='2020082100_1.txt',form='formatted',status='old')
INQUIRE(IOLENGTH=LREC) pr
open(3,file='2020082100_1.dat',form='unformatted', &
access='direct',recl=LREC)
do iz=1,nz
do ilat=nlat,1,-1
read(2,*) (pr(ilat,ilon,iz),ilon=1,1)
end do
end do
IREC=1
do iz=1,nz
write(3,rec=irec) ((pr(ilat,ilon,iz),ilon=1,nlon),ilat=1,nlat)
IREC=IREC+1
end do
close(2)
close(3)
end program convert
For example, the first few lines of the .txt file are:
30.7
29.4
25.9
24.2
24.4
...
However, the .dat file contains this:
30.7
0
0
0
0
...

So after tinkering with the code for a few hours, I figured out how to fix it myself.
Since all the data is writing on the wrong axis, I simply need to change a single line of code:
from this:write(3,rec=irec) ((pr(ilat,ilon,iz),ilon=1,nlon),ilat=1,nlat)
to this: write(3,rec=iz) ((pr(iz,ilon,ilat),ilon=1,nlon),ilat=1,nlat).
By changing this it completely worked. I did actually set the dimensions in write incorrectly.

Related

How to determine file size in Fortran 77

I have a Fortran program that needs to read ASCII files, however the list of files sometimes includes a file of size 0. The program then crashes when trying to read this file. I have not find any way so far that will allow me to flag such a file.
I have following READ statement in my code
read(10,220,END=320,ERR=195)parm(1:)
although I expect code to go to statement 195, or to statement 320, without crashing, it crashes
this is where the code crashes when the file size is zero, with the following messages
...
fmt: end of file
apparent state: unit 10 named junko.con
last format: (A)
lately reading sequential formatted external IO
I tried using the INQUIRE statement
inquire (unit=10,SIZE=nsize), but the program would not compile
the OPEN statement did not give any error when opening the zero size file, and the values of IOSTAT was the same, irrespective of the file size
As Ian noted, any modern Fortran compiler should have INQUIRE. A simple test of
program foo
integer sz
inquire(file='tmp.dat',size=sz)
print *, sz
end program foo
with an empty tmp.dat file sets sz=0.

Converting / Flattening RMS indexed files from OpenVMS

I was attempting to convert some Indexed files created on the OpenVMS to plain flat sequential files to be used in Windows or Linux.
Each indexed files contains x quantity of of POD structures (2594 bytes)
I have converted the files using a simple program such as this:
PROGRAM MAKE_FLAT
BYTE byte_array(2594)
PARAMETER FILE_IN = 1
PARAMETER FILE_OUT = 2
OPEN(UNIT=FILE_IN, fmt='UNFORMATTED',
1 FILE='input.data',
1 ORGANIZATION='INDEXED',
1 ACCESS='SEQUENTIAL',
1 KEY=(1:8:INTEGER), RECL=649)
OPEN(UNIT=FILE_OUT, fmt='UNFORMATTED',
1 FILE='output.data')
DO WHILE (.TRUE.)
READ(FILE_IN, END=999) byte_array
WRITE(FILE_OUT) byte_array
END DO
999 CONTINUE
CLOSE(FILE_IN)
CLOSE(FILE_OUT)
END
If there are 1000 records in the file, and I should be expecting a file that is
~ 10002594 bytes, but instead it resulted with 10002044 bytes shown using:
DIR/FULL output.data
Why is it that the program writing fewer bytes per record? Did I do something wrong?
Using the built-in utility of OpenVMS gives me the expected flat file.
ANAL/RMS/FDL FILE.FDL input.data
EDIT/FDL/ANALY=FILE.FDL FILE.FDL
After changing organization from 'INDEXED' to 'SEQUENTIAL' and contiguous to 'YES', performing the following command gives me the flat file of correct size (include padding per record).
CONVERT/FDL=FILE.FDL input.data output.data
If you do not really need to do this in a program, just use CONVERT
$ CONVERT/FDL=FIXED.FDL IN-FILE OUT-FILE
You can use $ EDIT/FDL FIXED.FDL and follow the prompts for making a sequential file.
2044 looks like the max. record size FORTRAN on VMS is using to write the data. If the file size is really 1000*2044 something is wrong.
What's the output of DUMP/HEADER/BLOCKS=COUNT=0 FOR002.DAT in the lines 'Record size', 'End of file block' and 'End of file byte'?
I would expect that the 2594 bytes are written in two records. Given that there are two bytes for a flag, you will see records with length 2044 and 554. (You can confirm this with a DUMP/RECORD FOR002.DAT/PAGE.) Each record has a record length field of two bytes. That is, you should have a file size of 1000*(2044+2+554+2) = 2602000.
You can double check that with the "End of file" data from the first DUMP command: (End of file block-1)*512 + End of file byte.

Unable to read a number from a text file

I am using Fortran to make a subroutine to use in a CFD shallow water software.
I have written this code to read and use the values stored.
PROGRAM hieto
! Calcula la precipitacion efectiva en funcion del tiempo
!IMPLICIT NONE
real::a
!Abrir CSV
!OPEN(UNIT=10,FILE="datos.txt",FORM="formatted",STATUS="replace",ACTION="readwrite",ACCESS='sequential')
open(unit=10, file='datos.txt')
!Leer el archivo
read(10, *, iostat=ios)a
print*,ios
print*, a
close (UNIT=10)
END PROGRAM hieto
My text file datos, looks like this
1
2
3
When I run the code as is, I get the following output
-1
0.0000000000
Process return 0 (0x0) execution time: 0.002 s
the first number in the row one is one not zero, so I don't know why this happens.
And if I remove the iostat=ios from the read statement, I get the following error:
At ine 13 (the line od the read stament) of file /home/Dropbox/scripts_tesis/fortran/hieto_telemac.f90 (unit=10, file=datos.txt')
Fortran runtime error: end of file.
Proceess returned 2 (0x2)
I have read some answers here so I tried adding end=3 in the read statement, and also to end my text file with a blank line at the end.
The end=3 gives an error saying 3 is not a defined label and putting a blank row in the text file does nothing.
I am using ubuntu 16.04 LTS and Gfortran compiler.
What happens is that your file is empty.
Make sure that there is indeed a file called datos.txt in that directory. Pay attention to the exact name. datos.txt and just datos is not the same thing.
If you tried to open it before with the commented command that includes STATUS="replace" your old file would have been replaced.
And because the file is empty, you didn't real anything useful. If iostat is non-zero, and your is -1, then the value of the variable being read is undefined. So your a is undefined. Again, because your file is empty.
Additionally, you cannot just blindly put end=3 in your code because you saw it somewhere on Stack Overflow. You must first understand what it is supposed to do. There is no reason to combine iostat= and end=. The iostat is perfectly sufficient.

Unexpected end of file with the read command

I'm trying to read data from a mesh file in Fortran 2003, but I'm getting an unexpected end of file runtime error. Some lines in the file seem to be skipped by the read command. For example, with this sample.txt file :
1 2 2 0 1 1132 1131 1165
2 2 2 0 2 1099 1061 1060
I want to read the first integer from each line, so my program is :
program read_file
implicit none
integer :: ierr, i, j
open(unit=10,file='sample.txt',status='old',action='read',iostat=ierr)
read(10,*) i
read(10,*) j
write(*,*) i, j
end program read_file
And at runtime, I'm getting
Fortran runtime error: End of file
What is odd is that if I force a carriage return at the end of the file, the program will read the two integers just fine.
If you really need to fix this on the read side (ie. properly terminating the last line of the file is not practical for some reason ) you might try reading each line into a string, then internal reading from the string:
character*80 line
integer i
do ..
read(unit,'(a)')line
read(line,*)i
enddo
Of course this may or may not work depending on the compiler as well..
Obviously fixing the file is the best option ( Whatever program is creating this file should be fixed )
Every record in a sequential file must be properly terminated. The records in text files are the lines. They must be properly terminated. In some editors that means you must add an empty line to the end. Every line containing data must be terminated.
Some compilers are less sensitive to this issue than others and will terminate the last record for you.

Fortran routine skips lines but is not allowed to.

I made a Fortan routine to read a weather file into my program. This file contains 2 header lines and then lines of data for every 10 minutes and is therefor 52562 lines long.
When reading the file with the code below it returns the error Fortran runtime error: End of file for i = 52548 in the do-loop.
bdst=600
allocate(clidat(int(3.1536d7/bdst),15))
open(2001,file='church_10m.cli',action='read')
read(2001,*); read(2001,*)
do i=1,size(clidat,1)
read(2001,*) clidat(i,:)
enddo
close(2001);
The file used can be found using this public dropbox link: church_10m.cli. I checked and the file does contain the 52562 lines. The line corresponding to i = 52548 is the last line of the file. The line corresponding to i=1 is the third line of the file (which starts with 0). So I suspect that some lines are skipped in between. Any thoughts why this happens?
If a line doesn't contain 15 values (the size of clidat) the read statement just goes to the next line and reads the next values. There were a couple of lines in the church_10m.cli file that didn't have enough values. (for example line 1957).
This was a result of the conversion from an excel file to a txt file.