def set_first_charge(self, index): """ Sets the first charge index """ # Has it already been set? if self.first_charge != -1: if index != self.first_charge: raise AmberError('First charge already set differently') self.first_charge = index
def set_first_state(self, index): """ Sets the first state index """ # Has the first state already been set? if self.first_state != -1: if index != self.first_state: raise AmberError('First state already set differently') self.first_state = index
def add_states(self, protcnts, charges, refenes): """ Add multiple titratable states for this titratable residue """ if len(protcnts) != len(charges) or len(protcnts) != len(refenes): raise AmberError('Inconsistent list of parameters for ' 'TitratableResidue.add_states') for i in range(len(protcnts)): self.add_state(protcnts[i], charges[i], refenes[i])
def add_residue(self, residue, resnum, first_atom, state=0): """ Adds a residue to the list """ list.append(self, residue) self.first_atoms.append(first_atom) self.residue_nums.append(resnum) if state < 0 or state >= len(residue.states): raise AmberError('Residue %s only has states 0-%d (%d chosen)' % (residue.resname, len(residue.states)-1, state)) self.resstates.append(state)
def cpin_pointers(self, first_atom): """ Sets and returns the cpin info """ if self.first_state == -1 or self.first_charge == -1: raise AmberError('Must set residue pointers before writing ' 'cpin info!') return {'FIRST_ATOM' : first_atom, 'FIRST_CHARGE' : self.first_charge, 'FIRST_STATE' : self.first_state, 'NUM_ATOMS' : len(self.atom_list), 'NUM_STATES' : len(self.states)}
def set_states(self, statelist): """ Sets the initial protonation states from a list -- make sure there are enough states in the list to set every residue, or emit a warning """ if len(statelist) != len(self): warnings.warn(('Number of states (%d) does not equal number of ' 'residues (%d). Using default initial states.') % (len(statelist), len(self)), AmberWarning) return # Check that all states are allowable for i, state in enumerate(statelist): if state < 0 or state >= len(self[i].states): raise AmberError('Bad state choice (%d). Minimum is 0, ' 'maximum is %d' % (state, len(self[i].states))) # If we got here, then we are OK self.resstates = statelist
def process_arglist(arglist, argtype): """ This processes an argument list with an arbitrary number of arguments that may or may not be comma-delimited (with any number of spaces) """ # If the argument list is not set, just return None if arglist is None: return None # Otherwise, process the arguments processed_args = [] for arg in arglist: # Delete any spaces, split on commas, and add this to processed arg list for arg in arg.replace(' ', '').split(','): if not arg: continue try: processed_args.append(argtype(arg)) except ValueError: raise AmberError('Expected type %s for argument. Got %s' % (argtype.__name__, arg)) return processed_args
def add_flag(self, flag_name, flag_format, data=None, num_items=-1, comments=None, after=None): """ Adds a new flag with the given flag name and Fortran format string and initializes the array with the values given, or as an array of 0s of length num_items Parameters ---------- flag_name : str Name of the flag to insert. It is converted to all upper case flag_format : str Fortran format string representing how the data in this section should be written and read. Do not enclose in () data : list=None Sequence with data for the new flag. If None, a list of zeros of length ``num_items`` (see below) is given as a holder num_items : int=-1 Number of items in the section. This variable is ignored if a set of data are given in `data` comments : list of str=None List of comments to add to this section after : str=None If provided, the added flag will be added after the one with the name given to `after`. If this flag does not exist, IndexError will be raised Raises ------ AmberError if flag already exists IndexError if the ``after`` flag does not exist """ if flag_name in self.parm_data: raise AmberError('%s already exists' % (flag_name)) if after is not None: after = after.upper() if not after in self.flag_list: raise IndexError('%s not found in topology flag list' % after) # If the 'after' flag is the last one, just append if self.flag_list[-1] == after: self.flag_list.append(flag_name.upper()) else: # Otherwise find the index and add it after idx = self.flag_list.index(after) + 1 self.flag_list.insert(idx, flag_name.upper()) else: self.flag_list.append(flag_name.upper()) self.formats[flag_name.upper()] = FortranFormat(flag_format) if data is not None: self.parm_data[flag_name.upper()] = list(data) else: if num_items < 0: raise AmberError("If you do not supply prmtop data, num_items " "must be non-negative!") self.parm_data[flag_name.upper()] = [0 for i in range(num_items)] if comments is not None: if isinstance(comments, string_types): comments = [comments] else: comments = list(comments) self.parm_comments[flag_name.upper()] = comments else: self.parm_comments[flag_name.upper()] = []
def main(opt): # Check all of the arguments if not os.path.exists(opt.prmtop): raise AmberError('prmtop file (%s) is missing' % opt.prmtop) # Process the arguments that take multiple args resstates = process_arglist(opt.resstates, int) resnums = process_arglist(opt.resnums, int) notresnums = process_arglist(opt.notresnums, int) resnames = process_arglist(opt.resnames, str) notresnames = process_arglist(opt.notresnames, str) mineo = opt.mineo maxeo = opt.maxeo if not opt.igb in (1, 2, 5, 7, 8): raise AmberError('-igb must be 1, 2, 5, 7, or 8!') if resnums is not None and notresnums is not None: raise AmberError('Cannot specify -resnums and -notresnums together') if resnames is not None and notresnames is not None: raise AmberError('Cannot specify -resnames and -notresnames together') if opt.intdiel != 1 and opt.intdiel != 2: raise AmberError('-intdiel must be either 1 or 2 currently') # Set the list of residue names we will be willing to titrate titratable_residues = [] if notresnames is not None: for resname in residues.titratable_residues: if resname in notresnames: continue titratable_residues.append(resname) elif resnames is not None: for resname in resnames: if not resname in residues.titratable_residues: raise AmberError('%s is not a titratable residue!' % resname) elif not getattr(residues, resname).typ == "redox": raise AmberError( '%s is not a redox-active titratable residue!' % resname) titratable_residues.append(resname) else: for resname in residues.titratable_residues: if getattr(residues, resname).typ == "redox": titratable_residues.append(resname) solvent_ions = [ 'WAT', 'Na+', 'Br-', 'Cl-', 'Cs+', 'F-', 'I-', 'K+', 'Li+', 'Mg+', 'Rb+', 'CIO', 'IB', 'MG2' ] # Filter titratable residues based on min and max pKa new_reslist = [] for res in titratable_residues: if getattr(residues, res).Eo < mineo: continue if getattr(residues, res).Eo > maxeo: continue new_reslist.append(res) titratable_residues = new_reslist del new_reslist # Make sure we still have a couple residues if len(titratable_residues) == 0: raise AmberError('No titratable residues fit your criteria!') # Load the topology file parm = AmberParm(opt.prmtop) # Replace an un-set notresnums with an empty list so we get __contains__() if notresnums is None: notresnums = [] # If we have a list of residue numbers, check that they're all titratable if resnums is not None: for resnum in resnums: if resnum > parm.ptr('nres'): raise AmberError('%s only has %d residues. (%d chosen)' % (parm, parm.ptr('nres'), resnum)) if resnum <= 0: raise AmberError('Cannot select negative residue numbers.') resname = parm.parm_data['RESIDUE_LABEL'][resnum - 1] if not resname in titratable_residues: raise AmberError('Residue number %s [%s] is not titratable' % (resnum, resname)) else: # Select every residue except those in notresnums resnums = [] for resnum in range(1, parm.ptr('nres') + 1): if resnum in notresnums: continue resnums.append(resnum) solvated = False first_solvent = 0 if 'WAT' in parm.parm_data['RESIDUE_LABEL']: solvated = True for i, res in enumerate(parm.parm_data['RESIDUE_LABEL']): if res in solvent_ions: first_solvent = parm.parm_data['RESIDUE_POINTER'][i] break main_reslist = TitratableResidueList(system_name=opt.system, solvated=solvated, first_solvent=first_solvent) trescnt = 0 for resnum in resnums: resname = parm.parm_data['RESIDUE_LABEL'][resnum - 1] if not resname in titratable_residues: continue res = getattr(residues, resname) # Filter out termini (make sure the residue in the prmtop has as many # atoms as the titratable residue defined in residues.py) if resnum == parm.ptr('nres'): natoms = (parm.ptr('natom') + 1 - parm.parm_data['RESIDUE_POINTER'][resnum - 1]) else: natoms = (parm.parm_data['RESIDUE_POINTER'][resnum] - parm.parm_data['RESIDUE_POINTER'][resnum - 1]) if natoms != len(res.atom_list): continue # If we have gotten this far, add it to the list. main_reslist.add_residue(res, resnum, parm.parm_data['RESIDUE_POINTER'][resnum - 1]) trescnt += 1 # Prints a warning if the number of titratable residues is larger than 50 if trescnt > 50: sys.stderr.write( 'Warning: Your CEIN file has more than 50 titratable residues! pmemd and sander have a\n' ' default limit of 50 titrable residues, thus this CEIN file can only be used\n' ' if the definitions for this limit are modified at the top of\n' ' $AMBERHOME/src/pmemd/src/constante.F90 or $AMBERHOME/AmberTools/src/sander/constante.F90.\n' ' AMBER needs to be recompilied after these files are modified.\n' ) # Set the states if requested if resstates is not None: main_reslist.set_states(resstates) # Open the output file if opt.output is None: output = sys.stdout else: output = open(opt.output, 'w') main_reslist.write_cpin(output, opt.igb, opt.intdiel, False, "redox") if opt.output is not None: output.close() sys.stderr.write('CEIN generation complete!\n')
def main(opt): # Check all of the arguments if not os.path.exists(opt.prmtop): raise AmberError('prmtop file (%s) is missing' % opt.prmtop) # Process the arguments that take multiple args resstates = process_arglist(opt.resstates, int) resnums = process_arglist(opt.resnums, int) notresnums = process_arglist(opt.notresnums, int) resnames = process_arglist(opt.resnames, str) notresnames = process_arglist(opt.notresnames, str) minpka = opt.minpka maxpka = opt.maxpka if not opt.igb in (1, 2, 5, 7, 8): raise AmberError('-igb must be 1, 2, 5, 7, or 8!') if resnums is not None and notresnums is not None: raise AmberError('Cannot specify -resnums and -notresnums together') if resnames is not None and notresnames is not None: raise AmberError('Cannot specify -resnames and -notresnames together') if opt.intdiel != 1 and opt.intdiel != 2: raise AmberError('-intdiel must be either 1 or 2 currently') # Print warning about old format if opt.oldfmt: sys.stderr.write( 'Warning: The old format of the CPIN file can only be used for simulations with temp0=300.0!\n' ' You should use the new format for simulations with temperatures other than 300.0 Kelvins\n' ) # Set the list of residue names we will be willing to titrate titratable_residues = [] if notresnames is not None: for resname in residues.titratable_residues: if resname in notresnames: continue titratable_residues.append(resname) elif resnames is not None: for resname in resnames: if not resname in residues.titratable_residues: raise AmberError('%s is not a titratable residue!' % resname) elif not getattr(residues, resname).typ == "ph": raise AmberError('%s is not a pH titratable residue!' % resname) titratable_residues.append(resname) else: for resname in residues.titratable_residues: if getattr(residues, resname).typ == "ph": titratable_residues.append(resname) solvent_ions = [ 'WAT', 'Na+', 'Br-', 'Cl-', 'Cs+', 'F-', 'I-', 'K+', 'Li+', 'Mg+', 'Rb+', 'CIO', 'IB', 'MG2' ] # Filter titratable residues based on min and max pKa new_reslist = [] for res in titratable_residues: if getattr(residues, res).pKa < minpka: continue if getattr(residues, res).pKa > maxpka: continue new_reslist.append(res) titratable_residues = new_reslist del new_reslist # Make sure we still have a couple residues if len(titratable_residues) == 0: raise AmberError('No titratable residues fit your criteria!') # Load the topology file parm = AmberParm(opt.prmtop) # Replace an un-set notresnums with an empty list so we get __contains__() if notresnums is None: notresnums = [] # If we have a list of residue numbers, check that they're all titratable if resnums is not None: for resnum in resnums: if resnum > parm.ptr('nres'): raise AmberError('%s only has %d residues. (%d chosen)' % (parm, parm.ptr('nres'), resnum)) if resnum <= 0: raise AmberError('Cannot select negative residue numbers.') resname = parm.parm_data['RESIDUE_LABEL'][resnum - 1] if not resname in titratable_residues: raise AmberError('Residue number %s [%s] is not titratable' % (resnum, resname)) else: # Select every residue except those in notresnums resnums = [] for resnum in range(1, parm.ptr('nres') + 1): if resnum in notresnums: continue resnums.append(resnum) solvated = False first_solvent = 0 if 'WAT' in parm.parm_data['RESIDUE_LABEL']: solvated = True for i, res in enumerate(parm.parm_data['RESIDUE_LABEL']): if res in solvent_ions: first_solvent = parm.parm_data['RESIDUE_POINTER'][i] break main_reslist = TitratableResidueList(system_name=opt.system, solvated=solvated, first_solvent=first_solvent) for resnum in resnums: resname = parm.parm_data['RESIDUE_LABEL'][resnum - 1] if not resname in titratable_residues: continue res = getattr(residues, resname) # Filter out termini (make sure the residue in the prmtop has as many # atoms as the titratable residue defined in residues.py) if resnum == parm.ptr('nres'): natoms = (parm.ptr('natom') + 1 - parm.parm_data['RESIDUE_POINTER'][resnum - 1]) else: natoms = (parm.parm_data['RESIDUE_POINTER'][resnum] - parm.parm_data['RESIDUE_POINTER'][resnum - 1]) if natoms != len(res.atom_list): continue # If we have gotten this far, add it to the list. main_reslist.add_residue(res, resnum, parm.parm_data['RESIDUE_POINTER'][resnum - 1]) # Set the states if requested if resstates is not None: main_reslist.set_states(resstates) # Open the output file if opt.output is None: output = sys.stdout else: output = open(opt.output, 'w') main_reslist.write_cpin(output, opt.igb, opt.intdiel, opt.oldfmt, "ph") if opt.output is not None: output.close() if solvated: if opt.outparm is None: has_carboxylate = False for res in main_reslist: if res is residues.AS4 or res is residues.GL4 or res is residues.PRN: has_carboxylate = True break if has_carboxylate: sys.stderr.write( 'Warning: Carboxylate residues in explicit solvent ' 'simulations require a modified topology file!\n' 'Use the -op flag to print one.\n') else: changeRadii(parm, 'mbondi2').execute() change(parm, 'RADII', ':AS4,GL4,PRN@OD=,OE=,O1=,O2=', 1.3).execute() parm.overwrite = True parm.write_parm(opt.outparm) else: if opt.outparm is not None: sys.stderr.write( 'A new prmtop is only necessary for explicit solvent ' 'CpHMD/pH-REMD simulations.\n') sys.stderr.write('CPIN generation complete!\n')
def main(opt): # Check all of the arguments if not os.path.exists(opt.prmtop): raise AmberError('prmtop file (%s) is missing' % opt.prmtop) # Process the arguments that take multiple args resstates = process_arglist(opt.resstates, int) resnums = process_arglist(opt.resnums, int) notresnums = process_arglist(opt.notresnums, int) resnames = process_arglist(opt.resnames, str) notresnames = process_arglist(opt.notresnames, str) minpka = opt.minpka maxpka = opt.maxpka if not opt.igb in (1, 2, 5, 7, 8): raise AmberError('-igb must be 1, 2, 5, 7, or 8!') if resnums is not None and notresnums is not None: raise AmberError('Cannot specify -resnums and -notresnums together') if resnames is not None and notresnames is not None: raise AmberError('Cannot specify -resnames and -notresnames together') if opt.intdiel != 1 and opt.intdiel != 2: raise AmberError('-intdiel must be either 1 or 2 currently') # Print warning about old format if opt.oldfmt: sys.stderr.write('Warning: The old format of the CPIN file can only be used for simulations with temp0=300.0!\n' ' You should use the new format for simulations with temperatures other than 300.0 Kelvins\n') # Set the list of residue names we will be willing to titrate titratable_residues = [] if notresnames is not None: for resname in residues.titratable_residues: if resname in notresnames: continue titratable_residues.append(resname) elif resnames is not None: for resname in resnames: if not resname in residues.titratable_residues: raise AmberError('%s is not a titratable residue!' % resname) elif not getattr(residues, resname).typ == "ph": raise AmberError('%s is not a pH-active titratable residue!' % resname) titratable_residues.append(resname) else: for resname in residues.titratable_residues: if getattr(residues, resname).typ == "ph": titratable_residues.append(resname) solvent_ions = ['WAT', 'Na+', 'Br-', 'Cl-', 'Cs+', 'F-', 'I-', 'K+', 'Li+', 'Mg+', 'Rb+', 'CIO', 'IB', 'MG2'] # Filter titratable residues based on min and max pKa new_reslist = [] for res in titratable_residues: # @jaimergp: If None values are not filtered out, comparisons # will fail in Py3k. This patch was discussed and approved in # GitLab issue 122 (@vwcruzeiro, @swails) # Error obtained in serial tests in conda-forge builds: # Traceback (most recent call last): # File "/home/conda/amber/bin/cpinutil.py", line 325, in <module> # main(opt) # File "/home/conda/amber/bin/cpinutil.py", line 191, in main # if getattr(residues, res).pKa < minpka: continue # TypeError: '<' not supported between instances of 'NoneType' and 'int' # ./Run.cpin: Program error # make[1]: *** [test.cpinutil] Error 1 if getattr(residues, res).pKa is None: continue # /@jaimergp if getattr(residues, res).pKa < minpka: continue if getattr(residues, res).pKa > maxpka: continue new_reslist.append(res) titratable_residues = new_reslist del new_reslist # Make sure we still have a couple residues if len(titratable_residues) == 0: raise AmberError('No titratable residues fit your criteria!') # Load the topology file parm = AmberParm(opt.prmtop) # Replace an un-set notresnums with an empty list so we get __contains__() if notresnums is None: notresnums = [] # If we have a list of residue numbers, check that they're all titratable if resnums is not None: for resnum in resnums: if resnum > parm.ptr('nres'): raise AmberError('%s only has %d residues. (%d chosen)' % (parm, parm.ptr('nres'), resnum)) if resnum <= 0: raise AmberError('Cannot select negative residue numbers.') resname = parm.parm_data['RESIDUE_LABEL'][resnum-1] if not resname in titratable_residues: raise AmberError('Residue number %s [%s] is not titratable' % (resnum, resname)) else: # Select every residue except those in notresnums resnums = [] for resnum in range(1, parm.ptr('nres') + 1): if resnum in notresnums: continue resnums.append(resnum) solvated = False first_solvent = 0 if 'WAT' in parm.parm_data['RESIDUE_LABEL']: solvated = True for i, res in enumerate(parm.parm_data['RESIDUE_LABEL']): if res in solvent_ions: first_solvent = parm.parm_data['RESIDUE_POINTER'][i] break main_reslist = TitratableResidueList(system_name=opt.system, solvated=solvated, first_solvent=first_solvent) trescnt = 0 for resnum in resnums: resname = parm.parm_data['RESIDUE_LABEL'][resnum-1] if not resname in titratable_residues: continue res = getattr(residues, resname) # Filter out termini (make sure the residue in the prmtop has as many # atoms as the titratable residue defined in residues.py) if resnum == parm.ptr('nres'): natoms = (parm.ptr('natom') + 1 - parm.parm_data['RESIDUE_POINTER'][resnum-1]) else: natoms = (parm.parm_data['RESIDUE_POINTER'][resnum] - parm.parm_data['RESIDUE_POINTER'][resnum-1]) if natoms != len(res.atom_list): continue # If we have gotten this far, add it to the list. main_reslist.add_residue(res, resnum, parm.parm_data['RESIDUE_POINTER'][resnum-1]) trescnt += 1 # Prints a warning if the number of titratable residues is larger than 50 if trescnt > 50: sys.stderr.write('Warning: Your CPIN file has more than 50 titratable residues! pmemd and sander have a\n' ' default limit of 50 titrable residues, thus this CPIN file can only be used\n' ' if the definitions for this limit are modified at the top of\n' ' $AMBERHOME/src/pmemd/src/constantph.F90 or $AMBERHOME/AmberTools/src/sander/constantph.F90.\n' ' AMBER needs to be recompilied after these files are modified.\n') # Set the states if requested if resstates is not None: main_reslist.set_states(resstates) # Open the output file if opt.output is None: output = sys.stdout else: output = open(opt.output, 'w') main_reslist.write_cpin(output, opt.igb, opt.intdiel, opt.oldfmt, "ph") if opt.output is not None: output.close() if solvated: if opt.outparm is None: has_carboxylate = False for res in main_reslist: if res is residues.AS4 or res is residues.GL4 or res is residues.PRN: has_carboxylate = True break if has_carboxylate: sys.stderr.write( 'Warning: Carboxylate residues in explicit solvent ' 'simulations require a modified topology file!\n' ' Use the -op flag to print one.\n' ) else: changeRadii(parm, 'mbondi2').execute() change(parm, 'RADII', ':AS4,GL4,PRN@OD=,OE=,O1=,O2=', 1.3).execute() parm.overwrite = True parm.write_parm(opt.outparm) else: if opt.outparm is not None: sys.stderr.write( 'A new prmtop is only necessary for explicit solvent ' 'CpHMD/pH-REMD simulations.\n' ) sys.stderr.write('CPIN generation complete!\n')
def create_inputs(INPUT, prmtop_system, pre): """ Creates the input files for all necessary calculations """ stability = prmtop_system.stability # First check if we are running decomp if INPUT['decomprun']: # Get the cards that will go in the complex mdin file com_card, rc_card, lc_card = prmtop_system.Group( INPUT['print_res'], True) junk, rec_card, lig_card = prmtop_system.Group(INPUT['print_res'], False, rec_group_type='RES', lig_group_type='RES') full_com, full_rc, full_lc = prmtop_system.Group('all', True) junk, full_rec, full_lig = prmtop_system.Group('all', False) # Convert the strings into card objects # Now create the mdin objects if INPUT['gbrun']: if stability: rec_res = ['Residues considered as REC', full_rc] pri_res = ['Residues to print', com_card] com_mdin = SanderGBDecomp(INPUT, rec_res, pri_res) com_mdin.write_input(pre + 'gb_decomp_com.mdin') else: rec_res = ['Residues considered as REC', full_rc] lig_res = ['Residues considered as LIG', full_lc] pri_res = ['Residues to print', com_card] com_mdin = SanderGBDecomp(INPUT, rec_res, lig_res, pri_res) rec_res = ['Residues considered as REC', full_rec] pri_res = ['Residues to print', rec_card] rec_mdin = SanderGBDecomp(INPUT, rec_res, pri_res) lig_res = ['Residues considered as LIG', full_lig] pri_res = ['Residues to print', lig_card] lig_mdin = SanderGBDecomp(INPUT, lig_res, pri_res) com_mdin.write_input(pre + 'gb_decomp_com.mdin') rec_mdin.write_input(pre + 'gb_decomp_rec.mdin') lig_mdin.write_input(pre + 'gb_decomp_lig.mdin') if INPUT['pbrun']: if stability: rec_res = ['Residues considered as REC', full_rc] pri_res = ['Residues to print', com_card] com_mdin = SanderPBDecomp(INPUT, rec_res, pri_res) com_mdin.write_input(pre + 'pb_decomp_com.mdin') else: rec_res = ['Residues considered as REC', full_rc] lig_res = ['Residues considered as LIG', full_lc] pri_res = ['Residues to print', com_card] com_mdin = SanderPBDecomp(INPUT, rec_res, lig_res, pri_res) rec_res = ['Residues considered as REC', full_rec] pri_res = ['Residues to print', rec_card] rec_mdin = SanderPBDecomp(INPUT, rec_res, pri_res) lig_res = ['Residues considered as LIG', full_lig] pri_res = ['Residues to print', lig_card] lig_mdin = SanderPBDecomp(INPUT, lig_res, pri_res) com_mdin.write_input(pre + 'pb_decomp_com.mdin') rec_mdin.write_input(pre + 'pb_decomp_rec.mdin') lig_mdin.write_input(pre + 'pb_decomp_lig.mdin') else: # not decomp if INPUT['gbrun']: gb_prog = 'mmpbsa_py_energy' if INPUT['use_sander'] or INPUT['ifqnt'] == 1: gb_prog = 'sander' if gb_prog == 'mmpbsa_py_energy': gb_mdin = GBNabInput(INPUT) gb_mdin.write_input(pre + 'gb.mdin') else: # We need separate input files for QM/gmx_MMPBSA if INPUT['ifqnt']: com_input = deepcopy(INPUT) rec_input = deepcopy(INPUT) lig_input = deepcopy(INPUT) (com_input['qmmask'], rec_input['qmmask'], lig_input['qmmask']) = prmtop_system.Mask( INPUT['qm_residues'], in_complex=False) if not com_input['qmmask']: raise AmberError('No valid QM residues chosen!') com_input['qm_theory'] = "'%s'" % com_input['qm_theory'] com_input['qmmask'] = "'%s'" % com_input['qmmask'] com_input['qmcharge'] = com_input['qmcharge_com'] gb_mdin = SanderGBInput(com_input) gb_mdin.write_input(pre + 'gb_qmmm_com.mdin') if not stability: if not rec_input['qmmask']: rec_input['ifqnt'] = 0 else: rec_input['qmmask'] = "'%s'" % rec_input['qmmask'] rec_input[ 'qm_theory'] = "'%s'" % rec_input['qm_theory'] rec_input['qmcharge'] = rec_input['qmcharge_rec'] gb_mdin = SanderGBInput(rec_input) gb_mdin.write_input(pre + 'gb_qmmm_rec.mdin') if not lig_input['qmmask']: lig_input['ifqnt'] = 0 else: lig_input['qmmask'] = "'%s'" % lig_input['qmmask'] lig_input[ 'qm_theory'] = "'%s'" % lig_input['qm_theory'] lig_input['qmcharge'] = lig_input['qmcharge_lig'] gb_mdin = SanderGBInput(lig_input) gb_mdin.write_input(pre + 'gb_qmmm_lig.mdin') else: gb_mdin = SanderGBInput(INPUT) gb_mdin.write_input(pre + 'gb.mdin') if INPUT['pbrun']: pb_prog = 'mmpbsa_py_energy' if INPUT['sander_apbs']: pb_prog = 'sander.APBS' elif INPUT['use_sander']: pb_prog = 'sander' if pb_prog == 'mmpbsa_py_energy': pb_mdin = PBNabInput(INPUT) pb_mdin2 = PBNabInput(INPUT) elif pb_prog == 'sander.APBS': pb_mdin = SanderAPBSInput(INPUT) pb_mdin2 = SanderAPBSInput(INPUT) else: pb_mdin = SanderPBSAInput(INPUT) pb_mdin2 = SanderPBSA2Input(INPUT) pb_mdin.write_input(pre + 'pb.mdin') pb_mdin2.write_input(pre + 'pb.mdin2') # end if decomprun if INPUT['qh_entropy']: # quasi-harmonic approximation input file trj_suffix = 'mdcrd' if INPUT['netcdf']: trj_suffix = 'nc' com_mask, rec_mask, lig_mask = prmtop_system.Mask('all', True) if not INPUT['mutant_only']: qh_in = QuasiHarmonicInput(com_mask, rec_mask, lig_mask, stability=stability, prefix=pre, trj_suffix=trj_suffix) qh_in.write_input(pre + 'cpptrajentropy.in') if INPUT['alarun']: qh_in = QuasiHarmonicInput(com_mask, rec_mask, lig_mask, stability=stability, prefix=pre + 'mutant_', trj_suffix=trj_suffix) qh_in.write_input(pre + 'mutant_cpptrajentropy.in')
def check_length(key, length, required=True): if not required and not key in self.parm_data: return if len(self.parm_data[key]) != length: raise AmberError('FLAG %s has %d elements; expected %d' % (key, len(self.parm_data[key]), length))
def create_inputs(INPUT, prmtop_system, pre): """ Creates the input files for all necessary calculations """ stability = prmtop_system.stability # First check if we are running decomp if INPUT['decomprun']: # Get the cards that will go in the complex mdin file com_card, rc_card, lc_card = prmtop_system.Group( INPUT['print_res'], True) junk, rec_card, lig_card = prmtop_system.Group(INPUT['print_res'], False, rec_group_type='RES', lig_group_type='RES') full_com, full_rc, full_lc = prmtop_system.Group('all', True) junk, full_rec, full_lig = prmtop_system.Group('all', False) # Convert the strings into card objects # Now create the mdin objects if INPUT['gbrun']: com_arad = None rec_arad = None lig_arad = None if INPUT['alpb']: import subprocess com_top = parmed.load_file('COM.prmtop', xyz=f"{pre}COM.inpcrd") com_top.save('COM.pqr', format='pqr', overwrite=True) stdoutdata = subprocess.getoutput("elsize COM.pqr -hea") com_arad = stdoutdata.split()[INPUT['arad_method'] * -1] if not stability: rec_top = parmed.load_file('REC.prmtop', xyz=f"{pre}REC.inpcrd") rec_top.save('REC.pqr', format='pqr', overwrite=True) stdoutdata = subprocess.getoutput("elsize REC.pqr -hea") rec_arad = stdoutdata.split()[INPUT['arad_method'] * -1] lig_top = parmed.load_file('LIG.prmtop', xyz=f"{pre}LIG.inpcrd") lig_top.save('LIG.pqr', format='pqr', overwrite=True) stdoutdata = subprocess.getoutput("elsize LIG.pqr -hea") lig_arad = stdoutdata.split()[INPUT['arad_method'] * -1] rec_res = ['Residues considered as REC', full_rc] if stability: pri_res = ['Residues to print', com_card] com_input = deepcopy(INPUT) if com_arad: com_input['arad'] = com_arad com_mdin = SanderGBDecomp(com_input, rec_res, pri_res) com_mdin.write_input(f"{pre}gb_decomp_com.mdin") else: lig_res = ['Residues considered as LIG', full_lc] pri_res = ['Residues to print', com_card] com_input = deepcopy(INPUT) if com_arad: com_input['arad'] = com_arad com_mdin = SanderGBDecomp(com_input, rec_res, lig_res, pri_res) rec_res = ['Residues considered as REC', full_rec] pri_res = ['Residues to print', rec_card] rec_input = deepcopy(INPUT) if rec_arad: rec_input['arad'] = rec_arad rec_mdin = SanderGBDecomp(rec_input, rec_res, pri_res) lig_res = ['Residues considered as LIG', full_lig] pri_res = ['Residues to print', lig_card] lig_input = deepcopy(INPUT) if lig_arad: lig_input['arad'] = lig_arad lig_mdin = SanderGBDecomp(lig_input, lig_res, pri_res) com_mdin.write_input(f"{pre}gb_decomp_com.mdin") rec_mdin.write_input(f"{pre}gb_decomp_rec.mdin") lig_mdin.write_input(f"{pre}gb_decomp_lig.mdin") if INPUT['pbrun']: rec_res = ['Residues considered as REC', full_rc] if stability: pri_res = ['Residues to print', com_card] com_mdin = SanderPBDecomp(INPUT, rec_res, pri_res) com_mdin.write_input(f"{pre}pb_decomp_com.mdin") else: lig_res = ['Residues considered as LIG', full_lc] pri_res = ['Residues to print', com_card] com_mdin = SanderPBDecomp(INPUT, rec_res, lig_res, pri_res) rec_res = ['Residues considered as REC', full_rec] pri_res = ['Residues to print', rec_card] rec_mdin = SanderPBDecomp(INPUT, rec_res, pri_res) lig_res = ['Residues considered as LIG', full_lig] pri_res = ['Residues to print', lig_card] lig_mdin = SanderPBDecomp(INPUT, lig_res, pri_res) com_mdin.write_input(f"{pre}pb_decomp_com.mdin") rec_mdin.write_input(f"{pre}pb_decomp_rec.mdin") lig_mdin.write_input(f"{pre}pb_decomp_lig.mdin") else: # not decomp if INPUT['gbrun']: # We need separate input files for QM/gmx_MMPBSA com_arad = None rec_arad = None lig_arad = None if INPUT['alpb']: import subprocess com_top = parmed.load_file('COM.prmtop', xyz=f"{pre}COM.inpcrd") com_top.save('COM.pqr', format='pqr', overwrite=True) stdoutdata = subprocess.getoutput("elsize COM.pqr -hea") com_arad = stdoutdata.split()[INPUT['arad_method'] * -1] if not stability: rec_top = parmed.load_file('REC.prmtop', xyz=f"{pre}REC.inpcrd") rec_top.save('REC.pqr', format='pqr', overwrite=True) stdoutdata = subprocess.getoutput("elsize REC.pqr -hea") rec_arad = stdoutdata.split()[INPUT['arad_method'] * -1] lig_top = parmed.load_file('LIG.prmtop', xyz=f"{pre}LIG.inpcrd") lig_top.save('LIG.pqr', format='pqr', overwrite=True) stdoutdata = subprocess.getoutput("elsize LIG.pqr -hea") lig_arad = stdoutdata.split()[INPUT['arad_method'] * -1] if INPUT['ifqnt']: com_input = deepcopy(INPUT) rec_input = deepcopy(INPUT) lig_input = deepcopy(INPUT) (com_input['qmmask'], rec_input['qmmask'], lig_input['qmmask']) = prmtop_system.Mask( INPUT['qm_residues'], in_complex=False) if not com_input['qmmask']: raise AmberError('No valid QM residues chosen!') com_input['qm_theory'] = "'%s'" % com_input['qm_theory'] com_input['qmmask'] = "'%s'" % com_input['qmmask'] com_input['qmcharge'] = com_input['qmcharge_com'] # check if alpb if com_arad: com_input['arad'] = com_arad gb_mdin = SanderGBInput(com_input) gb_mdin.write_input(f'{pre}gb_qmmm_com.mdin') if not stability: if not rec_input['qmmask']: rec_input['ifqnt'] = 0 else: rec_input['qmmask'] = "'%s'" % rec_input['qmmask'] rec_input['qm_theory'] = "'%s'" % rec_input['qm_theory'] rec_input['qmcharge'] = rec_input['qmcharge_rec'] # check if alpb if rec_arad: rec_input['arad'] = rec_arad gb_mdin = SanderGBInput(rec_input) gb_mdin.write_input(f'{pre}gb_qmmm_rec.mdin') if not lig_input['qmmask']: lig_input['ifqnt'] = 0 else: lig_input['qmmask'] = "'%s'" % lig_input['qmmask'] lig_input['qm_theory'] = "'%s'" % lig_input['qm_theory'] lig_input['qmcharge'] = lig_input['qmcharge_lig'] # check if alpb if lig_arad: lig_input['arad'] = lig_arad gb_mdin = SanderGBInput(lig_input) gb_mdin.write_input(f'{pre}gb_qmmm_lig.mdin') elif INPUT['alpb']: com_input = deepcopy(INPUT) rec_input = deepcopy(INPUT) lig_input = deepcopy(INPUT) com_input['arad'] = com_arad gb_mdin = SanderGBInput(com_input) gb_mdin.write_input(f'{pre}gb_com.mdin') rec_input['arad'] = rec_arad gb_mdin = SanderGBInput(rec_input) gb_mdin.write_input(f'{pre}gb_rec.mdin') lig_input['arad'] = lig_arad gb_mdin = SanderGBInput(lig_input) gb_mdin.write_input(f'{pre}gb_lig.mdin') else: gb_mdin = SanderGBInput(INPUT) gb_mdin.write_input(f'{pre}gb.mdin') if INPUT['pbrun']: pb_prog = 'sander.APBS' if INPUT['sander_apbs'] else 'sander' if pb_prog == 'sander.APBS': pb_mdin = SanderAPBSInput(INPUT) pb_mdin2 = SanderAPBSInput(INPUT) else: pb_mdin = SanderPBSAInput(INPUT) pb_mdin2 = SanderPBSA2Input(INPUT) pb_mdin.write_input(f'{pre}pb.mdin') pb_mdin2.write_input(f'{pre}pb.mdin2') if INPUT['rismrun']: rism_mdin = SanderRISMInput(INPUT) rism_mdin.write_input(pre + 'rism.mdin') # end if decomprun if INPUT['qh_entropy']: # quasi-harmonic approximation input file trj_suffix = 'nc' if INPUT['netcdf'] else 'mdcrd' com_mask, rec_mask, lig_mask = prmtop_system.Mask('all', True) if not INPUT['mutant_only']: qh_in = QuasiHarmonicInput(com_mask, rec_mask, lig_mask, temperature=INPUT['temperature'], stability=stability, prefix=pre, trj_suffix=trj_suffix) qh_in.write_input(f'{pre}cpptrajentropy.in') if INPUT['alarun']: qh_in = QuasiHarmonicInput(com_mask, rec_mask, lig_mask, temperature=INPUT['temperature'], stability=stability, prefix=pre + 'mutant_', trj_suffix=trj_suffix) qh_in.write_input(f'{pre}mutant_cpptrajentropy.in')
def write_cpin(self, output, igb=2, intdiel=1.0, coions=False): """ Writes the CPIN file based on the titrated residues """ # Reset all residues for res in self: res.reset() # Sort our residue list self.sort() buf = _LineBuffer(output) buf.add_word('&CNSTPH') buf.flush() buf.add_word(' CHRGDAT=') charges, energies, protcnts, pointers = [], [], [], [] first_charge = 0 first_state = 0 for i, res in enumerate(self): if res.first_charge == -1: res.set_first_charge(first_charge) res.set_first_state(first_state) for state in res.states: # See which dielectric reference energies we want if intdiel == 2: refene = state.refene.dielc2 else: refene = state.refene # See if we want the explicit solvent refene or not if self.solvated: energies.append(getattr(refene.solvent, 'igb%d' % igb)) else: energies.append(getattr(refene, 'igb%d' % igb)) # Add protonation count of this state protcnts.append(state.protcnt) first_state += len(res.states) new_charges = [] for state in res.states: new_charges.extend(state.charges) charges.extend(new_charges) first_charge += len(new_charges) pointers.append(res.cpin_pointers(self.first_atoms[i])) # Print the charges for charge in charges: buf.add_word('%s,' % charge) buf.flush() # Print the protcnts buf.add_word(' PROTCNT=') for protcnt in protcnts: buf.add_word('%d,' % protcnt) buf.flush() # Print the residue names buf.add_word(" RESNAME='System: %s'," % self.system_name) for i, res in enumerate(self): buf.add_word("'Residue: %s %d'," % (res.resname, self.residue_nums[i])) buf.flush() # Print the residue states buf.add_word(" RESSTATE=") for state in self.resstates: buf.add_word('%d,' % state) buf.flush() # Print the residue pointers buf.add_word(' ') # get a leading space for i, p in enumerate(pointers): buf.add_word("STATEINF(%d)%%FIRST_ATOM=%d, " % (i, p['FIRST_ATOM'])) buf.add_word("STATEINF(%d)%%FIRST_CHARGE=%d, " % (i, p['FIRST_CHARGE'])) buf.add_word("STATEINF(%d)%%FIRST_STATE=%d, " % (i, p['FIRST_STATE'])) buf.add_word("STATEINF(%d)%%NUM_ATOMS=%d, " % (i, p['NUM_ATOMS'])) buf.add_word("STATEINF(%d)%%NUM_STATES=%d, " % (i, p['NUM_STATES'])) buf.flush() # Print the reference energies buf.add_word(' STATENE=') for i, energy in enumerate(energies): if energy is None: raise AmberError("%d'th reference energy not known for " "igb = %d" % (i, igb)) buf.add_word('%.6f,' % energy) buf.flush() # Print the # of residues and explicit solvent info if required buf.add_word(' TRESCNT=%d,' % len(self)) if self.solvated: buf.add_word('CPHFIRST_SOL=%d, CPH_IGB=%d, CPH_INTDIEL=%s, ' % (self.first_sol, igb, intdiel)) buf.flush() # Now scan through all of the waters buf.flush() buf.add_word('/'); buf.flush()
def add_state(self, protcnt, charges, refene): """ Add a single titratable state for this titratable residue """ new_state = _State(protcnt, charges, refene) if len(new_state.charges) != len(self.atom_list): raise AmberError('Wrong number of charges for new state') self.states.append(new_state)