-- ReplaceDegenerateSpinsByGroup.lua -- Downloadable from www.nmr.ch -- script to replace degenerate spins by their pseudoatom -- e.g. HB2 3.20 and HB3 3.20 are replaced by HB 3.20 -- e.g. PHE HD1 6.65 and HD2 6.65 are replaced by HD 6.65 -- and to eliminate spins that are assigned to methyl groups individual atoms -- (ResidueTypes do not allow the assignment of individual atoms of a methyl group -- since they are anyway usually degenerate. Instead, one shift is assigned to an atom with the group name) -- E.g. VAL HG11,HG12,HG13 -> HG11 renamed HG1, HG12 & HG13 are deleted -- This is necessary after creating a project from a BMRB *.str file. -- BMRB reports two entries for degenerate shifts. These are -- treated with a single pseudoatom in CARA. -- Note: the script requires that there are no SpinLinks in the project. -- It would be quite a bit more complex to transfer the SpinLinks from -- all the Spins in a Group to the Pseudoatom Spin - so I opted to -- exclude this possibility. -- Version 1 -- F.Damberger Feb.23.2005 -- Version 2 Version = 2 -- F.Damberger Jul.8.2010 -- added option to remove shifts corresponding to extra methyl atoms and rename one shift to the group name -- E.g. If the option RemoveExtraMethylAtoms is selected by the user in the dialog then -- For a Spinsystem assigned to VAL with three spins labeled HG11,HG12,HG13 -- ReplaceDegenerateSpinsByGroup does this: delete HG12 & HG13, rename HG11 to HG1 -- Also changes the magnitude of the methyl atoms in the ResidueTypes (same as CorrectAtomMagnitudes.lua) -- ----------------------------------------------------------------------------- -- Function GroupAssignedAndDegenerate -------------------------------------------------------------------------------------- function GroupAssignedAndDegenerate( Group, System, Project ) Atoms = Group:getAtoms() Result = false -- assume condition is not fulfilled AllShiftsAssigned = true -- assume all are assigned and then try to disprove Shifts = {} SpinsInGroup = {} i = 0 for AtomLabel,Atom in pairs( Atoms ) do local Match = false for SpinId,Spin in pairs( System:getSpins() ) do if Atom:getName() == Spin:getLabel() then Match = true i = i + 1 Shifts[ i ] = Spin:getShift() --collect the shifts of spins in group SpinsInGroup[ i ] = Spin -- collect the spins in group end end -- for System loop : search for Spin with match if not Match then AllShiftsAssigned = false end end --for Atoms loop : search all Atoms in Group to see if all assigned -- check whether shifts are all identical ShiftsDegenerate = true for ShiftId,Shift in pairs( Shifts ) do if ShiftId == 1 then ShiftOfFirst = Shift else -- not first Shift, so compare if Shift ~= ShiftOfFirst then ShiftsDegenerate = false end end -- if FirstShift in Table end -- for all Shifts in Table if i > 1 and AllShiftsAssigned and ShiftsDegenerate then -- Remove degenerate spins print( "Degenerate spins found: ") for SpinId,SpinInGroup in pairs( SpinsInGroup ) do if SpinId == 1 then print("Keeping spin: "..SpinInGroup:getLabel().." "..string.format( "%5.2f", Shifts[ SpinId ] ) ) else -- not first spin in group, so remove it print("Erase spin: "..SpinInGroup:getLabel().." "..string.format( "%5.2f", Shifts[ SpinId ] ) ) Project:unassignSpin( SpinInGroup ) Project:removeSpin( SpinInGroup ) -- I here assume that No spins are linked! Otherwise this will fail end end print( "Renaming Spin "..SpinsInGroup[ 1 ]:getLabel().." to "..Group:getName() ) Project:setLabel( SpinsInGroup[ 1 ], Group:getName() ) Result = true end return Result end -- Function GroupAssignedAndDegenerate -- Function GetGroups -------------------------------------------------------------------- function GetGroups( Atoms ) Groups = {} i = 0 for AtomLabel,Atom in pairs( Atoms ) do Group = Atom:getGroup() NewGroup = true if Group then for GroupId,GroupInGroups in pairs( Groups ) do if Group:getName() == GroupInGroups:getName() then NewGroup = false end end if NewGroup then i = i + 1 Groups[ i ] = Group end end -- if Group end -- for all Atoms in Res if i > 0 then return i,Groups else return i end end -- function GetGroups -------------------------------------------------------------- -- Function LinksExist function LinksExist( Project ) NumLinks = table.getn( Project:getSpinLinks() ) if NumLinks > 0 then return true else return false end end -- function LinksExist -------------------------------------------------------------- function SetValue( ResidueTypeName, AtomName ) Result = true ResType = cara:getResidueType( ResidueTypeName ) if ResType then Atom = ResType:getAtom(AtomName) if Atom then Atom:setMagnitude( 3 ) else MissingAtom = true print("Did not find the atom "..AtomName.." in ResidueType "..ResTypeName ) end -- if Atom exists else MissingResidueType = true print(" Did not find the ResidueType "..ResidueTypeName ) end -- if ResType exists return Result end -- function SetValue ---------------------------------------------------------------- function GetLabelOfSpin( Spin ) local Label = "No System" -- default Sys = Spin:getSystem() if Sys then Label = "Sys# "..Sys:getId() Res = Sys:getResidue() if Res then ResType = Res:getType() ResLetter = ResType:getLetter() Label = ResLetter..Res:getId() end end SpinLabel = Spin:getLabel() if SpinLabel then Label = Label.." "..SpinLabel else SpinLabel = "No spin label" end return Label end function RemoveSpin( Spin ) print("Removing spin#"..Spin:getId().." Assignment/Label: "..GetLabelOfSpin( Spin ) ) NumRemoved = NumRemoved + 1 Project:unassignSpin( Spin ) Project:removeSpin( Spin ) end function ChangeLabel( Spin, Label ) NumRelabeled = NumRelabeled + 1 SpinsAssignmentLabel = GetLabelOfSpin( Spin ) print( "Relabeling spin with assignment "..SpinsAssignmentLabel.." -> "..Label ) Project:setLabel( Spin, Label ) end function RemoveMethylGroups( System ) Residue = System:getResidue() ResType = Residue:getType() --print(ResType:getLetter()..System:getId()) Removed = false if ResType:getShort() == "ALA" then SetValue( "ALA", "HB" ) for SpinId,Spin in pairs( System:getSpins() ) do if Spin:getLabel() == "HB1" then ChangeLabel( Spin, "HB" ) end if Spin:getLabel() == "HB2" then RemoveSpin( Spin ) end if Spin:getLabel() == "HB3" then RemoveSpin( Spin ) end end end -- if ALA if ResType:getShort() == "ILE" then SetValue( "ILE", "HD1" ) SetValue( "ILE", "HG2" ) for SpinId,Spin in pairs( System:getSpins() ) do if Spin:getLabel() == "HD11" then ChangeLabel( Spin, "HD1" ) end if Spin:getLabel() == "HD12" then RemoveSpin( Spin ) end if Spin:getLabel() == "HD13" then RemoveSpin( Spin ) end if Spin:getLabel() == "HG21" then ChangeLabel( Spin, "HG2" ) end if Spin:getLabel() == "HG22" then RemoveSpin( Spin ) end if Spin:getLabel() == "HG23" then RemoveSpin( Spin ) end end end -- if ILE if ResType:getShort() == "LEU" then SetValue( "LEU", "HD1" ) SetValue( "LEU", "HD2" ) for SpinId,Spin in pairs( System:getSpins() ) do if Spin:getLabel() == "HD11" then ChangeLabel( Spin, "HD1" ) end if Spin:getLabel() == "HD12" then RemoveSpin( Spin ) end if Spin:getLabel() == "HD13" then RemoveSpin( Spin ) end if Spin:getLabel() == "HD21" then ChangeLabel( Spin, "HD2" ) end if Spin:getLabel() == "HD22" then RemoveSpin( Spin ) end if Spin:getLabel() == "HD23" then RemoveSpin( Spin ) end end end -- if LEU if ResType:getShort() == "LYS" then SetValue( "LYS", "HZ" ) for SpinId,Spin in pairs( System:getSpins() ) do if Spin:getLabel() == "HZ1" then ChangeLabel( Spin, "HZ" ) end if Spin:getLabel() == "HZ2" then RemoveSpin( Spin ) end if Spin:getLabel() == "HZ3" then RemoveSpin( Spin ) end end end -- if LYS if ResType:getShort() == "MET" then SetValue( "MET", "HE" ) for SpinId,Spin in pairs( System:getSpins() ) do if Spin:getLabel() == "HE1" then ChangeLabel( Spin, "HE" ) end if Spin:getLabel() == "HE2" then RemoveSpin( Spin ) end if Spin:getLabel() == "HE3" then RemoveSpin( Spin ) end end end -- if MET if ResType:getShort() == "VAL" then SetValue( "VAL", "HG1" ) SetValue( "VAL", "HG2" ) for SpinId,Spin in pairs( System:getSpins() ) do if Spin:getLabel() == "HG11" then ChangeLabel( Spin, "HG1" ) end if Spin:getLabel() == "HG12" then RemoveSpin( Spin ) end if Spin:getLabel() == "HG13" then RemoveSpin( Spin ) end if Spin:getLabel() == "HG21" then ChangeLabel( Spin, "HG2" ) end if Spin:getLabel() == "HG22" then RemoveSpin( Spin ) end if Spin:getLabel() == "HG23" then RemoveSpin( Spin ) end end end -- if VAL if ResType:getShort() == "THR" then SetValue( "THR", "HG2" ) for SpinId,Spin in pairs( System:getSpins() ) do if Spin:getLabel() == "HG21" then ChangeLabel( Spin, "HG2" ) end if Spin:getLabel() == "HG22" then RemoveSpin( Spin ) end if Spin:getLabel() == "HG23" then RemoveSpin( Spin ) end end end -- if THR return Removed end -- function RemoveMethylGroups -- MAIN BODY of Script ----------------------------------------------------------------- --1. Get ProjectName local ProjectNames = {} i = 0 for a,b in pairs(cara:getProjects()) do i = i + 1 ProjectNames[ i ] = b:getName() end local ProjectName = dlg.getSymbol("Select Project","", unpack( ProjectNames ) ) Project = cara:getProject( ProjectName ) --1b. Remove DegenerateSpins? RemoveDegenerateSpins = false local DialogInput_RemoveDegenerateSpins = dlg.getSymbol("Replace degenerate spins (consolidate to groups)","yes/no?", "NO","YES" ) if DialogInput_RemoveDegenerateSpins == "YES" then RemoveDegenerateSpins = true end --1c. Eliminate multiple atoms within methyl groups and replace by one atom? RemoveExtraMethylAtoms = false local DialogInput_RemoveExtraMethylAtoms = dlg.getSymbol("Remove extra methyl atoms (E.g. VAL HG11,HG12,HG13->HG1)","yes/no?", "NO","YES" ) if DialogInput_RemoveExtraMethylAtoms == "YES" then RemoveExtraMethylAtoms = true end --2. Check whether links exist (if yes, then abort) if LinksExist( Project ) then error( "\nERROR: Links found in project. \nThis script cannot remove spins when links are present\nReplaceDegenerateSpinsByPseudoAtom is finished." ) end --2. Scan sequence for Groups, -- eliminate spins with degenerate shifts, -- reassign the shift to Group (pseudoatom) local Seq = Project:getSequence() NumGroupsModified = 0 NumRemoved = 0 NumRelabeled = 0 for ResNum,Res in pairs( Seq ) do local System = Res:getSystem() local Type = Res:getType() local Atoms = Type:getAtoms() if System then if RemoveExtraMethylAtoms then RemoveMethylGroups( System ) end if RemoveDegenerateSpins then NumGroups,Groups = GetGroups( Atoms ) if NumGroups > 0 then for GroupId,Group in pairs ( Groups ) do if GroupAssignedAndDegenerate( Group, System, Project ) then -- remove the degenerate spins and assign the first spin to group (pseudoatom) print( "Degenerate spins removed for "..Type:getShort().." "..ResNum.." ".."Group:"..Group:getName() ) print( "--------------------------------------------------------------------" ) NumGroupsModified = NumGroupsModified + 1 end end -- for all Groups end --if Groups exist end -- if RemoveDegenerateSpins end -- if System exists end -- for all Residues --3. Summarize Results: ----------------------------------------------------------------------------- print( " SUMMARY: consolidated a total of "..NumGroupsModified.." Groups." ) print( " Total number of spins removed (degenerate methyl atoms) "..NumRemoved ) print( " Total number of spins relabeled (degenerate methyl atoms) "..NumRelabeled ) print( "ReplaceDegenerateSpinsByPseudoAtom version "..Version.." is finished")