Icon representing a recipe

Recipe: Contact Cement 3.0

created by Bruno Kestemont

Profile


Name
Contact Cement 3.0
ID
49544
Shared with
Public
Parent
None
Children
None
Created on
September 15, 2015 at 17:37 PM UTC
Updated on
September 15, 2015 at 17:37 PM UTC
Description

LoiciOiling Checks for contacts with non-zero heat. Displays fun facts about any such contacts found. Bands any contacts above a user-specifed heat cutoff. Band strength weithed by heat.

Best for


Code


--[[ Contact Cement Original Author: LociOiling Version 1.0 May 5, 2014 This recipe checks the contact heat for each pair of segments. The recipe reports the number of contacts with non-zero heat, and displays the minimum, maximum, mean, and median contact heat. The recipe can band contacts with a heat value at or above a specified minimum. The minimum is initially set to the mean heat. The bands are created with default strength and length. Version 2.0 by Bruno Kestemont 04/06/2014 (ideas = lincher) Added weighting of band strength relative to heat, and zone, as suggested by lincher Versions 2.01 07/06/2014, 2.02 20/06/2014 debugged Band strength = 0 at cut off heat or fc of heat Option to select the number of (best) bands. Ver 2.1 deleted band2keep option ]]-- -- -- globals section -- Recipe = "Contact Cement" Version = "3.0" ReVersion = Recipe .. " v" .. Version bndcut = 0 heatmap = {} tHeat = 0 minHeat = 0.5 maxHeat = 0.9 meanHeat = 0.7 mediHeat = 0.7 strengthFactor=1.5 -- new 04/06/2014 -- from 0.5 to 10 RELATIVE=true -- bands strength is fc of distance between threshold and max heat (false: simple fc. of heat from 0 to max) segCnt = structure.GetCount() segCnt2 = segCnt while structure.GetSecondaryStructure ( segCnt2 ) == "M" do segCnt2 = segCnt2 - 1 end segStart=1 segEnd=segCnt2 -- -- end of globals section -- function r4 ( i ) return i - i % 0.0001 end function SortByHeat ( tab ) local ii local jj for ii = 1, #tab - 1 do for jj = ii + 1, #tab do local h1 = tab [ ii ] [ 3 ] local h2 = tab [ jj ] [ 3 ] if h2 > h1 then tab [ ii ], tab [ jj ] = tab [ jj ], tab [ ii ] end end end return tab end function GetOnlyContacts() tHeat=0 heatmap = {} local ii local jj for ii = segStart, segEnd - 1 do -- 04/06/2004 for jj = ii + 1, segEnd do -- 04/06/2004 if ( ii ~= jj ) then local heat = contactmap.GetHeat ( ii, jj ) if ( heat > 0 ) then local heatpnt = { ii, jj, heat } heatmap [ #heatmap + 1 ] = heatpnt tHeat = tHeat + heat end end end end end function GetContacts( ) local ii local jj if ( #heatmap > 0 ) then if( #heatmap > 100 ) then -- no sorting to save time -- EXPERIMENTAL print("Too many contacts. Please be restrictive in options") end print("Sorting, please wait ...") SortByHeat ( heatmap ) -- 06/07/2014 if (#heatmap < 20 or ii==1 or ii== #heatmap) then print ( "seg1,seg2,heat" ) end minHeat = 9999999 maxHeat = 0 for ii = 1, #heatmap do if (#heatmap < 20 or ii==1 or ii== #heatmap) then print ( heatmap [ ii ] [ 1 ] .. "," .. heatmap [ ii ] [ 2 ] .. "," .. heatmap [ ii ] [ 3 ] ) end if heatmap [ ii ] [ 3 ] > maxHeat then maxHeat = heatmap [ ii ] [ 3 ] end if heatmap [ ii ] [ 3 ] < minHeat then minHeat = heatmap [ ii ] [ 3 ] end end print ( "minimum contact heat = " .. r4 ( minHeat ) ) print ( "maximum contact heat = " .. r4 ( maxHeat ) ) meanHeat = tHeat / #heatmap print ( "mean contact heat = " .. r4 ( meanHeat ) ) ii = math.floor ( #heatmap / 2 ) if #heatmap % 2 == 0 or ii==0 then -- even number of entries ii = ii + 1 mediHeat = ( mediHeat + heatmap [ ii ] [ 3 ] )/2 -- corrected BK 04/06/2014 else mediHeat = heatmap [ ii ] [ 3 ] end print ( "median contact heat = " .. r4 ( mediHeat ) ) end end function BandContacts () local ii local bndCnt = 0 local bandstrength=1-- new 04/06/2014 strength fc of heat local heatrange=maxHeat-bndcut-- new 04/06/2014 strength fc of heat if heatrange == 0 then heatrange=maxHeat end -- fixed bug 07/06/2014 local bandnum=0 for ii = 1, #heatmap do --print("DEBUG heat "..ii.." = "..heatmap [ ii ] [ 3 ]) if heatmap [ ii ] [ 3 ] >= bndcut then if RELATIVE then bandstrength= ((heatmap [ ii ] [ 3 ]-bndcut)/heatrange)*strengthFactor or strengthFactor-- new 04/06/2014 strength fc of heat (or 1) --NB: strength is fc. of relative heat from threshold to max (not absolute) else bandstrength= ((heatmap [ ii ] [ 3 ])/maxHeat)*strengthFactor or strengthFactor-- new 04/06/2014 strength fc of heat (or 1) --NB: strength is fc. of absolute heat end bandnum=band.AddBetweenSegments ( heatmap [ ii ] [ 1 ], heatmap [ ii ] [ 2 ] ) --print("band n "..bandnum.." / "..#heatmap) if bandnum > 0 then -- else bug some bands are not created band.SetStrength(bandnum,bandstrength) -- new 04/06/2014 strength fc of heat end bndCnt = bndCnt + 1 else break end end print ( "contact heat cutoff = " .. bndcut ) print ( bndCnt .. " contacts banded" ) end function GetParams() local dlg = dialog.CreateDialog( ReVersion ) if #heatmap == 0 then dlg.l0 = dialog.AddLabel ( "No contacts found." ) dlg.l1 = dialog.AddLabel ( "This recipe is for puzzles with a contact map." ) dlg.cancel = dialog.AddButton ( "Cancel", 0 ) dialog.Show ( dlg ) return false else dlg.l0 = dialog.AddLabel ( #heatmap .. " contacts with non-zero heat found" ) dlg.l1 = dialog.AddLabel ( "minimum contact heat = " .. r4 ( minHeat ) ) dlg.l2 = dialog.AddLabel ( "maximum contact heat = " .. r4 ( maxHeat ) ) dlg.l3 = dialog.AddLabel ( "mean contact heat = " .. r4 ( meanHeat ) ) dlg.l4 = dialog.AddLabel ( "median contact heat = " .. r4 ( mediHeat ) ) if not meanHeat==maxHeat then dlg.l5 = dialog.AddLabel ( "Select minimum heat to band" )-- 07/06/2014 (otherways bug) dlg.bndpct = dialog.AddSlider ( "Heat cutoff" , meanHeat, minHeat, maxHeat, 3 ) dlg.RELATIVE = dialog.AddCheckbox("cutoff band strength = 0", RELATIVE) dlg.l6 = dialog.AddLabel ( "unchecked: cutoff band strength fc of heat") end dlg.strengthFactor = dialog.AddSlider ( "Max band strength" , strengthFactor, 0.5, 10, 2 ) -- 04/06/2014 dlg.ok = dialog.AddButton ( "OK", 1 ) dlg.cancel = dialog.AddButton ( "Cancel", 0 ) if dialog.Show ( dlg ) > 0 then if not meanHeat==maxHeat then bndcut = dlg.bndpct.value RELATIVE=dlg.RELATIVE.value -- 07/06/2014 end strengthFactor = dlg.strengthFactor.value return true else print( "dialog cancelled" ) end end return false end function GetParamsSmall() local dlg = dialog.CreateDialog( ReVersion ) if #heatmap == 0 then dlg.l0 = dialog.AddLabel ( "No contacts found." ) dlg.l1 = dialog.AddLabel ( "This recipe is for puzzles with a contact map." ) dlg.cancel = dialog.AddButton ( "Cancel", 0 ) dialog.Show ( dlg ) return false else dlg.l0 = dialog.AddLabel ( #heatmap .. " contacts with non-zero heat found" ) if( #heatmap > 100 ) then -- no sorting to save time -- EXPERIMENTAL dlg.l01 = dialog.AddLabel ("It'll take a lot of time. Consider selecting smaller zone:") print("Too many contacts. Please be restrictive in options") end dlg.segStart=dialog.AddTextbox("From seg ", segStart) -- 04/06/2014 dlg.segEnd=dialog.AddTextbox("To seg ", segEnd) -- 04/06/2014 dlg.ok = dialog.AddButton ( "OK", 1 ) dlg.cancel = dialog.AddButton ( "Cancel", 0 ) if dialog.Show ( dlg ) > 0 then --bndcut = dlg.bndpct.value --strengthFactor = dlg.strengthFactor.value segStart = dlg.segStart.value segEnd = dlg.segEnd.value return true else print( "dialog cancelled" ) end end return false end function cleanup ( error ) print ( error ) end function main() print ( ReVersion ) GetOnlyContacts() print ( #heatmap .. " contacts with non-zero heat found" ) if GetParamsSmall() then GetOnlyContacts() -- reset of (smaler) contact map print("Contacts selected = "..#heatmap) --06/07/2014 end GetContacts () if GetParams() then BandContacts () end end xpcall ( main, cleanup )

Comments


Bruno Kestemont Lv 1

Run several time on different zones in order to set different band strengths to different zones.
This way, you can, for example, band structures pairs one by one.

Then when you are done, use any recipe or hand work you want; Fuze works good.

Note: when all heats are equal, related options are hided.