Files
lammps/examples/PACKAGES/cgdna/util/lj2real.py
Kierran Falloon 775a73b67c cgDNA 'real' units and potential file reading for non-modifiable potential parameters (#15)
* oxDNA potential file reading and real units

This allows for pair and bond coefficients to be read from an appropriately formatted potential file, and also allows for the use of 'real' units within oxDNA1. The correct backend coefficients for pair and bonded interactions are set when the atom vector is initialised through the "ConstantsOxdna" class, based on the units specified within the input file.

* Extract seqav/seqdep and temp from potential files

Also includes miscellaneous string consistency changes and removes unnecessary parameter from reader.next_line instances.

* oxDNA2 potential file reading and real units

This extends previous changes to oxDNA2 specific potentials, being FENE, excluded volume, coaxial stacking and Debye-Hückel. Units now default to LJ values rather than 0.

* oxDNA potential files

* LJ <-> real units conversion tool

Converts standard oxDNA data and input file to real units, with inverse flag available for real -> LJ.

* oxRNA2 potential file reading and real units

For RNA, d_cs_x is treated as d_cs within ConstantsOxdna in order to reduce code duplication and complexity.

* Reparameterise real units

* Generalise PotentialFileReader logs

* Extract stk xi and kappa from potential files

This allows users to edit these values from the input script, as is documented, rather than them being within the potential files.

* Real unit and potential file documentation

This adds examples for real unit parameters and specific potential file documentation for each bond and pair style.
2024-05-03 15:00:29 +01:00

605 lines
26 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
/* ----------------------------------------------------------------------
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
https://www.lammps.org/ Sandia National Laboratories
Steve Plimpton, sjplimp@sandia.gov
Copyright (2003) Sandia Corporation. Under the terms of Contract
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
certain rights in this software. This software is distributed under
the GNU General Public License.
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing authors: Kierran Falloon (University of Strathclyde, Glasgow)
Oliver Henrich (University of Strathclyde, Glasgow)
------------------------------------------------------------------------- */
Program:
Usage:
$$ python lj2real.py <datafile> <inputfile> [-i]
$$ [-i] flag is optional and is used to convert real -> LJ units.
Requirements:
LAMMPS data file and input file.
This script assumes a input and data file structure similar to those found in examples/PACKAGES/cgdna/examples/.
"""
import datetime
import os
import sys
class Sections:
"""Sections of the data file"""
def __init__(
self,
bounds: bool,
masses: bool,
atoms: bool,
velocities: bool,
ellipsoids: bool,
):
self.bounds = bounds # xlo, xhi, ylo, yhi, zlo, zhi
self.masses = masses # Masses
self.atoms = atoms # Atoms
self.velocities = velocities # Velocities
self.ellipsoids = ellipsoids # Ellipsoids
# Conversion factors
class ConversionFactors:
"""Conversion factors for LJ to real units"""
def __init__(self, invert: bool = False):
self.inverted = False
self.temp_conv_factor = 3000.038822
self.energy_conv_factor = 5.961689060210325
self.kT_conv_factor = 0.001987204155
self.mass_conv_factor = 100.0277580236
self.length_conv_factor = 8.518
self.time_conv_factor = 1706.0
self.vel_conv_factor = 0.004992966002344666
self.angular_mom_conv_factor = 4.254188991883894
self.density_conv_factor = 0.2687551067436886
self.oxdna_fene_string = "11.92337812042065 2.1295 6.409795"
self.oxdna_excv_string = "11.92337812042065 5.9626 5.74965 11.92337812042065 4.38677 4.259 11.92337812042065 2.81094 2.72576"
self.oxdna_stk_string = "0.70439070204273 3.4072 7.6662 2.72576 6.3885 1.3 0.0 0.8 0.9 0.0 0.95 0.9 0.0 0.95 2.0 0.65 2.0 0.65"
self.oxdna_hbond_string = "0.0 0.93918760272364 3.4072 6.3885 2.89612 5.9626 1.5 0.0 0.7 1.5 0 0.7 1.5 0 0.7 0.46 3.141592654 0.7 4.0 1.570796327 0.45 4.0 1.570796327 0.45"
self.oxdna_hbond_1_4_2_3_string = "6.42073911784652 0.93918760272364 3.4072 6.3885 2.89612 5.9626 1.5 0 0.7 1.5 0.0 0.7 1.5 0 0.7 0.46 3.141592654 0.7 4.0 1.570796327 0.45 4.0 1.570796327 0.45"
self.oxdna_xstk_string = "3.9029021145006 4.89785 5.74965 4.21641 5.57929 2.25 0.791592654 0.58 1.7 1.0 0.68 1.7 1.0 0.68 1.5 0 0.65 1.7 0.875 0.68 1.7 0.875 0.68"
self.oxdna_coaxstk_string = "3.77965257404268 3.4072 5.1108 1.87396 4.94044 2.0 2.541592654 0.65 1.3 0 0.8 0.9 0 0.95 0.9 0 0.95 2 -0.65 2 -0.65"
self.oxdna2_fene_string = "11.92337812042065 2.1295 6.4430152"
self.oxdna2_excv_string = "11.92337812042065 5.9626 5.74965 11.92337812042065 4.38677 4.259 11.92337812042065 2.81094 2.72576"
self.oxdna2_stk_string = "0.70439070204273 3.4072 7.6662 2.72576 6.3885 1.3 0.0 0.8 0.9 0.0 0.95 0.9 0.0 0.95 2.0 0.65 2.0 0.65"
self.oxdna2_hbond_string = "0.0 0.93918760272364 3.4072 6.3885 2.89612 5.9626 1.5 0.0 0.7 1.5 0 0.7 1.5 0 0.7 0.46 3.141592654 0.7 4.0 1.570796327 0.45 4.0 1.570796327 0.45"
self.oxdna2_hbond_1_4_2_3_string = "6.36589157849259 0.93918760272364 3.4072 6.3885 2.89612 5.9626 1.5 0 0.7 1.5 0.0 0.7 1.5 0 0.7 0.46 3.141592654 0.7 4.0 1.570796327 0.45 4.0 1.570796327 0.45"
self.oxdna2_xstk_string = "3.9029021145006 4.89785 5.74965 4.21641 5.57929 2.25 0.791592654 0.58 1.7 1.0 0.68 1.7 1.0 0.68 1.5 0 0.65 1.7 0.875 0.68 1.7 0.875 0.68"
self.oxdna2_coaxstk_string = "4.80673207785863 3.4072 5.1108 1.87396 4.94044 2.0 2.891592653589793 0.65 1.3 0 0.8 0.9 0 0.95 0.9 0 0.95 40.0 3.116592653589793"
self.oxrna2_fene_string = "11.92337812042065 2.1295 6.482800913"
self.oxrna2_excv_string = "11.92337812042065 5.9626 5.74965 11.92337812042065 4.38677 4.259 11.92337812042065 2.81094 2.72576"
self.oxrna2_stk_string = "0.70439070204273 3.66274 7.92174 2.9813 6.64404 0.9 0.0 0.95 0.9 0.0 0.95 1.3 0.0 0.8 1.3 0.0 0.8 2.0 0.65 2.0 0.65"
self.oxrna2_hbond_string = "0.0 0.93918760272364 3.4072 6.3885 2.89612 5.9626 1.5 0.0 0.7 1.5 0.0 0.7 1.5 0.0 0.7 0.46 3.141592653589793 0.7 4.0 1.5707963267948966 0.45 4.0 1.5707963267948966 0.45"
self.oxrna2_hbond_1_4_2_3_3_4_string = "5.18928666388042 0.93918760272364 3.4072 6.3885 2.89612 5.9626 1.5 0.0 0.7 1.5 0.0 0.7 1.5 0.0 0.7 0.46 3.141592653589793 0.7 4.0 1.5707963267948966 0.45 4.0 1.5707963267948966 0.45"
self.oxrna2_xstk_string = "4.92690859644113 4.259 5.1108 3.57756 4.94044 2.25 0.505 0.58 1.7 1.266 0.68 1.7 1.266 0.68 1.7 0.309 0.68 1.7 0.309 0.68"
self.oxrna2_coaxstk_string = "6.57330882442206 4.259 5.1108 3.57756 4.94044 2.0 2.592 0.65 1.3 0.151 0.8 0.9 0.685 0.95 0.9 0.685 0.95 2.0 -0.65 2.0 -0.65"
if invert:
self.invert()
def invert(self):
"""Inverts the conversion factors for real -> LJ"""
self.inverted = True
self.temp_conv_factor = 1.0 / self.temp_conv_factor
self.energy_conv_factor = 1.0 / self.energy_conv_factor
self.kT_conv_factor = 1.0 / self.kT_conv_factor
self.mass_conv_factor = 1.0 / self.mass_conv_factor
self.length_conv_factor = 1.0 / self.length_conv_factor
self.time_conv_factor = 1.0 / self.time_conv_factor
self.vel_conv_factor = 1.0 / self.vel_conv_factor
self.angular_mom_conv_factor = 1.0 / self.angular_mom_conv_factor
self.density_conv_factor = 1.0 / self.density_conv_factor
self.oxdna_fene_string = "2.0 0.25 0.7525"
self.oxdna_excv_string = "2.0 0.7 0.675 2.0 0.515 0.5 2.0 0.33 0.32"
self.oxdna_stk_string = (
"6.0 0.4 0.9 0.32 0.75 1.3 0 0.8 0.9 0 0.95 0.9 0 0.95 2.0 0.65 2.0 0.65"
)
self.oxdna_hbond_string = "0.0 8.0 0.4 0.75 0.34 0.7 1.5 0 0.7 1.5 0 0.7 1.5 0 0.7 0.46 3.141592653589793 0.7 4.0 1.5707963267948966 0.45 4.0 1.5707963267948966 0.45"
self.oxdna_hbond_1_4_2_3_string = "1.077 8.0 0.4 0.75 0.34 0.7 1.5 0 0.7 1.5 0 0.7 1.5 0 0.7 0.46 3.141592653589793 0.7 4.0 1.5707963267948966 0.45 4.0 1.5707963267948966 0.45"
self.oxdna_xstk_string = "47.5 0.575 0.675 0.495 0.655 2.25 0.791592653589793 0.58 1.7 1.0 0.68 1.7 1.0 0.68 1.5 0 0.65 1.7 0.875 0.68 1.7 0.875 0.68"
self.oxdna_coaxstk_string = "46.0 0.4 0.6 0.22 0.58 2.0 2.541592653589793 0.65 1.3 0 0.8 0.9 0 0.95 0.9 0 0.95 2.0 -0.65 2.0 -0.65"
self.oxdna2_fene_string = "2.0 0.25 0.7564"
self.oxdna2_excv_string = "2.0 0.7 0.675 2.0 0.515 0.5 2.0 0.33 0.32"
self.oxdna2_stk_string = (
"6.0 0.4 0.9 0.32 0.75 1.3 0 0.8 0.9 0 0.95 0.9 0 0.95 2.0 0.65 2.0 0.65"
)
self.oxdna2_hbond_string = "0.0 8.0 0.4 0.75 0.34 0.7 1.5 0 0.7 1.5 0 0.7 1.5 0 0.7 0.46 3.141592653589793 0.7 4.0 1.5707963267948966 0.45 4.0 1.5707963267948966 0.45"
self.oxdna2_hbond_1_4_2_3_string = "1.0678 8.0 0.4 0.75 0.34 0.7 1.5 0 0.7 1.5 0 0.7 1.5 0 0.7 0.46 3.141592653589793 0.7 4.0 1.5707963267948966 0.45 4.0 1.5707963267948966 0.45"
self.oxdna2_xstk_string = "47.5 0.575 0.675 0.495 0.655 2.25 0.791592653589793 0.58 1.7 1.0 0.68 1.7 1.0 0.68 1.5 0 0.65 1.7 0.875 0.68 1.7 0.875 0.68"
self.oxdna2_coaxstk_string = "58.5 0.4 0.6 0.22 0.58 2.0 2.891592653589793 0.65 1.3 0 0.8 0.9 0 0.95 0.9 0 0.95 40.0 3.116592653589793"
self.oxrna2_fene_string = "2.0 0.25 0.761070781051"
self.oxrna2_excv_string = "2.0 0.7 0.675 2.0 0.515 0.5 2.0 0.33 0.32"
self.oxrna2_stk_string = "6.0 0.43 0.93 0.35 0.78 0.9 0 0.95 0.9 0 0.95 1.3 0 0.8 1.3 0 0.8 2.0 0.65 2.0 0.65"
self.oxrna2_hbond_string = "0.0 8.0 0.4 0.75 0.34 0.7 1.5 0 0.7 1.5 0 0.7 1.5 0 0.7 0.46 3.141592653589793 0.7 4.0 1.5707963267948966 0.45 4.0 1.5707963267948966 0.45"
self.oxrna2_hbond_1_4_2_3_3_4_string = "0.870439 8.0 0.4 0.75 0.34 0.7 1.5 0 0.7 1.5 0 0.7 1.5 0 0.7 0.46 3.141592653589793 0.7 4.0 1.5707963267948966 0.45 4.0 1.5707963267948966 0.45"
self.oxrna2_xstk_string = "59.9626 0.5 0.6 0.42 0.58 2.25 0.505 0.58 1.7 1.266 0.68 1.7 1.266 0.68 1.7 0.309 0.68 1.7 0.309 0.68"
self.oxrna2_coaxstk_string = "80 0.5 0.6 0.42 0.58 2.0 2.592 0.65 1.3 0.151 0.8 0.9 0.685 0.95 0.9 0.685 0.95 2.0 -0.65 2.0 -0.65"
def check_datafile_header(line: str, sections: Sections):
"""Checks for headers to modify corresponding data, since datafile is split into headers.
Modifies the Sections object to keep track of the current section.
Args:
line (str): The line to check
masses_section (bool): If the current section is the masses section
atoms_section (bool): If the current section is the atoms section
velocities_section (bool): If the current section is the velocities section
ellipsoids_section (bool): If the current section is the ellipsoids section
"""
if any(header in line for header in ["xlo", "xhi", "ylo", "yhi", "zlo", "zhi"]):
sections.bounds = True
sections.masses = False
sections.atoms = False
sections.velocities = False
sections.ellipsoids = False
elif "Masses" in line:
sections.bounds = False
sections.masses = True
sections.atoms = False
sections.velocities = False
sections.ellipsoids = False
elif "Atoms" in line:
sections.bounds = False
sections.masses = False
sections.atoms = True
sections.velocities = False
sections.ellipsoids = False
elif "Velocities" in line:
sections.bounds = False
sections.masses = False
sections.atoms = False
sections.velocities = True
sections.ellipsoids = False
elif "Ellipsoids" in line:
sections.bounds = False
sections.masses = False
sections.atoms = False
sections.velocities = False
sections.ellipsoids = True
elif "Bonds" in line:
sections.bounds = False
sections.masses = False
sections.atoms = False
sections.velocities = False
sections.ellipsoids = False
def modify_datafile(datafile_path: str, conversion_factors: ConversionFactors):
"""Modifies the file by header to use real units.
Args:
datafile_path (str): The path to the file to modify
"""
lines_changed = 0
current_section = Sections(False, False, False, False, False)
with open(datafile_path, "r", encoding="UTF-8") as file:
lines = file.readlines()
if conversion_factors.inverted:
lines[0] = (
"LAMMPS data file in LJ units via oxdna lj2real.py, date "
+ str(datetime.date.today())
+ "\n"
)
else:
lines[0] = (
"LAMMPS data file in real units via oxdna lj2real.py, date "
+ str(datetime.date.today())
+ "\n"
)
for i, line in enumerate(lines):
check_datafile_header(line, current_section) # check for headers
elements = line.split()
if (
not elements
or elements[0] == "#"
or any(
header in line
for header in ["Masses", "Atoms", "Velocities", "Ellipsoids", "Bonds"]
)
):
continue
# modify the line based on the current section it is in
if current_section.bounds:
elements[0:2] = [
str(int(float(x) * conversion_factors.length_conv_factor))
for x in elements[0:2]
]
lines[i] = " ".join(elements) + "\n"
lines_changed += 1
if current_section.masses:
elements[1] = str(
round(float(elements[1]) * conversion_factors.mass_conv_factor, 4)
)
lines[i] = " ".join(elements) + "\n"
lines_changed += 1
elif current_section.atoms:
elements[2:5] = [
str(float(x) * conversion_factors.length_conv_factor)
for x in elements[2:5]
]
elements[7] = str(
float(elements[7]) * conversion_factors.density_conv_factor
)
lines[i] = " ".join(elements) + "\n"
lines_changed += 1
elif current_section.velocities:
elements[1:4] = [
str(float(x) * conversion_factors.vel_conv_factor)
for x in elements[1:4]
]
elements[4:7] = [
str(float(x) * conversion_factors.angular_mom_conv_factor)
for x in elements[4:7]
]
lines[i] = " ".join(elements) + "\n"
lines_changed += 1
elif current_section.ellipsoids:
elements[1:4] = [
str(float(x) * conversion_factors.length_conv_factor)
for x in elements[1:4]
]
lines[i] = " ".join(elements) + "\n"
lines_changed += 1
if conversion_factors.inverted:
new_datafile_path = datafile_path + "_lj"
else:
new_datafile_path = datafile_path + "_real"
with open(new_datafile_path, "w", encoding="UTF-8") as file:
file.writelines(lines)
if lines_changed == 0:
print(
"Warning: No lines changed in data file. Ensure correct usage: python lj2real.py <datafile> <inputfile> [-i]"
)
else:
print(f"Data file lines changed: {lines_changed}")
return new_datafile_path
def modify_inputfile(inputfile_path: str, conversion_factors: ConversionFactors):
"""Modifies the input file line by line to use real units.
Args:
inputfile_path (str): The path to the input file to modify
"""
lines_changed = 0
oxdna2_flag, oxrna2_flag = False, False
with open(inputfile_path, "r", encoding="UTF-8") as file:
lines = file.readlines()
for i, line in enumerate(lines):
if "oxdna2" in line and not oxdna2_flag:
oxdna2_flag = True
print("Note: oxdna2 found in input file. Using oxdna2 conversion factors.")
if "oxrna2" in line and not oxrna2_flag:
oxrna2_flag = True
print("Note: oxrna2 found in input file. Using oxrna2 conversion factors.")
if oxdna2_flag and oxrna2_flag:
print(
"Warning: Both oxdna2 and oxrna2 found in input file. Output will likely be incorrect."
)
if "variable T" in line:
old_value = line.split()[3]
new_value = str(
round(float(old_value) * conversion_factors.temp_conv_factor, 1)
)
lines[i] = line.replace(old_value, new_value)
lines_changed += 1
elif "units" in line:
if conversion_factors.inverted:
lines[i] = "units lj\n"
else:
lines[i] = "units real\n"
lines_changed += 1
elif "atom_modify" in line:
elements = line.split()
elements[3] = str(
round(float(elements[3]) * conversion_factors.length_conv_factor, 3)
)
lines[i] = " ".join(elements) + "\n"
lines_changed += 1
elif "neighbor" in line:
elements = line.split()
elements[1] = str(
round(float(elements[1]) * conversion_factors.length_conv_factor, 3)
)
lines[i] = " ".join(elements) + "\n"
lines_changed += 1
elif "read_data" in line:
elements = line.split()
if conversion_factors.inverted:
elements[1] = elements[1] + "_lj"
else:
elements[1] = (
elements[1] + "_real"
) # naming convention of datafile after conversion
lines[i] = " ".join(elements) + "\n"
lines_changed += 1
elif "mass" in line:
elements = line.split()
elements[4] = str(
round(float(elements[4]) * conversion_factors.mass_conv_factor, 4)
)
lines[i] = " ".join(elements) + "\n"
lines_changed += 1
elif "bond_coeff" in line or "pair_coeff" in line:
if ".lj" in line or ".real" in line:
if conversion_factors.inverted:
line = line.replace(".real", ".lj")
else:
line = line.replace(".lj", ".real")
lines[i] = line
lines_changed += 1
if "stk" in line and "xstk" not in line and "coaxstk" not in line:
elements = line.split()
elements[6] = str( # convert xi
round(
float(elements[6]) * conversion_factors.energy_conv_factor,
14,
)
)
elements[7] = str( # convert kappa
round(float(elements[7]) * conversion_factors.kT_conv_factor, 9)
)
lines[i] = " ".join(elements) + "\n"
else:
elements = line.split()
if "bond_coeff" in line:
if oxdna2_flag:
elements[2:] = conversion_factors.oxdna2_fene_string.split()
elif oxrna2_flag:
elements[2:] = conversion_factors.oxrna2_fene_string.split()
else:
elements[2:] = conversion_factors.oxdna_fene_string.split()
elif "excv" in line:
if oxdna2_flag:
elements[4:] = conversion_factors.oxdna2_excv_string.split()
elif oxrna2_flag:
elements[4:] = conversion_factors.oxrna2_excv_string.split()
else:
elements[4:] = conversion_factors.oxdna_excv_string.split()
elif "stk" in line:
if "coaxstk" in line:
if oxdna2_flag:
elements[4:] = (
conversion_factors.oxdna2_coaxstk_string.split()
)
elif oxrna2_flag:
elements[4:] = (
conversion_factors.oxrna2_coaxstk_string.split()
)
else:
elements[4:] = (
conversion_factors.oxdna_coaxstk_string.split()
)
elif "xstk" in line:
if oxdna2_flag:
elements[4:] = conversion_factors.oxdna2_xstk_string.split()
elif oxrna2_flag:
elements[4:] = conversion_factors.oxrna2_xstk_string.split()
else:
elements[4:] = conversion_factors.oxdna_xstk_string.split()
else: # stk
elements[6] = str( # convert xi
round(
float(elements[6])
* conversion_factors.energy_conv_factor,
14,
)
)
elements[7] = str( # convert kappa
round(
float(elements[7]) * conversion_factors.kT_conv_factor,
9,
)
)
if oxdna2_flag:
elements[8:] = conversion_factors.oxdna2_stk_string.split()
elif oxrna2_flag:
elements[8:] = conversion_factors.oxrna2_stk_string.split()
else:
elements[8:] = conversion_factors.oxdna_stk_string.split()
elif "hbond" in line:
if elements[1] == "*" and elements[2] == "*":
if oxdna2_flag:
elements[5:] = (
conversion_factors.oxdna2_hbond_string.split()
)
elif oxrna2_flag:
elements[5:] = (
conversion_factors.oxrna2_hbond_string.split()
)
else:
elements[5:] = conversion_factors.oxdna_hbond_string.split()
else:
if oxdna2_flag:
elements[5:] = (
conversion_factors.oxdna2_hbond_1_4_2_3_string.split()
)
elif oxrna2_flag:
elements[5:] = (
conversion_factors.oxrna2_hbond_1_4_2_3_3_4_string.split()
)
else:
elements[5:] = (
conversion_factors.oxdna_hbond_1_4_2_3_string.split()
)
lines[i] = " ".join(elements) + "\n"
lines_changed += 1
elif "langevin" in line:
elements = line.split()
elements[6] = str(
round(float(elements[6]) * conversion_factors.time_conv_factor, 2)
)
lines[i] = " ".join(elements) + "\n"
lines_changed += 1
elif "timestep" in line:
elements = line.split()
elements[1] = str(
round(float(elements[1]) * conversion_factors.time_conv_factor, 5)
)
lines[i] = " ".join(elements) + "\n"
lines_changed += 1
elif "comm_modify" in line:
elements = line.split()
elements[2] = str(
round(float(elements[2]) * conversion_factors.length_conv_factor, 1)
)
lines[i] = " ".join(elements) + "\n"
lines_changed += 1
else:
continue
if conversion_factors.inverted:
new_inputfile_path = inputfile_path + "_lj"
else:
new_inputfile_path = inputfile_path + "_real"
with open(new_inputfile_path, "w", encoding="UTF-8") as file:
if conversion_factors.inverted:
file.write(
"# LAMMPS input file in LJ units via oxdna lj2real.py, date "
+ str(datetime.date.today())
+ "\n"
)
else:
file.write(
"# LAMMPS input file in real units via oxdna lj2real.py, date "
+ str(datetime.date.today())
+ "\n"
)
file.writelines(lines)
if lines_changed == 0:
print(
"Warning: No lines changed in input file. Ensure correct usage: python lj2real.py <datafile> <inputfile> [-i]"
)
else:
print(f"Input file lines changed: {lines_changed}")
return new_inputfile_path
def main():
"""Main function"""
print(
"\nLAMMPS data and input file conversion to real units via oxdna convert_data.py\n"
"Note: This script assumes a input and data file structure similar to those found in examples/PACKAGES/cgdna/examples/.\n"
"Ensure output is checked for correctness."
)
if len(sys.argv) > 2:
datafile_path = sys.argv[1]
inputfile_path = sys.argv[2]
invert = False
if len(sys.argv) > 3:
if sys.argv[3] == "-i":
invert = True
print("Performing real -> LJ conversion.")
else:
print(
"Invalid flag. Usage: python lj2real.py <datafile> <inputfile> [-i]"
)
sys.exit(1)
if invert:
conversion_factors = ConversionFactors(invert=True)
print(
"\nUsing conversion factors (real T, m, l, t, v, ρ -> LJ T*, m*, l*, t*, v*, ρ*):"
)
else:
conversion_factors = ConversionFactors(invert=False)
print(
"\nUsing conversion factors (LJ T*, m*, l*, t*, v*, ρ* -> real T, m, l, t, v, ρ):"
)
else:
print("\nUsage: python lj2real.py <datafile> <inputfile> [-i]")
print("\t[-i] flag is optional and is used to convert real -> LJ units.\n")
sys.exit(1)
conversion_factors_string = (
f"Temperature T\t{round(conversion_factors.temp_conv_factor, 6)} T* (K)\n"
f"Energy ε\t{round(conversion_factors.energy_conv_factor, 6)} ε* (kcal/mol)\n"
f"Mass m\t\t{round(conversion_factors.mass_conv_factor, 6)} m* (g/mol)\n"
f"Length l\t{round(conversion_factors.length_conv_factor, 6)} l* (Å)\n"
f"Time t\t\t{round(conversion_factors.time_conv_factor, 6)} t* (fs)\n"
f"Velocity v\t{round(conversion_factors.vel_conv_factor, 6)} v* (Å/fs)\n"
f"AngMom l\t{round(conversion_factors.angular_mom_conv_factor, 6)} (g/mol Å^2/fs)\n"
f"Density ρ\t{round(conversion_factors.density_conv_factor, 6)} ρ* (g/cm^3)\n"
f"Calculated using Sengar, Ouldridge, Henrich, Rovigatti, & Šulc. Front Mol Biosci 8 (2021). & https://docs.lammps.org/units.html.\n"
f"See examples/PACKAGES/cgdna/util/lj2real.py for exact conversion factors.\n"
)
print(conversion_factors_string)
print("Current directory: ", os.getcwd())
try:
new_datafile_path = modify_datafile(datafile_path, conversion_factors)
print(f"New data file: {new_datafile_path}")
except Exception as e:
print(f"Error modifying data file: {e}")
try:
new_inputfile_path = modify_inputfile(inputfile_path, conversion_factors)
print(f"New input file: {new_inputfile_path}\n")
except Exception as e:
print(f"Error modifying input file: {e}")
if __name__ == "__main__":
main()