/
SurfaceDistancePairScore.h
187 lines (159 loc) · 6.21 KB
/
SurfaceDistancePairScore.h
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
/**
* \file IMP/score_functor/SurfaceDistancePairScore.h
* \brief A Score on the distance between a pair of particles.
*
* Copyright 2007-2022 IMP Inventors. All rights reserved.
*/
#ifndef IMPSCORE_FUNCTOR_SURFACE_DISTANCE_PAIR_SCORE_H
#define IMPSCORE_FUNCTOR_SURFACE_DISTANCE_PAIR_SCORE_H
#include <IMP/score_functor/score_functor_config.h>
#include <IMP/score_functor/internal/surface_helpers.h>
#include <IMP/score_functor/internal/direction_helpers.h>
#include <IMP/PairScore.h>
#include <IMP/pair_macros.h>
IMPSCOREFUNCTOR_BEGIN_NAMESPACE
//! Create efficient surface distance-based pair scores.
/** This class allows one to create efficient distance-based
pair scores between a surface and a point in C++ by simply
writing a functor (Score) that does the scoring.
\note In the passed `ParticleIndexPair`, the first particle must
be for the surface.
\see SurfaceDistancePairScore
\see DistancePairScore
\see Score
*/
template <class DistanceScoreT>
class SurfaceDistancePairScore : public PairScore {
private:
DistanceScoreT ds_;
//! Get the distance from the surface to the point.
virtual double get_distance(const algebra::Vector3D ¢er,
const algebra::Vector3D &normal,
const algebra::Vector3D &point,
algebra::Vector3D *delta) const {
return internal::get_distance_from_surface(center, normal, point, delta);
}
public:
typedef DistanceScoreT DistanceScore;
SurfaceDistancePairScore(
const DistanceScore &t0,
std::string name = "FunctorSurfaceDistancePairScore %1%")
: PairScore(name), ds_(t0) {}
//! Compute the score and the derivative if needed
/** \note In the passed `ParticleIndexPair`, the first particle must
be for the surface.
*/
virtual double evaluate_index(Model *m,
const ParticleIndexPair &pip,
DerivativeAccumulator *da) const override;
virtual ModelObjectsTemp do_get_inputs(
Model *m, const ParticleIndexes &pis) const override;
DistanceScoreT& get_score_functor()
{ return ds_; }
IMP_PAIR_SCORE_METHODS(SurfaceDistancePairScore);
IMP_OBJECT_METHODS(SurfaceDistancePairScore);
};
#ifndef IMP_DOXYGEN
template <class DistanceScore>
inline double SurfaceDistancePairScore<DistanceScore>::evaluate_index(
Model *m, const ParticleIndexPair &p,
DerivativeAccumulator *da) const {
algebra::Vector3D delta; // normal vector from surface to point
double dist = get_distance(
m->get_sphere(std::get<0>(p)).get_center(),
internal::get_direction(m, std::get<0>(p)),
m->get_sphere(std::get<1>(p)).get_center(), &delta);
// Using squared distance for trivial check currently doesn't work for surfaces
// if (ds_.get_is_trivially_zero(m, p, dist * dist)) {
// return 0;
// }
if (da) {
std::pair<double, double> sp = ds_.get_score_and_derivative(m, p, dist);
m->add_to_coordinate_derivatives(std::get<0>(p), -delta * sp.second, *da);
m->add_to_coordinate_derivatives(std::get<1>(p), delta * sp.second, *da);
return sp.first;
} else {
return ds_.get_score(m, p, dist);
}
}
template <class DistanceScore>
inline ModelObjectsTemp SurfaceDistancePairScore<
DistanceScore>::do_get_inputs(
Model *m, const ParticleIndexes &pis) const {
ModelObjectsTemp ret;
ret += ds_.get_inputs(m, pis);
return ret;
}
#endif
//! Create efficient surface height-based pair scores.
/** This class allows one to create efficient height-based
pair scores between a surface and a point in C++ by simply
writing a functor (Score) that does the scoring.
\note In the passed `ParticleIndexPair`, the first particle must
be for the surface.
\see SurfaceDistancePairScore
\see DistancePairScore
\see Score
*/
#if defined(SWIG) || defined(IMP_DOXYGEN)
template <class DistanceScoreT>
class SurfaceHeightPairScore : public PairScore {
public:
SurfaceHeightPairScore(
const DistanceScore &t0,
std::string name = "FunctorSurfaceHeightPairScore %1%");
};
#else
template <class DistanceScore>
class SurfaceHeightPairScore : public SurfaceDistancePairScore<
DistanceScore> {
virtual double get_distance(const algebra::Vector3D ¢er,
const algebra::Vector3D &normal,
const algebra::Vector3D &point,
algebra::Vector3D *delta) const override {
return internal::get_height_above_surface(center, normal, point, delta);
}
public:
SurfaceHeightPairScore(
const DistanceScore &t0,
std::string name = "FunctorSurfaceHeightPairScore %1%")
: SurfaceDistancePairScore<DistanceScore>(t0, name) {}
};
#endif
//! Create efficient surface depth-based pair scores.
/** This class allows one to create efficient depth-based
pair scores between a surface and a point in C++ by simply
writing a functor (Score) that does the scoring.
\note In the passed `ParticleIndexPair`, the first particle must
be for the surface.
\see SurfaceDistancePairScore
\see DistancePairScore
\see Score
*/
#if defined(SWIG) || defined(IMP_DOXYGEN)
template <class DistanceScoreT>
class SurfaceDepthPairScore : public PairScore {
public:
SurfaceDepthPairScore(
const DistanceScore &t0,
std::string name = "FunctorSurfaceDepthPairScore %1%");
};
#else
template <class DistanceScore>
class SurfaceDepthPairScore : public SurfaceDistancePairScore<
DistanceScore> {
virtual double get_distance(const algebra::Vector3D ¢er,
const algebra::Vector3D &normal,
const algebra::Vector3D &point,
algebra::Vector3D *delta) const override {
return internal::get_depth_below_surface(center, normal, point, delta);
}
public:
SurfaceDepthPairScore(
const DistanceScore &t0,
std::string name = "FunctorSurfaceDepthPairScore %1%")
: SurfaceDistancePairScore<DistanceScore>(t0, name) {}
};
#endif
IMPSCOREFUNCTOR_END_NAMESPACE
#endif /* IMPSCORE_FUNCTOR_SURFACE_DISTANCE_PAIR_SCORE_H */