// **************************************************************************** // Name: ProteinDeeSpace.h // By: Mark Voorhies and Navin Pokala // On: 6/24/2003 // Time-stamp: // Implimented in: ProteinDeeSpace.cpp // Description: // ProteinDeeSpace implements the DeeSpace object in terms of the EGAD // PROTEIN struct. // **************************************************************************** #ifndef MSV_PROTEINDEESPACE_HEADER_FLAG #define MSV_PROTEINDEESPACE_HEADER_FLAG #include "DeeSpace.h" #include #include struct PROTEIN; struct CHROMOSOME; class ProteinDeeSpace : public DeeSpace { // ============================================================ // Private Data and Member Functions // ============================================================ private: struct PosInfo { // Backbone positions unified at this "super"-position. The values are // indices into the PROTEIN.var_pos array. Since var_pos is an EGAD // array, indexing starts at 1 for these values. std::list Pos; // "Super"-resimers allowed at this "super"-position. If pos.size() == 1, // then res holds simple resimer indices. Otherwise, the values in res // are a function of the available resimers at each element of pos and // may be decomposed into simple resimer indices using UnpackResimers. // Simple resimer indices can be translated into EGAD resimer indices // using the ResimerMap array. std::vector Res; PosInfo() : Pos(0), Res(0){} PosInfo(unsigned int iPosition, unsigned int iNumRes) : Pos(1, iPosition), Res(iNumRes) { for(unsigned int i = 0; i < iNumRes; ++i) { Res[i] = i; } } }; // EGAD energy and sequence data const PROTEIN *protein; // Set of variable positions in this space std::vector VariablePositions; // Set of positions whose resimer identity has been determined. The indexing // is the same as for PosInfo.Pos. The resimer identity for a particular // fixed position can be found in the ResimerMap array (fixed positions will // have only a single resimer entry). std::list FixedPositions; // ResimerMap maps a reduced set of resimer indices to the original set of // resimer indices for each backbone position. The purpose of this layer // is to reduce the amount of memory required for storing elimination tables // after several rounds of unification. std::vector > ResimerMap; // Self energy for each resimer, i.e. the component of this resimer's energy // that is independent of other variable positions. ResimerMap[pos][res] // corresponds to VariablePositions[pos]->Res[res]. std::vector > self_energy; // Energy for fixed interactions, i.e. the component of the total energy that // is independent of the variable positions. double fixed_energy; // Given a list of positions, corresponding to VariablePositions[i]->Pos, // returns a list of indices into ResimerMap, corresponding to the resimers // of super-resimer v at i. // (e.g. ures = UnpackResimers(VariablePositions[i]->Pos, // VariablePositions[i]->Res[r]); // x = ResimerMap[VariablePositions[i]->Pos[0]][ures.front()]; // sets x to the appropriate resimer index for the first backbone position // of super-resimer r at i.) // std::list UnpackResimers(const std::list& pos, // unsigned int v) const; // Input: pos is an index into VariablePositions // resimer is an index into VariablePositions[pos]->Res // Output: list of resimer indices compatible with protein->var_pos std::list UnpackResimers(const unsigned int pos, unsigned int resimer) const; void PackResimers(unsigned int i, unsigned int j); public: // ================================================== // Construction/Destruction // ================================================== ProteinDeeSpace(const PROTEIN *prot_i); ProteinDeeSpace(const ProteinDeeSpace& rhs); virtual ~ProteinDeeSpace(); // ================================================== // Operators // ================================================== ProteinDeeSpace& operator=(const ProteinDeeSpace& rhs); // ================================================== // Functions definining the design space // ================================================== // Number of variable positions in the design space virtual unsigned int NumPos() const {return VariablePositions.size();} // Number of resimer choices at pos virtual unsigned int NumResimers(unsigned int pos) const {return VariablePositions[pos]->Res.size();} // ================================================== // Functions describing the design space in terms // of the real world // ================================================== // Name of position pos (e.g. "28A") virtual std::string PosID(unsigned int pos) const; // Name of resimer at pos (e.g. "14") virtual std::string ResimerID(unsigned int pos, unsigned int resimer) const; // Name of residue for resimer at pos (e.g. "GLU") virtual std::string ResType(unsigned int pos, unsigned int resimer) const; // Dump resimer values of fixed positions virtual void DumpFixedPositions() const; // Convert a converged space to an EGAD CHROMOSOME. chr is assumed to // be a pre-allocated CHROMOSOME and is filled in with the appropriate // data. The function returns 1 on success, 0 on failure. In the case // of failure, the state of chr is undefined (we can change this). If // soln is non-zero, it should have size equal to the number of undetermined // positions (in theory, this means (soln->size() == NumPos), but this can // fail if some positions have been determined but not fixed. Therefore, // all solved positions should be fixed using FixPos() prior to generating // soln. In this case, the values in soln indicate resimer choices for // the undetermined positions and chr will be filled in accordingly. int DeeSoln_to_CHROMOSOME(CHROMOSOME *chr, const std::vector *soln = 0) const; // ================================================== // Accessor Functions for the Energy Table // ================================================== // Get true sidechain-sidechain energy between two positions virtual double Get(unsigned int ipos, unsigned int ires, unsigned int jpos, unsigned int jres) const; // Get true sidechain-template energy for a single position virtual double Get(unsigned int ipos, unsigned int ires) const { // Note: This implementation requires us to update all self_energy values // during unification. return self_energy[ipos][ires]; //return self_energy.at(ipos).at(ires); } // pair_energy folds the self energies into the pairwise energy terms // (useful for bounding calculations) virtual double pair_energy(unsigned int ipos, unsigned int ires, unsigned int jpos, unsigned int jres) const; // Get the component of the energy that is independent of the variable // positions. This value should change when variable positions are // removed from the design space. virtual double FixedEnergy() const { return fixed_energy; } // ================================================== // Functions modifying the description of the Space // ================================================== // Fuse positions i and j into a single "super-rotamer" position virtual void Unify(unsigned int i, unsigned int j); // Remove position i from the space, fixing it at resimer r virtual void FixPos(unsigned int i, unsigned int r); // Remove positions i to j from the space, fixing them to the resimer // values in vecR virtual void FixPos(unsigned int i, unsigned int j, const std::vector& vecR); // Remove resimer choice r at i from the space. All indices greater than // r at i will be shifted down by 1. virtual void RemoveRes(unsigned int i, unsigned int r); // Remove resimer choices r through s at i. All indices greater than s // at i will be shifted down by (r - s + 1) virtual void RemoveRes(unsigned int i, unsigned int r, unsigned int s); }; #endif