3737)
3838from sire .units import GeneralUnit as _sire_GeneralUnit
3939
40- from BioSimSpace . Sandpit . Exscientia .Types ._general_unit import (
40+ from . .Types ._general_unit import (
4141 GeneralUnit as _GeneralUnit ,
4242)
4343from ..Types import Angle as _Angle , Length as _Length , Temperature as _Temperature
@@ -450,7 +450,7 @@ def format_bond(equilibrium_values, force_constants):
450450 )
451451
452452 # Format the parameters for the angles and dihedrals
453- def format_angle (equilibrium_values , force_constants , restraint_lambda ):
453+ def format_angle (equilibrium_values , force_constants , restraint_lambda , perturbed = True ):
454454 """
455455 Format the angle equilibrium values and force constant
456456 in into the Gromacs topology format.
@@ -465,20 +465,30 @@ def format_angle(equilibrium_values, force_constants, restraint_lambda):
465465
466466 When restraint_lambda is True, the dihedrals will be stored in the dihedral_restraints.
467467 """
468- converted_equ_val = (
468+ if isinstance (equilibrium_values , _Angle ):
469+ converted_equ_val = equilibrium_values / _degree
470+ else :
471+ converted_equ_val = (
469472 self ._restraint_dict ["equilibrium_values" ][equilibrium_values ] / _degree
470473 )
471- converted_fc = self ._restraint_dict ["force_constants" ][force_constants ] / (
472- _kj_per_mol / (_radian * _radian )
473- )
474+
475+ if isinstance (force_constants , _GeneralUnit ):
476+ converted_fc = force_constants / (
477+ _kj_per_mol / (_radian * _radian )
478+ )
479+ else :
480+ converted_fc = self ._restraint_dict ["force_constants" ][force_constants ] / (
481+ _kj_per_mol / (_radian * _radian )
482+ )
483+
474484 par_string = (
475485 dihedral_restraints_parameters_string
476486 if restraint_lambda
477487 else parameters_string
478488 )
479489 return par_string .format (
480490 eq0 = "{:.3f}" .format (converted_equ_val ),
481- fc0 = "{:.2f}" .format (0 ),
491+ fc0 = "{:.2f}" .format (0 if perturbed else converted_fc ),
482492 eq1 = "{:.3f}" .format (converted_equ_val ),
483493 fc1 = "{:.2f}" .format (converted_fc ),
484494 )
@@ -493,12 +503,12 @@ def write_bond(key_list, equilibrium_values, force_constants):
493503 parameters = format_bond (equilibrium_values , force_constants ),
494504 )
495505
496- def write_angle (key_list , equilibrium_values , force_constants ):
506+ def write_angle (key_list , equilibrium_values , force_constants , func_type = 1 , perturbed = True ):
497507 return master_string .format (
498508 index = format_index (key_list ),
499- func_type = 1 ,
509+ func_type = func_type ,
500510 parameters = format_angle (
501- equilibrium_values , force_constants , restraint_lambda = False
511+ equilibrium_values , force_constants , restraint_lambda = False , perturbed = perturbed
502512 ),
503513 )
504514
@@ -539,6 +549,22 @@ def write_dihedral(
539549 output .append (write_angle (("r2" , "r1" , "l1" ), "thetaA0" , "kthetaA" ))
540550 # Angles: r1-l1-l2 (thetaB0, kthetaB)
541551 output .append (write_angle (("r1" , "l1" , "l2" ), "thetaB0" , "kthetaB" ))
552+ # Bent angle: r2-r1-l1
553+ # Center is 90 degree
554+ # force constant is set by evaluating the free energy of adding a harmonic angle potential with fc at kcal/mol/rad2 at 135 degree
555+ #| fc (kcal/mol/rad2) | FE (kcal/mol) |
556+ #|--------------------|---------------|
557+ #| control | 1.05 |
558+ #| 0 | 1.05 |
559+ #| 0.1 | 0.99 |
560+ #| 1 | 1.17 |
561+ #| 5 | 2.14 |
562+ #| 10 | 3.46 |
563+ #| 100 | 14.92 |
564+ # Thus 1 kcal/mol/rad2 is choosen
565+ output .append (write_angle (("r2" , "r1" , "l1" ), 90 * _degree , 1 * _kcal_per_mol / _radian ** 2 , func_type = 10 , perturbed = False ))
566+ # Bent angle: r2-r1-l1
567+ output .append (write_angle (("r1" , "l1" , "l2" ), 90 * _degree , 1 * _kcal_per_mol / _radian ** 2 , func_type = 10 , perturbed = False ))
542568
543569 if restraint_lambda :
544570 output .append ("[ dihedral_restraints ]" )
0 commit comments