File size: 6,678 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
190
#ifndef DISTANCE_RESTRAINT_H
#define DISTANCE_RESTRAINT_H

#include <Vector3.h>
#include <RigidTrans3.h>

#include <vector>
#include <limits>

class DistanceRestraint {
public:
  DistanceRestraint(const std::vector<Vector3>& p1,
                    const std::vector<Vector3>& p2,
                    float maxdist, float mindist = 0.0, float weight=1.0)
    : p1_(p1), p2_(p2), mindist_(mindist), maxdist_(maxdist),
      mindist2_(mindist*mindist), maxdist2_(maxdist*maxdist),
      weight_(weight) {}

  DistanceRestraint(const std::vector<Vector3>& p1,
                    const std::vector<Vector3>& p2,
                    const std::vector<std::pair<std::string, std::string>>& p1Info,
                    const std::vector<std::pair<std::string, std::string>>& p2Info,
                    float maxdist, float mindist = 0.0, float weight=1.0)
    : DistanceRestraint(p1, p2, maxdist, mindist, weight) {
    p1Info_ = p1Info;
    p2Info_ = p2Info;
  }

  DistanceRestraint(const Vector3& p1, const Vector3& p2,
                    float maxdist, float mindist = 0.0, float weight=1.0)
    :  mindist_(mindist), maxdist_(maxdist),
      mindist2_(mindist*mindist), maxdist2_(maxdist*maxdist),
      weight_(weight)
  {
    p1_.push_back(p1);
    p2_.push_back(p2);
  }

  DistanceRestraint() = default;

  float getWeight() const { return weight_; }
  float getMinDistance() const { return mindist_; }
  float getMaxDistance() const { return maxdist_; }
  const std::vector<Vector3>& getPoints1() const { return p1_; }
  const std::vector<Vector3>& getPoints2() const { return p2_; }

  bool isViolated() const {
    // calculate the distance and compare to mindist_ and maxdist_
    for(unsigned int i = 0; i < p1_.size(); i++) {
      for(unsigned int j = 0; j < p2_.size(); j++) {
        float dist2 = p1_[i].dist2(p2_[j]);
        if(dist2 <= maxdist2_) return false; // found one in range
      }
    }
    return true;
  }

  bool isViolated(const std::vector<RigidTrans3>& trans) const {
    // calculate the distance and compare to mindist_ and maxdist_
    for(unsigned int i = 0; i < p1_.size(); i++) {
      for(unsigned int j = 0; j < p2_.size(); j++) {
        float dist2 = p1_[i].dist2(trans[j]*p2_[j]);
        if(dist2 <= maxdist2_) return false; // found one in range
      }
    }
    return true;
  }

  bool isViolated(const std::vector<RigidTrans3>& trans1,

                  const std::vector<RigidTrans3>& trans2) const {
    // calculate the distance and compare to mindist_ and maxdist_
    for(unsigned int i = 0; i < p1_.size(); i++) {
      Vector3 transP1 = trans1[i]*p1_[i];
      for(unsigned int j = 0; j < p2_.size(); j++) {
        float dist2 = transP1.dist2(trans2[j]*p2_[j]);
        if(dist2 <= maxdist2_) return false; // found one in range
      }
    }
    return true;
  }

  // backward compatability
  bool isSatisfied() const { return !isViolated(); }
  bool isSatisfied(const RigidTrans3& trans) const {
    std::vector<RigidTrans3> t(p2_.size(), trans);
    return !isViolated(t);
  }
  bool isSatisfied(const RigidTrans3& trans1,

                   const RigidTrans3& trans2) const {
    std::vector<RigidTrans3> t1(p1_.size(), trans1);
    std::vector<RigidTrans3> t2(p2_.size(), trans2);
    return !isViolated(t1, t2);
  }

  //calculate violationDistance
  float violationDistance() const {
    float bestdist = distance();
    if(bestdist > maxdist_) return bestdist - maxdist_;
    return 0.0;
  }

  float violationDistance(const std::vector<RigidTrans3>& trans) const {
    float bestdist = distance(trans);
    if(bestdist > maxdist_) return bestdist - maxdist_;
    return 0.0;
  }

  float violationDistance(const std::vector<RigidTrans3>& trans1,

                          const std::vector<RigidTrans3>& trans2) const {
    float bestdist = distance(trans1, trans2);
    if(bestdist > maxdist_) return bestdist - maxdist_;
    return 0.0;
  }

  float distance2() const {
    float bestdist2 = std::numeric_limits<float>::max();
    for(unsigned int i = 0; i < p1_.size(); i++) {
      for(unsigned int j = 0; j < p2_.size(); j++) {
        float dist2 = p1_[i].dist2(p2_[j]);
        if(dist2 < bestdist2) bestdist2 = dist2;
      }
    }
    return bestdist2;
  }

  float distance() const { return sqrt(distance2()); }

  float distance2(const std::vector<RigidTrans3>& trans) const {
    float bestdist2 = std::numeric_limits<float>::max();
    for(unsigned int i = 0; i < p1_.size(); i++) {
      for(unsigned int j = 0; j < p2_.size(); j++) {
        float dist2 = p1_[i].dist2(trans[j]*p2_[j]);
        if(dist2 < bestdist2) bestdist2 = dist2;
      }
    }
    return bestdist2;
  }

  float distance(const std::vector<RigidTrans3>& trans) const {
    return sqrt(distance2(trans));
  }

  float distance(const RigidTrans3& trans) const {
    std::vector<RigidTrans3> t(1, trans);
    return distance(t);
  }

  float distance2(const std::vector<RigidTrans3>& trans1,

                  const std::vector<RigidTrans3>& trans2) const {
    float bestdist2 = std::numeric_limits<float>::max();
    for(unsigned int i = 0; i < p1_.size(); i++) {
      Vector3 transP1 = trans1[i]*p1_[i];
      for(unsigned int j = 0; j < p2_.size(); j++) {
        float dist2 = transP1.dist2(trans2[j]*p2_[j]);
        if(dist2 < bestdist2) bestdist2 = dist2;
      }
    }
    return bestdist2;
  }

  float distance(const std::vector<RigidTrans3>& trans1,

                 const std::vector<RigidTrans3>& trans2) const {
    return sqrt(distance2(trans1, trans2));
  }

  // TODO: add trans versions
  float minDistanceIndices(unsigned int& index1, unsigned int& index2) const;

  std::string getChimeraXPseudoBond() const;

  bool operator < (const DistanceRestraint& d) const { return (maxdist_ < d.maxdist_); }

  friend std::ostream& operator<<(std::ostream& s, const DistanceRestraint& d) {
    // TODO
    return s << d.p1_[0] << ' ' << d.p2_[0] << ' ' << d.mindist_ <<' ' << d.maxdist_;
  }

private:
  std::vector<Vector3> p1_; // end point1, vector for ambiguity
  std::vector<Vector3> p2_; // end point2, vector for ambiguity
  std::vector<std::pair<std::string, std::string>> p1Info_, p2Info_; // residueSequenceID and chain for p1 and p2 endpoints
  float mindist_; // minimal distance threshold
  float maxdist_; // maximal distance threshold
  float mindist2_; // minimal distance threshold (squared)
  float maxdist2_; // maximal distance threshold (squared)
  float weight_;
};

#endif /* DISTANCE_RESTRAINT_H */