11from pyqchem .qc_input import QchemInput
22from pyqchem .errors import ParserError , OutputError
33from pyqchem .utils import get_sdm
4- from subprocess import Popen , PIPE
4+ from subprocess import Popen , PIPE , STDOUT
55from pathlib import Path
66import os , shutil , sys
77import numpy as np
@@ -164,15 +164,15 @@ def func_wrapper(*args, **kwargs):
164164 return func_wrapper
165165
166166
167- def local_run (input_file_name , work_dir , fchk_file , use_mpi = False , processors = 1 ):
167+ def local_run (input_file_name , work_dir , fchk_file , use_mpi = False , processors = 1 , stream_output = False ):
168168 """
169169 Run Q-Chem locally
170170
171171 :param input_file_name: Q-Chem input file in plain text format
172172 :param work_dir: Scratch directory where calculation run
173173 :param fchk_file: filename of fchk
174174 :param use_mpi: use mpi instead of openmp
175-
175+ :param stream_output: print Q-Chem output live during execution
176176 :return: output, err: Q-Chem standard output and standard error
177177 """
178178
@@ -188,57 +188,20 @@ def local_run(input_file_name, work_dir, fchk_file, use_mpi=False, processors=1)
188188 binary = Path (qc_dir ).joinpath (exe_dir ).joinpath ('qcprog.exe' )
189189 command = [binary , Path (work_dir ).joinpath (input_file_name ), Path (work_dir )]
190190
191- qchem_process = Popen (command , stdout = PIPE , stdin = PIPE , stderr = PIPE , cwd = work_dir )
192- (output , err ) = qchem_process .communicate ()
193- qchem_process .wait ()
194- output = output .decode (errors = 'ignore' )
195- err = err .decode ()
196-
197- return output , err
198-
199- def local_run_stream (input_file_name , work_dir , fchk_file , use_mpi = False , processors = 1 , print_stream = True ):
200- """
201- Run Q-Chem locally
202-
203- :param input_file_name: Q-Chem input file in plain text format
204- :param work_dir: Scratch directory where calculation run
205- :param fchk_file: filename of fchk
206- :param use_mpi: use mpi instead of openmp
207- :param print_stream: set True to print output stream during execution
208-
209- :return: output, err: Q-Chem standard output and standard error
210- """
211-
212- if not use_mpi :
213- os .environ ["QCTHREADS" ] = "{}" .format (processors )
214- os .environ ["OMP_NUM_THREADS" ] = "{}" .format (processors )
215- os .environ ["MKL_NUM_THREADS" ] = "1"
216-
217- os .environ ["GUIFILE" ] = fchk_file
218- qc_dir = os .getenv ('QC' )
219-
220- exe_dir = os .getenv ('QC_EXE_DIR' ) if 'QC_EXE_DIR' in os .environ else 'exe'
221- binary = Path (qc_dir ).joinpath (exe_dir ).joinpath ('qcprog.exe' )
222- command = [binary , Path (work_dir ).joinpath (input_file_name ), Path (work_dir )]
223-
224- qchem_process = Popen (command , stdout = PIPE , stdin = PIPE , stderr = PIPE , cwd = work_dir )
225-
226- output = ''
227- err = ''
228- while True :
229- line_out = qchem_process .stdout .readline ()
230- line_err = qchem_process .stderr .readline ()
231-
232- if not line_out and not line_err :
233- break
234-
235- if print_stream :
236- print (line_out .strip ().decode (errors = 'ignore' ))
237-
238- sys .stdout .flush ()
239-
240- output += line_out .decode (errors = 'ignore' )
241- err += line_err .decode (errors = 'ignore' )
191+ if stream_output :
192+ qchem_process = Popen (command , stdout = PIPE , stdin = PIPE , stderr = STDOUT , cwd = work_dir , text = True , bufsize = 1 )
193+ output = ''
194+ err = ''
195+ for line_out in qchem_process .stdout :
196+ print (line_out , end = '' ) # Print output as generated
197+ output += line_out
198+ qchem_process .wait ()
199+ else :
200+ qchem_process = Popen (command , stdout = PIPE , stdin = PIPE , stderr = PIPE , cwd = work_dir )
201+ (output , err ) = qchem_process .communicate ()
202+ qchem_process .wait ()
203+ output = output .decode (errors = 'ignore' )
204+ err = err .decode ()
242205
243206 return output , err
244207
@@ -359,6 +322,7 @@ def retrieve_additional_files(input_qchem, data_fchk, work_dir, scratch_read_lev
359322 :param data_fchk: FCHK parsed dictionary
360323 :param work_dir: scratch directory
361324 :param scratch_read_level: defines what data to retrieve
325+
362326 :return: dictionary with additional data
363327 """
364328
@@ -487,6 +451,7 @@ def get_output_from_qchem(input_qchem,
487451 fchk_only = False ,
488452 store_full_output = False ,
489453 delete_scratch = True ,
454+ stream_output = False ,
490455 remote = None ,
491456 scratch_read_level = 0 ):
492457
@@ -514,6 +479,7 @@ def get_output_from_qchem(input_qchem,
514479 :param remote: dictionary containing the data for remote calculation (beta)
515480 :param store_full_output: store full output in plain text in pkl file
516481 :param delete_scratch: delete all scratch files when calculation is finished
482+ :param stream_output: print Q-Chem output live during execution
517483
518484 :return: output [, electronic_structure]
519485 """
@@ -587,7 +553,8 @@ def get_output_from_qchem(input_qchem,
587553 if output is None or force_recalculation is True :
588554 if remote is None :
589555 # print('local:')
590- output , err = local_run (temp_filename , work_dir , fchk_filename , use_mpi = use_mpi , processors = processors )
556+ output , err = local_run (temp_filename , work_dir , fchk_filename ,
557+ use_mpi = use_mpi , processors = processors , stream_output = stream_output )
591558 else :
592559 # print('Remote:')
593560 output , err = remote_run (temp_filename , work_dir , fchk_filename , remote , use_mpi = use_mpi , processors = processors )
0 commit comments