Search code examples
fortrantext-filesfortran77

How can I read data from a text file and save/write parts/variables to different text files?


I'm fairly new to Fortran so this might be a naive question. I would like to read a huge .txt file with a # of rows=540001. The data are from a sonic anemometer with measurements of velocity and temperature as u,v,w,T at five heights. Here are the first few lines of the file:

"2011-07-10 09:30:00",9838,1.132,2.30225,-0.5635,29.18585,0.30275,0.689,-0.01125,29.67004,0.2165,-0.25475,0.12725,29.8923,0.51425,3.0405,-0.58375,29.5242,-0.0085,3.6235,-0.65175,29.61972,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
"2011-07-10 09:30:00.05",9839,-0.21325,3.22775,-0.17,29.10953,0.33925,0.6867501,-0.0015,29.67874,0.1715,-0.196,0.1235,29.8923,0.035,2.6915,-0.3845,29.82806,-0.102,3.5505,-0.15825,29.61795,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
"2011-07-10 09:30:00.1",9840,0.403,3.1195,-0.37175,29.22574,0.06550001,0.6655,0.1275,29.76208,0.196,-0.2,0.1,29.901,0.16225,2.31525,-0.5975,29.69263,0.24175,3.11925,-0.3725,29.57977,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0

etc...

I would like to save/write the matrices u(5,540001),v(5,540001),w(5,540001), and T(5,540001) so that I can do some calculations and plots. Here is what I am using:

PROGRAM READ_MAIZE
   IMPLICIT NONE

   REAL,DIMENSION(:,:),Allocatable :: u_r, v_r, w_r, T_r

   CHARACTER(len=*) :: fname
   fname='FINALDATA.txt'
   open(unit=1,file=fname,status='old',action='read')

   do i=1,540001
  READ(1,*)timestamp(i),count(i),u_r(5,i),v_r(5,i),w_r(5,i), &
    T_r(5,i),u_r(2,i),v_r(2,i),w_r(2,i),T_r(2,i), &
u_r(1,i),v_r(1,i),w_r(1,i),T_r(1,i), &
    u_r(3,i),v_r(3,i),w_r(3,i),T_r(3,i), &
u_r(4,i),v_r(4,i),w_r(4,i),T_r(4,i),flags(1:20)
   end do
   close(1)

   WRITE(U_maize,'(A,I7.7,A,I7.7,A)'), &
         '.txt'
   open(11,file=U_maize,status='unknown',action='write')
   write(11,'(F20.14)')(u_r)
   end

Never mind the order in u_r(5,i) followed by u_r(2,i)... (they just correspond to different heights that are out of order). This is not working.


Solution

  • There's quite a lot going on in your code which makes it hard to understand what you're trying to do in the first place. I have annotated your code below and turned it into something that compiles and produces output. Maybe it'll help.

    PROGRAM READ_MAIZE
        IMPLICIT NONE   ! This means that every variable has to be declared
                        ! explicitly. You don't do that. So I did it for you
    
        REAL,DIMENSION(:,:),Allocatable :: u_r, v_r, w_r, T_r
        integer, dimension(:), allocatable :: data_count  ! using fortran keywords
                ! (such as "count") as variables is dangerous and should be avoided
        character(len=len("2011-07-10 09:30:00.05")), allocatable :: timestamp(:)
    
        CHARACTER(len=*), parameter :: fname='FINALDATA.txt'
        character(len=len("U_XXXXXXX_XXXXXXX.txt")) :: U_maize
        integer :: in_unit, out_unit    ! Use integer variables for the unit.
                                        ! together with newunit keyword, this is
                                        ! safer
        integer, parameter :: num_records = 3   ! you need to up this number to
                                                ! 540001 again
        integer :: i
    
        ! If you have allocatable arrays, you need to allocate them before you
        ! can use them
        allocate(u_r(5, num_records))
        allocate(v_r(5, num_records))
        allocate(w_r(5, num_records))
        allocate(T_r(5, num_records))
        allocate(data_count(num_records))
        allocate(timestamp(num_records))
    
        ! the "newunit" keyword is a safe way to create a unique unit
        ! identifier. You should really use this.
        open(newunit=in_unit,file=fname,status='old',action='read')
    
        do i=1,num_records
            READ(in_unit,*) timestamp(i), data_count(i),    &
                u_r(5,i),v_r(5,i),w_r(5,i),T_r(5,i),        &
                u_r(2,i),v_r(2,i),w_r(2,i),T_r(2,i),        &
                u_r(1,i),v_r(1,i),w_r(1,i),T_r(1,i),        &
                u_r(3,i),v_r(3,i),w_r(3,i),T_r(3,i),        &
                u_r(4,i),v_r(4,i),w_r(4,i),T_r(4,i)     ! I left out the flags
                                                        ! since I didn't know what
                                                        ! that was.
        end do
        close(in_unit)
    
        ! I don't know how the file name should be constructed, except
        ! that it should end in a .txt, and the format. So I made something up.
        write(U_maize, '(A, I7.7, A, I7.7, A)') 'U_', 35, '_', 6, '.txt'
    
        open(newunit=out_unit,file=U_maize,status='unknown',action='write')
    
        ! To make it more readable, I tell write to write 5 numbers per row,
        ! Not sure whether this is what you want.
        write(out_unit,'(5(X, F20.14))') u_r
        close(out_unit) ! I know it isn't technically needed, but please always
            ! close files when finished, even if the program terminates anyway.
    end program READ_MAIZE   ! tell the compiler what you want to end here.