float Docking::scoring(vector<Vector3> transPosB){ HashGridBox3<Vector3>* currentBox; HashGridBox3<Vector3>::BoxIterator box_it; HashGridBox3<Vector3>::DataIterator data_it; float distance; int contact = 0; int overlap = 0; int maxOverlap = 250; for (vector<Vector3>::iterator transPosB_it= transPosB.begin(); transPosB_it !=transPosB.end(); ++transPosB_it){ currentBox = grid.getBox(*transPosB_it); //getBox liefert 0 zurück falls außerhalb der HashGrid Dimension if (currentBox == 0){ continue; } box_it = currentBox->beginBox(); for (; +box_it; ++box_it){ //Alle Kombinationen aus Punkten werden angeschaut for (data_it = box_it->beginData(); data_it != box_it->endData(); ++data_it){ //berechne Abstand zwischen betrachtetem Punkt aus A und dem jetzt angeschauten distance = (*data_it-*transPosB_it).getSquareLength(); if (distance < 7.5625) { overlap++; //wenn overlap hier bereits überschritten, betrachte es nicht weiter if (overlap > maxOverlap) return 0; } else if (distance < 16) contact++; } } } //end positionsA if (contact < 650) return 0; ///TODO wieder aktivieren!! float k1 = 1.4; //Belohnung contakt float k2 = 1.8; //Strafe overlap float geomScore = k1*contact - k2* overlap; // if (contact > 700 && overlap < 250) cout << "Found more than 700 contacts and less than 250 overlaps!\nwith Score: " << geomScore << endl; return geomScore; }
Matrix4x4 DockingAlgorithm::mapCompounds(const AtomContainer& S1, const AtomContainer& S2, Size& no_matched_heavy_atoms, double& rmsd, double upper_bound, double lower_bound, double tolerance) { // calculate bounding box of protein S1 BoundingBoxProcessor box_processor; // BoundingBoxProcessor can unfortunately not operate on const AtomContainer, althought it does NOT change the system AtomContainer* S1nc = const_cast<AtomContainer*>(&S1); S1nc->apply(box_processor); /// insert positions of the heavy atoms of S1 into a three-dimensional hashgrid and in the array heavy_atoms Vector3 upper_bound_vector(upper_bound, upper_bound, upper_bound); HashGrid3 < Position > grid_S1(box_processor.getLower() - upper_bound_vector, box_processor.getUpper() - box_processor.getLower() + (float) 2.0 * upper_bound_vector, upper_bound); AtomConstIterator atom_it; vector<Vector3> heavy_atoms_S1; // vector<Position> index_heavy_S1; Position no_heavy_S1 = 0; for (atom_it = S1.beginAtom(); +atom_it; ++atom_it) { if (((*atom_it).getElement() != PTE[Element::H])) { grid_S1.insert((*atom_it).getPosition(), no_heavy_S1); no_heavy_S1++; heavy_atoms_S1.push_back((*atom_it).getPosition()); // index_heavy_S1.push_back(type_map[(*atom_it).getFragment()->getName()]); } } // calculate bounding box of protein S2 // BoundingBoxProcessor can unfortunately not operate on const AtomContainer, althought it does NOT change the system AtomContainer* S2nc = const_cast<AtomContainer*>(&S2); S2nc->apply(box_processor); /// insert positions of the heavy atoms of S2 into the hashgrid grid_S2 HashGrid3<Position> grid_S2(box_processor.getLower() - upper_bound_vector, box_processor.getUpper() - box_processor.getLower() +(float) 2.0 * upper_bound_vector, upper_bound); Vector3 tolerance_vector(2 * tolerance, 2 * tolerance, 2 * tolerance); HashGrid3<Position> fine_grid_S2(box_processor.getLower() - tolerance_vector, box_processor.getUpper() - box_processor.getLower() + tolerance_vector, 2 * tolerance); vector<Vector3> heavy_atoms_S2; // vector<Position> index_heavy_S2; Size no_heavy_S2 = 0; for (atom_it = S2.beginAtom(); +atom_it; ++atom_it) { if (((*atom_it).getElement() != PTE[Element::H])) { grid_S2.insert((*atom_it).getPosition(), no_heavy_S2); fine_grid_S2.insert((*atom_it).getPosition(), no_heavy_S2); no_heavy_S2++; heavy_atoms_S2.push_back((*atom_it).getPosition()); // index_heavy_S2.push_back(type_map[(*atom_it).getFragment()->getName()]); } } /// calculate triangles between heavy atoms of S2 whose edge length are larger than lower_bound /// and smaller than upperbound and store them in a hashgrid with respect to their edge length Vector3 upper(upper_bound + 1, upper_bound + 1, upper_bound + 1); Vector3 lower(lower_bound - 1, lower_bound - 1, lower_bound - 1); HashGrid3<TVector3<Position> > triangles_S2(lower, upper - lower, tolerance); // tolerance == spacing of hashgrid HashGrid3 < Position >::BoxIterator b_it1; HashGridBox3 < Position >::BoxIterator b_it2, b_it3; HashGridBox3 < Position >::DataIterator d_it1, d_it2, d_it3; TVector3 < Position > index_vector; Vector3 distance_vector; float square_upper = upper_bound * upper_bound; float square_lower = lower_bound * lower_bound; float distance1, distance2, distance3; for (b_it1 = grid_S2.beginBox(); +b_it1; ++b_it1) { for (d_it1 = (*b_it1).beginData(); +d_it1; ++d_it1) { for (b_it2 = (*b_it1).beginBox(); +b_it2; ++b_it2) { for (d_it2 = (*b_it2).beginData(); +d_it2; ++d_it2) { if ((*d_it2) != (*d_it1)) { distance1 = heavy_atoms_S2[(*d_it1)].getSquareDistance(heavy_atoms_S2[(*d_it2)]); if (distance1 < square_upper && distance1 > square_lower) { for (b_it3 = (*b_it1).beginBox(); +b_it3; ++b_it3) { for (d_it3 = (*b_it3).beginData(); +d_it3; ++d_it3) { if ((*d_it3) != (*d_it1) && (*d_it3) != (*d_it2)) { distance2 = heavy_atoms_S2[(*d_it1)].getSquareDistance(heavy_atoms_S2[(*d_it3)]); if (distance2 < square_upper && distance2 > square_lower) { distance3 = heavy_atoms_S2[(*d_it2)].getSquareDistance(heavy_atoms_S2[(*d_it3)]); if (distance3 < square_upper && distance3 > square_lower) { distance1 = sqrt(distance1); distance2 = sqrt(distance2); distance3 = sqrt(distance3); distance_vector.set(distance1, distance2, distance3); index_vector.set((*d_it1), (*d_it2), (*d_it3)); triangles_S2.insert(distance_vector, index_vector); } } } } } } } } } } } /// calculate all triangles between heavy atoms of S1 and /// search similar triangles between heavy atoms of S2 stored in triangles_S2 HashGridBox3 < TVector3 < Position > >::BoxIterator b_it4; HashGridBox3 < TVector3 < Position > >::DataIterator d_it4; HashGridBox3 < TVector3 < Position > >*box; HashGridBox3 < Position > *ibox; HashGridBox3 < Position >::BoxIterator ibox_it; HashGridBox3 < Position >::DataIterator id_it; Matrix4x4 T_best; const float square_tolerance = tolerance * tolerance; no_matched_heavy_atoms = 0; for (b_it1 = grid_S1.beginBox(); +b_it1; ++b_it1) { for (d_it1 = (*b_it1).beginData(); +d_it1; ++d_it1) { for (b_it2 = (*b_it1).beginBox(); +b_it2; ++b_it2) { for (d_it2 = (*b_it2).beginData(); +d_it2; ++d_it2) { if ((*d_it2) != (*d_it1)) { distance1 = heavy_atoms_S1[(*d_it1)].getSquareDistance(heavy_atoms_S1[(*d_it2)]); if (distance1 < square_upper && distance1 > square_lower) { distance1 = sqrt(distance1); for (b_it3 = (*b_it1).beginBox(); +b_it3; ++b_it3) { for (d_it3 = (*b_it3).beginData(); +d_it3; ++d_it3) { if ((*d_it3) != (*d_it1) && (*d_it3) != (*d_it2)) { distance2 = heavy_atoms_S1[*d_it1].getSquareDistance(heavy_atoms_S1[*d_it3]); if (distance2 < square_upper && distance2 > square_lower) { distance2 = sqrt(distance2); distance3 = heavy_atoms_S1[*d_it2].getSquareDistance(heavy_atoms_S1[*d_it3]); if (distance3 < square_upper && distance3 > square_lower) { distance3 = sqrt(distance3); distance_vector.set(distance1, distance2, distance3); index_vector.set(*d_it1, *d_it2, *d_it3); // the positions of the atoms of S1 that are part of this triangle box = triangles_S2.getBox(distance_vector); /// iterate over all triangles of S2 that have similar edge lengths for (b_it4 = box->beginBox(); +b_it4; ++b_it4) // iterate over all buckets... { for (d_it4 = (*b_it4).beginData(); +d_it4; ++d_it4) { // if (index_heavy_S1[(*d_it1)] == index_heavy_S2[(*d_it4).x] && index_heavy_S1[(*d_it2)] == index_heavy_S2[(*d_it4).y] && index_heavy_S1[(*d_it3)] == index_heavy_S2[(*d_it4).z]) { Matrix4x4 T = StructureMapper::matchPoints( heavy_atoms_S1[(*d_it1)], heavy_atoms_S1[(*d_it2)], heavy_atoms_S1[(*d_it3)], heavy_atoms_S2[(*d_it4).x], heavy_atoms_S2[(*d_it4).y], heavy_atoms_S2[(*d_it4).z] ); size_t matched_heavy_atoms = 0u; float current_rmsd = 0.0f; /// iterate over all heavy atoms of S1 and define them as matched if there is an atom of S2 within square_tolerance; /// calculate RMSD out of all matched atoms for (Size i = 0; i < no_heavy_S1; i++) { Vector3 v = T * heavy_atoms_S1[i]; ibox = fine_grid_S2.getBox(v); if (ibox != 0) { bool matched = false; for (ibox_it = ibox->beginBox(); +ibox_it && !matched; ++ibox_it) { for (id_it = (*ibox_it).beginData(); +id_it && !matched; ++id_it) { float squared_atom_dist = v.getSquareDistance(heavy_atoms_S2[(*id_it)]); if (squared_atom_dist <= square_tolerance) { matched_heavy_atoms++; matched = true; current_rmsd += squared_atom_dist; } } } } } if (matched_heavy_atoms >= no_matched_heavy_atoms) { current_rmsd = sqrt(current_rmsd / matched_heavy_atoms); if (matched_heavy_atoms == no_matched_heavy_atoms) { if (current_rmsd < rmsd) { T_best = T; rmsd = current_rmsd; } } else // if more atoms could be mapped, always use new { // transformation T_best = T; rmsd = current_rmsd; } no_matched_heavy_atoms = matched_heavy_atoms; } } } } } } } } } } } } } } } return T_best; }