Icon representing a recipe

Recipe: Contact Cement 1.01

created by LociOiling

Profile


Name
Contact Cement 1.01
ID
49061
Shared with
Public
Parent
None
Children
Created on
July 17, 2014 at 19:23 PM UTC
Updated on
July 17, 2014 at 19:23 PM 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. Version 1.01 includes fixes Bruno Kestemont made in version 2.02

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 1.01 July 13, 2014 * fix issues found by Bruno Kestemont in version 2 ]]-- -- -- globals section -- Recipe = "Contact Cement" Version = "1.01" ReVersion = Recipe .. " v" .. Version bndcut = 1 heatmap = {} tHeat = 0 minHeat = 0 maxHeat = 0 meanHeat = 0 mediHeat = 0 segCnt = structure.GetCount() segCnt2 = segCnt while structure.GetSecondaryStructure ( segCnt2 ) == "M" do segCnt2 = segCnt2 - 1 end max_residue = 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 GetContacts( ) local ii local jj for ii = 1, segCnt2 - 1 do for jj = ii + 1, segCnt2 do 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 print ( #heatmap .. " contacts with non-zero heat found" ) if ( #heatmap > 0 ) then SortByHeat ( heatmap ) print ( "seg1,seg2,heat" ) minHeat = 9999999 maxHeat = 0 for ii = 1, #heatmap do print ( heatmap [ ii ] [ 1 ] .. "," .. heatmap [ ii ] [ 2 ] .. "," .. heatmap [ ii ] [ 3 ] ) 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 end print ( "median contact heat = " .. r4 ( mediHeat ) ) end end function BandContacts () local ii local bndCnt = 0 for ii = 1, #heatmap do if heatmap [ ii ] [ 3 ] >= bndcut then band.AddBetweenSegments ( heatmap [ ii ] [ 1 ], heatmap [ ii ] [ 2 ] ) 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 meanHeat ~= maxHeat then dlg.l5 = dialog.AddLabel ( "Select minimum heat to band" ) dlg.bndpct = dialog.AddSlider ( "Heat cutoff" , meanHeat, minHeat, maxHeat, 3 ) end dlg.ok = dialog.AddButton ( "OK", 1 ) dlg.cancel = dialog.AddButton ( "Cancel", 0 ) if dialog.Show ( dlg ) > 0 then if meanHeat ~= maxHeat then bndcut = dlg.bndpct.value else bndcut = meanHeat end return true else print( "dialog cancelled" ) end end return false end function cleanup ( error ) local reason local start, stop, line, msg if error == nil then reason = "complete" else start, stop, line, msg = error:find ( ":(%d+):%s()" ) error = error:sub ( msg, #error ) if error:find ( "Cancelled" ) ~= nil then reason = "cancelled" else reason = "error" end end print ( ReVersion .. " " .. reason ) print ( "Puzzle: " .. puzzle.GetName () ) print ( "Track: " .. ui.GetTrackName () ) if reason == "error" then print ( "Unexpected error detected" ) print ( "Error line: " .. line ) print ( "Error: \"" .. error .. "\"" ) end end function main() print ( ReVersion ) GetContacts () if GetParams() then BandContacts () end end xpcall ( main, cleanup )

Comments


LociOiling Lv 1

The recipe displays the minimum, maximum, mean, and median heat of the non-zero contacts it finds.

The heat cutoff slider allows you to band any contacts at or above the specified heat. The initial cutoff value is the mean contact heat, which seems to be 1 in the limited testing conducted so far.

The bands created have default length and strength.

If you don't wish to band the contacts, simply click cancel.

The contacts are also listed in the scriptlog in comma-separated value (CSV) format, suitable for import into spreadsheets and such.

Deleted user

Thank you for sharing and making this neat and clear recipe.

To further it, it would be nice to see an :
1- Upper threshold for Contacts.
2- Make the bond strength linked to the heat map
3- Only work on certain protein segments at a time

These are my 2 cents.

LociOiling Lv 1

This version of Contact Cement includes some fixes Bruno Kestemont made in Contact Cement 2.02.

The original version of Contact Cement crashed if all contacts had the same strength. The original version also misreported the median contact heat.

As a banding tool, this version has been made obsolete by recent enhancements to the contact map tool. The contact map tool now allows you to band either all contacts or only empty contacts.

This version of the recipe is still useful, since it prints out a complete list of contacts in comma-delimited (CSV) format. The list can be easily imported into a spreadsheet or another tool for further analysis.

This version is also useful as a simple starting point for more ambitious contact tools.