Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[
- Structure Changes V3.100 by Crashguard303
- part of my "cardinal segment detection" used in GA+EO Remix
- finds changes in secondary structures and
- creates a segment list, where changes do occur.
- can also:
- -- freeze complete puzzle,
- then unfreeze detected segments to use them as "ankles" or
- -- band detected segments to use them as scaffolding nodes
- you can use this script:
- -- just for detection, or
- -> to protect the puzzle from breaking apart
- while wiggling and turning the CI to low values ;)
- ]]--
- function structure_changes_append(structure_changes,seg_count)
- -- scan secondary structures of all puzzle segments (1 to seg_count)
- -- append segment indices with ss changes to table structure_changes
- local structure_changes= structure_changes
- local seg_count2= seg_count-1
- local i=1
- -- initialize segment iterator
- -- (position 1 -> first segment of puzzle)
- while i<seg_count2 do
- -- with iterator i,
- -- cycle through all puzzle segments (but not last)
- local ss1=structure.GetSecondaryStructure(i)
- -- check ss of segment with index i
- local ss2=structure.GetSecondaryStructure(i+1)
- -- check ss of segment behind index i
- if ss1~=ss2
- -- are ss different?
- -- primary, we want to find segments with loop-ss at the end of helix or sheet sections
- -- but sometimes helices are directly near (adjacent to) sheets
- then if ss1=="L"
- -- loop found at i? (-> other ss: behind i)
- then table.insert(structure_changes,i)
- elseif ss2=="L"
- -- loop found directly after i? (-> other ss: at i)
- then table.insert(structure_changes,(i+1))
- i=i+1
- elseif ss1=="H"
- -- helix found at i? (-> other ss (but no loop): behind i)
- then table.insert(structure_changes,i)
- elseif ss2=="H"
- -- helix found directly after i? (-> other ss (but no loop): at i)
- then table.insert(structure_changes,(i+1))
- i=i+1
- end -- if ss1,ss2
- end -- if ss1~=ss2
- i=i+1
- -- increase iterator
- -- (next position -> next segment)
- end -- while i<seg_count2
- return structure_changes
- end -- structure_changes_append()
- function structure_changes_filter(structure_changes)
- -- remove duplicate entries from table structure_changes
- local structure_changes= structure_changes
- local i=1
- -- initialize element iterator
- -- (position 1 -> first element of list)
- while i<=(#structure_changes-1) do
- -- with iterator i,
- -- cycle through all (but not last) elements in list
- if structure_changes[i]==structure_changes[i+1]
- -- element at current position identical with direct next one?
- then table.remove(structure_changes,(i+1))
- -- remove next one
- i=i-1
- -- as element was removed,
- -- we need to shift iterator
- end -- if structure_changes[i]==structure_changes[i+1]
- i=i+1
- -- increase iterator
- -- (next position -> next element)
- end
- return structure_changes
- end -- structure_changes_filter()
- function structure_changes_find(option)
- -- detect structure changes
- -- option.first=true: generally add first segment
- -- option.last= true: generally add last segment
- print("Detecting changes...")
- local seg_count=structure.GetCount()
- -- get number of segments
- local structure_changes={}
- -- initialize found list table
- if option.first -- activated?
- then table.insert(structure_changes,1)
- -- add first segment to list
- end -- if option.first
- structure_changes= structure_changes_append(structure_changes,seg_count)
- -- get segment numbers, where structure changes do occur
- if option.last -- activated?
- then table.insert(structure_changes,seg_count)
- -- add last segment to list
- end -- if option.last
- structure_changes= structure_changes_filter(structure_changes)
- -- remove duplicate entries
- return structure_changes
- end -- structure_changes_find()
- function structure_changes_show(structure_changes,option)
- -- show detected structure changes
- -- if set, do some freezing or banding
- -- option.freeze= true: freeze complete puzzle and unfreeze detected segments
- -- option.sbands= true: band detected segments with each other (scaffolding)
- -- option.freeze_invert= true: invert freezing
- -- option.sbands_mode= "grid": scaffold all detected segments with each other
- -- option.sbands_mode= "ring": scaffold all detected segments with next only
- -- option.sbands_pitch =0: use scaffolding - fix seg's distances, how they are
- -- option.sbands_pitch >0: use scaffolding - change seg's distances (expand puzzle)
- -- option.sbands_pitch <0: use scaffolding - change seg's distances (compress puzzle)
- -- option.sbands_strength: strength of scaffolding
- print("\nFound changes:")
- if option.freeze -- activated?
- then if option.freeze_invert -- activated?
- then freeze.UnfreezeAll()
- -- unfreeze all segments
- else freeze.FreezeAll()
- -- freeze all segments
- end -- if option.freeze_invert
- end -- if option.freeze
- local i
- -- initialize element iterator
- for i=1,#structure_changes do
- -- by variable i, cycle through all elements in list
- -- giving segments which have been found
- print('#'..i..': idx'..structure_changes[i])
- -- show segment number
- if option.freeze -- activated?
- then if option.freeze_invert -- activated?
- then freeze.Freeze(structure_changes[i],true,true)
- -- freeze segment number
- else freeze.Unfreeze(structure_changes[i],true,true)
- -- unfreeze segment number
- end -- if option.freeze_invert
- end -- if option.freeze
- end -- for i
- if option.sbands -- activated?
- then print("\nAdding bands:")
- if option.sbands_mode=="ring"
- then sbands_apply_ring(structure_changes,option.sbands_pitch,option.sbands_strength)
- else -- if option.sbands_mode~="ring" -> =="grid"
- sbands_apply_grid(structure_changes,option.sbands_pitch,option.sbands_strength)
- end -- if option.sbands_mode
- end -- if option.bands
- end -- structure_changes_show()
- function sbands_apply_ring(structure_changes,sbands_pitch,sbands_strength)
- -- using list structure_changes
- local i
- for i=1,#structure_changes do
- -- by variable i (origin segment),
- -- cycle through all elements in list structure_changes
- -- giving segments which have been found
- local j= i+1
- -- target segment: next element to i in list
- if j>#structure_changes
- -- element index out of list range?
- then j= 1
- -- take first element
- end -- if j
- band.AddBetweenSegments2(structure_changes[i],structure_changes[j],sbands_pitch,sbands_strength)
- -- band segment stored in element i to segment stored in element j
- end -- for i
- end -- function sbands_apply_ring
- function sbands_apply_grid(structure_changes,sbands_pitch,sbands_strength)
- -- using list structure_changes
- local i
- for i=1,(#structure_changes-1) do
- -- by variable i (origin segment),
- -- cycle from "first element" to "second last element" in list structure_changes
- -- giving segments which have been found
- local j
- for j=(i+1),#structure_changes do
- -- by variable j (target segment),
- -- cycle from "element behind i" to "last element" in list structure_changes
- -- giving other segments which have been found
- band.AddBetweenSegments2(structure_changes[i],structure_changes[j],sbands_pitch,sbands_strength)
- -- band segment stored in element i to segment stored in element j
- end -- for j
- end -- for i
- end -- function sbands_apply_grid
- function band.AddBetweenSegments2(i,j,sbands_pitch,sbands_strength)
- -- i: origin segment index
- -- j: target segment index
- -- sbands_pitch: add this to measured distance, giving band length
- -- sbands_strength: strength of bands
- if (math.abs(j-i))>1
- -- bands not directly near each other?
- then local band_GetCount1= band.GetCount()
- band.AddBetweenSegments(i,j)
- -- band segment i to segment j
- local band_GetCount2= band.GetCount()
- if band_GetCount2>band_GetCount1
- -- has band been added?
- then local length= structure.GetDistance(i,j)+sbands_pitch
- if length<0
- then length= 0
- -- to prevent errors
- end -- if length
- band.SetGoalLength(band_GetCount2,length)
- -- set length of applied band to measured distance (scaffolding)
- -- +/- sbands_pitch
- band.SetStrength(band_GetCount2,sbands_strength)
- -- set strength of applied band to sbands_strength
- print('#'..band_GetCount2..': idx'..i..':idx'..j..' l:'..length..' s:'..sbands_strength)
- end -- if band_GetCount2>
- end -- if >1
- end -- function band.AddBetweenSegments2
- -- get list containing those segments where ss changes occur
- -- and remove duplicate entries:
- structure_changes= structure_changes_find({first=true;last=true})
- -- first=true: generally add first segment
- -- last= true: generally add last segment
- -- show results:
- structure_changes_show(structure_changes,
- {freeze=true;
- -- activate freezing?
- freeze_invert=false;
- -- invert freezing?
- sbands=false;
- -- activate bands?
- sbands_mode="ring";
- -- band mode?
- sbands_pitch=0;
- -- change segment distance by?
- sbands_strength=1}
- -- band strength?
- )
- -- you should activate either freeze or bands:
- -- freeze= true: freeze complete puzzle and unfreeze detected segments (detected segments serve as "ankles")
- -- freeze_invert= true: invert freezing
- -- sbands= true: band detected segments with each other (detected segments serve as scaffolding nodes)
- -- sbands_mode= "grid": scaffold all detected segments with each other
- -- sbands_mode= "ring": scaffold all detected segments with next only
- -- sbands_pitch: add this value to measured segment distance, giving band length
- -- sbands_pitch =0: fix seg's distances, how they are
- -- sbands_pitch >0: change seg's distances (expand puzzle)
- -- sbands_pitch <0: change seg's distances (compress puzzle)
- -- sbands_strength: strength of scaffolding
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement