There are different implementations for calcuating the $\rm MLD$. One possible approach is to consider $\rm MLD$ as the heighest value of all possible mountain plots, generated by shifting the beginning of your sequence. The highest value of a mountain plot tells you the maximal ladder distance that can be reached from the first nucleotide. But the longest path might not begin at the first nucleotide, and that is why you have to go through all possible shifts of the sequence.
Here is an example of this implementation in Python. The algorithm is as following:
- Convert dot-bracket notation to a list of base pairs (
dot2pairs
).
- Calculate the first mountain plot.
- Calculate required
shifts
. This is not strictly neccessary because you can swipe through all possible shifts = list(range(0, length))
, but it gives better performance.
- Iterate through all
shifts
, calculate the MLD
at each step, and return the maximal one.
import numpy as np
from collections import deque
def dot2pairs(dot):
stack, pairs = deque(), []
for i, n in enumerate(dot):
if n == '(':
stack.append(i)
elif n == ')':
pairs.append((stack.pop(), i))
return np.array(pairs)
def dot2MLD(dot):
# Convert to a list of base pairs
pairs0 = dot2pairs(dot)
if len(pairs0) == 0:
return 0
MLD = 0
shifts = [0]
length = len(dot)
seq = np.zeros(length, dtype=int)
curr_mount = None
while shifts:
# Shift the sequence
pairs = (pairs0 - shifts.pop()) % length
# Find positions of opening and closing nucleotides
opens, closes = np.min(pairs, axis=1), np.max(pairs, axis=1)
seq.fill(0)
seq[opens] = 1
seq[closes] = -1
mountain = np.cumsum(seq)
MLD = max(MLD, int(np.max(mountain)))
# In first iteration, calculate all required shifts
if curr_mount is None:
curr_mount = mountain[0]
for i, m in enumerate(mountain):
if m == curr_mount:
shifts.append(i)
else:
curr_mount = m
return MLD
Let's test it on your structure:
dot2MLD("..(((((.......)))...((.((((((.......))))))..)).)).")
11
And on a larger structure:
dot2MLD(s)
1141
It took ~ 5 seconds for this 17481 nt long structure (and it takes ~ 20 seconds if you don't precalculate requires shifts
).
{}
) to format it in a monospace font for clarity. $\endgroup$