<commit_before>#ifndef JARNGREIPR_FORCEFIELD_AICG2_PLUS_H
#define JARNGREIPR_FORCEFIELD_AICG2_PLUS_H
#include <jarngreipr/forcefield/ForceFieldGenerator.hpp>
#include <jarngreipr/geometry/distance.hpp>
#include <jarngreipr/geometry/angle.hpp>
#include <jarngreipr/geometry/dihedral.hpp>
#include <mjolnir/util/get_toml_value.hpp>
#include <iterator>
#include <algorithm>
#include <iostream>
#include <vector>
#include <limits>

namespace jarngreipr
{

template<typename realT>
class AICG2Plus final : public IntraChainForceFieldGenerator<realT>
{
  public:
    typedef IntraChainForceFieldGenerator<realT> base_type;
    typedef typename base_type::real_type real_type;
    typedef typename base_type::bead_type bead_type;

  public:

    AICG2Plus(const toml::Table& para, const std::vector<std::size_t>& flex);
    ~AICG2Plus() override = default;

    // generate parameters and write out to `ostrm`.
    void generate(toml::Table& out,
        const std::vector<std::unique_ptr<bead_type>>& chain) const override;

    bool check_beads_kind(
        const std::vector<std::unique_ptr<bead_type>>& chain) const override;

  private:

    bool is_flexible_region(const std::size_t bead_idx) const
    {
        return std::binary_search(this->flexible_beads_.begin(),
                                  this->flexible_beads_.end(), bead_idx);
    }

    bool is_backbone(const PDBAtom<realT>& atom) const
    {
        return (atom.atom_name == " N  " || atom.atom_name == " C  " ||
                atom.atom_name == " O  " || atom.atom_name == " OXT" ||
                atom.atom_name == " CA ");
    }
    bool is_sidechain(const PDBAtom<realT>& atom) const
    {
        return !is_backbone(atom) &&
            atom.atom_name.at(0) != 'H' && atom.atom_name.at(1) != 'H';
    }

    bool is_donor(const PDBAtom<realT>& atom) const
    {
        return (atom.atom_name.at(1) == 'N' ||
                (atom.residue_name == "SER" && atom.atom_name == " OG ") ||
                (atom.residue_name == "THR" && atom.atom_name == " OG1") ||
                (atom.residue_name == "TYR" && atom.atom_name == " OH ") ||
                (atom.residue_name == "CYS" && atom.atom_name.at(1) == 'S'));
    }
    bool is_acceptor(const PDBAtom<realT>& atom) const
    {
        return (atom.atom_name.at(1) == 'O' || atom.atom_name.at(1) == 'S');
    }
    bool is_cation(const PDBAtom<realT>& atom) const
    {
	    return ((atom.residue_name == "ARG" && atom.atom_name == " NH1") ||
                (atom.residue_name == "ARG" && atom.atom_name == " NH2") ||
                (atom.residue_name == "LYS" && atom.atom_name == " NZ "));
    }
    bool is_anion(const PDBAtom<realT>& atom) const
    {
		return ((atom.residue_name == "GLU" && atom.atom_name == " OE1") ||
                (atom.residue_name == "GLU" && atom.atom_name == " OE2") ||
                (atom.residue_name == "ASP" && atom.atom_name == " OD1") ||
                (atom.residue_name == "ASP" && atom.atom_name == " OD2"));
    }
    bool is_carbon(const PDBAtom<realT>& atom) const
    {
        return (atom.atom_name.at(1) == 'C');
    }

    real_type calc_contact_coef(const std::unique_ptr<bead_type>& bead1,
                                const std::unique_ptr<bead_type>& bead2) const;

    real_type min_distance_sq(const std::unique_ptr<bead_type>& bead1,
                              const std::unique_ptr<bead_type>& bead2) const
    {
        real_type min_dist = std::numeric_limits<real_type>::max();
        for(const auto& atom1 : bead1->atoms())
        {
            for(const auto& atom2 : bead2->atoms())
            {
                const real_type dist = distance_sq(atom1.position, atom2.position);
                if(dist < min_dist) {min_dist = dist;}
            }
        }
        return min_dist;
    }

    real_type limit_energy(const real_type val) const
    {
        if(val >= this->e_max_) {return e_max_;}
        if(val <= this->e_min_) {return e_min_;}
        return val;
    }

  private:
<commit_msg>ignore hydrogens when detecting native contacts<commit_after>#ifndef JARNGREIPR_FORCEFIELD_AICG2_PLUS_H
#define JARNGREIPR_FORCEFIELD_AICG2_PLUS_H
#include <jarngreipr/forcefield/ForceFieldGenerator.hpp>
#include <jarngreipr/geometry/distance.hpp>
#include <jarngreipr/geometry/angle.hpp>
#include <jarngreipr/geometry/dihedral.hpp>
#include <mjolnir/util/get_toml_value.hpp>
#include <iterator>
#include <algorithm>
#include <iostream>
#include <vector>
#include <limits>

namespace jarngreipr
{

template<typename realT>
class AICG2Plus final : public IntraChainForceFieldGenerator<realT>
{
  public:
    typedef IntraChainForceFieldGenerator<realT> base_type;
    typedef typename base_type::real_type real_type;
    typedef typename base_type::bead_type bead_type;

  public:

    AICG2Plus(const toml::Table& para, const std::vector<std::size_t>& flex);
    ~AICG2Plus() override = default;

    // generate parameters and write out to `ostrm`.
    void generate(toml::Table& out,
        const std::vector<std::unique_ptr<bead_type>>& chain) const override;

    bool check_beads_kind(
        const std::vector<std::unique_ptr<bead_type>>& chain) const override;

  private:

    bool is_flexible_region(const std::size_t bead_idx) const
    {
        return std::binary_search(this->flexible_beads_.begin(),
                                  this->flexible_beads_.end(), bead_idx);
    }

    bool is_backbone(const PDBAtom<realT>& atom) const
    {
        return (atom.atom_name == " N  " || atom.atom_name == " C  " ||
                atom.atom_name == " O  " || atom.atom_name == " OXT" ||
                atom.atom_name == " CA ");
    }
    bool is_sidechain(const PDBAtom<realT>& atom) const
    {
        return !is_backbone(atom) &&
            atom.atom_name.at(0) != 'H' && atom.atom_name.at(1) != 'H';
    }

    bool is_donor(const PDBAtom<realT>& atom) const
    {
        return (atom.atom_name.at(1) == 'N' ||
                (atom.residue_name == "SER" && atom.atom_name == " OG ") ||
                (atom.residue_name == "THR" && atom.atom_name == " OG1") ||
                (atom.residue_name == "TYR" && atom.atom_name == " OH ") ||
                (atom.residue_name == "CYS" && atom.atom_name.at(1) == 'S'));
    }
    bool is_acceptor(const PDBAtom<realT>& atom) const
    {
        return (atom.atom_name.at(1) == 'O' || atom.atom_name.at(1) == 'S');
    }
    bool is_cation(const PDBAtom<realT>& atom) const
    {
	    return ((atom.residue_name == "ARG" && atom.atom_name == " NH1") ||
                (atom.residue_name == "ARG" && atom.atom_name == " NH2") ||
                (atom.residue_name == "LYS" && atom.atom_name == " NZ "));
    }
    bool is_anion(const PDBAtom<realT>& atom) const
    {
		return ((atom.residue_name == "GLU" && atom.atom_name == " OE1") ||
                (atom.residue_name == "GLU" && atom.atom_name == " OE2") ||
                (atom.residue_name == "ASP" && atom.atom_name == " OD1") ||
                (atom.residue_name == "ASP" && atom.atom_name == " OD2"));
    }
    bool is_carbon(const PDBAtom<realT>& atom) const
    {
        return (atom.atom_name.at(1) == 'C');
    }

    real_type calc_contact_coef(const std::unique_ptr<bead_type>& bead1,
                                const std::unique_ptr<bead_type>& bead2) const;

    real_type min_distance_sq(const std::unique_ptr<bead_type>& bead1,
                              const std::unique_ptr<bead_type>& bead2) const
    {
        real_type min_dist = std::numeric_limits<real_type>::max();
        for(const auto& atom1 : bead1->atoms())
        {
            if(atom1.element == " H") {continue;}
            for(const auto& atom2 : bead2->atoms())
            {
                if(atom2.element == " H") {continue;}
                const real_type dist = distance_sq(atom1.position, atom2.position);
                if(dist < min_dist) {min_dist = dist;}
            }
        }
        return min_dist;
    }

    real_type limit_energy(const real_type val) const
    {
        if(val >= this->e_max_) {return e_max_;}
        if(val <= this->e_min_) {return e_min_;}
        return val;
    }

  private:

{'fraction_non_alphanumeric': 0.14345267287886218, 'fraction_numerical': 0.007356547327121138, 'mean_word_length': 2.6156914893617023, 'pattern_counts': {'":': 0, '<': 67, '<?xml version=': 0, '>': 77, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3086311', 'n_tokens_mistral': 2922, 'n_tokens_neox': 2790, 'n_words': 511}