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

How can I read a file with varying number of columns?

Yeon__Jejoon
Novice
1,686 Views

Hello

My input file looks like this: 

8055 3 2 5608 5176 0 0.900 0.814 1.714 2.000 -0.466
8444 3 3 5755 6479 3139 0 0.473 0.309 0.729 1.511 2.000 -0.391
6479 1 6 8444 6895 6710 144 8257 3374 0 0.309 0.623 0.743 0.515 0.650 0.636 3.726 0.000 1.142
8407 2 3 8760 2459 9228 0 0.751 0.811 0.412 2.474 0.000 1.133
5222 3 2 4801 7092 0 0.690 0.615 1.524 2.000 -0.437
1089 3 3 7284 4801 7092 0 0.392 0.900 0.359 1.651 2.000 -0.519

As you can see, the file contains varying numbers of columns per each line. But the important thing is, the third column contains the number of contents for the next columns. 

Here are the lists of columns. 

First column = C1 

Second column = C2

Third column = C3 = number of next columns. If C3 = 3, then there will be 3 columns from the next. If C3=6, then there will be 6 columns from the next. 

Column group A1~An (n = C3) 

Column C4

Column group B1~Bn (n = C3) 

Column C5

Column C6

Column C7

In short, it is C1, C2, C3, A1~An, C4, B1~Bn, C5, C6, C7, where n = C3. 

To read this, I used something like this:

       Program test
       implicit none
       integer nn
       parameter (nn = 50000)
       ...
       integer,dimension(nn,nn) :: conn
       integer,dimension(nn) :: atype,nbonds,atindex,atpointer
       integer,dimension(nn) :: molnr,atid2,atype2,paint,atid
       real,dimension(nn,nn) :: bos
       real,dimension(nn) :: x,y,z,abo,nlp,q,aBO2,aBO3,aBO4,aBO5,aBO6
       real,dimension(nn) :: aBO7,aBO8,aBO9,charge,charge2
       real,dimension(nn) :: sBO2,sBO3,sBO4,sBO5,sBO6,sBO7,sBO8,sBO9

       ...
       do i=1,nat
       read (2,*)atid2(i),atype2(i),nbonds(i),(conn(i,j),j=1,nbonds(i)),molnr(i),(bos(i,j),j=1,nbonds(i)),abo(i),nlp(i),charge2(i)
       enddo
       ...

Index i is to read the file for a number of lines for each data block (number of line = nat)

But it seems that I cannot use nbonds(i), which is the number of contents for next columns, to read 2D data conn(i,j) and boss(i,j) using j=1,nbonds(i)

How can I read this type of data in intel fortran? 

0 Kudos
3 Replies
mecej4
Honored Contributor III
1,667 Views

I cannot understand what you meant by

But it seems that I cannot use nbonds(i), which is the number of contents for next columns, to read 2D data conn(i,j) and boss(i,j) using j=1,nbonds(i)

It is permitted to use an input data value in a formatted record to decide how many more data values are to be read from the remaining part of the record. The following program reads the six lines of data that you showed and completes normally.

 

program xyeon
implicit none
integer C1,C2,C3,A(6),C4,i,nf,nr
real C5,C6,C7,B(6)
nr=0
do
   read(*,*,end=10)c1,c2,c3,(A(i),i=1,c3),c4,(B(i),i=1,c3),c5,c6,c7
   nr=nr+1
   nf=7+2*c3
   print *,nr,c3,nf
end do
10 continue
end program

There may be problems caused by the use of two arrays that are of size 50000 X 50000, which would require 10 GB each. Cut them down to what is really needed for the data that you wish to process, and try again.

 

andrew_4619
Honored Contributor III
1,655 Views

 

character(2048) :: gbuf
integer :: jj
       ...
do i=1,nat
  read(2,'(A)') gbuf
  read(gbuf,*)   atid2(i),atype2(i), jj     
read(gbuf,*)atid2(i),atype2(i),nbonds(i),conn(i,j),j=1,jj),molnr(i),bos(i,j),j=1,jj),abo(i),nlp(i),charge2(i)
enddo

ensure the character  buffer is big enough for the longest line

 

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,622 Views

Yeon,

Andrew's suggestion can be more helpful in diagnosing errors in your input data files (as you see/log input lines while being read).

Jim Dempsey

0 Kudos
Reply