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;
}