Скопируйте вывод FORTRAN (вызывается через F2PY) в Python

Я использую некоторый код fortran в python через f2py. Я хотел бы перенаправить вывод fortran на переменную, с которой я могу играть. Есть этот вопрос, который я нашел полезным. Перенаправление вывода FORTRAN (вызываемого через F2PY) в Python

Тем не менее, я также хотел бы опционально, чтобы код fortran записывался на терминал, а также записывался. Это возможно?

У меня есть следующий глупый класс, который я собрал из вопроса выше, а также из http://websrv.cs.umt.edu/isis/index.php/F2py_example.

class captureTTY:
    ''' 
    Class to capture the terminal content. It is necessary when you want to
    grab the output from a module created using f2py.
    '''
    def __init__(self,  tmpFile = '/tmp/out.tmp.dat'):
        ''' 
        Set everything up
        '''
        self.tmpFile = tmpFile       
        self.ttyData = []
        self.outfile = False
        self.save = False
    def start(self):
        '''
        Start grabbing TTY data. 
        '''
        # open outputfile
        self.outfile = os.open(self.tmpFile, os.O_RDWR|os.O_CREAT)
        # save the current file descriptor
        self.save = os.dup(1)
        # put outfile on 1
        os.dup2(self.outfile, 1)
        return
    def stop(self):
        '''
        Stop recording TTY data
        '''
        if not self.save:
            # Probably not started
            return
        # restore the standard output file descriptor
        os.dup2(self.save, 1)
        # parse temporary file
        self.ttyData = open(self.tmpFile, ).readlines()
        # close the output file
        os.close(self.outfile)        
        # delete temporary file
        os.remove(self.tmpFile)

Мой код в настоящее время выглядит примерно так:

from fortranModule import fortFunction
grabber = captureTTY()
grabber.start()
fortFunction()
grabber.stop()

Моя идея состоит в том, чтобы иметь флаг, называемый молчанием, который я мог бы использовать, чтобы проверить, разрешаю ли я отображать вывод fortran или нет. Затем это будет передано в captureTTY, когда я его создам, т.е.

from fortranModule import fortFunction
silent = False
grabber = captureTTY(silent)
grabber.start()
fortFunction()
grabber.stop()

Я не совсем уверен, как это реализовать. Очевидно, что нужно сделать следующее:

from fortranModule import fortFunction
silent = False
grabber = captureTTY()
grabber.start()
fortFunction()
grabber.stop()
if not silent:
    for i in grabber.ttyData:
        print i

Я не большой поклонник этого, так как мой метод на фортране требует много времени для запуска, и было бы неплохо видеть его обновление в реальном времени, а не только в конце.

Есть идеи? Код будет запускаться на компьютерах с Linux и Mac, а не на Windows. Я просмотрел Интернет, но не нашел решения. Если он есть, я уверен, что это будет до боли очевидно!

Ваше здоровье,

G

Пояснение:

Из комментариев я понимаю, что вышеизложенное не самое ясное. В настоящее время у меня есть возможность записывать вывод метода фортрана. Однако это предотвращает его печать на экране. Я могу распечатать его на экране, но не могу записать. Я хочу иметь возможность делать оба одновременно, то есть записывать вывод и распечатывать его на экране в режиме реального времени.

Кроме того, код на Фортране представляет собой алгоритм подбора, а фактический результат, который меня интересует, — это параметры для каждой итерации.


person Ger    schedule 29.05.2012    source источник
comment
возможно, вам не нравится эта идея, но я обычно просто прошу fortran записывать вывод в файл журнала с частым сбросом, а затем прошу python или другие сценарии заглянуть в журнал.   -  person nye17    schedule 29.05.2012
comment
Как выглядит вывод на Фортране? Это массив чисел? Если это так, f2py должен иметь возможность передать это напрямую в виде массива numpy.   -  person mgilson    schedule 29.05.2012
comment
@mgilson & nye17 Я немного прояснил проблему, см. выше. Я думаю, что я, возможно, не был самым ясным в том, что моя проблема.   -  person Ger    schedule 29.05.2012
comment
Я не уверен, сработает это или нет, но вы можете попробовать tail -F во временном файле. (в start: self.tail=subprocess.Popen('tail -F %s'%self.tmpFile), а затем в stop: self.tail.terminate(), чтобы убедиться, что он закрыт...) -- Однако это может дважды направить вывод в ваш файл журнала. Я не уверен.   -  person mgilson    schedule 29.05.2012
comment
@user1027686 user1027686 хорошо, только что увидел ваше разъяснение. Тогда мой наивный подход будет заключаться в том, чтобы попросить фортран напечатать как в стандартный вывод, так и в файл журнала. Хотя у вас есть флаг для управления тем, где вы хотите печатать, вы также можете настроить свой python для извлечения записей из файла журнала.   -  person nye17    schedule 30.05.2012
comment
@ nye17 Спасибо за идею - только что попробовал. Мне пришлось немного изменить его, self.tail = subprocess.Popen('exec tail -f %s'%self.tmpFile, shell = 'bash'). Без exec он разветвил бы хвостовой процесс и не был бы убит вызовом terminate(). Однако это не работает: оно не выводится на экран и сбивает с толку, в основном, повторяющиеся строки в файл журнала. Спасибо за идею!   -  person Ger    schedule 30.05.2012
comment
@mgilson Оппс! Комментарий выше был адресован вам. Не могу сейчас отредактировать.   -  person Ger    schedule 30.05.2012
comment
@user1027686 user1027686 Кажется странным, что хвостовой процесс не будет уничтожен завершением. Нет ничего удивительного в том, что выходные данные дважды отправляются в журнал — очевидно, дочерний процесс наследует дескрипторы терминала своего родителя. Из любопытства, что произойдет, если вы отправите вывод tail в stderr вместо stdout? (self.tail = subprocess.Popen('exec tail -f %s 1>&2'%self.tmpFile, shell = 'bash'))   -  person mgilson    schedule 30.05.2012


Ответы (1)


Вы пробовали что-то подобное в подпрограмме Fortran? (Предполагая, что foo — это то, что вы хотите напечатать, а 52 — это номер единицы вашего файла журнала)

write(52,*) foo
write(*,*) foo

Это должно вывести foo в файл журнала и на экран.

person astay13    schedule 13.06.2012