Code
-- bandD2.lua
recipeName = "bandD2 v0.04" -- https://fold.it/portal/recipe/104918
function patchD2(iBand, doEnd2, strFactor)
if not band.IsEnabled(iBand) then -- already Disabled: no action needed
return
end
local iEnd = band.GetResidueEnd(iBand)
if iEnd==0 then -- Band in Space: no action needed
return
end
local iChain = math.floor(iEnd / (nSegments+1))
iEnd = iEnd % (nSegments+1)
if iChain==0 or iChain==2 then -- no action needed for chains 0 and 2
return
end
-- we have a band to either chain 1 or chain 3: replace it!
local iAtomEnd = band.GetAtomEnd(iBand)
local iBase = band.GetResidueBase(iBand)
local iAtomBase = band.GetAtomBase(iBand)
local strength = band.GetStrength(iBand) * strFactor
local actualL = band.GetLength(iBand) / 2
local goalLen = band.GetGoalLength(iBand) / 2
band.Disable(iBand) -- do not Remove, so we can use it for alignment
addBiS(iBase, iAtomBase, actualL, goalLen, strength)
if doEnd2 then
addBiS(iEnd, iAtomEnd, actualL, goalLen, strength)
end
end
function addBiS(iSegm, iAtom, actualL, goalLen, strength)
-- Add a Band in Space attached to iAtom, pointing away (?) from this residue
local iXaxis = iSegm - 1 -- use preceding residue for the x axis
local iYaxis = iSegm + 1 -- and next one for the y axis, except:
if iSegm==1 then
iXaxis = iSegm + 2 -- first segment: use another x axis
elseif iSegm==nSegments then
iYaxis = iSegm - 2 -- last segment: use another y axis
end
local iNewBand = band.Add(iSegm, iXaxis, iYaxis, actualL,
math.pi/2, math.pi, iAtom
)
if iNewBand>0 then
band.SetStrength(iNewBand, strength)
band.SetGoalLength(iNewBand, goalLen)
end
return iNewBand
end
function mkDialog(text, btns) -- make a Dialog; parameters are optional
local newDialog = dialog.CreateDialog(recipeName)
if text then -- "line" or { "ln1" [ , "ln2" ... ] }
if type(text)~="table" then
text = { text }
end
for iTxt, txt in ipairs(text) do
newDialog["line"..iTxt] = dialog.AddLabel(txt)
end
end
if btns then -- "btn" or {"btn1" [ , "btn2" ... ] }
if type(btns)~="table" then
btns = { btns }
end
for iBtn, txtBtn in ipairs(btns) do
newDialog["btn"..iBtn] = dialog.AddButton(txtBtn, iBtn)
end
end
return newDialog
end
--------------------------------------------------------------------------------
local action = dialog.Show(mkDialog(
{ "",
"This script is a workaroud for a bug with bands",
"in a D2 symmetry puzzle (June 2021).",
"",
"In case a band is found from Chain 0 to",
"either Chain 1 or Chain 3, it will be disabled and",
"replaced by one or two Bands in Space, starting",
"at the corresponding end points on Chain 0,",
"with half of the original goal length.",
"",
"You can choose to create a Band in Space",
"only at the start of the original band, or",
"also for the endpoint (but on Chain 0, of course).",
"When you choose 1 side only, the strength will be",
"twice the original, unless you choose \"1, single\".",
"",
"You will have to adjust the end points",
"of each of these new Bands in Space BY HAND.",
"Apologies for this inconvenience.",
""
},
{ "Cancel", "Both sides", "1 side only", "1, single" }
) )
if action>=2 then
nSegments = structure.GetCount()
nBands = band.GetCount()
local doEndToo = action==2
local strFactor = 1
if action==3 then
strFactor = 2
end
for iBand = nBands, 1, -1 do -- backwards, so we /can/ remove bands!
patchD2(iBand, doEndToo, strFactor)
end
end