Icon representing a recipe

Recipe: Sheet Straightener v0.2 - Brow42

created by brow42

Profile


Name
Sheet Straightener v0.2 - Brow42
ID
37067
Shared with
Public
Parent
None
Children
None
Created on
January 05, 2012 at 03:14 AM UTC
Updated on
January 05, 2012 at 03:14 AM UTC
Description

Straighten sheets by pushing ends apart. Lua 2 + dialog

Best for


Code


--[[ * Sheet Straightener * Original author: Brow42 * Version 0.2 2012/1/4 Brow 42 * Lua v2 * Dialog box for the options * Can now use selection interface to set ranges * Version 0.1 2011/12/2 Brow42 * Pushes end of sheets (or loops, or specified ranges) apart. * Pushing continues until user manually stops the wiggle or cancels the recipe. * Original banding is preserved and restored on normal exit. * Version 0.1 defaults are very aggressive. * Feel free to freeze sections you don't want straightened. * To properly straighten loops, either change their SS, set a range, or freeze, cancel, and remove bands from loops that must be unfrozen but not straightened. --]] -- =================== Begin Options ================ -- Set to false to disable the options dialog and go straight to straightening! ShowOptions = true -- 3.2 to 3.4 plus a little extra for tension, de novo is 3.55-3.58 -- Pick smaller for less destructive, but may cause contraction NominalAADistance = 3.6 -- 0.1 to 10 depending on how much you really mean it BandStrength = 3.0 -- Add start/stop indices of where you want to straighten, or leave commented out --[[ regions= { {3,10},{27,20} } --]] AutoSelectType='E' -- E, H, or L if you didn't specify specific regions -- Doesn't work with H, too much twist -- Set to true if you prefer to use the selection interface UseSelection = false -- Method Priority: Ranges > Selection > Structure -- True to disable pre-existing bands, false to leave them in their current state DisableBands=false nWiggle = 10 _debuglevel = 0 -- ================= End Options ==================== -- globals version = 0.2 title = 'Sheet Straightener v '..tostring(version) regions = regions or {} -- make sure regions is a table nSeg = structure.GetCount() function debugmsg(str,lvl) if (lvl or 1) <= _debuglevel then print(str) end end -- Parse a string into regions function Parse(str) debugmsg('Entering Parse') ranges = {} local _start, _end, i, j local pat1 = '%s*%d+' local pat2 = '%s*,' while true do i,j = string.find(str,pat1) if i == nil then break end _start = string.sub(str,i,j) str = string.sub(str,j+1) i,j = string.find(str,pat2) if i == nil then break end str = string.sub(str,j+1) i,j = string.find(str,pat1) if i == nil then break end _end = string.sub(str,i,j) _start = tonumber(_start) _end = tonumber(_end) if _start == nil or _end == nil then break end table.insert(ranges,{_start,_end}) end debugmsg('Found '..tostring(#ranges)..' ranges.') return ranges end -- Error dialog function ErrorDialog(msg,button) d = dialog.CreateDialog(title) d.error = dialog.AddLabel(msg) d.button = dialog.AddButton(button,0) dialog.Show(d) end -- Options dialog -- Return 1 okay, 0 cancel, -1 error function Options() debugmsg('Entering Options()') local d = dialog.CreateDialog(title) local regions_set = #regions > 0 local default_regions = '' for iReg = 1,#regions do if iReg > 1 then default_regions = default_regions..' ' end default_regions = default_regions..regions[iReg][1]..','..regions[iReg][2] end d.label = dialog.AddLabel('Selection Method:') d.sheet = dialog.AddCheckbox('Sheets',AutoSelectType=='E' and not regions_set and not UseSelection) d.helix = dialog.AddCheckbox('Helices',AutoSelectType=='H' and not regions_set and not UseSelection) d.loop = dialog.AddCheckbox('Loops',AutoSelectType=='L' and not regions_set and not UseSelection) d.selected = dialog.AddCheckbox('Selected in Selelection Interface',UseSelection and not regions_set) d.specified = dialog.AddCheckbox('Specified below start,stop <space> ',regions_set) d.ranges = dialog.AddTextbox('Ranges:',default_regions) d.label4 = dialog.AddLabel('Set as to how straight you REALLY want it:') d.label5 = dialog.AddLabel('(Large values may hurt backbone)') d.band = dialog.AddSlider('Band Strength:',BandStrength,0.1,10.0,1) d.label2 = dialog.AddLabel('Typical is 3.2 to 3.4, de novo is 3.55 to 3.58') d.label3 = dialog.AddLabel('Pick smaller for less destructive, but may actually bend the sheet!') d.dist = dialog.AddSlider('AA Distance:',NominalAADistance,2.3,4.0,2) d.disable = dialog.AddCheckbox('Disable Bands:',DisableBands) d.button = dialog.AddButton('Start!',1) d.quit = dialog.AddButton('Wait, no.',0) local rc = dialog.Show(d) if rc == 0 then return 0 end local nSelected = 0 regions={} UseSelection=false SelectionFunction = IsMatchingStructure -- parse and error check options if d.sheet.value then SelectionFunction = IsMatchingStructure AutoSelectType = 'E' nSelected = nSelected+1 end if d.helix.value then SelectionFunction = IsMatchingStructure AutoSelectType = 'H' nSelected = nSelected+1 end if d.loop.value then SelectionFunction = IsMatchingStructure AutoSelectType = 'L' nSelected = nSelected+1 end if d.selected.value then SelectionFunction = IsSelected UseSelection = true nSelected = nSelected+1 end if d.specified.value then regions = Parse(d.ranges.value) nSelected = nSelected+1 if #regions == 0 then ErrorDialog('Your range list was empty or not parsable.','Oops!') return -1 end end NominalAADistance = d.dist.value BandStrength = d.band.value DisableBands = d.disable.value if nSelected ~= 1 then ErrorDialog('Pick exactly one method, please!','Oops!') return -1 end return 1 end -- A selection function, true for all AAs that are the same as AutoSelectType function IsMatchingStructure(iSeg) debugmsg('IsMatchingStructure: '..tostring(iSeg)..structure.GetSecondaryStructure(iSeg)..AutoSelectType,2) return structure.GetSecondaryStructure(iSeg) == AutoSelectType end -- A selection function, true for all selected AAs function IsSelected(iSeg) debugmsg('IsSelected: '..tostring(iSeg)..tostring(selection.IsSelected(iSeg)),2) return selection.IsSelected(iSeg) end -- Find sequences satisfying the selection function function IdentifyRanges(func) debugmsg('Entering IdentifyRanges()') local isActive= false for iSeg=1,nSeg do if func(iSeg) and not isActive then isActive=true iStart = iSeg end if isActive and not(func(iSeg)) then isActive=false table.insert(regions,{iStart,iSeg-1}) end end if isActive then table.insert(regions,{iStart,nSeg}) end debugmsg('Regions found: '..tostring(#regions)) end -- Identify Ranges function math.round(x,n) n = math.max(n or 0, 0) return math.floor(x * 10^n+0.5)/10^n end -- =============== Begin Main Program =================== if ShowOptions then repeat local rc = Options() if rc == 0 then return end until rc == 1 end -- Disable existing bands nBandOrig = band.GetCount() if DisableBands then band.DisableAll() end if #regions == 0 then SelectionFunction = SelectionFunction or IsMatchingStructure IdentifyRanges(SelectionFunction) end -- Create bands between sheet ends debugmsg('Creating Bands') iBand = nBandOrig for iReg=1,#regions do s1,s2 = regions[iReg][1], regions[iReg][2] debugmsg(tostring(iReg)..' '..tostring(s1)..' '..tostring(s2)) if (s1 > s2) then s1,s2 = s2,s1 end -- Check on user input if s1 < 1 then s1 = 1 end if s2 > nSeg then s2 = nSeg end if (s2 - s1 > 1) then -- Cannot band to self or adjacent AA d = structure.GetDistance(s1,s2) print('Region #',iBand-nBandOrig+1,' ',s1,' - ',s2, ': ',math.round(d/(s2-s1),2)) d = NominalAADistance * (s2-s1) local old = iBand iBand = band.AddBetweenSegments(s1,s2) if iBand > old then -- make sure band got added band.SetGoalLength(iBand,d) band.SetStrength(iBand,BandStrength) end end end if iBand == nBandOrig then print('No regions meeting your criteria were found.') else print() print('Pushing apart to distance of ',NominalAADistance) print('Hit Stop at any time (or Cancel to retain bands).') print('Wiggling for',nWiggle,'iterations...') structure.WiggleAll(nWiggle,true,true) print('Stopped.') end -- Remove my bands debugmsg('Removing Bands.') nBand = band.GetCount() for iBand = nBand,1+nBandOrig,-1 do band.Delete(iBand) end

Comments


brow42 Lv 1

This is a Lua 2 version of https://fold.it/portal/recipe/35990.

–[[

  • Sheet Straightener
  • Original author: Brow42

  • Version 0.2 2012/1/4 Brow 42

  • Lua v2
  • Dialog box for the options
  • Can now use selection interface to set ranges

  • Version 0.1 2011/12/2 Brow42

  • Pushes end of sheets (or loops, or specified ranges) apart.
  • Pushing continues until user manually stops the wiggle or
    cancels the recipe.
  • Original banding is preserved and restored on normal exit.
  • Version 0.1 defaults are very aggressive.
  • Feel free to freeze sections you don't want straightened.
  • To properly straighten loops, either change their SS,
    set a range, or freeze, cancel, and remove bands from
    loops that must be unfrozen but not straightened.

–]]
– =================== Begin Options ================
– Set to false to disable the options dialog and go straight to straightening!
ShowOptions = true

– 3.2 to 3.4 plus a little extra for tension, de novo is 3.55-3.58
– Pick smaller for less destructive, but may cause contraction
NominalAADistance = 3.6

– 0.1 to 10 depending on how much you really mean it
BandStrength = 3.0

– Add start/stop indices of where you want to straighten, or leave commented out
—[[
regions= {
{3,10},{27,20}
}
–]]

AutoSelectType='E' – E, H, or L if you didn't specify specific regions
– Doesn't work with H, too much twist

– Set to true if you prefer to use the selection interface
UseSelection = false

– Method Priority: Ranges > Selection > Structure

– True to disable pre-existing bands, false to leave them in their current state
DisableBands=false

nWiggle = 10
_debuglevel = 0
– ================= End Options ====================

srlowry22 Lv 1

Puzzled by tweak. (tutorial 4-3) Any details on how to operate the straight arrows? I would have imagined sliding a pleat along 1 amino acid, then twisting 180. Not what seems to happen. What am I missing?

Thanks in advance-