def GetInterfaceChainsAndResiduesInfo(MolName1, ChainIDs1, MolName2, ChainIDs2, Method, Cutoff): """Get interface chains and residues info for chains using a specified methodology.""" InterfaceChainsResiduesInfo1 = None InterfaceChainsResiduesInfo2 = None ChainNames1 = ",".join(ChainIDs1) ChainNames2 = ",".join(ChainIDs2) if re.match("^BySASAChange$", Method, re.I): InterfaceChainsResiduesInfo1, InterfaceChainsResiduesInfo2 = PyMOLUtil.GetInterfaceChainsResiduesBySASAChange( MolName1, ChainNames1, MolName2, ChainNames2, Cutoff) elif re.match("^ByHeavyAtomsDistance$", Method, re.I): InterfaceChainsResiduesInfo1, InterfaceChainsResiduesInfo2 = PyMOLUtil.GetnterfaceChainsResiduesByHeavyAtomsDistance( MolName1, ChainNames1, MolName2, ChainNames2, Cutoff) elif re.match("^ByCAlphaAtomsDistance$", Method, re.I): InterfaceChainsResiduesInfo1, InterfaceChainsResiduesInfo2 = PyMOLUtil.GetInterfaceChainsResiduesByCAlphaAtomsDistance( MolName1, ChainNames1, MolName2, ChainNames2, Cutoff) else: MiscUtil.PrintError( "Failed to retrieve interface residues information: Method %s is not valid..." % Method) return InterfaceChainsResiduesInfo1, InterfaceChainsResiduesInfo2
def GetPocketSelectionResiduesInfo(MolName, ChainID, LigandResName, LigandResNum, PocketDistanceCutoff, SelectionType): """Get pocket residues info for a specified selection type. """ SelectionInfo = None if re.match("^Pockets$", SelectionType, re.I): SelectionInfo = PyMOLUtil.GetPocketPolymerResiduesInfo( MolName, ChainID, LigandResName, LigandResNum, PocketDistanceCutoff) elif re.match("^PocketSolvents$", SelectionType, re.I): SelectionInfo = PyMOLUtil.GetPocketSolventResiduesInfo( MolName, ChainID, LigandResName, LigandResNum, PocketDistanceCutoff) elif re.match("^PocketInorganics$", SelectionType, re.I): SelectionInfo = PyMOLUtil.GetPocketInorganicResiduesInfo( MolName, ChainID, LigandResName, LigandResNum, PocketDistanceCutoff) else: MiscUtil.PrintError( "Failed to retrieve pocket residues information: Selection type %s is not valid..." % SelectionType) return SelectionInfo
def GetSelectionResiduesInfo(MolName, ChainID, SelectionType): """Get residues info for a specified selection type. """ SelectionInfo = None SelectionLabel = None if re.match("^Ligands$", SelectionType, re.I): SelectionLabel = "ligand" SelectionInfo = PyMOLUtil.GetLigandResiduesInfo( MolName, ChainID) if ChainID is not None else None elif re.match("^Solvents$", SelectionType, re.I): SelectionLabel = "solvent" SelectionInfo = PyMOLUtil.GetSolventResiduesInfo( MolName, ChainID) if ChainID is not None else None elif re.match("^Inorganics$", SelectionType, re.I): SelectionLabel = "inorganic" SelectionInfo = PyMOLUtil.GetInorganicResiduesInfo( MolName, ChainID) if ChainID is not None else None elif re.match("^Chains$", SelectionType, re.I): SelectionLabel = "polymer chain" SelectionInfo = PyMOLUtil.GetPolymerResiduesInfo( MolName, ChainID) if ChainID is not None else None elif re.match("^NonStandardAminoAcids$", SelectionType, re.I): SelectionLabel = "non-standard amino acids" SelectionInfo = PyMOLUtil.GetAminoAcidResiduesInfo( MolName, ChainID, "NonStandard") if ChainID is not None else None else: MiscUtil.PrintError( "Failed to retrieve residues information: Selection type %s is not valid..." % SelectionType) return SelectionInfo, SelectionLabel
def ProcessChainIDs(): """Process specified chain IDs for infiles.""" OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"] = [] OptionsInfo["InfilesInfo"]["ChainSelections"] = [] for FileIndex in range(0, len(OptionsInfo["InfilesInfo"]["InfilesNames"])): MiscUtil.PrintInfo("\nProcessing specified chain IDs for input file %s..." % OptionsInfo["InfilesInfo"]["InfilesNames"][FileIndex]) ChainsAndLigandsInfo = OptionsInfo["InfilesInfo"]["ChainsAndLigandsInfo"][FileIndex] SpecifiedChainsAndLigandsInfo = PyMOLUtil.ProcessChainsAndLigandsOptionsInfo(ChainsAndLigandsInfo, "-c, --chainIDs", OptionsInfo["ChainIDs"], None, None) # Setup chain selections... ChainSelections = None if not OptionsInfo["AllChains"]: Chains = [] for ChainID in SpecifiedChainsAndLigandsInfo["ChainIDs"]: Chains.append("chain %s" % ChainID) ChainSelections = " or ".join(Chains) ChainSelections = "(%s)" % ChainSelections OptionsInfo["InfilesInfo"]["SpecifiedChainsAndLigandsInfo"].append(SpecifiedChainsAndLigandsInfo) OptionsInfo["InfilesInfo"]["ChainSelections"].append(ChainSelections) MiscUtil.PrintInfo("Specified chain IDs: %s" % (", ".join(SpecifiedChainsAndLigandsInfo["ChainIDs"])))
def GetFormattedPropertyValue(Selection, Name): """Calculate and return a formatted property value. """ Quiet = OptionsInfo["Quiet"] Precision = OptionsInfo["Precision"] Value = None if re.match("^CenterOfMass$", Name, re.I): Value = PyMOLUtil.CalculateCenterOfMass(Selection, Quiet) elif re.match("^MolecularWeight$", Name, re.I): Value = pymol.util.compute_mass(Selection, implicit = False, quiet = Quiet) elif re.match("^MolecularSurfaceArea$", Name, re.I): Value = pymol.util.get_area(Selection, -1, 0, quiet = Quiet) elif re.match("^SumOfFormalCharges$", Name, re.I): Value = pymol.util.sum_formal_charges(Selection, quiet = Quiet) elif re.match("^SumOfPartialCharges$", Name, re.I): Value = pymol.util.sum_partial_charges(Selection, quiet = Quiet) elif re.match("^SolventAccessibleSurfaceArea$", Name, re.I): Value = pymol.util.get_sasa(Selection, quiet = Quiet) else: MiscUtil.PrintError("The property name specified, %s, using \"-m, --mode\" option is not a valid name." % Name) if Value is None: FormattedValue = "NA" else: if type(Value) is list: FormattedValues = [] for ListElement in Value: FormattedListElement = "%.*f" % (Precision, ListElement) FormattedValues.append(FormattedListElement) FormattedValue = " ".join(FormattedValues) else: FormattedValue = "%.*f" % (Precision, Value) return FormattedValue
def ListFileInfo(Infile): """List information for macromolecules in a file.""" FileDir, FileName, FileExt = MiscUtil.ParseFileName(Infile) MolName = FileName # Load infile... pymol.cmd.load(Infile, MolName) ChainIDs = PyMOLUtil.GetChains(MolName) ListHeaderInfo(Infile) ListChainsInfo(MolName, ChainIDs) ListChainsResiduesInfo(MolName, ChainIDs) ListLigandsInfo(MolName, ChainIDs) ListSolventsInfo(MolName, ChainIDs) ListInorganicsInfo(MolName, ChainIDs) ListPocketsInfo(MolName, ChainIDs) ListInterfaceResiduesInfo(MolName, ChainIDs) ListSurfaceResiduesInfo(MolName, ChainIDs) ListPhiPsiAnglesInfo(MolName, ChainIDs) ListBoundingBoxInfo(MolName) # Delete infile object... pymol.cmd.delete(MolName) ListFileSizeAndModificationInfo(Infile)
def ListPocketsInfo(MolName, ChainIDs): """List pockect residues information across all chains.""" if not (OptionsInfo["All"] or OptionsInfo["PocketLigands"] or OptionsInfo["PocketSolvents"] or OptionsInfo["PocketInorganics"]): return for ChainID in ChainIDs: MiscUtil.PrintInfo( "\nListing ligand pockets information for chain %s..." % (ChainID)) LigandsInfo = PyMOLUtil.GetLigandResiduesInfo(MolName, ChainID) if not len(LigandsInfo["ResNames"]): MiscUtil.PrintInfo("\nNumber of residues in ligand pocket: None") MiscUtil.PrintInfo("Chain ID: %s; Ligands: None" % (ChainID)) continue for LigandResName in sorted(LigandsInfo["ResNames"]): for LigandResNum in LigandsInfo["ResNum"][LigandResName]: ListPocketsPolymerInfo(MolName, ChainID, LigandResName, LigandResNum) ListPocketsSolventsInfo(MolName, ChainID, LigandResName, LigandResNum) ListPocketsInorganicsInfo(MolName, ChainID, LigandResName, LigandResNum)
def RetrieveInfileInfo(): """Retrieve information for input file.""" Infile = OptionsInfo["Infile"] InfileRoot = OptionsInfo["InfileRoot"] ChainsAndLigandsInfo = PyMOLUtil.GetChainsAndLigandsInfo(Infile, InfileRoot) OptionsInfo["ChainsAndLigandsInfo"] = ChainsAndLigandsInfo
def ProcessChainIDs(): """Process specified chain IDs for infile.""" MiscUtil.PrintInfo("\nProcessing specified chain IDs for input file %s..." % OptionsInfo["Infile"]) ChainsAndLigandsInfo = OptionsInfo["ChainsAndLigandsInfo"] SpecifiedChainsAndLigandsInfo = PyMOLUtil.ProcessChainsAndLigandsOptionsInfo(ChainsAndLigandsInfo, "-c, --chainIDs", OptionsInfo["ChainIDs"], None, None) OptionsInfo["SpecifiedChainsAndLigandsInfo"] = SpecifiedChainsAndLigandsInfo MiscUtil.PrintInfo("Specified chain IDs: %s" % (", ".join(SpecifiedChainsAndLigandsInfo["ChainIDs"])))
def ProcessChainAndLigandIDs(): """Process chain and ligand IDs""" MolName = OptionsInfo["InfileRoot"] ChainsAndLigandsInfo = PyMOLUtil.GetChainsAndLigandsInfo( OptionsInfo["Infile"], MolName) OptionsInfo["ChainsAndLigandsInfo"] = ChainsAndLigandsInfo MiscUtil.PrintInfo( "\nProcessing specified chain and ligand IDs for input file %s..." % OptionsInfo["Infile"]) SpecifiedChainsAndLigandsInfo = PyMOLUtil.ProcessChainsAndLigandsOptionsInfo( ChainsAndLigandsInfo, "-c, --chainIDs", OptionsInfo["ChainIDs"], "-l, --ligandIDs", OptionsInfo["LigandIDs"]) OptionsInfo[ "SpecifiedChainsAndLigandsInfo"] = SpecifiedChainsAndLigandsInfo CheckPresenceOfValidLigandIDs(ChainsAndLigandsInfo, SpecifiedChainsAndLigandsInfo)
def ConvertLigandFileFormat(): """Comvert ligand file format.""" Infile = OptionsInfo["Infile"] Outfile = OptionsInfo["Outfile"] MiscUtil.PrintInfo("\nGenerating file %s..." % Outfile) PyMOLUtil.ConvertFileFormat(Infile, Outfile) if not os.path.exists(Outfile): MiscUtil.PrintWarning("Failed to generate Outfile file, %s..." % (Outfile))
def GeneratePSEFile(): """Comvert PML file to PSE file.""" PMLFile = OptionsInfo["Infile"] PSEFile = OptionsInfo["Outfile"] MiscUtil.PrintInfo("\nGenerating file %s..." % PSEFile) PyMOLUtil.ConvertPMLFileToPSEFile(PMLFile, PSEFile, OutputFeedback=OptionsInfo["Feedback"]) if not os.path.exists(PSEFile): MiscUtil.PrintWarning("Failed to generate PSE file, %s..." % (PSEFile))
def ListPhiPsiAnglesInfo(MolName, ChainIDs): """List phi and psi torsion angles for polymer chains with in a molecule.""" if not (OptionsInfo["All"] or OptionsInfo["PhiPsi"]): return MiscUtil.PrintInfo("\nListing phi and psi angles information...") if not len(ChainIDs): MiscUtil.PrintInfo("\nNumber of phi and psi angles: None\n") return for ChainID in ChainIDs: if re.match("^Categories$", OptionsInfo["PhiPsiMode"], re.I): # Retrieve phi and psi angles by categories used for Ramachandran plots GeneralPhiPsiInfo, GlyPhiPsiInfo, ProPhiPsiInfo, PreProPhiPsiInfo = PyMOLUtil.GetPhiPsiCategoriesResiduesInfo( MolName, ChainID) SetupAndListPhiPsiResiduesInfo( GeneralPhiPsiInfo, "General (All residues except glycine, proline, or pre-proline)", ChainID) SetupAndListPhiPsiResiduesInfo(GlyPhiPsiInfo, "Glycine (Only glycine residues)", ChainID) SetupAndListPhiPsiResiduesInfo(ProPhiPsiInfo, "Proline (Only proline residues)", ChainID) SetupAndListPhiPsiResiduesInfo( PreProPhiPsiInfo, "Pre-Proline (Only residues before proline not including glycine or proline)", ChainID) else: PhiPsiResiduesInfo = PyMOLUtil.GetPhiPsiResiduesInfo( MolName, ChainID, Categorize=True) SetupAndListPhiPsiResiduesInfo(PhiPsiResiduesInfo, "All", ChainID)
def CalculatePhiPsiAngles(): """Calculate phi and psi angles for macromolecules containing amino acids.""" SetupOutputFiles() WriteColumnLabels() Infile = OptionsInfo["Infile"] MolName = OptionsInfo["InfileRoot"] MiscUtil.PrintInfo("\nCalculating phi and psi torsion angles for input file %s..." % Infile) # Load infile pymol.cmd.load(Infile, MolName) OutDelim = OptionsInfo["OutDelim"] Precision = OptionsInfo["Precision"] # Go over specified chain IDs.. for ChainID in OptionsInfo["SpecifiedChainsAndLigandsInfo"]["ChainIDs"]: # Write out information for combined file... PhiPsiInfo = PyMOLUtil.GetPhiPsiResiduesInfo(MolName, ChainID, Categorize = True) OptionsInfo["OutfileResCount"] += len(PhiPsiInfo["ResNums"]) WritePhiPsiInfo(OptionsInfo["OutFH"], MolName, ChainID, PhiPsiInfo, OutDelim, Precision) # Write out information for category fies... if OptionsInfo["MultipleOutFiles"]: PhiPsiInfoList = [] GeneralPhiPsiInfo, GlycinePhiPsiInfo, ProlinePhiPsiInfo, PreProlinePhiPsiInfo = PyMOLUtil.GetPhiPsiCategoriesResiduesInfo(MolName, ChainID) PhiPsiInfoList.extend([GeneralPhiPsiInfo, GlycinePhiPsiInfo, ProlinePhiPsiInfo, PreProlinePhiPsiInfo]) for Index, Category in enumerate(OptionsInfo["Categories"]): OptionsInfo["CategoriesResCount"][Category] += len(PhiPsiInfoList[Index]["ResNums"]) WritePhiPsiInfo(OptionsInfo["CategoriesOutFHs"][Category], MolName, ChainID, PhiPsiInfoList[Index], OutDelim, Precision) # Delete MolName object pymol.cmd.delete(MolName) # Close all files... CloseOutputFiles() # List number of phi and psi angles in output files... MiscUtil.PrintInfo("\nNumber of phi and psi angles in output file %s: %d" % (OptionsInfo["Outfile"], OptionsInfo["OutfileResCount"])) if OptionsInfo["MultipleOutFiles"]: MiscUtil.PrintInfo("") for Index, Category in enumerate(OptionsInfo["Categories"]): MiscUtil.PrintInfo("Number of phi and psi angles in output file %s: %d" % (OptionsInfo["CategoriesOutfiles"][Category], OptionsInfo["CategoriesResCount"][Category]))
def RetrieveChainIDs(Infile, InfileRoot): """Retrieve chains IDs for an input file.""" pymol.cmd.reinitialize() MolName = InfileRoot pymol.cmd.load(Infile, MolName) ChainIDs = PyMOLUtil.GetChains(MolName) pymol.cmd.delete(MolName) if ChainIDs is None: ChainIDs = [] # Print out chain and ligand IDs... ChainInfo = ", ".join(ChainIDs) if len(ChainIDs) else "None" MiscUtil.PrintInfo("Chain IDs: %s" % ChainInfo) return ChainIDs
def ListSurfaceResiduesInfo(MolName, ChainIDs): """List surface and buried residues for polymer chains with in a molecule.""" if not (OptionsInfo["All"] or OptionsInfo["SurfaceResidues"]): return MiscUtil.PrintInfo("\nListing surface and buried residues information...") if not len(ChainIDs): MiscUtil.PrintInfo( "\nNumber of surface residues: None\nNumber of buried residues: None" ) return TotalSurfaceResidues, TotalBuriedResidues = [0] * 2 for ChainID in ChainIDs: SurfaceResiduesSelectionInfo, BuriedResiduesSelectionInfo = PyMOLUtil.GetSurfaceAndBuriedResiduesInfo( MolName, ChainID, OptionsInfo["SurfaceResiduesCutoff"]) SurfaceResiduesCount, SurfaceResiduesDistribution, SurfaceResiduesIDs = SetupSelectionResiduesInfo( SurfaceResiduesSelectionInfo) BuriedResiduesCount, BuriedResiduesDistribution, BuriedResiduesIDs = SetupSelectionResiduesInfo( BuriedResiduesSelectionInfo) TotalSurfaceResidues += SurfaceResiduesCount MiscUtil.PrintInfo("\nChainID: %s; Number of surface residues: %d" % (ChainID, SurfaceResiduesCount)) MiscUtil.PrintInfo("Residue distribution: %s" % (SurfaceResiduesDistribution)) if OptionsInfo["SurfaceResiduesIDs"]: MiscUtil.PrintInfo("Residue IDs: %s" % (SurfaceResiduesIDs)) TotalBuriedResidues += BuriedResiduesCount MiscUtil.PrintInfo("\nChainID: %s; Number of buried residues: %d" % (ChainID, BuriedResiduesCount)) MiscUtil.PrintInfo("Residue distribution: %s" % (BuriedResiduesDistribution)) if OptionsInfo["SurfaceResiduesIDs"]: MiscUtil.PrintInfo("Residue IDs: %s" % (BuriedResiduesIDs)) MiscUtil.PrintInfo( "\nTotal number of surface residues: %d\nTotal number of buried residues: %s" % (TotalSurfaceResidues, TotalBuriedResidues))
def RetrieveInfilesInfo(): """Retrieve information for input files.""" InfilesInfo = {} InfilesInfo["InfilesNames"] = [] InfilesInfo["InfilesRoots"] = [] InfilesInfo["ChainsAndLigandsInfo"] = [] for Infile in OptionsInfo["InfilesNames"]: FileDir, FileName, FileExt = MiscUtil.ParseFileName(Infile) InfileRoot = FileName ChainsAndLigandInfo = PyMOLUtil.GetChainsAndLigandsInfo(Infile, InfileRoot) InfilesInfo["InfilesNames"].append(Infile) InfilesInfo["InfilesRoots"].append(InfileRoot) InfilesInfo["ChainsAndLigandsInfo"].append(ChainsAndLigandInfo) OptionsInfo["InfilesInfo"] = InfilesInfo
def RetrieveChainsIDs(): """Retrieve chain IDs. """ MolName = OptionsInfo["InfileRoot"] Infile = OptionsInfo["Infile"] MiscUtil.PrintInfo("\nRetrieving chains information for input file %s..." % Infile) LoadMolecule(Infile, MolName) ChainIDs = PyMOLUtil.GetChains(MolName) DeleteMolecule(MolName) if ChainIDs is None: ChainIDs = [] # Print out chain and ligand IDs... ChainInfo = ", ".join(ChainIDs) if len(ChainIDs) else "None" MiscUtil.PrintInfo("Chain IDs: %s" % ChainInfo) OptionsInfo["ChainIDs"] = ChainIDs
def ProcessSpecifiedMutations(): """Process specified mutations""" MiscUtil.PrintInfo("\nProcessing specified mutations...") SpecifiedMutationsInfo = [] Mutations = re.sub(" ", "", OptionsInfo["Mutations"]) MutationsWords = Mutations.split(",") if not len(MutationsWords): MiscUtil.PrintError("The number of comma delimited mutations specified using \"-m, --mutations\" option, \"%s\", must be > 0." % (OptionsInfo["Mutations"])) # Load macromolecule from input file... MolName = OptionsInfo["InfileRoot"] LoadMolecule(OptionsInfo["Infile"], MolName) FirstMutation = True CurrentChainID = None CanonicalMutationMap = {} MutationsCount, ValidMutationsCount = [0] * 2 for Mutation in MutationsWords: MutationsCount += 1 if not len(Mutation): MiscUtil.PrintWarning("The mutation, \"%s\", specified using \"-m, --mutations\" option is empty.\nIgnoring mutation..." % (Mutation)) continue CanonicalMutation = Mutation.lower() if CanonicalMutation in CanonicalMutationMap: MiscUtil.PrintWarning("The mutation, \"%s\", specified using \"-m, --mutations\" option already exist.\nIgnoring mutation..." % (Mutation)) continue CanonicalMutationMap[CanonicalMutation] = Mutation # Match with a chain ID... MatchedResults = re.match(r"^([a-z0-9]+):([a-z]+)([0-9]+)([a-z]+)$", Mutation, re.I) if not MatchedResults: # Match without a chain ID... MatchedResults = re.match(r"^([a-z]+)([0-9]+)([a-z]+)$", Mutation, re.I) if not MatchedResults: MiscUtil.PrintWarning("The format of mutation, \"%s\", specified using \"-m, --mutations\" option is not valid. Supported format: <ChainID>:<ResName><ResNum><ResName> or <ResName><ResNum><ResName>\nIgnoring mutation..." % (Mutation)) continue NumOfMatchedGroups = len(MatchedResults.groups()) if NumOfMatchedGroups == 3: ResName, ResNum, NewResName = MatchedResults.groups() elif NumOfMatchedGroups == 4: CurrentChainID, ResName, ResNum, NewResName = MatchedResults.groups() else: MiscUtil.PrintWarning("The format of mutation, \"%s\", specified using \"-m, --mutations\" option is not valid. Supported format: <ChainID>:<ResName><ResNum><ResName> or <ResName><ResNum><ResName>\nIgnoring mutation..." % (Mutation)) continue if FirstMutation: FirstMutation = False if CurrentChainID is None: MiscUtil.PrintError("The first mutation, \"%s\", specified using \"-m, --mutations\" option must be colon delimited and contain only two values, the first value corresponding to chain ID" % (Mutation)) ResName = ResName.upper() NewResName = NewResName.upper() # Is ResNum and ResName present in input file? SelectionCmd = "%s and chain %s and resi %s and resn %s" % (MolName, CurrentChainID, ResNum, ResName) ResiduesInfo = PyMOLUtil.GetSelectionResiduesInfo(SelectionCmd) if (ResiduesInfo is None) or (not len(ResiduesInfo["ResNames"])): MiscUtil.PrintWarning("The residue name, %s, and residue number, %s, in mutation, \"%s\", specified using \"-m, --mutations\" option appears to be missing in input file.\nIgnoring mutation..." % (ResName, ResNum, Mutation)) continue ValidMutationsCount += 1 # Track mutation information... SpecifiedMutationsInfo.append([Mutation, CurrentChainID, ResName, ResNum, NewResName]) # Delete macromolecule... DeleteMolecule(MolName) MiscUtil.PrintInfo("\nTotal number of mutations: %d" % MutationsCount) MiscUtil.PrintInfo("Number of valid mutations: %d" % ValidMutationsCount) MiscUtil.PrintInfo("Number of ignored mutations: %d" % (MutationsCount - ValidMutationsCount)) if not len(SpecifiedMutationsInfo): MiscUtil.PrintError("No valid mutations, \"%s\" specified using \"-m, --mutations\" option." % (OptionsInfo["Mutations"])) OptionsInfo["SpecifiedMutationsInfo"] = SpecifiedMutationsInfo
def CalculatePhiPsiAngles(): """Calculate phi and psi angles for scatter plots.""" Infile = OptionsInfo["Infile"] MolName = OptionsInfo["InfileRoot"] # Load molecule... pymol.cmd.reinitialize() pymol.cmd.load(Infile, MolName) MiscUtil.PrintInfo( "\nCalculating phi and psi torsion angles for input file %s..." % Infile) # Initialize... OptionsInfo["PlotTypesInfo"]["PhiAngles"] = {} OptionsInfo["PlotTypesInfo"]["PsiAngles"] = {} OptionsInfo["PlotTypesInfo"]["ResCount"] = {} for PlotType in OptionsInfo["PlotTypesInfo"]["Types"]: OptionsInfo["PlotTypesInfo"]["PhiAngles"][PlotType] = [] OptionsInfo["PlotTypesInfo"]["PsiAngles"][PlotType] = [] OptionsInfo["PlotTypesInfo"]["ResCount"][PlotType] = 0 Precision = OptionsInfo["Precision"] TotalResCount = 0 # Go over specified chain IDs.. for ChainID in OptionsInfo["SpecifiedChainsAndLigandsInfo"]["ChainIDs"]: PhiPsiInfoList = [] GeneralPhiPsiInfo, GlycinePhiPsiInfo, ProlinePhiPsiInfo, PreProlinePhiPsiInfo = PyMOLUtil.GetPhiPsiCategoriesResiduesInfo( MolName, ChainID) PhiPsiInfoList.extend([ GeneralPhiPsiInfo, GlycinePhiPsiInfo, ProlinePhiPsiInfo, PreProlinePhiPsiInfo ]) for Index, PlotType in enumerate( OptionsInfo["PlotTypesInfo"]["Types"]): PhiPsiInfo = PhiPsiInfoList[Index] ResCount = len(PhiPsiInfo["ResNums"]) if not ResCount: continue TotalResCount += ResCount OptionsInfo["PlotTypesInfo"]["ResCount"][PlotType] += ResCount PhiAngles, PsiAngles = ProcessPsiInfo(PhiPsiInfo, Precision) OptionsInfo["PlotTypesInfo"]["PhiAngles"][PlotType].extend( PhiAngles) OptionsInfo["PlotTypesInfo"]["PsiAngles"][PlotType].extend( PsiAngles) # Delete MolName object pymol.cmd.delete(MolName) MiscUtil.PrintInfo("\nTotal number of phi and psi angles: %d" % TotalResCount) MiscUtil.PrintInfo("") for PlotType in OptionsInfo["PlotTypesInfo"]["Types"]: MiscUtil.PrintInfo( "Number of \"%s\" phi and psi angles: %s" % (PlotType, OptionsInfo["PlotTypesInfo"]["ResCount"][PlotType])) if not TotalResCount: MiscUtil.PrintInfo("") MiscUtil.PrintWarning( "No valid phi and psi angles found in input file. Ramachandran plots will be generated without phi and psi scatter plots..." )