0

I have several input data files with the name angleFile1.dat, angleFile2.dat, angleFile3.dat and so on. (I have more than 100 files)

Each file contain 45000 data of angles. I want to group these angles to get a distribution within 0 to 360 degrees.

I have written a Fortran code to do the job for one file at a time.

This code will read in the input file "angleFile1.dat" and write the distribution (in bins) in the "angleOut.dat" file.

program binangle
implicit none

integer :: i, j, k
integer,parameter :: arr=45000

real,dimension(1:arr) :: aangle
integer,dimension(0:360) :: binaangle

do i = 0,360
 binaangle(i) = 0.0
end do

 !OPEN OUTPUT FILE
open(unit=49,status="unknown",file="angleOut.dat")

 !OPEN INPUT FILE
open(unit=50,status="unknown",file="angleFile1.dat")
read(50,'(F8.3)') (aangle(i), i = 1,arr)


! DO THE BINNING    
do j = 1, arr
        binaangle(int(aangle(j))) = binaangle(int(aangle(j))) + 1
end do


! WRITE INTO OUTPUT FILE    
do k = 0,360
write(49,*) k, "    ", binaangle(k)
end do

How to make this code to recursively take in the input files (angleFile1.dat, angleFile2.dat, angleFile3.dat and say until angleFile100.dat) and write the distribution in the same output file?

Help is much appreciated.

Vijay
  • 965
  • 5
  • 13
  • 27
  • 2
    The answer to this question -- http://stackoverflow.com/questions/6146516/writing-multiple-output-files-in-fortran -- shows you how to build the file name while the program executes. And when you write 'recursively' I think you mean 'iteratively'. – High Performance Mark Mar 11 '15 at 11:08

1 Answers1

1

Well, one way would be to split the reading into a separate subroutine. Something like (untested):


program binangle
implicit none

integer :: i, k
integer,parameter :: nfiles = 100 ! Use get_command_argument to read the
                                  ! value at runtime rather than hardcoded,
                                  ! left as an exercise to the reader

integer,dimension(361) :: binaangle

binaangle = 0 ! Use array op rather than manual loop

do i = 1, nfiles
  call add_angles_to_bins(binaangle, i)
end do

!OPEN OUTPUT FILE
open(unit=49,status="replace",file="angleOut.dat")

! WRITE INTO OUTPUT FILE    
do k = 1, ubound(binaangle, 1)
  write(49,*) k - 1, "    ", binaangle(k)
end do

contains
subroutine add_angles_to_bins(bins, fnum)
  integer, intent(inout) :: bins(:)
  integer, intent(in) :: fnum
  character(len=200) :: fname
  integer, parameter :: arr = 45000
  real :: aangle(arr)
  write(fname, '(A,I0,A)') 'angleFile', fnum, '.dat'
  !OPEN INPUT FILE
  open(unit=50,status="old",file=fname)
  read(50,'(F8.3)') aangle
  close(50)
  ! DO THE BINNING    
  do j = 1, arr
    binaangle(int(aangle(j)) + 1) = binaangle(int(aangle(j)) + 1) + 1
  end do
end program binangle

(One might add that the above suggested solution does not use recursion.)

janneb
  • 36,249
  • 2
  • 81
  • 97
  • Thank you. I defined the "j" and added "end subroutine add_angles_to_bins" phrase. If you don't mind, I would like to ask how if want to normalize the column #2 in the output file "angleOut.dat". Thats all. – Vijay Mar 12 '15 at 05:16
  • @Vijay: If by normalize you mean that you want the largest bin to have the value 1.0, and the others less than that, then it's easy, just keep track of the largest bin count, then at the end divide the entire array by that largest count. (You also need to make binaangle of type REAL then, of course). – janneb Mar 12 '15 at 06:55
  • Yea, that's rite. I just feel lost to figure out the Fotran code to keep tract and select the maximum value in the array "binaangle". – Vijay Mar 12 '15 at 07:05