Source code for openff.bespokefit.optimizers.forcebalance.templates

import abc
import os
from typing import Dict, Generic, List, Set, TypeVar

from jinja2 import Template
from openff.utilities import get_data_file_path

from openff.bespokefit.schema.optimizers import ForceBalanceSchema
from openff.bespokefit.schema.targets import (
    AbInitioTargetSchema,
    OptGeoTargetSchema,
    TargetSchema,
    TorsionProfileTargetSchema,
    VibrationTargetSchema,
)

T = TypeVar("T", bound=TargetSchema)


[docs]class BaseTargetTemplate(Generic[T]):
[docs] @classmethod @abc.abstractmethod def template_name(cls) -> str: raise NotImplementedError()
[docs] @classmethod def schema_exclusions(cls) -> Set[str]: return set()
[docs] @classmethod def generate(cls, schema: T, target_names: List[str]) -> str: template_file_name = get_data_file_path( os.path.join("templates", "force-balance", cls.template_name()), "openff.bespokefit", ) with open(template_file_name) as file: template = Template(file.read()) rendered_template = "\n\n".join( template.render( name=target_name, **schema.dict( exclude={"type", "reference_data", *cls.schema_exclusions()} ), ) for target_name in target_names ) return rendered_template
[docs]class AbInitioTargetTemplate(BaseTargetTemplate[AbInitioTargetSchema]):
[docs] @classmethod def template_name(cls) -> str: return "ab-initio-target.txt"
[docs]class TorsionProfileTargetTemplate(BaseTargetTemplate[TorsionProfileTargetSchema]):
[docs] @classmethod def template_name(cls) -> str: return "torsion-profile-target.txt"
[docs]class OptGeoTargetTemplate(BaseTargetTemplate[OptGeoTargetSchema]):
[docs] @classmethod def template_name(cls) -> str: return "opt-geo-target.txt"
[docs]class VibrationTargetTemplate(BaseTargetTemplate[VibrationTargetSchema]):
[docs] @classmethod def template_name(cls) -> str: return "vibration-target.txt"
[docs]class OptGeoOptionsTemplate:
[docs] @classmethod def schema_exclusions(cls) -> Set[str]: return { "bond_denominator", "angle_denominator", "dihedral_denominator", "improper_denominator", }
[docs] @classmethod def generate(cls, target: OptGeoTargetSchema, record_ids: List[str]) -> str: template_file_name = get_data_file_path( os.path.join("templates", "force-balance", "opt-geo-options.txt"), "openff.bespokefit", ) with open(template_file_name) as file: template = Template(file.read()) rendered_template = template.render( **target.dict(include=cls.schema_exclusions()), systems=record_ids ) return rendered_template
[docs]class InputOptionsTemplate:
[docs] @classmethod def generate( cls, settings: ForceBalanceSchema, priors: Dict[str, float], targets_section: str, ) -> str: template_file_name = get_data_file_path( os.path.join("templates", "force-balance", "optimize.txt"), "openff.bespokefit", ) with open(template_file_name) as file: template = Template(file.read()) rendered_template = template.render( **settings.dict(), priors=priors, targets_contents=targets_section ) return rendered_template