Icon representing a recipe

Recipe: Contact Cement 2.02

created by Bruno Kestemont

Profile


Name
Contact Cement 2.02
ID
49437
Shared with
Public
Parent
None
Children
Created on
June 20, 2014 at 05:51 AM UTC
Updated on
June 20, 2014 at 05:51 AM UTC
Description

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. ]]-- -- -- globals section -- Recipe = "Contact Cement" Version = "2.02" 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 bndNb2keep=0 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 GetOnlyContacts() print ( #heatmap .. " contacts with non-zero heat found" ) if ( #heatmap > 0 ) then if( #heatmap > 100 ) then -- no sorting to save time -- EXPERIMENTAL print("Too many contacts. Please be restrictive in options") if GetParamsSmall() then GetOnlyContacts() -- reset of (smaler) contact map end else print("Sorting, please wait ...") SortByHeat ( heatmap ) end 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 ) mediHeat = heatmap [ ii ] [ 3 ] if #heatmap % 2 == 0 then -- even number of entries ii = ii + 1 mediHeat = ( mediHeat + heatmap [ ii ] [ 3 ] )/2 -- corrected BK 04/06/2014 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, bndNb2keep do -- 07/06/2014 takes the x best bands 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 if bndNb2keep==0 then if #heatmap >bndNb2keep then bndNb2keep= #heatmap end if #heatmap >100 then bndNb2keep= 100 end end dlg.bndNb2keep=dialog.AddSlider ( "Band best:" , bndNb2keep, 1, #heatmap, 0 ) -- 07/06/2014 dlg.strengthFactor = dialog.AddSlider ( "Max band strength" , strengthFactor, 0.5, 10, 2 ) -- 04/06/2014 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 if not meanHeat==maxHeat then bndcut = dlg.bndpct.value bndNb2keep = dlg.bndNb2keep.value -- 07/06/2014 RELATIVE=dlg.RELATIVE.value -- 07/06/2014 end strengthFactor = dlg.strengthFactor.value segStart = dlg.segStart.value segEnd = dlg.segEnd.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" ) --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 ) ) --dlg.l5 = dialog.AddLabel ( "Select minimum heat to band" ) --dlg.bndpct = dialog.AddSlider ( "Heat cutoff" , meanHeat, minHeat, maxHeat, 3 ) --dlg.strengthFactor = dialog.AddSlider ( "Max band strength" , strengthFactor, 0.5, 10, 2 ) -- 04/06/2014 if #heatmap >bndNb2keep then bndNb2keep= #heatmap end if #heatmap >100 then bndNb2keep= 100 end dlg.bndNb2keep=dialog.AddSlider ( "Band best:" , bndNb2keep, 1, #heatmap, 0 ) -- 07/06/2014 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 bndNb2keep = dlg.bndNb2keep.value -- 07/06/2014 return true else print( "dialog cancelled" ) end end return false end function cleanup ( error ) print ( error ) end function main() print ( ReVersion ) GetContacts () if GetParams() then BandContacts () end end xpcall ( main, cleanup )

Comments