File size: 5,275 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 | #include <math.h>
#include "Match.h"
#include "macros.h"
typedef Match::ParticleMatch ParticleMatch;
typedef Match::MatchList MatchList;
typedef MatchList::const_iterator const_iterator;
typedef MatchList::iterator iterator;
ParticleMatch::ParticleMatch()
: model(0), scene(0), score(0.0), priority(0.0) {}
ParticleMatch::ParticleMatch(unsigned int modelParticle,
unsigned int sceneParticle,
float sc, float pri) :
model(modelParticle), scene(sceneParticle), score(sc), priority(pri) {}
std::ostream& operator<<(std::ostream& s, const ParticleMatch& pm)
{
s.setf(std::ios::fixed, std::ios::floatfield);
s.setf(std::ios::right, std::ios::adjustfield);
s.precision(3);
s.width(8);
s << pm.model;
s.width(8);
s << pm.scene;
s.width(10);
s << pm.score;
s.width(10);
s << pm.priority;
return s;
}
Match::Match() : rms(0.0), sc(0.0), trans() {}
Match::Match(const RigidTrans3& rt) : rms(0.0), sc(0.0), trans(rt) {}
Match::Match(const Match& m) :
pairs(m.pairs), rms(m.rms), sc(m.sc), trans(m.trans) {}
// The add method is complicated by the fact that the pair being added may
// clash with a pair that has already been inserted into the match. This
// is handled using the priority parameter. Pairs with higher priorities
// are preferred.
bool Match::add(const unsigned int modelParticle,
const unsigned int sceneParticle,
const float score,
const float priority)
{
iterator sceneClash = pairs.end();
iterator modelClash = pairs.end();
bool canAdd = true;
// Find if there are any clashes when adding the pair.
// Developer's Note: I've tried this class out using two binary search
// trees (STL map.h) instead of a vector. The idea was to speed up the
// search for clashes using binary trees. I tested the two implementations
// using random match additions to a set of matches. Besides being at
// least 4 times more costly in terms of memory the binary tree
// implementation also ran almost twice as slow! So, if you're going to
// try it remember I was there first.
for (iterator it = pairs.begin(); it != pairs.end() && canAdd;
it++) {
if ((*it).scene == sceneParticle) { // check for clashes with scene part.
sceneClash = it;
canAdd = (priority > (*sceneClash).priority);
if (modelClash != pairs.end()) break; // if both scene and model clashes found break
}
else if ((*it).model == modelParticle) { // check for model part. clash
modelClash = it;
canAdd = (priority > (*modelClash).priority);
if (sceneClash != pairs.end()) break; // if both scene and model clashes found break
}
}
// if pair has higher priority or no clashes were found then add the new
// pair. if clashes occurred remove old pair or pairs from the data
// structures
if (canAdd) {
if (sceneClash != pairs.end()) {
// replace the scene clashed pair with the new pair.
*sceneClash = ParticleMatch(modelParticle, sceneParticle,
score, priority);
// if new pair clashed both with a model particle and a scene particle
// of different two pairs then then remove one pair.
if (modelClash != pairs.end()) pairs.erase(modelClash);
}
else if (modelClash != pairs.end())
// only model particle clashed. replace the clashed pair with the
// new pair.
*modelClash = ParticleMatch(modelParticle, sceneParticle,
score, priority);
else // no clashes.
pairs.push_back(ParticleMatch(modelParticle, sceneParticle,
score, priority));
}
return canAdd;
}
void Match::add(const unsigned int modelParticle,
const unsigned int sceneParticle,
const float score)
{
pairs.push_back(ParticleMatch(modelParticle, sceneParticle, score, 0.0));
}
void Match::add(const ParticleMatch& pm){
pairs.push_back(pm);
}
unsigned int Match::size() const
{
return pairs.size();
}
float Match::rmsd() const
{
return rms;
}
float Match::totalScore() const
{
return sc;
}
const RigidTrans3& Match::rigidTrans() const
{
return trans;
}
int Match::sceneParticle(const unsigned int modelParticle) const
{
for (const_iterator i = pairs.begin(); i != pairs.end(); i++)
if ((*i).model == modelParticle)
return (*i).scene;
return -1;
}
int Match::modelParticle(const unsigned int sceneParticle) const
{
for (const_iterator i = pairs.begin(); i != pairs.end(); i++)
if ((*i).scene == sceneParticle)
return (*i).model;
return -1;
}
float Match::calculateTotalScore()
{
sc = 0.0;
for (iterator it = pairs.begin(); it != pairs.end(); it++)
sc+= (*it).score;
return sc;
}
std::ostream& operator<<(std::ostream& s, const Match& m)
{
s << "#model #scene #score #priority" << std::endl;
for(std::vector<ParticleMatch>::const_iterator it=m.pairs.begin() ;
it != m.pairs.end(); ++it)
s << *it << std::endl;
s << std::endl;
s << "#The transformation is:" << std::endl;
s << m.trans << std::endl;
s << "#score: " << m.sc << "#Rms: " << m.rms << std::endl;
return s;
}
|