<commit_before>from ReportGenerator.Geom import Geom
from ReportComponents.Plot import Plot
from ReportGenerator.Top_ReportGenerator import Top_ReportGenerator
from ReportComponents.WebFile import WebFile
from ReportGenerator.Charges import Charges

import logging
log = logging.getLogger(__name__)

class Opt(Top_ReportGenerator):
    def __init__(self,we,parsed):
        super().__init__(we,parsed)
        self.multiple_geoms = False

    def prepare_for_report(self):
        self.opt_ok = (self.parsed.last_value('P_opt_ok')=='True')
        self.do_opt_progress = self.settings.FullGeomInfo or not self.opt_ok
        self.n_steps = self.parsed.last_value('P_opt_iter')

        if self.do_opt_progress:
            self.prepare_opt_convergence()

        if self.opt_ok:
            self.charges = Charges(self.we, self.parsed)
        else:
            self.charges = None

        if self.do_opt_progress:
            self.parsed_g = self.parsed.data[1:]  # TODO 1 might be program-dependent
        else:
            self.parsed_g = [self.parsed]

    def prepare_opt_convergence(self):
        conv = {'max_force':[],'rms_force':[],'max_displacement':[],'rms_displacement':[]}
        for cnv_type in conv.keys():
            s = 'P_'+cnv_type
            conv[cnv_type] = [o.last_value(s) for o in self.parsed.data[1:] if o.last_value(s) is not None]
        conv = {k:v for k,v in conv.items() if len(v) > 0}  # remove absent convergence criteria
        if len(conv)==0:
            self.do_opt_progress = False
            log.debug('Did not find any convergence criteria for plotting')
        else:
            (self.ylab, self.yval) = zip(*conv.items())  # reshape them

    def opt_conv_plot_html(self):
        plt = Plot(fname='-opt-conv.png', xlab='x', ylab='Convergence', legend=self.ylab, x=None, y=self.yval)
        if plt.nonempty:
            plt.save_plot()
            return self.img_tag(plt.web_path)
        else:
            return 'Not enough data to produce convergence plot'

    def opt_steps(self):
        return "Steps: %s" % self.n_steps

    def save_geom(self):
        v = [str(Geom(self.we,g)) for g in self.parsed_g]
        self.multiple_geoms = (len(v) > 1)
        s_geoms = "\n".join(v)
        if not s_geoms:
            return ''
        return WebFile(fname='-opt.xyz',content=s_geoms).write()

    def load_in_jmol(self, webpath):
        if self.do_opt_progress:
            label = 'Geometry optimization, step @{_modelNumber}'
        else:
            label = 'Optimized geometry'
        cmd = [
            self.we.jmol_load_file(webpath),
            'frame last',
            self.we.jmol_text(label)
            ]
        return "; ".join(cmd)

    def jobtype_html(self):
        sx = self.strong_tag('OPT')
        if self.opt_ok:
            return sx
        else:
            return self.color_tag(sx, 'err')

    def report_text(self):
        if not self.opt_ok:
            self.add_right('Geometry optimization is incomplete!')

    def report_html(self):
        webpath = self.save_geom()
        if webpath:
            load_command = self.load_in_jmol(webpath)<commit_msg>added support for bond constraints in OPT jobs<commit_after>from ReportGenerator.Geom import Geom
from ReportComponents.Plot import Plot
from ReportGenerator.Top_ReportGenerator import Top_ReportGenerator
from ReportComponents.WebFile import WebFile
from ReportGenerator.Charges import Charges

import logging
log = logging.getLogger(__name__)

class Opt(Top_ReportGenerator):
    def __init__(self,we,parsed):
        super().__init__(we,parsed)
        self.multiple_geoms = False

    def prepare_for_report(self):
        self.opt_ok = (self.parsed.last_value('P_opt_ok')=='True')
        self.do_opt_progress = self.settings.FullGeomInfo or not self.opt_ok
        self.n_steps = self.parsed.last_value('P_opt_iter')
        self.measure_bonds = self.parsed.last_value('P_bond_constraints')

        if self.do_opt_progress:
            self.prepare_opt_convergence()

        if self.opt_ok:
            self.charges = Charges(self.we, self.parsed)
        else:
            self.charges = None

        if self.do_opt_progress:
            self.parsed_g = self.parsed.data[1:]  # TODO 1 might be program-dependent
        else:
            self.parsed_g = [self.parsed]

    def prepare_opt_convergence(self):
        conv = {'max_force':[],'rms_force':[],'max_displacement':[],'rms_displacement':[]}
        for cnv_type in conv.keys():
            s = 'P_'+cnv_type
            conv[cnv_type] = [o.last_value(s) for o in self.parsed.data[1:] if o.last_value(s) is not None]
        conv = {k:v for k,v in conv.items() if len(v) > 0}  # remove absent convergence criteria
        if len(conv)==0:
            self.do_opt_progress = False
            log.debug('Did not find any convergence criteria for plotting')
        else:
            (self.ylab, self.yval) = zip(*conv.items())  # reshape them

    def opt_conv_plot_html(self):
        plt = Plot(fname='-opt-conv.png', xlab='x', ylab='Convergence', legend=self.ylab, x=None, y=self.yval)
        if plt.nonempty:
            plt.save_plot()
            return self.img_tag(plt.web_path)
        else:
            return 'Not enough data to produce convergence plot'

    def opt_steps(self):
        return "Steps: %s" % self.n_steps

    def measurements(self):
        out = ['measure %s %s' % tuple(m) for m in self.measure_bonds]
        return "; ".join(out)

    def save_geom(self):
        v = [str(Geom(self.we,g)) for g in self.parsed_g]
        self.multiple_geoms = (len(v) > 1)
        s_geoms = "\n".join(v)
        if not s_geoms:
            return ''
        return WebFile(fname='-opt.xyz',content=s_geoms).write()

    def load_in_jmol(self, webpath):
        if self.do_opt_progress:
            label = 'Geometry optimization, step @{_modelNumber}'
        else:
            label = 'Optimized geometry'
        cmd = [
            self.we.jmol_load_file(webpath),
            'frame last',
            self.measurements(),
            self.we.jmol_text(label)
            ]
        return "; ".join(cmd)

    def jobtype_html(self):
        sx = self.strong_tag('OPT')
        if self.opt_ok:
            return sx
        else:
            return self.color_tag(sx, 'err')

    def report_text(self):
        if not self.opt_ok:
            self.add_right('Geometry optimization is incomplete!')

    def report_html(self):
        webpath = self.save_geom()
        if webpath:
            load_command = self.load_in_jmol(webpath)
{'fraction_non_alphanumeric': 0.1122945830797322, 'fraction_numerical': 0.0018259281801582471, 'mean_word_length': 2.362148337595908, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1436796', 'n_tokens_mistral': 2141, 'n_tokens_neox': 2098, 'n_words': 452}