Icon representing a recipe

Recipe: HNetwork Probe 2.0

created by spvincent

Profile


Name
HNetwork Probe 2.0
ID
103779
Shared with
Public
Parent
None
Children
Created on
August 06, 2020 at 14:46 PM UTC
Updated on
August 06, 2020 at 14:46 PM UTC
Description

See first comment

Best for


Code


polar_aas = "stnqdehyw" n_polar_aas = 0 n_residues = 0 first_qs_slot = 13 last_qs_slot = 35 next_qs_slot = 0 start_slot = 1 select_unfrozen = true sidechain_minimum = -70 n_it = 0 mutate_list_ui = {} -- will be a list of 1's & 0's for each residue. 1 means can mutate. 0 means don't mutate. mutable_list = {} filter_list = {} init_filter_score = 0 function r3 ( x ) -- Round to 3 decimal places t = 10 ^ 3 return math.floor ( x*t + 0.5 ) / t end function GetFilterScore () filter_bonus = filter.GetBonus ( "Hydrogen Bond Network" ) return filter_bonus end function GetListOfMutablesUnfrozen () for i = 1 , n_residues do seg_backbone_frozen, seg_sidechain_frozen = freeze.IsFrozen ( i ) if ( ( seg_sidechain_frozen == false ) and -- ( seg_backbone_frozen == false ) and ( structure.IsMutable ( i ) == true ) ) then table.insert ( mutable_list , i ) end end end function GetListOfMutablesSelected () for i = 1 , n_residues do seg_backbone_frozen, seg_sidechain_frozen = freeze.IsFrozen ( i ) if ( ( seg_sidechain_frozen == false ) and ( mutate_list_ui [ i ] == 1 ) and ( structure.IsMutable ( i ) == true ) ) then table.insert ( mutable_list , i ) end end end -- getlist pinched from Loop Rebuild 9.0 -- http://www.lua.org/manual/5.2/manual.html#6.4 -- helped make this function 11/16/17 function getlist(liststr) local newlist={} local i,ilo,ihi,idir,substr for i=1,n_residues do newlist[i]=0 end -- for i -- below reads from liststr a series of substr's -- where each substr contains an integer -- followed by one or more '-' signs -- followed by an integer for substr in string.gmatch(liststr,"(%d+%-+%d+)") do -- substr includes one or more '-' characters in a row -- below gets ilo & ihi from substr ilo=string.gsub(substr,"(%d+)%-+(%d+)","%1")+0 ihi=string.gsub(substr,"(%d+)%-+(%d+)","%2")+0 -- above gets ilo & ihi from substr idir=1 -- the increment to use from ilo to ihi if ilo>ihi then idir= -1 end -- if ilo for i=ilo,ihi,idir do -- for i=ilo to ihi step idir if i>=1 and i<=n_residues then newlist[i]=1 end -- if i end -- for i end -- for substr -- below reads from liststr a series of substr's -- where each substr contains an integer for substr in string.gmatch(liststr,"(%d+)") do i=substr+0 -- converts substr into the number i if i>=1 and i<=n_residues then newlist[i]=1 end -- if i end -- for substr return newlist end function Init () save.Quickload ( start_slot ) for i = 1 , #mutable_list do k = math.random ( n_polar_aas ) structure.SetAminoAcid ( mutable_list [ i ] , string.sub ( polar_aas , k , k ) ) end selection.SelectAll () structure.WiggleSelected ( 2 , false , true ) -- sidechains end function PrintParameters () print ( "HNetworkProbe 2.0" ) print ( " n mutables " .. #mutable_list ) print ( "Amino acids to use : " .. polar_aas ) print ( "Sidechain minimum " .. r3 ( sidechain_minimum ) ) print ( "Using slots " .. first_qs_slot .. " to " .. last_qs_slot ) end function GetParameters () local dlog = dialog.CreateDialog ( "HNetworkProbe 2.0" ) dlog.use_unfrozen = dialog.AddCheckbox ( "Select unfrozen" , select_unfrozen ) dlog.mutate_list = dialog.AddTextbox ( "Mutate segments" , "" ) dlog.mlabela = dialog.AddLabel('List segs to mutate like 1-3,6,19-30,45-62') dlog.aa_list = dialog.AddTextbox ( "Amino acids" , polar_aas ) dlog.sidechain_minimum = dialog.AddSlider ( "Side chain minimum" , sidechain_minimum , -200 , -20 , 0 ) dlog.start_qs_slot = dialog.AddSlider( "Start quick save" , first_qs_slot , 1 , 99 , 0 ) dlog.end_qs_slot = dialog.AddSlider ( "End quick save" , last_qs_slot ,1 , 99 , 0 ) dlog.ok = dialog.AddButton ( "OK" , 1 ) dlog.cancel = dialog.AddButton ( "Cancel" , 0 ) if ( dialog.Show ( dlog ) > 0 ) then select_unfrozen = dlog.use_unfrozen.value mutate_list_ui = getlist(dlog.mutate_list.value) polar_aas = dlog.aa_list.value sidechain_minimum = dlog.sidechain_minimum.value first_qs_slot = dlog.start_qs_slot.value last_qs_slot = dlog.end_qs_slot.value return true else return false end end function main () n_residues = structure.GetCount () save.Quicksave ( start_slot ) if ( GetParameters () == false ) then return -- graceful exit end n_polar_aas = string.len ( polar_aas ) if ( select_unfrozen == true ) then GetListOfMutablesUnfrozen () else GetListOfMutablesSelected () end PrintParameters () if ( #mutable_list == 0 ) then print ( "No mutable residues found" ) exit (0) end if ( first_qs_slot > last_qs_slot ) then print ( "Invalid quicksave slot values" ) return end filter_list = filter.GetNames () print ( "Filters" ) print ( "" ) for i = 1 , #filter_list do if ( filter_list [ i ] == "Hydrogen Bond Network" ) then filter.Enable ( filter_list [ i ] ) print ( "Enabling " .. filter_list [ i ] ) else filter.Disable ( filter_list [ i ] ) print ( "Disabling " .. filter_list [ i ] ) end end band.DisableAll () undo.SetUndo ( false ) init_filter_score = GetFilterScore () print ( "Init HNet score " .. r3 ( init_filter_score ) ) math.randomseed ( os.time () ) next_qs_slot = first_qs_slot Init () while ( next_qs_slot <= last_qs_slot ) do n_it = n_it + 1 i = math.random ( #mutable_list ) nn = 0 valid_replacement_found = false -- a bit untidy this code repeat nn = nn + 1 k = math.random ( n_polar_aas ) replacement_aa = string.sub ( polar_aas , k , k ) if ( structure.CanMutate ( mutable_list [ i ] , replacement_aa ) == true ) then structure.SetAminoAcid ( mutable_list [ i ] , replacement_aa ) sidechain_score = current.GetSegmentEnergySubscore ( mutable_list [ i ] , "Sidechain" ) --print ( "nn " .. nn .. " " .. mutable_list [ i ] .. " " .. replacement_aa .. " " .. r3 ( sidechain_score ) ) if ( sidechain_score > sidechain_minimum ) then valid_replacement_found = true end end until ( ( nn > 5 ) or ( valid_replacement_found == true ) ) selection.SelectAll () --structure.ShakeSidechainsSelected ( 1 ) structure.WiggleSelected ( 2 , false , true ) -- sidechains filter_score = GetFilterScore () if ( filter_score > init_filter_score ) then print ( "Found network ( gain " .. r3 ( filter_score - init_filter_score ) .. " ) storing in qs " .. next_qs_slot ) save.Quicksave ( next_qs_slot ) next_qs_slot = next_qs_slot + 1 Init () end end cleanup () end function cleanup () print ( "Cleaning up" ) print ( "n_it " .. n_it ) undo.SetUndo ( true ) if ( next_qs_slot > first_qs_slot ) then print ( "Loading quick saves " .. first_qs_slot .. " to " .. next_qs_slot - 1 ) for i = first_qs_slot , next_qs_slot - 1 do save.Quickload ( i ) end end band.EnableAll () end --main () xpcall ( main , cleanup )

Comments


LociOiling Lv 1

Here are a few things I've found out about how HNetwork Probe works.

The recipe has two ways to specify which segments to mutate:

  1. If "select unfrozen" is checked, only segments with unfrozen sidechains are mutated.
  2. Otherwise, the "mutate segments" box can be used to specify numeric ranges of segments, such as "1-3,6,19-30,45-62". The recipe will try to mutate the segments in these ranges, as long as they are mutable and have unfrozen sidechains. </ol> You must use one or the other of these methods. The "amino acids" box lists the amino acids the recipe will try when mutating. The recipe disables all filters except "Hydrogen Bond Network". (Call it HBN for short.) The recipe mainly checks the HBN score, and not the overall score. The recipe initially mutates each specified segment to a random amino acid from the list specified in the dialog. The recipe then does a minimal wiggle sidechains. This is the start of a "run". The recipe then picks one mutable from the ones specified, and tries up to five further mutations on it. The recipe does a minimal wiggle sidechains after each mutation. If the HBN score improves, the new pose is saved in a quick save slot, and a message is printed. Otherwise, the recipe just keeps going, again making random mutations to each specified segment, starting another "run". Each run includes the random mutate of all the specified segments, plus a new random pick of the segment to focus on for five more mutations. The recipe is quiet unless there's a gain, so the output window may not change for a long time. The recipe only does wiggle sidechains, there's no shake sidechains or wiggle backbone. The recipe stops when the specified range of quick save slots it exhausted. In many cases, this means the recipe runs until you cancel it. The recipe turns off undo processing at the start. At the end, it turns undo processing back on, and then loads each quick save slot it used, in sequence. In theory, this means you should see the best hydrogen bond network score when the recipe terminates. Undo or control-z gets you the next best HBN score, and so on. The recipe is focused on the best hydrogen bond network score. If there's a gain, you should see the pose with the best HBN score at the end. If there's no gain, the protein will just be left where it was when you cancelled the recipe. You'll need to restore credit best or load a previous save. The recipe does not re-enable any conditions at the end, so the final score will almost certainly be invalid, unless you're working on a test puzzle which includes only an HBN condition.