File size: 9,692 Bytes
8efb4bd | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 | #include "ComplexDistanceConstraint.h"
#include "BB.h"
void ComplexDistanceConstraint::addConstraint(int suInd1, int suInd2, Vector3 receptorAtom, Vector3 ligandAtom,
float maxDistance, float minDistance) {
int ind = suInd1 * noOfSUs_ + suInd2;
constraints_[ind].push_back(DistanceRestraint(receptorAtom, ligandAtom, maxDistance, minDistance));
}
bool ComplexDistanceConstraint::areConstraintsSatisfied(int suInd1, int suInd2, RigidTrans3 &trans2) const {
int ind = suInd1 * noOfSUs_ + suInd2;
for (unsigned int index = 0; index < constraints_[ind].size(); index++) {
bool sat = constraints_[ind][index].isSatisfied(trans2);
if (!sat) {
return false;
}
}
return true;
}
int ComplexDistanceConstraint::addChainConnectivityConstraints() {
for (int suInd1 = 0; suInd1 < noOfSUs_; suInd1++) {
for (int suInd2 = suInd1 + 1; suInd2 < noOfSUs_; suInd2++) {
std::vector<std::pair<char, std::pair<int, int>>> constraints;
int counter = 0;
float epsilon = 20.0; // for shorter connections
bbs_[suInd1]->getChainConnectivityConstraints(*bbs_[suInd2], constraints);
for (int i = 0; i < (int)constraints.size(); i++) {
int su1resIndex = constraints[i].second.first;
int su2resIndex = constraints[i].second.second;
int receptorAtomIndex = bbs_[suInd1]->allAtoms_.getFirstAtomEntryForResIndex(
constraints[i].first, std::to_string(su1resIndex));
int ligandAtomIndex = bbs_[suInd2]->allAtoms_.getFirstAtomEntryForResIndex(constraints[i].first,
std::to_string(su2resIndex));
Vector3 receptorAtom = bbs_[suInd1]->getChemAtomByIndex(receptorAtomIndex).position();
Vector3 ligandAtom = bbs_[suInd2]->getChemAtomByIndex(ligandAtomIndex).position();
int sequenceDist = std::fabs(su1resIndex - su2resIndex);
if (sequenceDist < 100) {
float maxDist = sequenceDist * 2.0;
if (sequenceDist <= 5)
maxDist += epsilon;
addConstraint(suInd1, suInd2, receptorAtom, ligandAtom, maxDist);
addConstraint(suInd2, suInd1, ligandAtom, receptorAtom, maxDist);
std::cerr << "DISTANCE CONSTRAINT ADDED: " << constraints[i].first << " su1 endpoint "
<< su1resIndex << " su2 endpoint " << su2resIndex << " " << maxDist << std::endl;
counter++;
}
}
numberOfConstraints_ += counter;
}
}
return numberOfConstraints_;
}
std::set<int> ComplexDistanceConstraint::getSUs(const std::string residueSequenceID, const std::string chains,
int maxOffset) const {
int rOffset = 0;
std::set<int> ret;
// iterate chains
for (unsigned int chainIndex = 0; chainIndex < chains.size(); chainIndex++) {
// for each chain find corresponding SU
for (int suIndex = 0; suIndex < noOfSUs_; suIndex++) {
int atomIndex = bbs_[suIndex]->allAtoms_.getClosestAtomEntryForResIndex(
chains[chainIndex], residueSequenceID, maxOffset, rOffset);
if (atomIndex != -1) { // found
ret.insert(suIndex);
continue;
}
}
}
return ret;
}
int ComplexDistanceConstraint::readRestraintsFile(const std::string fileName) {
// read cross links
std::vector<CrossLink> crosslinks;
int xnum = readCrossLinkFile(fileName, crosslinks);
Logger::infoMessage() << "# of xlinks " << xnum << " read from file" << fileName << std::endl;
int MAX_OFFSET = 20;
crosslinkIndToWeight_ = std::vector<float>(crosslinks.size());
// map them to BB pairs
for (unsigned int i = 0; i < crosslinks.size(); i++) {
crosslinkIndToWeight_[i] = crosslinks[i].getWeight();
// SUs that have xlinks endpoints (sus1, sus2)
std::string residueSequenceID1 = std::to_string(crosslinks[i].getResidue1());
std::set<int> sus1 = getSUs(residueSequenceID1, crosslinks[i].getChain1());
if (sus1.size() == 0)
sus1 = getSUs(residueSequenceID1, crosslinks[i].getChain1(), MAX_OFFSET);
std::string residueSequenceID2 = std::to_string(crosslinks[i].getResidue2());
std::set<int> sus2 = getSUs(residueSequenceID2, crosslinks[i].getChain2());
if (sus2.size() == 0)
sus2 = getSUs(residueSequenceID2, crosslinks[i].getChain2(), MAX_OFFSET);
// iterate over all pairs of SUs
for (auto suIndexIter1 = sus1.begin(); suIndexIter1 != sus1.end(); suIndexIter1++) {
for (unsigned int chainIndex1 = 0; chainIndex1 < crosslinks[i].getChain1().size(); chainIndex1++) {
char chainId1 = crosslinks[i].getChain1()[chainIndex1];
int rOffset = 0;
int receptorAtomIndex = bbs_[*suIndexIter1]->allAtoms_.getClosestAtomEntryForResIndex(
chainId1, residueSequenceID1, MAX_OFFSET, rOffset);
if (rOffset < 0)
rOffset = -1 * rOffset;
if (receptorAtomIndex == -1)
continue;
Vector3 rcoord = bbs_[*suIndexIter1]->getChemAtomByIndex(receptorAtomIndex).position();
for (auto suIndexIter2 = sus2.begin(); suIndexIter2 != sus2.end(); suIndexIter2++) {
for (unsigned int chainIndex2 = 0; chainIndex2 < crosslinks[i].getChain2().size(); chainIndex2++) {
char chainId2 = crosslinks[i].getChain2()[chainIndex2];
int lOffset = 0;
int ligandAtomIndex = bbs_[*suIndexIter2]->allAtoms_.getClosestAtomEntryForResIndex(
chainId2, residueSequenceID2, MAX_OFFSET, lOffset);
if (ligandAtomIndex == -1)
continue;
if (lOffset < 0)
lOffset = -1 * lOffset;
Vector3 lcoord = bbs_[*suIndexIter2]->getChemAtomByIndex(ligandAtomIndex).position();
float maxDistance = crosslinks[i].getMaxDistance() + (rOffset + lOffset) * 3.0;
float minDistance = crosslinks[i].getMinDistance();
int ind1 = *suIndexIter1 * noOfSUs_ + *suIndexIter2;
DistanceRestraint d1(rcoord, lcoord, maxDistance, minDistance, crosslinks[i].getWeight());
restraintIndsToCrosslinkInds_[ind1].push_back(i);
restraints_[ind1].push_back(d1);
int ind2 = *suIndexIter2 * noOfSUs_ + *suIndexIter1;
DistanceRestraint d2(lcoord, rcoord, maxDistance, minDistance, crosslinks[i].getWeight());
restraintIndsToCrosslinkInds_[ind2].push_back(i);
restraints_[ind2].push_back(d2);
std::cout << " adding restraint to " << *suIndexIter1 << "x" << *suIndexIter2 << " :"
<< residueSequenceID1 << chainId1 << " : " << residueSequenceID2 << chainId2
<< " dist " << maxDistance << " " << minDistance << " indexes " << ind1 << " : "
<< ind2 << std::endl;
}
}
}
}
}
return crosslinks.size();
}
float ComplexDistanceConstraint::getRestraintsRatio(const std::vector<std::shared_ptr<const BB>> &bbs,
const std::vector<RigidTrans3> &trans) const {
std::set<unsigned int> totalSeenCrosslinks;
std::set<unsigned int> satisfiedCrosslinks;
for (int suInd1 = 0; suInd1 < (int)bbs.size(); suInd1++) {
for (int suInd2 = 0; suInd2 < (int)bbs.size(); suInd2++) {
int index1 = bbs[suInd1]->getID();
int index2 = bbs[suInd2]->getID();
if (index1 == index2)
continue;
int suPairIndex = index1 * noOfSUs_ + index2;
for (unsigned int restraintIndex = 0; restraintIndex < restraints_[suPairIndex].size(); restraintIndex++) {
unsigned int crosslinkIndex = restraintIndsToCrosslinkInds_[suPairIndex][restraintIndex];
if (satisfiedCrosslinks.find(crosslinkIndex) != satisfiedCrosslinks.end()) {
continue;
}
totalSeenCrosslinks.insert(crosslinkIndex);
if (restraints_[suPairIndex][restraintIndex].isSatisfied(trans[suInd1], trans[suInd2]))
satisfiedCrosslinks.insert(crosslinkIndex);
}
}
}
if (totalSeenCrosslinks.size() == 0)
return 1.0;
float satisfiedWeight = 0.0;
float totalWeight = 0.0;
for (auto it = satisfiedCrosslinks.begin(); it != satisfiedCrosslinks.end(); it++) {
satisfiedWeight += crosslinkIndToWeight_[*it];
}
for (auto it = totalSeenCrosslinks.begin(); it != totalSeenCrosslinks.end(); it++) {
totalWeight += crosslinkIndToWeight_[*it];
}
return satisfiedWeight / totalWeight;
// return (float)satisfiedCrosslinks.size() / (float)totalSeenCrosslinks.size();
} |