Processor::Result ResidueChecker::operator () (Residue& residue) { String res_name; if ((residue.getChain() != 0) && (residue.getChain()->getName() != BALL_CHAIN_DEFAULT_NAME)) { res_name = residue.getChain()->getName() + ":"; } res_name += residue.getName() + ":" + residue.getID(); // Check charges. status_ &= checkCharge(residue, res_name); // Check atom positions. status_ &= checkAtomPositions(residue, res_name); // if a fragment data base is defined, check for completeness // of the residue if (fragment_db_ != 0) { const Residue* reference = dynamic_cast<const Residue*>(fragment_db_->getReferenceFragment(residue)); if (reference == 0) { if (isEnabled(UNKNOWN_RESIDUES)) { Log.warn() << "ResidueChecker: didn't find a reference fragment for " << res_name << endl; status_ = false; // If selection is enabled, mark the whol residue if (selection_) { residue.select(); } } } else { status_ &= checkCompleteness(residue, *reference, res_name); status_ &= checkTemplate(residue, *reference, res_name); } } return Processor::CONTINUE; }
CHECK(const Chain* getChain() const throw()) Chain c1("X"); SecondaryStructure s1("s1"); c1.append(s1); const Chain p2(c1); TEST_EQUAL(s1.getChain()->getName(), "X") RESULT CHECK(Residue* getResidue(Position position) throw()) SecondaryStructure s1("s1"); TEST_EQUAL(s1.getResidue(0), 0) Residue r1("X"); s1.insert(r1); s1.getResidue(0)->setName("r1"); TEST_EQUAL(r1.getName(), "r1") RESULT CHECK(const Residue* getResidue(Position position) const throw()) SecondaryStructure s1("s1"); TEST_EQUAL(s1.getResidue(0), 0) Residue r1("r1"); s1.insert(r1); TEST_EQUAL(s1.getResidue(0), &r1) RESULT CHECK(PDBAtom* getPDBAtom(Position position) throw()) SecondaryStructure s1("s1"); TEST_EQUAL(s1.getPDBAtom(0), 0) PDBAtom a1("x"); Residue r1;
void MolecularInformation::getName_(Composite& composite) { String temp = "UNKNOWN"; switch(type_) { case TYPE__BOND: { temp.clear(); Bond* bond = RTTI::castTo<Bond>(composite); Atom* a1 = (Atom*) bond->getFirstAtom(); Atom* a2 = (Atom*) bond->getSecondAtom(); temp = getBondAtomName_(a1) + " -> " + getBondAtomName_(a2); } break; case TYPE__SYSTEM: { System* system = RTTI::castTo<System>(composite); temp = system->getName(); } break; case TYPE__RESIDUE: { Residue* residue = RTTI::castTo<Residue>(composite); temp = residue->getName(); temp += " "; temp += residue->getID(); } break; case TYPE__MOLECULE: case TYPE__PROTEIN: case TYPE__CHAIN: case TYPE__FRAGMENT: case TYPE__SECONDARY_STRUCTURE: { AtomContainer* atom_container = RTTI::castTo<AtomContainer>(composite); temp = atom_container->getName(); } break; case TYPE__ATOM: { Atom* atom = RTTI::castTo<Atom>(composite); temp = atom->getName(); } break; default: break; } if (type_ == TYPE__SECONDARY_STRUCTURE) { const SecondaryStructure* ss = dynamic_cast<SecondaryStructure*>(&composite); if (ss != 0) { switch (ss->getType()) { case SecondaryStructure::HELIX: temp += " Helix"; break; case SecondaryStructure::TURN: temp += " Turn"; break; case SecondaryStructure::STRAND: temp += " Strand"; break; case SecondaryStructure::COIL: temp += " Coil"; break; default: temp += " Unknown"; } } else { temp += " Unknown"; } } else { if (temp == "") { temp = "<"; temp += type_name_; temp += ">"; } } name_ = temp; }
bool ResidueChecker::checkCompleteness (const Residue& residue, const Residue& reference, const String& res_name) { // Make sure we are suppose to do this. if (!isEnabled(EXTRA_ATOMS) && !isEnabled(MISSING_ATOMS)) { return true; } bool result = true; // First, check for completeness HashSet<String> reference_names; AtomConstIterator atom_it; for (atom_it = reference.beginAtom(); +atom_it; ++atom_it) { reference_names.insert(atom_it->getName()); } // Check for extra atoms in the residue. for (atom_it = residue.beginAtom(); +atom_it; ++atom_it) { if (reference_names.has(atom_it->getName())) { reference_names.erase(atom_it->getName()); } else if (isEnabled(EXTRA_ATOMS)) { Log.warn() << "ResidueChecker: did not find atom " << atom_it->getName() << " of " << res_name << " in the reference residue " << reference.getName() << endl; result = false; // If selection is enabled, mark the residue if (selection_) { const_cast<Residue&>(residue).select(); } } } // Check for missing atoms in the residue. if (isEnabled(MISSING_ATOMS) && (reference_names.size() > 0)) { Log.warn() << "ResidueChecker: did not find the following atoms in " << res_name << " : "; HashSet<String>::Iterator set_it = reference_names.begin(); for (; set_it != reference_names.end(); ++set_it) { Log.warn() << *set_it << " "; } Log.warn() << " (template was " << reference.getName() << ")" << endl; result = false; // If selection is enabled, mark the residue if (selection_) { const_cast<Residue&>(residue).select(); } } return result; }
//TODO switch to real Angle float calculateResidueChiAngles(const Residue& residue) { // some variables Atom const* N = 0; Atom const* CA = 0; Atom const* CB = 0; Atom const* X = 0; int num_of_atoms = 0; float angle = 0;//FLOAT_VALUE_NA; String residue_name = residue.getName(); // we assume that GLY has no typical CHI_1 - angle if (residue_name == "GLY" ) { return angle; } AtomConstIterator r_it = residue.beginAtom(); for (; r_it != residue.endAtom(); ++r_it) { String name = r_it->getName(); if (name == "N") { N = &(*r_it); num_of_atoms += 1; } else if (name == "CA") { CA = &(*r_it); num_of_atoms += 1; } else if (name == "CB") { CB = &(*r_it); num_of_atoms += 1; } } if (num_of_atoms != 3) { Log.info() << "calculateResidueChiAngles: Torsion angle of " << residue_name<< std::endl; return angle; } // determine the missing atom X /* Sidechain dihedral angle chi1 is defined (for non-Gly residues) as follows: Chi1: N(i)-CA(i)-CB(i)-X(i) where X is the following atom for the following residue types: X Residue type ---- ---------------------------- HB1 Ala (for models with protons,labelled 1HB in PDB files). SG Cys CG Asp, Glu, Phe, His, Lys, Leu, Met, Asn, Pro, Gln, Arg, Trp, Tyr CG1 Ile, Val OG Ser OG1 Thr In order to be conform with ShiftX we leave out GLY and ALA */ if (residue_name == "GLY") { Log.info() << "calculateResidueChiAngles: Torsion angle of a Glycine could not be computed!" << std::endl; return angle; } else if (residue_name == "ALA") { r_it = residue.beginAtom(); for (;r_it != residue.endAtom(); ++r_it) { if (r_it->getName() == "HB1" || r_it->getName() == "1HB") { X = &(*r_it); num_of_atoms += 1; break; } } } else if (residue_name == "CYS") { r_it = residue.beginAtom(); for (;r_it != residue.endAtom(); ++r_it) { if (r_it->getName() == "SG") { X = &(*r_it); num_of_atoms += 1; break; } } } else if (residue_name == "ASP" || residue_name == "GLU" || residue_name == "PHE" || residue_name == "HIS" || residue_name == "LYS" || residue_name == "LEU" || residue_name == "MET" || residue_name == "ASN" || residue_name == "PRO" || residue_name == "GLN" || residue_name == "ARG" || residue_name == "TRP" || residue_name == "TYR") { r_it = residue.beginAtom(); for (;r_it != residue.endAtom(); ++r_it) { if (r_it->getName() == "CG") { X = &(*r_it); num_of_atoms += 1; break; } } } else if (residue_name == "VAL" || residue_name == "ILE") { r_it = residue.beginAtom(); for (;r_it != residue.endAtom(); ++r_it) { if (r_it->getName() == "CG1") { X = &(*r_it); num_of_atoms += 1; break; } } } else if (residue_name == "SER") { r_it = residue.beginAtom(); for (;r_it != residue.endAtom(); ++r_it) { if (r_it->getName() == "OG") { X = &(*r_it); num_of_atoms += 1; break; } } } else if (residue_name == "THR") { r_it = residue.beginAtom(); for (;r_it != residue.endAtom(); ++r_it) { if (r_it->getName() == "OG1") { X = &(*r_it); num_of_atoms += 1; break; } } } if (num_of_atoms != 4) { Log.info() << "calculateResidueChiAngles: Chi torsion angle of " << residue.getID() << "-"<< residue.getName() << " could not be computed!" << std::endl; return angle; } Vector3 a = N->getPosition(); Vector3 b = CA->getPosition(); Vector3 c = CB->getPosition(); Vector3 d = X->getPosition(); //angle = getTorsionAngle(a.x, a.y, a.z, b.x, b.y, b.z, // c.x, c.y, c.z, d.x, d.y, d.z)*180./M_PI; angle = calculateTorsionAngle(*N,*CA,*CB,*X).toRadian(); while (angle < 0.) { angle = angle + 2*BALL::Constants::PI; } return angle; // TODO return real angle }
//TODO switch to real Angle float calculateResidueChi2Angles(const Residue& residue) { // some variables Atom const* CA = 0; Atom const* CB = 0; Atom const* CG = 0; Atom const* XG = 0; int num_of_atoms = 0; float angle = 0; // FLOAT_VALUE_NA; String residue_name = residue.getName(); // GLY, ALA, SER and CYS have no typical CHI2 - angle if ( (residue_name == "ALA") || (residue_name == "GLY") || (residue_name == "SER") || (residue_name == "CYS")) { Log.info() << "calculateResidueChi2Angles: Chi torsion angle of " << residue.getID() << "-"<< residue.getName() << " could not be computed!" << std::endl; return angle; } // Sidechain dihedral angle chi2 is defined as follows: // // Chi2: CA(i)-CB(i)-CG(i)-XG(i) // where XG is the following atom for the following // residue types: // // CG XG residue // ------------------------------------- // CG CD PRO, GLN, GLU, LYS, ARG // CD1 LEU,TRP,PHE,TYR, // OD1 ASN, ASP // ND1 HIS // SD MET // CG1 CD1 ILE // 1HG1 VAL // CG2 (1HG2 VAL) // 1HG2 THR // // Note: in some amino acids the atom names can be switched, i.e. // for chi2 in amino acids PHE: CD1 <-> CD2 // TYR: CD1 <-> CD2 // ASP: OD1 <-> OD2 AtomConstIterator r_it = residue.beginAtom(); for (; r_it != residue.endAtom(); ++r_it) { String name = r_it->getName(); if (name == "CA") { CA = &(*r_it); num_of_atoms += 1; } else if (name == "CB") { CB = &(*r_it); num_of_atoms += 1; } if (name == "CG") { CG = &(*r_it); num_of_atoms += 1; } } //look for XG if ( (residue_name == "ARG") || (residue_name == "GLN") || (residue_name == "GLU") || (residue_name == "LYS") || (residue_name == "PRO")) { r_it = residue.beginAtom(); for (;r_it != residue.endAtom(); ++r_it) { if (r_it->getName() == "CD") { XG = &(*r_it); num_of_atoms += 1; break; } } } else if ( (residue_name == "ASN") || (residue_name == "ASP") ) { r_it = residue.beginAtom(); for (;r_it != residue.endAtom(); ++r_it) { if (r_it->getName() == "OD1") { XG = &(*r_it); num_of_atoms += 1; break; } } } else if ( (residue_name == "LEU") || (residue_name == "TRP") ||(residue_name == "PHE") || (residue_name == "TYR") ) { r_it = residue.beginAtom(); for (;r_it != residue.endAtom(); ++r_it) { if (r_it->getName() == "CD1") { XG = &(*r_it); num_of_atoms += 1; break; } } } else if (residue_name == "HIS") { r_it = residue.beginAtom(); for (;r_it != residue.endAtom(); ++r_it) { if (r_it->getName() == "ND1") { XG = &(*r_it); num_of_atoms += 1; break; } } } else if(residue_name == "MET") { r_it = residue.beginAtom(); for (;r_it != residue.endAtom(); ++r_it) { if (r_it->getName() == "SD") { XG = &(*r_it); num_of_atoms += 1; break; } } } // we have to take special care about ILE, VAL and THR else if(residue_name == "ILE") { r_it = residue.beginAtom(); for (;r_it != residue.endAtom(); ++r_it) { if (r_it->getName() == "CG1") { CG = &(*r_it); num_of_atoms += 1; } else if (r_it->getName() == "CD1") { XG = &(*r_it); num_of_atoms += 1; } } } else if(residue_name == "VAL") { r_it = residue.beginAtom(); for (;r_it != residue.endAtom(); ++r_it) { if (r_it->getName() == "1HG1") { XG = &(*r_it); num_of_atoms += 1; } else if (r_it->getName() == "CG1") { CG = &(*r_it); num_of_atoms += 1; } } } else if(residue_name == "THR") { r_it = residue.beginAtom(); for (;r_it != residue.endAtom(); ++r_it) { if (r_it->getName() == "1HG2") { XG = &(*r_it); num_of_atoms += 1; } else if (r_it->getName() == "CG2") { CG = &(*r_it); num_of_atoms += 1; } } } if (num_of_atoms != 4) { Log.info() << "calculateResidueChi2Angles: Chi torsion angle of " << residue.getID() << "-"<< residue.getName() << " could not be computed!" << std::endl; return angle; } Vector3 a = CA->getPosition(); Vector3 b = CB->getPosition(); Vector3 c = CG->getPosition(); Vector3 d = XG->getPosition(); angle = calculateTorsionAngle(*CA,*CB,*CG,*XG).toRadian(); while (angle < 0.) { angle = angle + 2*BALL::Constants::PI; } return angle; // TODO return real angle }
START_SECTION((static double getCIonPlusTwoToFullAverageWeight())) TEST_REAL_SIMILAR(e_ptr->getCIonPlusTwoToFullAverageWeight(), 2.01588) END_SECTION START_SECTION((static double getCIonPlusTwoToFullMonoWeight())) TEST_REAL_SIMILAR(e_ptr->getCIonPlusTwoToFullMonoWeight(), 2.0156500638) END_SECTION START_SECTION(Residue(const Residue &residue)) Residue copy(*e_ptr); TEST_EQUAL(copy, *e_ptr) END_SECTION START_SECTION(Residue(const String &name, const String &three_letter_code, const String &one_letter_code, const EmpiricalFormula &formula)) Residue copy(e_ptr->getName(), e_ptr->getThreeLetterCode(), e_ptr->getOneLetterCode(), e_ptr->getFormula()); TEST_EQUAL(copy.getName(), e_ptr->getName()) TEST_EQUAL(copy.getThreeLetterCode(), e_ptr->getThreeLetterCode()) TEST_EQUAL(copy.getOneLetterCode(), e_ptr->getOneLetterCode()) TEST_EQUAL(copy.getFormula(), e_ptr->getFormula()) END_SECTION START_SECTION(Residue& operator=(const Residue &residue)) Residue copy; copy = *e_ptr; TEST_EQUAL(copy, *e_ptr) END_SECTION START_SECTION(void setName(const String &name)) Residue copy(*e_ptr); e_ptr->setName("BLUBB"); TEST_NOT_EQUAL(copy, *e_ptr)
Structure* PDBReader::readStructure(Alphabet* alphabet, char* filename, const char* backboneAtomName) { FILE* infile = fopen(filename, "r"); if (infile == NULL) { return 0; } Structure* structure = new Structure(alphabet, filename); // Create the entries from the PDB file. char recordType[7]; char serialNumber[6]; char atomName[5]; char altLoc[2]; char residueName[4]; char chain[2]; char resID[5]; char insertion[2]; char x[9]; char y[9]; char z[9]; // Go through the file and parse out the records. char line[1024]; Coordinate3D backboneCoord; Residue* currentResidue = NULL; while (!feof(infile)) { // Get the next line. if (fgets(line, 1023, infile) == NULL) break; // Make sure this is an atom or hetatom record. parseField(recordType, line, 0, 6); if (strcmp(recordType, "ATOM") == 0 || strcmp(recordType, "HETATOM") == 0) { // Parse the fields. parseField(serialNumber, line, 6, 5); parseField(atomName, line, 12, 4); parseField(altLoc, line, 16, 1); parseField(residueName, line, 17, 3); parseField(chain, line, 21, 1); parseField(resID, line, 22, 4); parseField(insertion, line, 26, 1); parseField(x, line, 30, 8); parseField(y, line, 38, 8); parseField(z, line, 46, 8); // If this is a new residue, save the old one (if we have one) and start over. if (currentResidue == NULL || (strcmp(resID, currentResidue->getResID()) != 0 || strcmp(insertion, currentResidue->getInsertionName()) != 0)) { if (currentResidue != NULL) { structure->addResidue(currentResidue->getName(), backboneCoord, currentResidue); } // Start the new residue. backboneCoord.unset(); currentResidue = new Residue(residueName, resID, insertion); } // If this is a backbone atom, save it. if (strcmp(atomName, backboneAtomName) == 0) { backboneCoord.set(charToFloat(x), charToFloat(y), charToFloat(z)); } // Add the atom to the list. currentResidue->addAtom(new Atom(atomName, charToFloat(x),charToFloat(y),charToFloat(z))); } else if (strcmp(recordType, "TER") == 0) { break; } } // If we have one last residue, save it. if (currentResidue != NULL) { structure->addResidue(currentResidue->getName(), backboneCoord, currentResidue); } fclose(infile); return structure; }