Source code for pyfurnace.prepare.oxdna_sim

from typing import Union
import os
import zipfile
import tempfile
import warnings
from ..design.core import Origami


[docs] def oxdna_simulations( origami: Origami, oxdna_directory: str, directory: Union[None, str] = None, zip_directory: bool = False, temperature: Union[int, float] = 37, mc_relax_steps: Union[int, float] = 5e3, md_relax_steps: Union[int, float] = 1e7, md_equil_steps: Union[int, float] = 1e8, md_prod_steps: Union[int, float] = 1e9, ) -> Union[str, None]: """ Prepare the files for the OxDNA simulations. The function saves the files for oxdna simulations in the specified directory (created if it does not exist). The function also creates a zip file with the files for the simulations if the flag zip_directory is set to True. If the directory is set to None, the program automatically creates a zip file and returns the path to the zip file. Parameters ---------- origami : Origami The origami object. oxdna_directory : str The path to the OxDNA executable. It is important to load sequence dependent parameters. directory : str The output directory for the MD simulations files. If None, the zip_directory flag is set to True. zip_directory : bool If True, the function creates a zip file with the files for the simulations and returns the path to the zip file. If False, the function returns None. temperature : Union[int, float], optional The temperature in Celsius, by default 37. mc_relax_steps : Union[int, float], optional The number of Monte Carlo relaxation steps, by default 5e3. md_relax_steps : Union[int, float], optional The number of MD relaxation steps, by default 1e7. md_equil_steps : Union[int, float], optional The number of MD equilibration steps, by default 1e8. md_prod_steps : Union[int, float], optional The number of MD production steps, by default 1e9. Returns ------- Union[str, None] If zip_directory is True or directory is None, the function returns the path to the zip file. If zip_directory is False and directory is not None, the function returns None. """ inputs_dir = __file__.replace("oxdna_sim.py", "oxdna_inputs") ### CHECK THE TEMPORARY DIRECTORY if directory is None: zip_directory = True tempdir = tempfile.TemporaryDirectory() directory = tempdir.name else: directory = os.path.abspath(directory) if not os.path.exists(directory): warnings.warn(f"Directory {directory} does not exist. Creating it.") os.makedirs(directory) tempdir = None directory = directory # save configuration and forces origami.save_3d_model( directory + os.sep + "start", config=True, topology=False, forces=True, pk_forces=True, ) # rename the forces file forces_file = os.path.join(directory, "start_forces.txt") new_forces_file = os.path.join(directory, "forces.txt") os.rename(forces_file, new_forces_file) # rename the pk_forces file pk_forces_file = os.path.join(directory, "start_pk_forces.txt") new_pk_forces_file = os.path.join(directory, "pk_forces.txt") os.rename(pk_forces_file, new_pk_forces_file) # save topology origami.save_3d_model( directory + os.sep + "topology", config=False, topology=True, ) for file in os.listdir(inputs_dir): path = os.path.join(inputs_dir, file) with open(path, "r") as f: text = f.read() text = text.replace("TEMPERATURE", str(temperature)) text = text.replace("OXDNA_DIRECTORY", oxdna_directory) match file: case "MC_relax.txt": steps = mc_relax_steps case "MD_relax.txt": steps = md_relax_steps case "MD_equil.txt": steps = md_equil_steps case "MD_prod.txt": steps = md_prod_steps text = text.replace("STEPS", str(int(steps))) with open(os.path.join(directory, file), "w", encoding="utf-8") as f: f.write(text) files_to_include = [ "start.dat", "topology.top", "forces.txt", "pk_forces.txt", "MC_relax.txt", "MD_relax.txt", "MD_equil.txt", "MD_prod.txt", ] if zip_directory: # create a temporary zip file temp_zip = tempfile.NamedTemporaryFile(suffix=".zip", delete=False) temp_zip.close() # Close so we can write to it # Create the zip and add selected files with zipfile.ZipFile(temp_zip.name, "w", zipfile.ZIP_DEFLATED) as zipf: for file in files_to_include: # Store relative to directory for cleaner archive structure zipf.write(os.path.join(directory, file), arcname=file) if tempdir is not None: # Close the temporary directory tempdir.cleanup() # Return the path to the zip file if zip_directory: return temp_zip.name