From ee8ae8797cbc1d35bfb89ff25d0d36ffa5d57972 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Pleva=C4=8D?= Date: Wed, 15 Nov 2023 19:16:46 +0100 Subject: [PATCH] First working --- .vscode/settings.json | 3 + exmaple.asm | 16 ----- rule110.asm | 14 ++++ src/SIMDDNA/ascii.py | 11 +-- src/SIMDDNA/assembly.py | 0 src/SIMDDNA/molecule.py | 8 +++ src/SIMDDNA/register.py | 144 +++++++++++++++++++++++++++++++++------- src/SIMDDNA/svg.py | 42 ++++++++++++ 8 files changed, 192 insertions(+), 46 deletions(-) create mode 100644 .vscode/settings.json delete mode 100644 exmaple.asm create mode 100644 rule110.asm create mode 100644 src/SIMDDNA/assembly.py create mode 100644 src/SIMDDNA/svg.py diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..1b37f5a --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "svg.preview.background": "custom" +} \ No newline at end of file diff --git a/exmaple.asm b/exmaple.asm deleted file mode 100644 index de6becc..0000000 --- a/exmaple.asm +++ /dev/null @@ -1,16 +0,0 @@ -// -// Example NOT program -// - -data: - // -> - // || - // ---- - [CD] - -instructions: - // ----- - // ----- - {A*B*C*D*E*}; - // -- - {A*B*} \ No newline at end of file diff --git a/rule110.asm b/rule110.asm new file mode 100644 index 0000000..d8d19fa --- /dev/null +++ b/rule110.asm @@ -0,0 +1,14 @@ +define: + 0 [ABC][DE] + 1 {A}[BCDE] + +data: + 1001111010 + +instructions: + {D*E*A*F*} # mark 01 + {D*E*A*B*C*G*} # mark 11 + {DEABCG} # remove mark 11 + {A*B*C*} {D*E*} # write 0 + {DEAF} # remove mark 01 + {B*C*D*E*} # write 1 \ No newline at end of file diff --git a/src/SIMDDNA/ascii.py b/src/SIMDDNA/ascii.py index e0a6cd7..6d7dcfb 100644 --- a/src/SIMDDNA/ascii.py +++ b/src/SIMDDNA/ascii.py @@ -8,7 +8,9 @@ def toBindingLen(chainID, curPOS, molecule): for basePos in range(curPOS, len(molecule)): if molecule.getBase(chainID, basePos) != nothing: if isComplementary(molecule.getBase(chainID, basePos), molecule.getBase(0, basePos)): - return toBLen + #if only this binded here + if molecule.bindedCountAt(basePos) == 1: + return toBLen toBLen += 1 @@ -18,7 +20,8 @@ def toBindingLen(chainID, curPOS, molecule): for basePos in range(curPOS, -1, -1): if molecule.getBase(chainID, basePos) != nothing: if isComplementary(molecule.getBase(chainID, basePos), molecule.getBase(0, basePos)): - return toBLen + if molecule.bindedCountAt(basePos) == 1: + return toBLen toBLen -= 1 @@ -50,10 +53,8 @@ def showMolecule(molecule, spacing = ""): if lenToBinding is None: print(f"Warning: no binded for chain {chainID}") + elif lenToBinding == 0: - if bounded: - print(f"Warning: two or more posible bindings on base {basePos}") - bounded = True Invlines[1] += "|" diff --git a/src/SIMDDNA/assembly.py b/src/SIMDDNA/assembly.py new file mode 100644 index 0000000..e69de29 diff --git a/src/SIMDDNA/molecule.py b/src/SIMDDNA/molecule.py index 9fc769f..9ed54ce 100644 --- a/src/SIMDDNA/molecule.py +++ b/src/SIMDDNA/molecule.py @@ -84,6 +84,14 @@ class Molecule: def getBase(self, chainID, baseID): return self.chains[chainID][baseID] + def bindedCountAt(self, baseID): + binding = 0 + for chain in self.chains: + if isComplementary(self.chains[0][baseID], chain[baseID]): + binding += 1 + + return binding + def charAddBase(self, chainID, char, isBackward = False): if isBackward: if len(self.chains[chainID]) == 0 or self.getBase(chainID, 0) != nothing: diff --git a/src/SIMDDNA/register.py b/src/SIMDDNA/register.py index 3fb3aaf..ce3fb92 100644 --- a/src/SIMDDNA/register.py +++ b/src/SIMDDNA/register.py @@ -9,42 +9,104 @@ class Register: self.mol = mol def inscription(self, IMols): - for _ in range(1): - used = False - for imol in IMols: - bindIndex, unbindChain = self.getNearestBinding(imol) + for mol in IMols: + self.doAllBinding(mol) + self.removeUnbinded() + self.removeReplaced() + self.removeUnstable() + + def removeReplaced(self): + while True: + done = True + # for all chains in register + # primary detach newer + for chainI in range(self.mol.chainsCount() - 1, 0, -1): + # for all bases in molecule + binded = False + for pos in range(len(self.mol)): + if molecule.isComplementary(self.mol.getBase(chainI, pos), self.mol.getBase(0, pos)) and self.mol.bindedCountAt(pos) == 1: # binde minimaly once - if unbindChain is not None: - used = True - self.mol.removeChain(unbindChain) + binded = True + break - if bindIndex is not None: - used = True - chain = self.mol.addChain() - self.mol.padChain(chain, bindIndex) - self.mol.chain2chain(chain, imol.getChain(0)) - self.mol.endPad() + if not(binded): + self.mol.removeChain(chainI) + done = False + break - if not used: + + if done: break - def getNearestBinding(self, imol): + def removeUnbinded(self): + while True: + done = True + # for all chains in register + for chainIA in range(1, self.mol.chainsCount()): + for chainIB in range(1, self.mol.chainsCount()): + # for all bases in molecule + bindScore = 0 + for pos in range(len(self.mol)): + if not(molecule.isComplementary(self.mol.getBase(chainIA, pos), self.mol.getBase(chainIB, pos))): + if not(self.mol.getBase(chainIB, pos) == molecule.nothing and self.mol.getBase(chainIA, pos) == molecule.nothing): + bindScore -= 1 + + if bindScore == 0: + self.mol.removeChain(max(chainIA, chainIB)) + self.mol.removeChain(min(chainIA, chainIB)) + done = False + break + + if not(done): + break + + if done: + break + + def removeUnstable(self): + while True: + done = True + # for all chains in register + # primary detach newer + for chainI in range(self.mol.chainsCount() - 1, 0, -1): + # for all bases in molecule + bindScore = 0 + for pos in range(len(self.mol)): + if molecule.isComplementary(self.mol.getBase(chainI, pos), self.mol.getBase(0, pos)) and self.mol.bindedCountAt(pos) == 1: # binde minimaly once + bindScore += 1 + + if bindScore < 2: + self.mol.removeChain(chainI) + done = False + break + + + if done: + break + + def doAllBinding(self, imol): + # for all chains in register for chainI in range(self.mol.chainsCount()): + # for all possible aligment in molecule for aligment in range(len(self.mol)): + # calculate align score for all possible aligments align_score = 0 for baseID in range(min(len(imol), len(self.mol) - aligment)): if molecule.isComplementary(self.mol.getBase(chainI, baseID + aligment), imol.getBase(0, baseID)): align_score += 1 - elif align_score > 0: + elif align_score < 2: + align_score = 0 + + # this will definitly bind + if align_score >= 2: break # ok now finded binding if align_score >= 2: - if chainI == 0: - return aligment, None - - - return None, None + chain = self.mol.addChain() + self.mol.padChain(chain, aligment) + self.mol.chain2chain(chain, imol.getChain(0)) + self.mol.endPad() def show(self): return self.mol.rawPrint() @@ -58,8 +120,11 @@ print("Before") print("---------------------------------\n") # create register +num1 = "{A}[BCDE]" +num0 = "[ABC][DE]" + myreg = Register(molecule.parse( - "{EEEBCDEEEBCD}" + num1 + num0 + num0 + num1 + num1 + num1 + num1 + num0 + num1 + num0 )) myreg.asciiShow() @@ -76,11 +141,40 @@ print("---------------------------------\n") # do instruction # remove + myreg.inscription([ - molecule.parse("{A*B*C*D*A*}") + molecule.parse("{D*E*A*F*}") ]) +myreg.asciiShow("") -myreg.show() +myreg.inscription([ + molecule.parse("{D*E*A*B*C*G*}") +]) -myreg.asciiShow() \ No newline at end of file +myreg.asciiShow("") + +myreg.inscription([ + molecule.parse("{DEABCG}") +]) + +myreg.asciiShow("") + +myreg.inscription([ + molecule.parse("{A*B*C*}"), + molecule.parse("{D*E*}") +]) + +myreg.asciiShow("") + +myreg.inscription([ + molecule.parse("{DEAF}") +]) + +myreg.asciiShow("") + +myreg.inscription([ + molecule.parse("{B*C*D*E*}") +]) + +myreg.asciiShow("") \ No newline at end of file diff --git a/src/SIMDDNA/svg.py b/src/SIMDDNA/svg.py new file mode 100644 index 0000000..3199149 --- /dev/null +++ b/src/SIMDDNA/svg.py @@ -0,0 +1,42 @@ +import svgwrite + +# Vytvoření nového SVG dokumentu +svg_document = svgwrite.Drawing('complementary_strands.svg', profile='tiny', size=(400, 60)) + +# Nukleotidy pro první vlákno +strand1 = "ATGCTAAGCTAGCTA" + +# Funkce pro získání komplementárního nukleotidu +def get_complementary_base(base): + if base == 'A': + return 'T' + elif base == 'T': + return 'A' + elif base == 'C': + return 'G' + elif base == 'G': + return 'C' + else: + return base + +# Nukleotidy pro druhé komplementární vlákno +strand2 = ''.join([get_complementary_base(base) for base in strand1]) + +# Barvy pro jednotlivé nukleotidy +color_map = {'A': 'blue', 'T': 'red', 'C': 'green', 'G': 'yellow'} + +# Vykreslení prvního vlákna +for i, base in enumerate(strand1): + + baseSize = 30 + + x1 = i * baseSize + y1 = 10 + x2 = x1 + baseSize + y2 = 10 + + svg_document.add(svgwrite.shapes.Line(start=(x1, y1), end=(x2, y2), stroke=color_map[base], stroke_width=2)) + svg_document.add(svgwrite.text.Text(base, insert=(x1 + baseSize / 2 - 12 / 2, y1), font_size=12, fill=color_map[base])) + +# Uložení SVG dokumentu +svg_document.save()