def create_setup(strand_seq, num_traj, T=25, rate_method_k_or_m="Metropolis", material="DNA"): # Essentially, creates the options object and prepares to simulate the hybridization of the strand and its complement. onedomain = Domain(name="itall",sequence=strand_seq) top = Strand(name="top",domains=[onedomain]) bot = top.C # Note that the structure is specified to be single stranded, but this will be over-ridden when Boltzmann sampling is turned on. start_complex_top = Complex(strands=[top],structure=".") start_complex_bot = Complex(strands=[bot],structure=".") start_complex_top.boltzmann_count = num_traj start_complex_bot.boltzmann_count = num_traj start_complex_top.boltzmann_sample = True start_complex_bot.boltzmann_sample = True # Turns Boltzmann sampling on for this complex and also does sampling more efficiently by sampling 'num_traj' states. # Stop when the exact full duplex is achieved. (No breathing!) success_complex = Complex(strands=[top, bot],structure="(+)") success_stop_condition = StopCondition("SUCCESS",[(success_complex,Exact_Macrostate,0)]) # Declare the simulation unproductive if the strands become single-stranded again. failed_complex = Complex(strands = [top], structure=".") failed_stop_condition = StopCondition("FAILURE",[(failed_complex,Dissoc_Macrostate,0)]) o = Options(simulation_mode="First Step",parameter_type="Nupack", substrate_type=material, rate_method = rate_method_k_or_m, num_simulations = num_traj, simulation_time=1.0, dangles = "Some", temperature = T, rate_scaling = "Calibrated", verbosity = 0) o.start_state = [start_complex_top, start_complex_bot] o.stop_conditions = [success_stop_condition,failed_stop_condition] return o
def getOptions(trials, material, complex1, complex2, success_stop_conditions, failed_stop_conditions, T=25, supersample=25): o = Options(simulation_mode="First Step", substrate_type=material, rate_method="Metropolis", num_simulations=trials, simulation_time=ATIME_OUT, temperature=T) for x in [complex1, complex2]: x.boltzmann_supersample = supersample x.boltzmann_count = trials x.boltzmann_sample = True conds=[] for x in [success_stop_conditions, failed_stop_conditions]: try: # x is a list conds += x except TypeError: # x is a single input conds.append(x) o.start_state = [complex1, complex2] o.stop_conditions = conds # Using new parameters. setArrheniusConstantsDNA23(o) return o
def first_step_simulation(strand_seq, trials, T=25, material="DNA"): print "Running %d first step mode simulations for %s (with Boltzmann sampling)..." % (trials, strand_seq) # Using domain representation makes it easier to write secondary structures. onedomain = Domain(name="itall",sequence=strand_seq) top = Strand(name="top",domains=[onedomain]) bot = top.C # Note that the structure is specified to be single stranded, but this will be over-ridden when Boltzmann sampling is turned on. start_complex_top = Complex(strands=[top],structure=".") start_complex_bot = Complex(strands=[bot],structure=".") start_complex_top.boltzmann_count = trials start_complex_bot.boltzmann_count = trials start_complex_top.boltzmann_sample = True start_complex_bot.boltzmann_sample = True # Turns Boltzmann sampling on for this complex and also does sampling more efficiently by sampling 'trials' states. # Stop when the exact full duplex is achieved. (No breathing!) success_complex = Complex(strands=[top, bot],structure="(+)") success_stop_condition = StopCondition("SUCCESS",[(success_complex,Exact_Macrostate,0)]) # Declare the simulation unproductive if the strands become single-stranded again. failed_complex = Complex(strands = [top], structure=".") failed_stop_condition = StopCondition("FAILURE",[(failed_complex,Dissoc_Macrostate,0)]) o = Options(simulation_mode="First Step",parameter_type="Nupack", substrate_type=material, rate_method = "Metropolis", num_simulations = trials, simulation_time=1.0, dangles = "Some", temperature = T, rate_scaling = "Calibrated", verbosity = 0) o.start_state = [start_complex_top, start_complex_bot] o.stop_conditions = [success_stop_condition,failed_stop_condition] # Now go ahead and run the simulations. initialize_energy_model(o) # concentration changes, so we must make sure energies are right s = SimSystem(o) s.start() dataset = o.interface.results # Now determine the reaction model parameters from the simulation results. (Simplified from hybridization_first_step_mode.py.) collision_rates = np.array( [i.collision_rate for i in dataset] ) was_success = np.array([1 if i.tag=="SUCCESS" else 0 for i in dataset]) was_failure = np.array([0 if i.tag=="SUCCESS" else 1 for i in dataset]) forward_times = np.array( [i.time for i in dataset if i.tag == "SUCCESS"] ) reverse_times = np.array( [i.time for i in dataset if i.tag == "FAILURE" or i.tag == None] ) # Calculate first-order rate constants for the duration of the reactions (both productive and unproductive). k2 = 1.0/np.mean(forward_times) k2prime = 1.0/np.mean(reverse_times) # Calculate second-order rate constants for productive and unproductive reactions. k1 = np.mean( collision_rates * was_success ) k1prime = np.mean( collision_rates * was_failure ) return k1, k2, k1prime, k2prime
def test_options(self): """ Test [Options]: Create an options object using some default values and start/stop states""" o = Options() o.simulation_mode = 3 o.use_stop_states = True o.parameter_type = 1 o.substrate_type = 2 o.num_simulations = 3 o.simulation_time = 0.5 o.start_state = [self.complexes[0], self.complexes[1]] o.stop_conditions = [self.conditions[0], self.conditions[1]]
def first_passage_dissociation(strand_seq, trials, T=25, material="DNA"): print "Running %d first passage time simulations for dissociation of %s..." % ( trials, strand_seq) # Using domain representation makes it easier to write secondary structures. onedomain = Domain(name="itall", sequence=strand_seq) top = Strand(name="top", domains=[onedomain]) bot = top.C single_strand_top = Complex(strands=[top], structure=".") single_strand_bot = Complex(strands=[bot], structure=".") duplex_complex = Complex(strands=[top, bot], structure="(+)") # Declare the simulation complete if the strands become single-stranded again. success_stop_condition = StopCondition( "SUCCESS", [(single_strand_top, Dissoc_Macrostate, 0)]) o = Options( simulation_mode="First Passage Time", parameter_type="Nupack", substrate_type=material, rate_method="Metropolis", num_simulations=trials, simulation_time=10.0, join_concentration= 1e-6, # 1 uM concentration, but doesn't matter for dissociation dangles="Some", temperature=T, rate_scaling="Calibrated", verbosity=0) o.start_state = [duplex_complex] o.stop_conditions = [success_stop_condition] # Now go ahead and run the simulations. initialize_energy_model( o) # concentration changes, so we must make sure energies are right s = SimSystem(o) s.start() dataset = o.interface.results times = np.array([i.time for i in dataset]) timeouts = [i for i in dataset if not i.tag == 'SUCCESS'] if len(timeouts) > 0: print "Warning: %d of %d dissociation trajectories did not finishin allotted %g seconds..." % ( len(timeouts), len(times), 10.0) for i in timeouts: assert (i.tag == Literals.time_out) assert (i.time >= 10.0) krev = 1.0 / np.mean(times) return krev
def standardOptions(simMode=Literals.first_step, tempIn=25.0, trials=10, timeOut=0.1): output = Options(simulation_mode=simMode, num_simulations=trials, simulation_time=timeOut, temperature=tempIn) output.DNA23Metropolis() output.rate_method = Literals.metropolis return output
def setup_options_hairpin(trials, stem_seq, hairpin_seq): # Define the domains stem = Domain(name="stem", sequence=stem_seq, length=len(stem_seq)) hairpin = Domain(name="hairpin", sequence=hairpin_seq, length=len(hairpin_seq)) s = stem + hairpin + stem.C # We give domain-level structures for the open and closed hairpin configurations start_complex = Complex(strands=[s], structure="...") stop_complex = Complex(strands=[s], structure="(.)") full_sc = StopCondition("CLOSED", [(stop_complex, Exact_Macrostate, 0)]) # Note: unlike in Transition Mode, in First Passage Time Mode, no "stop:" prefix is needed in the macrostate name # in order for the StopCondition to trigger the end of the simulation. o = Options(simulation_mode="First Passage Time", parameter_type="Nupack", substrate_type="DNA", temperature=310.15, num_simulations=trials, simulation_time=0.1, rate_scaling='Calibrated', verbosity=0, start_state=[start_complex], stop_conditions=[full_sc]) return o
def setUp(self): self.domains = [] self.strands = [] self.complexes = [] self.conditions = [] self.domains.append( Domain("d1", "d", 5, False) ) self.domains.append( Domain("d1p", "d", 5, True) ) self.strands.append( Strand("s1", "s1", "ACTTG", [self.domains[0]])) self.strands.append( Strand("s2", "s2", "CAAGT", [self.domains[1]])) self.complexes.append( Complex("c1", "c1", [self.strands[0]], ".....")) self.complexes.append( Complex("c2", "c2", [self.strands[1]], ".....")) self.complexes.append( Complex("c3", "c3", [self.strands[0], self.strands[1]], "(((((+)))))")) self.conditions.append( StopCondition("REVERSE", [(self.complexes[0], 2, 0), (self.complexes[1], 2, 0)])) self.conditions.append( StopCondition("END", [(self.complexes[2], 4, 1)])) self.options = Options() self.options.simulation_mode = 3 self.options.use_stop_states = True self.options.parameter_type = 1 self.options.substrate_type = 2 self.options.num_simulations = 3 self.options.simulation_time = 0.5 self.options.start_state = [self.complexes[0], self.complexes[1]] self.options.stop_conditions = [self.conditions[0], self.conditions[1]]
def create_test0C(): domain_seq = "AGT" domain_seq2 = "GTA" left = Domain(name="branch_migration", sequence=domain_seq, seq_length=3) right = Domain(name="branch_migration2", sequence=domain_seq2, seq_length=3) incoming = left + right substrate = incoming.C start_complex1 = Complex(strands=[incoming], structure="..") start_complex2 = Complex(strands=[substrate], structure="..") stop_complex = Complex(strands=[incoming, substrate], structure="((+))") full_sc = StopCondition("CLOSED", [(stop_complex, Literals.dissoc_macrostate, 2)]) o1 = Options(simulation_mode=Literals.first_passage_time, temperature=273.15 + 25.0, num_simulations=10, simulation_time=0.00001, rate_scaling='Calibrated', verbosity=0, join_concentration=1e-9, rate_method="Metropolis", start_state=[start_complex1, start_complex2], stop_conditions=[full_sc]) return o1
def first_passage_association(strand_seq, trials, concentration, T=25, material="DNA"): print "Running %d first passage time simulations for association of %s at %s..." % (trials, strand_seq, concentration_string(concentration)) # Using domain representation makes it easier to write secondary structures. onedomain = Domain(name="itall",sequence=strand_seq) top = Strand(name="top",domains=[onedomain]) bot = top.C duplex_complex = Complex(strands=[top, bot],structure="(+)") single_strand_top = Complex(strands=[top],structure=".") single_strand_bot = Complex(strands=[bot],structure=".") # Start with Boltzmann-sampled single-strands... it only seems fair. single_strand_top.boltzmann_count = trials single_strand_bot.boltzmann_count = trials single_strand_top.boltzmann_sample = True single_strand_bot.boltzmann_sample = True # Declare the simulation complete if the strands become a perfect duplex. success_stop_condition = StopCondition("SUCCESS",[(duplex_complex,Exact_Macrostate,0)]) o = Options(simulation_mode="First Passage Time",parameter_type="Nupack", substrate_type=material, rate_method = "Metropolis", num_simulations = trials, simulation_time=10.0, join_concentration=concentration, dangles = "Some", temperature = T, rate_scaling = "Calibrated", verbosity = 0) o.start_state = [single_strand_top, single_strand_bot] o.stop_conditions = [success_stop_condition] # Now go ahead and run the simulations. initialize_energy_model(o) # concentration changes, so we must make sure energies are right s = SimSystem(o) s.start() dataset = o.interface.results times = np.array([i.time for i in dataset]) timeouts = [i for i in dataset if not i.tag == 'SUCCESS'] if len(timeouts)>0 : print "some association trajectories did not finish..." for i in timeouts : assert (i.type_name=='Time') assert (i.tag == None ) assert (i.time >= 10.0) print "average completion time = %g seconds at %s" % (np.mean(times),concentration_string(concentration)) keff = 1.0/np.mean( times )/concentration return keff
def transition_mode_simulation(strand_seq, duration, concentration, T=25, material="DNA"): print "Running %g seconds of transition mode simulations of %s at %s..." % (duration, strand_seq, concentration_string(concentration)) # Using domain representation makes it easier to write secondary structures. onedomain = Domain(name="itall",sequence=strand_seq) top = Strand(name="top",domains=[onedomain]) bot = top.C duplex_complex = Complex(strands=[top, bot],structure="(+)") single_strand_top = Complex(strands=[top],structure=".") single_strand_bot = Complex(strands=[bot],structure=".") # Declare macrostates single_stranded_macrostate = Macrostate("SINGLE",[(single_strand_top,Dissoc_Macrostate,0)]) duplex_macrostate = Macrostate("DUPLEX",[(duplex_complex,Loose_Macrostate,4)]) o = Options(simulation_mode="Transition",parameter_type="Nupack", substrate_type=material, rate_method = "Metropolis", num_simulations = 1, simulation_time=float(duration), # time must be passed as float, not int join_concentration=concentration, dangles = "Some", temperature = T, rate_scaling = "Calibrated", verbosity = 0) o.start_state = [single_strand_top, single_strand_bot] o.stop_conditions = [single_stranded_macrostate, duplex_macrostate] # not actually stopping, just tracking # Now go ahead and run the simulations until time-out. initialize_energy_model(o) # concentration changes, so we must make sure energies are right s = SimSystem(o) s.start() # Now make sense of the results. transition_dict = parse_transition_lists(o.interface.transition_lists) print_transition_dict( transition_dict, o ) # A is SINGLE, B is DUPLEX N_AtoA = float(len( transition_dict['A -> A'] )) if 'A -> A' in transition_dict else 0 dT_AtoA = np.mean( transition_dict['A -> A'] ) if N_AtoA > 0 else 1 # will be mult by zero in that case N_AtoB = float(len( transition_dict['A -> B'] )) if 'A -> B' in transition_dict else 0 dT_AtoB = np.mean( transition_dict['A -> B'] ) if N_AtoB > 0 else 1 N_BtoB = float(len( transition_dict['B -> B'] )) if 'B -> B' in transition_dict else 0 dT_BtoB = np.mean( transition_dict['B -> B'] ) if N_BtoB > 0 else 1 N_BtoA = float(len( transition_dict['B -> A'] )) if 'B -> A' in transition_dict else 0 dT_BtoA = np.mean( transition_dict['B -> A'] ) if N_BtoA > 0 else 1 keff = 1.0/(dT_AtoB + (N_AtoA/N_AtoB)*dT_AtoA)/concentration if N_AtoB > 0 else None krev = 1.0/(dT_BtoA + (N_BtoB/N_BtoA)*dT_BtoB) if N_BtoA > 0 else None return keff, krev
def getOptions(trials, material, duplex_complex, dangle, success_stop_condition, failed_stop_condition): o = Options(simulation_mode="First Step", substrate_type=material, rate_method="Metropolis", num_simulations=trials, simulation_time=ATIME_OUT, temperature=T) o.start_state = [duplex_complex, dangle] o.stop_conditions = [success_stop_condition, failed_stop_condition] # FD: The result of this script depend significantly on JS or DNA23 parameterization. # o.JSMetropolis25() o.DNA23Metropolis() return o
def create_setup(toehold_length, num_traj, rate_method_k_or_m): # essentially, creates the options object and prepares to simulate toehold_seq = "TCTCCATGTCACTTC" # toehold sequence bm_design = "CCCTCATTCAATACCCTACG" # branch migration domain # creating Domain objects toehold = Domain(name="toehold", sequence=toehold_seq[0:toehold_length]) branch_migration = Domain(name="bm", sequence=bm_design) incoming = branch_migration + toehold # you can concatenate domains to make domains incoming.name = "incoming" # here the "invader" (according to Zhange & Winfree 2009) is called the "incoming" strand. toehold_extra = Domain(name="toehold_extra", sequence=toehold_seq[toehold_length:]) substrate = toehold_extra.C + toehold.C + branch_migration.C incumbent = Strand(name="incumbent", domains=[branch_migration]) # creates the substrate-incumbent start complex start_complex_substrate_incumbent = Complex(strands=[substrate, incumbent], structure="..(+)") # creates incoming ("invader") complex. start_complex_incoming = Complex(strands=[incoming], structure="..") # by default, Boltzmann sampling is *NOT* used in first step mode. See hybridization_first_step_mode.py for Boltzmann sampling. # creates a complex for a "succcessful displacement" stop condition. This is the incumbent strand forming a complex of its own which means it has been displaced. complete_complex_success = Complex(strands=[incumbent], structure=".") success_stop_condition = StopCondition("SUCCESS", [(complete_complex_success, Dissoc_Macrostate, 0)]) # creates the successful displacement stop condition # complex to create failed displacement stop condition; incumbent falls off. failed_complex = Complex(strands=[incoming], structure="..") failed_stop_condition = StopCondition("FAILURE", [(failed_complex, Dissoc_Macrostate, 0)]) # creates failed stop condition o = Options(simulation_mode="First Step", parameter_type="Nupack", substrate_type="DNA", rate_method=rate_method_k_or_m, num_simulations=num_traj, simulation_time=10.0, # note the 10 second simulation time, to make sure simulations finish dangles="Some", temperature=25 + 273.15, rate_scaling="Calibrated", verbosity=0) o.start_state = [start_complex_incoming, start_complex_substrate_incumbent] o.stop_conditions = [success_stop_condition, failed_stop_condition] return o
def createOptions(start_complex, stop_complex, simMode): full_sc = StopCondition("CLOSED", [(stop_complex, Literals.dissoc_macrostate, 2)]) o1 = Options( simulation_mode=simMode, # "First Passage Time", parameter_type="Nupack", substrate_type="DNA", temperature=273.15 + 25.0, num_simulations=10, simulation_time=0.00001, # rate_scaling='Calibrated', verbosity=0, join_concentration=1.0, rate_method="Metropolis", start_state=[start_complex], stop_conditions=[full_sc]) o1.DNA23Metropolis() return o1
def setup_options(trials, seq, concentration): """ setup_options( seq ) creates an Options object using the sequence passed as a single domain with initially unpaired structure. """ d = Domain(name="initial", sequence=seq, length=len(seq)) s = Strand(domains=[d]) c = Complex(strands=[s], structure=".") o = Options(simulation_mode="Normal", parameter_type="Nupack", substrate_type="DNA", num_sims=trials, sim_time=0.008, start_state=[c]) o.DNA23Metropolis() o.temperature = 310.15 o.join_concentration = concentration return o
def create_options(): print "creating options..." d1 = Domain(name="d1", sequence="GTTGGTTTGTGTTTGGTGGG") s1 = Strand(name="s1", domains=[d1]) c1 = Complex(name="c1", strands=[s1], structure=".") c2 = Complex(name="c2", strands=[s1.C], structure=".") c3 = Complex(name="c3", strands=[s1, s1.C], structure="(+)") sc_rev = StopCondition("REVERSE", [(c1, 2, 0), (c2, 2, 0)]) sc_for = StopCondition("END", [(c3, 4, 6)]) o = Options(simulation_mode = 'First Step', num_simulations = 100, simulation_time = 0.5, start_state = [RestingState("1", [c1]), RestingState("2", [c2])], stop_conditions = [sc_rev, sc_for]) #o.initial_seed = random.SystemRandom().randrange(-2147483648, 2147483647) print "finished options. creating simsystem..." #print o.interface return o
def create_setup(trials, toehold_seq, toehold_seq2, domain_seq): # build complexes with domain-level information toehold = Domain(name="toehold", sequence=toehold_seq, length=len(toehold_seq2)) toehold_2 = Domain(name="toehold", sequence=toehold_seq2, length=len(toehold_seq2)) branch_migration = Domain(name="branch_migration", sequence=domain_seq, seq_length=len(domain_seq)) incoming = branch_migration.C + toehold.C substrate = toehold + branch_migration + toehold_2 incumbent = Strand(name="incumbent", domains=[toehold_2.C, branch_migration.C]) # Note that "+" is used to indicate strand breaks. # So the initial structures represent the incoming strand bound by its toehold, # and we'll see that either it completes strand displacement, or it dissociates. start_complex = Complex(strands=[incoming, substrate, incumbent], structure=".(+)((+))") stop_complex = Complex(strands=[incoming, substrate, incumbent], structure="((+))(+).") full_sc = StopCondition("CLOSED", [(stop_complex, Literals.exact_macrostate, 0)]) o1 = Options(simulation_mode="First Passage Time", parameter_type="Nupack", substrate_type="DNA", temperature=273.15 + 25.0, num_simulations=trials, simulation_time=0.0001, rate_scaling='Calibrated', verbosity=0, start_state=[start_complex], stop_conditions=[full_sc]) return o1
def setup_options_hairpin(): """ setup_options_hairpin( ) Returns the options object for simple hairpin example of transition mode in Chapter 7.3 of Schaeffer's PhD thesis. """ # Once domains are defined, strands can be built from them using "+". stem = Domain(name="stem",sequence="GCATGC",length=6) hp = Domain(name="hairpin", sequence="AAAA",length=4) s = stem + hp + stem.C # Note that because we defined domains, we can either represent secondary structures at the domain level or at the sequence level. start_complex = Complex(strands=[s], structure="...") pathway_endside_exact_complex = Complex(strands=[s], structure="(((..........)))") pathway_endside_loose_complex = Complex(strands=[s], structure="(((**********)))") pathway_hpside_exact_complex = Complex(strands=[s], structure="...(((....)))...") pathway_hpside_loose_complex = Complex(strands=[s], structure="***(((****)))***") full_complex = Complex( strands=[s], structure="(.)") # Define macrostates to be tracked, i.e. we look for transitions between them. initial_sc = Macrostate( "INITIAL", [(start_complex,Exact_Macrostate,0)]) pathway_hp_exact_sc = Macrostate( "HPSIDE_EXACT", [(pathway_hpside_exact_complex,Exact_Macrostate,0)]) pathway_hp_loose_sc = Macrostate( "HPSIDE_LOOSE", [(pathway_hpside_loose_complex,Loose_Macrostate,2)]) # within distance 2 pathway_end_exact_sc = Macrostate( "ENDSIDE_EXACT", [(pathway_endside_exact_complex,Exact_Macrostate,0)]) pathway_end_loose_sc = Macrostate( "ENDSIDE_LOOSE", [(pathway_endside_loose_complex,Loose_Macrostate,2)]) # within distance 2 full_sc = StopCondition( "stop:FULL", [(full_complex,Exact_Macrostate,0)]) # Multistrand treats Macrostates and StopConditions interchangeably; here we choose the name as a mnemonic for how it will be used. # The simulation will stop the first time that 'full_sc' is reached, so we call it a StopCondition. # The simulation keeps track of where it is, but keeps going, when it visits the others -- so they are called Macrostates. # But the simulation would proceed identically if randomly called some Macrostates and others StopConditions. # What determines Multistrand's behavior is that the name of 'full_sc' begins with "stop:" -- this is what causes the simulation to stop when 'full_sc' is reached. # We will set up two Transition Mode simulations, one looking at transitions between exact states... o_exact = Options(simulation_mode="Transition",parameter_type="Nupack",substrate_type="DNA", temperature=310.15, num_simulations = 1000, simulation_time=.01, start_state=[start_complex], rate_scaling='Calibrated', verbosity=0) o_exact.stop_conditions = [initial_sc, pathway_end_exact_sc, pathway_hp_exact_sc,full_sc] # ... and one looking at transitions between loosely defined macrostates o_loose = Options(simulation_mode="Transition",parameter_type="Nupack",substrate_type="DNA", temperature=310.15, num_simulations = 1000, simulation_time=.01, start_state=[start_complex], rate_scaling='Calibrated', verbosity=0) o_loose.stop_conditions = [initial_sc, pathway_end_loose_sc, pathway_hp_loose_sc,full_sc] # change verbosity to 1, above, and you'll see a print-out during the simulation runs, every time a stop state is reached. return o_exact,o_loose
def setup_threewaybm_comparison(trials=10, toehold_seq = "GTGGGT", bm_design_A = "ACCGCACGTCCACGGTGTCG", bm_design_B = "ACCGCACGTCACTCACCTCG"): toehold = Domain(name="toehold",sequence=toehold_seq,length=len(toehold_seq)) branch_migration_A = Domain(name="bm_A", sequence=bm_design_A, seq_length=len(bm_design_A)) branch_migration_B = Domain(name="bm_B", sequence=bm_design_B, seq_length=len(bm_design_B)) substrate_A = toehold + branch_migration_A substrate_B = toehold + branch_migration_B incumbent_A = Strand(name="incumbent",domains=[branch_migration_A.C]) incumbent_B = Strand(name="incumbent",domains=[branch_migration_B.C]) incoming_A = substrate_A.C incoming_B = substrate_B.C # start with the full toehold bound start_complex_A = Complex(strands=[incoming_A, substrate_A, incumbent_A], structure=".(+)(+)") start_complex_B = Complex(strands=[incoming_B, substrate_B, incumbent_B], structure=".(+)(+)") complete_complex_A = Complex(strands=[incumbent_A],structure=".") complete_complex_B = Complex(strands=[incumbent_B],structure=".") failed_complex_A = Complex(strands=[incoming_A],structure="..") failed_complex_B = Complex(strands=[incoming_B],structure="..") # the "success" state complete_sc_A = StopCondition("complete",[(complete_complex_A,Dissoc_Macrostate,0)]) complete_sc_B = StopCondition("complete",[(complete_complex_B,Dissoc_Macrostate,0)]) # the "failure" state failed_sc_A = StopCondition("failed",[(failed_complex_A,Dissoc_Macrostate,0)]) failed_sc_B = StopCondition("failed",[(failed_complex_B,Dissoc_Macrostate,0)]) o1 = Options(simulation_mode="First Passage Time", parameter_type="Nupack", substrate_type="DNA", num_simulations = trials, simulation_time=1.0, dangles = "Some", temperature = 310.15, join_concentration=1e-6, # 1 uM concentration start_state=[start_complex_A], rate_scaling='Calibrated') o1.stop_conditions = [complete_sc_A,failed_sc_A] o2 = Options(simulation_mode="First Passage Time", parameter_type="Nupack", substrate_type="DNA", num_simulations = trials, simulation_time=1.0, dangles = "Some", temperature = 310.15, join_concentration=1e-6, # 1 uM concentration start_state=[start_complex_B], rate_scaling='Calibrated') o2.stop_conditions = [complete_sc_B,failed_sc_B] return o1,o2
def doReaction(arguments): # the first argument is always the number of paths options = Options(trials=arguments[0]) #options.output_interval = 1 # do not uncomment ---> might get memory issues options.num_simulations = arguments[0] options.simulation_time = arguments[1] options.sodium = arguments[5] options.magnesium = arguments[6] options.temperature = arguments[9] + arguments[10] options.join_concentration = arguments[12] * arguments[11] if arguments[13] == Literals.metropolis: set_Metropolis_params(options, arguments[7]) elif arguments[13] == Literals.arrhenius: set_Arrhenius_params(options, arguments[7]) options.simulation_mode = Literals.trajectory if arguments[14] == True: endComplex1 = arguments[15][-1][0] stopSuccess = StopCondition( Literals.success, [(endComplex1, Literals.exact_macrostate, 0)]) options.stop_conditions = [stopSuccess] if use_Gillespie_MFPT == True: options.start_state = arguments[15][0] return options
def show_interesting_trajectories(result_lists, seqs, type='fastest'): mintimes = [] maxtimes = [] slowseeds = [] fastseeds = [] for n in range(len(result_lists)): times = 1e6 * np.array([ i.time for i in result_lists[n] ]) # convert from seconds to microseconds units. slowseeds.append(result_lists[n][np.argmax( times)].seed) # find the seed used for the slowest simulation fastseeds.append(result_lists[n][np.argmin( times)].seed) # find the seed used for the fastest simulation mintimes.append(np.min(times)) maxtimes.append(np.max(times)) # taken from hairpin_trajectories.py def print_trajectory(o): print(o.full_trajectory[0][0][3]) # the strand sequence print(o.start_state[0].structure) for i in range(len(o.full_trajectory)): time = 1e6 * o.full_trajectory_times[i] state = o.full_trajectory[i][0] struct = state[4] dG = state[5] print(struct + ' t=%11.9f microseconds, dG=%6.2f kcal/mol' % (time, dG)) # take a look at the fastest folds. to take a look at the more interesting slowest folds, # change "mintimes" to "maxtimes" and change "fastseeds" to "slowseeds"; do this based on 'type' argument seeds = fastseeds if type == 'fastest' else slowseeds times = mintimes if type == 'fastest' else maxtimes for (seq, seed, time) in zip(seqs, seeds, times): s1 = Strand(name="hairpin", sequence=seq) c1 = Complex(strands=[s1], structure=16 * '.') # hard-coded length 16 c2 = Complex(strands=[s1], structure="((((((....))))))" ) # hard-coded stem length 6, loop length 4 sc = StopCondition("CLOSED", [(c2, Exact_Macrostate, 0)]) # For future reference, StopConditions and Macrostates (same thing) are provided as a list of match conditions, # all of which must be matched. I.e. there is an implicit AND being evaluated. E.g. # sc = StopCondition( "EXAMPLE", [(c2,Loose_Macrostate,8), (c1,Loose_Macrostate,4)] # would specify the intersection of those two macrostates, i.e. any 2 base pairs of the helix (and maybe more). o = Options( temperature=310.15, dangles='Some', start_state=[c1], simulation_time= 0.1, # 0.1 seconds (lots more time than hairpin_trajectories, to accommodate slow folds) num_simulations=1, # don't play it again, Sam output_interval=1, # record every single step rate_method= 'Metropolis', # the default is 'Kawasaki' (numerically, these are 1 and 2 respectively) rate_scaling= 'Calibrated', # this is the same as 'Default'. 'Unitary' gives values 1.0 to both. simulation_mode='Trajectory' ) # numerically 128. See interface/_options/constants.py for more info about all this. o.stop_conditions = [sc] # don't wait for the time-out o.initial_seed = seed # start with the same random seed as before... s = SimSystem(o) s.start() print_trajectory(o) print("Original run's time: %g microseconds" % time)
def create_setup(seed): # build complexes with domain-level information toehold_seq = "GTGGGT" bm_design_B = "ACCGCACGTCACTCACCTCG" toehold_extra = "TTT" toehold = Domain(name="toehold", sequence=toehold_seq, length=6) branch_migration_B = Domain(name="bm_B", sequence=bm_design_B, seq_length=20) substrate_B = toehold + branch_migration_B incumbent_B = Strand(name="incumbent", domains=[branch_migration_B.C]) incoming_B = substrate_B.C start_complex_B1 = Complex( strands=[incoming_B, substrate_B, incumbent_B], structure= "..(.((.....)).).....((((((+))))))((((((((((((((((((((+))))))))))))))))))))" ) o2 = Options() o2.simulation_mode = 0x0080 # trajectory mode o2.current_seed = 20 o2.initial_seed = seed o2.num_simulations = 1 o2.simulation_time = 0.0001 o2.temperature = 37.0 o2.dangles = 1 o2.start_state = [start_complex_B1] o2.output_interval = 1 o2.JSDefault() return o2
def setup_options_threewaybm(toehold_seq="GTGGGT", bm_design="ACCGCACGTCACTCACCTCG"): # the structures below are hard-coded for these lengths assert len(toehold_seq) == 6 assert len(bm_design) == 20 toehold = Domain(name="toehold", sequence=toehold_seq, length=6) branch_migration = Domain(name="bm", sequence=bm_design, seq_length=20) substrate = toehold + branch_migration incumbent = Strand(name="incumbent", domains=[branch_migration.C]) incoming = substrate.C # start with 6-base toehold fully bound start_complex = Complex(strands=[incoming, substrate, incumbent], structure=".(+)(+)") initial_structure_dp = "....................((((((+))))))((((((((((((((((((((+))))))))))))))))))))" six_bases_structure_dp = "..............((((((((((((+))))))))))))((((((((((((((+))))))))))))))......" six_bases_loose_dp = "**************((**********+**********))((************+************))******" twelve_bases_struc_dp = "........((((((((((((((((((+))))))))))))))))))((((((((+))))))))............" twelve_bases_loose_dp = "********((*****************+***************))((******+******))************" eighteen_structure_dp = "..((((((((((((((((((((((((+))))))))))))))))))))))))((+)).................." eighteen_loose_dp = "**((**********************+**********************))((+))******************" six_bases_complex = Complex(strands=[incoming, substrate, incumbent], structure=six_bases_structure_dp) twelve_bases_complex = Complex(strands=[incoming, substrate, incumbent], structure=twelve_bases_struc_dp) eighteen_bases_complex = Complex(strands=[incoming, substrate, incumbent], structure=eighteen_structure_dp) six_basesloose_complex = Complex(strands=[incoming, substrate, incumbent], structure=six_bases_loose_dp) twelve_basesloose_complex = Complex( strands=[incoming, substrate, incumbent], structure=twelve_bases_loose_dp) eighteen_basesloose_complex = Complex( strands=[incoming, substrate, incumbent], structure=eighteen_loose_dp) disassoc_complex = Complex(strands=[incumbent], structure=".") # succesful strand displacement failed_complex = Complex( strands=[incoming], structure="..") # failed strand displacement attempt start_sc = Macrostate("INITIAL", [ (start_complex, Count_Macrostate, 2) ]) # Within distance 2 of the start_complex state. six_sc_exact = Macrostate("SIX_EXACT", [ (six_bases_complex, Exact_Macrostate, 0) ]) # the third parameter is ignored; not needed for exact macrostates six_sc_loose = Macrostate("SIX_LOOSE", [ (six_basesloose_complex, Loose_Macrostate, 2) ]) # 8 base pairs defined; must have at least 6 to match. twelve_sc_exact = Macrostate("TWELVE_EXACT", [(twelve_bases_complex, Exact_Macrostate, 0)]) twelve_sc_loose = Macrostate( "TWELVE_LOOSE", [(twelve_basesloose_complex, Loose_Macrostate, 2)]) eighteen_sc_exact = Macrostate( "EIGHTEEN_EXACT", [(eighteen_bases_complex, Exact_Macrostate, 0)]) eighteen_sc_loose = Macrostate( "EIGHTEEN_LOOSE", [(eighteen_basesloose_complex, Loose_Macrostate, 2)]) # why bother giving a list of just one macrostate-def tuple? A Macrostate with a list of multiple tuples give the AND (i.e. intersection) of microstates. completed_sc = StopCondition("stop:COMPLETE", [ (disassoc_complex, Dissoc_Macrostate, 0) ]) # incumbent strand fell off rejected_sc = StopCondition( "stop:REJECTED", [(failed_complex, Dissoc_Macrostate, 0)]) # incoming strand fell off # join_concentration is not defined, because in this simulation we stop before there's any chance for association steps o_exact = Options(simulation_mode="Transition", parameter_type="Nupack", dangles="Some", substrate_type="DNA", num_simulations=5, simulation_time=.01, temperature=310.15, start_state=[start_complex], rate_scaling='Calibrated', verbosity=0) o_exact.stop_conditions = [ start_sc, six_sc_exact, twelve_sc_exact, eighteen_sc_exact, completed_sc, rejected_sc ] o_loose = Options(simulation_mode="Transition", parameter_type="Nupack", dangles="Some", substrate_type="DNA", num_simulations=5, simulation_time=.01, temperature=310.15, start_state=[start_complex], rate_scaling='Calibrated', verbosity=0) o_loose.stop_conditions = [ start_sc, six_sc_loose, twelve_sc_loose, eighteen_sc_loose, completed_sc, rejected_sc ] return o_exact, o_loose
def create_setup(): # build complexes with domain-level information toehold_seq = "GTGGGT" bm_design_A = "ACCGCACGTCCACGGTGTCG" bm_design_B = "ACCGCACGTCACTCACCTCG" toehold = Domain(name="toehold", sequence=toehold_seq, length=6) branch_migration_A = Domain(name="bm_A", sequence=bm_design_A, seq_length=20) branch_migration_B = Domain(name="bm_B", sequence=bm_design_B, seq_length=20) substrate_A = toehold + branch_migration_A substrate_B = toehold + branch_migration_B incumbent_A = Strand(name="incumbent", domains=[branch_migration_A.C]) incumbent_B = Strand(name="incumbent", domains=[branch_migration_B.C]) incoming_A = substrate_A.C incoming_B = substrate_B.C # Note that "+" is used to indicate strand breaks. # So the initial structures represent the incoming strand bound by its toehold, # and we'll see that either it completes strand displacement, or it dissociates. start_complex_A = Complex(strands=[incoming_A, substrate_A, incumbent_A], structure=".(+)(+)") start_complex_B = Complex(strands=[incoming_B, substrate_B, incumbent_B], structure=".(+)(+)") o1 = Options() o1.simulation_mode = 0x0080 # trajectory mode o1.num_simulations = 1 o1.simulation_time = 0.00002 # 200 microseconds, about 250 steps o1.temperature = 37.0 o1.dangles = 1 o1.output_interval = 100 # record every 100 steps (so we'll get around 100 record entries) o1.start_state = [start_complex_A] o1.rate_scaling = "Calibrated" o1.join_concentration = 1e-6 # 1 uM o1.verbosity = 0 # doesn't turn off output during simulation -- but it should. please wait for multistrand 3.0. # the alternative is to increase the output_interval so something ridiculously high, but this also eliminates the trajectory record o2 = Options() o2.simulation_mode = 0x0080 # trajectory mode o2.num_simulations = 1 o2.simulation_time = 0.00002 # 200 us, about 250 steps o2.temperature = 37.0 o2.dangles = 1 o2.start_state = [start_complex_B] o2.output_interval = 100 # could do o2.output_time to get trajectory items evenly spaced in time instead of by number of steps o2.rate_scaling = "Calibrated" o1.join_concentration = 1e-6 # 1 uM return o1, o2
print struct + ' t=%11.9f seconds, dG=%6.2f kcal/mol' % (time, dG) # Sequence is from Schaeffer's PhD thesis, chapter 7, figure 7.1 -- start with no base pairs formed. c = Complex(strands=[Strand(name="hairpin", sequence="GTTCGGGCAAAAGCCCGAAC")], structure=20 * '.') # WARNING! Unfortunately, Multistrand currently does not test to check that the requested structure is valid. # Providing an invalid structure is likely to lead to a core dump or segmentation fault. o = Options( temperature=25.0, dangles='Some', start_state=[c], simulation_time=0.0000001, # 0.1 microseconds num_simulations=1, # don't play it again, Sam output_interval=1, # record every single step rate_method=Literals. metropolis, # the default is 'Kawasaki' (numerically, these are 1 and 2 respectively) rate_scaling= 'Calibrated', # this is the same as 'Default'. 'Unitary' gives values 1.0 to both. simulation_mode='Trajectory' ) # numerically 128. See interface/_options/constants.py for more info about all this. print "k_uni = %g /s, k_bi = %g /M/s" % ( o.unimolecular_scaling, o.bimolecular_scaling ) # you can also set them to other values if you want # This actually runs the simulation. s = SimSystem(o) s.start() # Important caveat: SimSystem will initialize the energy model according to information in Options 'o'
if False: # only needed if you're having trouble with your Multistrand installation import multistrand_setup try: from multistrand.objects import * from multistrand.options import Options from multistrand.system import energy, initialize_energy_model except ImportError: print("Could not import Multistrand.") raise ############# o = Options(temperature=25, dangles="Some") # prepares for simulation. initialize_energy_model( o ) # necessary if you want to use energy() without running a simulation first. # see more about the energy model usage and initialization in threewaybm_trajectories.py # More meaningful names for argument values to the energy() function call, below. Loop_Energy = 0 # requesting no dG_assoc or dG_volume terms to be added. So only loop energies remain. Volume_Energy = 1 # requesting dG_volume but not dG_assoc terms to be added. No clear interpretation for this. Complex_Energy = 2 # requesting dG_assoc but not dG_volume terms to be added. This is the NUPACK complex microstate energy, sans symmetry terms. Tube_Energy = 3 # requesting both dG_assoc and dG_volume terms to be added. Summed over complexes, this is the system state energy. # Sequence is from Schaeffer's PhD thesis, chapter 7, figure 7.1 # Just for illustration, create a hairping strand with just the outermost 4 base pairs of the stem formed: c = Complex(strands=[Strand(name="hairpin", sequence="GTTCGGGCAAAAGCCCGAAC")],
if False: # only needed if you're having trouble with your Multistrand installation import multistrand_setup try: from multistrand.objects import * from multistrand.options import Options from multistrand.system import * except ImportError: print("Could not import Multistrand.") raise ############# o = Options() o.dangles = 1 # 0 is "None", 1 is "Some", 2 is "All". You can use the string names only when passing as arguments to Options(). o.temperature = 25 # values between 0 and 100 are assumed to be Celsius; between 273.15 and 373.0 are assumed to be Kelvin. o.join_concentration = 1e-9 # the volume is scaled such that a single strand is at 1 nM concentration. initialize_energy_model( o ) # only necessary if you want to use energy() without running a simulation first. # More meaningful names for argument values to the energy() function call, below. Loop_Energy = 0 # requesting no dG_assoc or dG_volume terms to be added. So only loop energies remain. Volume_Energy = 1 # requesting dG_volume but not dG_assoc terms to be added. No clear interpretation for this. Complex_Energy = 2 # requesting dG_assoc but not dG_volume terms to be added. This is the NUPACK complex microstate energy, sans symmetry terms. Tube_Energy = 3 # requesting both dG_assoc and dG_volume terms to be added. Summed over complexes, this is the system state energy. # Sequences are from Zhang & Winfree, JACS 2009. toe = Domain(name='toehold', sequence='TCTCCATGTC')
def helper_create_Multistrand_options(self, sequence, time, count): """ helper """ s1 = Strand("test_strand1", str(sequence), None) c1 = Complex(1, "start", [s1], "." * len(sequence)) o = Options() o.simulation_mode = Constants.SIMULATION_MODE['Python Module'] o.use_stop_states = False o.num_simulations = count o.simulation_time = time o.start_state = [c1] o.dangles = Constants.DANGLES['All'] o.rate_method = Constants.RATEMETHOD['Kawasaki'] o.bimolecular_scaling = 1.0 o.unimolecular_scaling = 1.0 o.temperature = 37.0 o.boltzmann_sample = False return o