Oxpy
Oxpy is a Python3 library that makes it possible to use oxDNA from Python.
An example of a simple simulation
The following snippet imports the oxpy
module, initialises the simulation machinery, runs a short simulation using the input file input
, changes the temperature, runs more simulations steps and computes the average position of the final configuration:
import numpy as np
import oxpy
with oxpy.Context():
# init the manager with the given input file
manager = oxpy.OxpyManager("input")
# run 1k steps
manager.run(1000)
# change the temperature
manager.update_temperature(0.11)
# run 1k steps more
manager.run(1000)
# do some computation with the current configuration
particles = manager.config_info().particles()
# compute the average position of the particles' backbones
avg_pos = np.average(list(map(lambda p: p.backbone_site(), particles)), axis=0)
print("Average final position:", avg_pos)
# and the interaction energy between the first two particles
print("Interaction energy between particle 0 and particle 1:", manager.config_info().interaction.pair_interaction(particles[0], particles[1]))
Warning
There is a known issue that makes the code segfault whenever multiple with oxpy.Context()
are used in a single script. In these cases a simple workaround is to add a del manager
instruction at the end of the with
code block, like this:
for _ in range(N_sims):
with oxpy.Context():
manager = oxpy.OxpyManager("input")
manager.run(N_steps)
del manager # <-- if you comment this line the script will segfault
If you want, you can initialise the input file yourself and change some of the options before initialising the manager:
my_input = oxpy.InputFile()
my_input.init_from_filename("input")
my_input["backend"] = "CUDA"
my_input["steps"] = "1e9"
manager = oxpy.OxpyManager(my_input)
You can also use oxpy.utils.generate_default_input()
to generate the following basic input file:
backend = CPU
sim_type = MD
verlet_skin = 0.2
dt = 0.001
T = 0.1
steps = 10000
print_energy_every = 1000
print_conf_interval = 100000
restart_step_counter = yes
refresh_vel = true
time_scale = linear
topology = topology.top
conf_file = init_conf.dat
trajectory_file = trajectory.dat
energy_file = energy.dat
An example of a simple analysis
Here we loop over all the configurations stored in an oxDNA trajectory file, printing the position of the first particle.
import numpy as np
import oxpy
with oxpy.Context():
inp = oxpy.InputFile()
inp.init_from_filename("input")
# this object will make it possible to access the trajectory data
backend = oxpy.analysis.AnalysisBackend(inp)
# loop over all the configurations stored in the trajectory file
while backend.read_next_configuration():
# you can access the particles' details from BaseParticle instances
print(backend.particles[0].pos)
# or from the flattened_conf object, which exposes the simulation data as vectors that can be converted to numpy arrays
numpy_positions = np.array(backend.flattened_conf.positions, copy=False)
print(numpy_positions[0])
Library API
Exceptions
The oxDNA code raises oxDNAException
s when the simulation cannot be correctly initialised or when it incurs in an unrecoverable error. These exceptions are automatically translated into Python exceptions of type oxpy.core.OxDNAError
, which can then be handled in a regular try except
block.