Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
27522 Discussions

How to read a .csv file and then store data in a matrix in Fortran90?

g_don
Novice
723 Views

Hi guys,
I've exported a table from Matlab in a .csv file (attached to this post: "NEOs_asteroids_filtered.csv" ).

I read the file in order to create a vector of six element (6 orbital parameter) for each asteroid (whose data are stored in the rows of my .csv file).

I created a derived data type named NEO and then I read all data in a variable named asteroids

Now I would want to perform something like this:

matrix = (asteroids%a, asteroids%e, asteroids%i,  asteroids%om, asteroids%w, asteroids%ma)

matrix of dimension: num_row = number of asteroids and num_columns = number of orbital elements (i.e. only 6 columns instead of 11). How can I perform this task?

Can you help me in the coding?


Here my attempt code for data reading (main):

 

 

program LagrangePoints_Main

    use DataType
    use Constants
    
    implicit none   
    
    !  NEOs data :
    !  pdes      Object primary designation
    !  IAU name  Object IAU name
    !  Epoch     Epoch Julian Date (TDB: Barycentric Dynamical Time): Julian Date of osculating elements 
    !  a         Semi-major axis (AU)
    !  e         Eccentricity       
    !  i         Inclination w.r.t. xy-plane (deg)
    !  om        Longitude of Ascending Node w.r.t. to ecliptic/equinox (deg)
    !  w         Argument of Perihelion wrt to ecliptic/equinox (deg)
    !  ma        Mean anomaly (deg)
    !  q         Perihelion distance (AU)
    !  ad        Aphelion distance (AU)
  
    ! Declarations
    character*100 :: input_path,input_filename_ast, output_path, output_filename_ast
    character*118 :: str_line
    character*30, dimension (4) :: str_output    !for header of output file for Matlab
    integer :: i,iflag, n_lines
    type(NEO), dimension (:), allocatable :: asteroids   
    real(pr), dimension (:,:), allocatable :: elem_matrix
    
     ! Definition of constants, paths names and file names
   
    input_path = 'D:\OneDrive\MSc_Thesis\Projects\NEOs_orbits\InputFiles\'
    input_filename_ast = 'NEOs_asteroids_filtered.csv'
    !output_path =  'D:\OneDrive\MSc_Thesis\Projects\NEOs_orbits\OutputFiles\'
    !output_filename_ast = 'Asteroids_state_vec.txt'
   
    
    ! Reading of asteroids data
    open(unit = iu_in, file = trim(input_path) // trim(input_filename_ast), status='old', & 
         access = 'sequential',form = 'formatted', action='read')
    
    ! Count lines 
    n_lines = 0
    do
      read(iu_in,*,iostat = iflag)
      if (iflag/=0) exit
      n_lines = n_lines + 1
    enddo
    
    rewind(iu_in)
    
    ! Variables allocation
    allocate(asteroids(n_lines))
    
    read (iu_in,'(a35)') str_line
        do i = 1,55
            read(iu_in,*) asteroids(i)         
        enddo
    
    close(unit = iu_in, status='keep') 

    !allocate(elem_matrix(55,3))
    !
    !do i =1,55
    !          elem_matrix = (asteroids%a(i), asteroids%e(i), asteroids%i(i))
    !enddo
    
    print *, asteroids
    
    ! Convert Mean anomaly to true anomaly
    
    
    
    stop

    end program LagrangePoints_Main    

 

 

 

Labels (1)
0 Kudos
1 Solution
Arjen_Markus
Honored Contributor I
657 Views

I had a look at the file: the fields appear to be separated by commas, which is nice because that can be handled automatically by list-directed input (read( line, *) ...), but the first field may contain a space, which serves as a field separator for list-directed input as well. So the strategy I would use is:

  • Read in the complete line (easiest if there is a reasonable maximum, otherwise there are routines around to read a complete line of arbitrary length )
  • Find the first comma via the index intrinsic function and split off the first field. Store the rest of the line in, say, a variable rest
  • You can even remove the next comma as there is nothing in between
  • Then use "read( rest, * ) x1, x2, x3, ..." to read the remaining data

Nothing wildly complicated.

Wrt your question about the empty field: list-directed input will skip that, not touching the corresponding variable. Try it with a few simple examples in a test program.

View solution in original post

4 Replies
JohnNichols
Valued Contributor II
700 Views

Solution 1 - try it and report the errors

Solution 2 - use Notepad and change the , ,  to something like , dummy,

Solution 3 there are several read subroutines on this forum, you will need to search that show you how to solve this problem is read the line and look for the commas. 

g_don
Novice
691 Views

Thanks @JohnNichols , can you write the link where I can find the read subroutines on this forum?

g_don
Novice
695 Views

Thanks @JohnNichols , can you write the link where I can find the read subroutines on this forum?

P.S. Sorry, I answered in wrong way here. 

Arjen_Markus
Honored Contributor I
658 Views

I had a look at the file: the fields appear to be separated by commas, which is nice because that can be handled automatically by list-directed input (read( line, *) ...), but the first field may contain a space, which serves as a field separator for list-directed input as well. So the strategy I would use is:

  • Read in the complete line (easiest if there is a reasonable maximum, otherwise there are routines around to read a complete line of arbitrary length )
  • Find the first comma via the index intrinsic function and split off the first field. Store the rest of the line in, say, a variable rest
  • You can even remove the next comma as there is nothing in between
  • Then use "read( rest, * ) x1, x2, x3, ..." to read the remaining data

Nothing wildly complicated.

Wrt your question about the empty field: list-directed input will skip that, not touching the corresponding variable. Try it with a few simple examples in a test program.

Reply