def run(self, rank, stdout=sys.stdout, stderr=sys.stderr): """ Runs the program. All command-line arguments must be set before calling this method. Command-line arguments should be set in setup() """ from subprocess import Popen, PIPE # If this has not been set up yet # then raise a stink if not self.calc_setup: raise CalcError('Cannot run a calculation without calling its' + ' its setup() function!') # Make sure the inptraj and output are rank-substituted instring = self._get_instring(rank) process = Popen([self.program, self.prmtop], stdin=PIPE, stdout=PIPE, stderr=PIPE) out, err = process.communicate(instring.encode()) calc_failed = bool(process.wait()) if calc_failed: raise CalcError('%s failed with prmtop %s!' % (self.program, self.prmtop))
def run(self, rank, stdout=sys.stdout, stderr=sys.stderr): """ Runs the program. All command-line arguments must be set before calling this method. Command-line arguments should be set in setup() """ from subprocess import Popen # If this has not been set up yet # then raise a stink if not self.calc_setup: raise CalcError('Cannot run a calculation without calling its' + ' its setup() function!') # Here, make sure that we could pass a file *OR* a string as stdout/stderr. # If they are strings, then open files up with that name, and make sure to # close them afterwards. The setup() method should make sure that they are # either a file or a string! own_handleo = own_handlee = False try: process_stdout = open(stdout, 'w') own_handleo = True except TypeError: process_stdout = stdout try: process_stderr = open(stderr, 'w') own_handlee = True except TypeError: process_stderr = stderr # The setup() method sets the command-line arguments and makes sure that # all of the CL arguments are set. Now all we have to do is start the # process and monitor it for success. # Popen can only take strings as command-line arguments, so convert # everything to a string here. And if it appears to need the rank # substituted into the file name, substitute that in here try: for i in range(len(self.command_args)): self.command_args[i] = str(self.command_args[i]) if '%d' in self.command_args[i]: self.command_args[i] = self.command_args[i] % rank process = Popen(self.command_args, stdin=None, stdout=process_stdout, stderr=process_stderr) calc_failed = bool(process.wait()) if calc_failed: raise CalcError('%s failed with prmtop %s!' % (self.program, self.prmtop)) finally: if own_handleo: process_stdout.close() if own_handlee: process_stdout.close()
def run(self, rank, stdout=sys.stdout, stderr=sys.stderr): """ Runs the program. All command-line arguments must be set before calling this method. Command-line arguments should be set in setup() stdout is ignored here because we need to parse it for errors """ import re from subprocess import Popen, PIPE # If this has not been set up yet # then raise a stink if not self.calc_setup: raise CalcError('Cannot run a calculation without calling its' + ' its setup() function!') errorre = re.compile('(pb (?:bomb)|(?:warning))', re.I) # Here, make sure that we could pass a file *OR* a string as stderr. own_handle = False try: process_stderr = open(stderr, 'w') own_handle = True except TypeError: process_stderr = stderr # The setup() method sets the command-line arguments and makes sure that # all of the CL arguments are set. Now all we have to do is start the # process and monitor it for success. # Popen can only take strings as command-line arguments, so convert # everything to a string here. If rank needs to be substituted in, do that # here try: for i in range(len(self.command_args)): self.command_args[i] = str(self.command_args[i]) if '%d' in self.command_args[i]: self.command_args[i] = self.command_args[i] % rank process = Popen(self.command_args, stdin=None, stdout=PIPE, stderr=process_stderr) out, err = process.communicate(b'') calc_failed = bool(process.wait()) if calc_failed: error_list = [s.strip() for s in out.split('\n') if errorre.match(s.strip())] raise CalcError('%s failed with prmtop %s!\n\t' % (self.program, self.prmtop) + '\n\t'.join(error_list) + '\n') finally: if own_handle: process_stderr.close()
def setup(self): """ Sets up a Quasi-harmonic calculation """ from subprocess import Popen, PIPE # Determine the prefix from our input file... hack way to do this if self.input_file.startswith(self.fnpre + 'mutant_'): prefix = self.fnpre + 'mutant_' else: prefix = self.fnpre # Make sure masks are a list, and that there are enough masks # First thing we need is the average PDB as a reference ptraj_str = 'trajin %s\naverage %savgcomplex.pdb pdb chainid " "\ngo' % ( self.inptraj, prefix) outfile = open(self.fnpre + 'create_average.out', 'w') process = Popen([self.program, self.prmtop], stdin=PIPE, stdout=outfile) out, err = process.communicate(ptraj_str.encode()) if process.wait(): raise CalcError('Failed creating average PDB') outfile.close() # Now that we have the PDB file self.command_args.extend((self.prmtop, self.input_file)) self.calc_setup = True