Source code for pydna_epbd.monitors.melting_and_fraction_many_monitor
from pydna_epbd.monitors.monitor import Monitor
[docs]class MeltingAndFractionManyMonitor(Monitor):
"""This collects whether the DNA is melted and the fraction of DNA base-pairs melted,
as in melting and fraction monitor, at many different time steps and thresholds.
By default, it collects melting and fraction observations 100 time steps throughout
the post preheating steps in an evenly separated manner. And twenty thresholds are chosen
in between [0.5, 2.5) Angstrom with step size 0.1.
"""
MELT_FRACTION_TRESHOLDS = [
i / 10 for i in range(5, 25)
] # start=0.5, end=2.5, step=0.1
MELT_FRACTION_SIZES = len(MELT_FRACTION_TRESHOLDS)
# MELT_FRACTION_TIME_STEP = 800
# MELT_FRACTION_MAX_STEPS = 80000
MELT_FRACTION_TIME_STEPS = (
100 # int(MELT_FRACTION_MAX_STEPS/MELT_FRACTION_TIME_STEP) # 100
)
def __init__(self, dna, n_preheating_steps) -> None:
"""Initialize MeltingAndFractionManyMonitor object.
Args:
dna (DNA): A DNA object.
n_steps_after_preheating (int): Number of post-preheating steps.
"""
super(MeltingAndFractionManyMonitor, self).__init__(dna)
self.n_preheating_steps = n_preheating_steps
self.melting_fraction_many = [0.0] * self.dna.n_nt_bases
self.melting_many = [
[0.0] * self.MELT_FRACTION_SIZES
for i in range(self.MELT_FRACTION_TIME_STEPS)
] # shape=(MELT_FRACTION_TIME_STEPS, MELT_FRACTION_SIZES)
self.fraction_many = [
[0.0] * self.MELT_FRACTION_SIZES
for i in range(self.MELT_FRACTION_TIME_STEPS)
] # shape=(MELT_FRACTION_TIME_STEPS, MELT_FRACTION_SIZES)
[docs] def collect_at_step(self, step_no):
"""Melting and fraction characteristics are collected at various time steps thoughout the post preheating steps.
Args:
step_no (int): Step number.
"""
for i in range(self.dna.n_nt_bases):
self.melting_fraction_many[i] += self.dna.coords_dist[i]
step = step_no - self.n_preheating_steps
if step % self.MELT_FRACTION_TIME_STEPS == 0:
time_step = int(step / self.MELT_FRACTION_TIME_STEPS)
self.__check_melting_and_fraction_many(step, time_step)
def __check_melting_and_fraction_many(self, step, time_step):
for thresh_idx in range(self.MELT_FRACTION_SIZES):
melting, fraction = 1.0, 0.0
for base_idx in range(self.dna.n_nt_bases):
if (
melting == 1.0
and self.melting_fraction_many[base_idx] / (step + 1)
< self.MELT_FRACTION_TRESHOLDS[thresh_idx]
):
melting = 0.0
break
if (
self.melting_fraction_many[base_idx] / (step + 1)
> self.MELT_FRACTION_TRESHOLDS[thresh_idx]
):
fraction += 1 # computing total fraction length for this threshold
self.melting_many[time_step][thresh_idx] += melting
self.fraction_many[time_step][thresh_idx] += fraction / self.dna.n_nt_bases