рекурсивно принимать входной файл для работы

У меня есть несколько файлов входных данных с именами angleFile1.dat,angleFile2.dat,angleFile3.dat и так далее. (у меня более 100 файлов)

Каждый файл содержит 45000 данных углов. Я хочу сгруппировать эти углы, чтобы получить распределение в пределах от 0 до 360 градусов.

Я написал код Fortran, чтобы выполнять работу для одного файла за раз.

Этот код будет читать входной файл «angleFile1.dat» и записывать распределение (в бинах) в файл «angleOut.dat».

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

Как заставить этот код рекурсивно принимать входные файлы (angleFile1.dat, angleFile2.dat, angleFile3.dat и, скажем, до angleFile100.dat) и записывать дистрибутив в тот же выходной файл?

Помощь очень ценится.


person Vijay    schedule 11.03.2015    source источник
comment
Ответ на этот вопрос -- stackoverflow.com /questions/6146516/ — показывает, как построить имя файла во время выполнения программы. И когда вы пишете «рекурсивно», я думаю, вы имеете в виду «итеративно».   -  person High Performance Mark    schedule 11.03.2015


Ответы (1)


Что ж, одним из способов было бы разделить чтение на отдельную подпрограмму. Что-то вроде (не проверено):


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

(Можно добавить, что предложенное выше решение не использует рекурсию.)

person janneb    schedule 11.03.2015
comment
Спасибо. Я определил j и добавил фразу end подпрограммы add_angles_to_bins. Если вы не возражаете, я хотел бы спросить, как нормализовать столбец № 2 в выходном файле angularOut.dat. Это все. - person Vijay; 12.03.2015
comment
@Vijay: Если под нормализацией вы подразумеваете, что хотите, чтобы самый большой бин имел значение 1,0, а остальные меньше этого, то это легко, просто отслеживайте наибольшее количество бинов, а затем в конце разделите весь массив на это самый большой счет. (Тогда, конечно, вам также нужно сделать бинарный угол типа REAL). - person janneb; 12.03.2015
comment
Да, это обряд. Я просто теряюсь, пытаясь понять код Fotran, чтобы сохранить тракт и выбрать максимальное значение в массиве binaangle. - person Vijay; 12.03.2015