annotate reporter.h @ 249:1da9a9ed55a3

Slightly refactored the new trackSequenceQueryNNReporter so that it is a derived class of trackAveragingReporter. This reduces code duplication significantly. The reporter is still accessed via the nsequence QUERY directive from the command line.
author mas01mc
date Sun, 17 Feb 2008 16:39:57 +0000
parents 5682c7d7444b
children a6ee49f10296
rev   line source
mas01cr@239 1 #include <utility>
mas01cr@239 2 #include <queue>
mas01cr@239 3 #include <set>
mas01cr@239 4 #include <functional>
mas01cr@239 5
mas01cr@239 6 typedef struct nnresult {
mas01cr@239 7 unsigned int trackID;
mas01cr@239 8 double dist;
mas01cr@239 9 unsigned int qpos;
mas01cr@239 10 unsigned int spos;
mas01cr@239 11 } NNresult;
mas01cr@239 12
mas01cr@239 13 typedef struct radresult {
mas01cr@239 14 unsigned int trackID;
mas01cr@239 15 unsigned int count;
mas01cr@239 16 } Radresult;
mas01cr@239 17
mas01cr@239 18 bool operator< (const NNresult &a, const NNresult &b) {
mas01cr@239 19 return a.dist < b.dist;
mas01cr@239 20 }
mas01cr@239 21
mas01cr@239 22 bool operator> (const NNresult &a, const NNresult &b) {
mas01cr@239 23 return a.dist > b.dist;
mas01cr@239 24 }
mas01cr@239 25
mas01cr@239 26 bool operator< (const Radresult &a, const Radresult &b) {
mas01cr@239 27 return a.count < b.count;
mas01cr@239 28 }
mas01cr@239 29
mas01cr@239 30 class Reporter {
mas01cr@239 31 public:
mas01cr@239 32 virtual ~Reporter() {};
mas01cr@239 33 virtual void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) = 0;
mas01cr@239 34 // FIXME: this interface is a bit wacky: a relic of previous, more
mas01cr@239 35 // confused times. Really it might make sense to have separate
mas01cr@239 36 // reporter classes for WS and for stdout, rather than passing this
mas01cr@239 37 // adbQueryResponse thing everywhere; the fileTable argument is
mas01cr@239 38 // there solely for convertion trackIDs into names. -- CSR,
mas01cr@239 39 // 2007-12-10.
mas01cr@239 40 virtual void report(char *fileTable, adb__queryResponse *adbQueryResponse) = 0;
mas01cr@239 41 };
mas01cr@239 42
mas01cr@239 43 template <class T> class pointQueryReporter : public Reporter {
mas01cr@239 44 public:
mas01cr@239 45 pointQueryReporter(unsigned int pointNN);
mas01cr@239 46 ~pointQueryReporter();
mas01cr@239 47 void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist);
mas01cr@239 48 void report(char *fileTable, adb__queryResponse *adbQueryResponse);
mas01cr@239 49 private:
mas01cr@239 50 unsigned int pointNN;
mas01cr@239 51 std::priority_queue< NNresult, std::vector< NNresult >, T> *queue;
mas01cr@239 52 };
mas01cr@239 53
mas01cr@239 54 template <class T> pointQueryReporter<T>::pointQueryReporter(unsigned int pointNN)
mas01cr@239 55 : pointNN(pointNN) {
mas01cr@239 56 queue = new std::priority_queue< NNresult, std::vector< NNresult >, T>;
mas01cr@239 57 }
mas01cr@239 58
mas01cr@239 59 template <class T> pointQueryReporter<T>::~pointQueryReporter() {
mas01cr@239 60 delete queue;
mas01cr@239 61 }
mas01cr@239 62
mas01cr@239 63 template <class T> void pointQueryReporter<T>::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) {
mas01cr@242 64 if (!isnan(dist)) {
mas01cr@242 65 NNresult r;
mas01cr@242 66 r.trackID = trackID;
mas01cr@242 67 r.qpos = qpos;
mas01cr@242 68 r.spos = spos;
mas01cr@242 69 r.dist = dist;
mas01cr@242 70 queue->push(r);
mas01cr@242 71 if(queue->size() > pointNN) {
mas01cr@242 72 queue->pop();
mas01cr@242 73 }
mas01cr@239 74 }
mas01cr@239 75 }
mas01cr@239 76
mas01cr@239 77 template <class T> void pointQueryReporter<T>::report(char *fileTable, adb__queryResponse *adbQueryResponse) {
mas01cr@239 78 NNresult r;
mas01cr@239 79 std::vector<NNresult> v;
mas01cr@239 80 unsigned int size = queue->size();
mas01cr@239 81 for(unsigned int k = 0; k < size; k++) {
mas01cr@239 82 r = queue->top();
mas01cr@239 83 v.push_back(r);
mas01cr@239 84 queue->pop();
mas01cr@239 85 }
mas01cr@239 86 std::vector<NNresult>::reverse_iterator rit;
mas01cr@239 87
mas01cr@239 88 if(adbQueryResponse==0) {
mas01cr@239 89 for(rit = v.rbegin(); rit < v.rend(); rit++) {
mas01cr@239 90 r = *rit;
mas01cr@239 91 std::cout << fileTable + r.trackID*O2_FILETABLESIZE << " ";
mas01cr@239 92 std::cout << r.dist << " " << r.qpos << " " << r.spos << std::endl;
mas01cr@239 93 }
mas01cr@239 94 } else {
mas01cr@239 95 adbQueryResponse->result.__sizeRlist=size;
mas01cr@239 96 adbQueryResponse->result.__sizeDist=size;
mas01cr@239 97 adbQueryResponse->result.__sizeQpos=size;
mas01cr@239 98 adbQueryResponse->result.__sizeSpos=size;
mas01cr@239 99 adbQueryResponse->result.Rlist= new char*[size];
mas01cr@239 100 adbQueryResponse->result.Dist = new double[size];
mas01cr@239 101 adbQueryResponse->result.Qpos = new unsigned int[size];
mas01cr@239 102 adbQueryResponse->result.Spos = new unsigned int[size];
mas01cr@239 103 unsigned int k = 0;
mas01cr@239 104 for(rit = v.rbegin(); rit < v.rend(); rit++, k++) {
mas01cr@239 105 r = *rit;
mas01cr@239 106 adbQueryResponse->result.Rlist[k] = new char[O2_MAXFILESTR];
mas01cr@239 107 adbQueryResponse->result.Dist[k] = r.dist;
mas01cr@239 108 adbQueryResponse->result.Qpos[k] = r.qpos;
mas01cr@239 109 adbQueryResponse->result.Spos[k] = r.spos;
mas01cr@239 110 snprintf(adbQueryResponse->result.Rlist[k], O2_MAXFILESTR, "%s", fileTable+r.trackID*O2_FILETABLESIZE);
mas01cr@239 111 }
mas01cr@239 112 }
mas01cr@239 113 }
mas01cr@239 114
mas01cr@239 115 template <class T> class trackAveragingReporter : public Reporter {
mas01cr@239 116 public:
mas01cr@239 117 trackAveragingReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles);
mas01cr@239 118 ~trackAveragingReporter();
mas01cr@239 119 void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist);
mas01cr@239 120 void report(char *fileTable, adb__queryResponse *adbQueryResponse);
mas01mc@249 121 protected:
mas01cr@239 122 unsigned int pointNN;
mas01cr@239 123 unsigned int trackNN;
mas01cr@239 124 unsigned int numFiles;
mas01cr@239 125 std::priority_queue< NNresult, std::vector< NNresult>, T > *queues;
mas01cr@239 126 };
mas01cr@239 127
mas01cr@239 128 template <class T> trackAveragingReporter<T>::trackAveragingReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles)
mas01cr@239 129 : pointNN(pointNN), trackNN(trackNN), numFiles(numFiles) {
mas01cr@239 130 queues = new std::priority_queue< NNresult, std::vector< NNresult>, T >[numFiles];
mas01cr@239 131 }
mas01cr@239 132
mas01cr@239 133 template <class T> trackAveragingReporter<T>::~trackAveragingReporter() {
mas01cr@239 134 delete [] queues;
mas01cr@239 135 }
mas01cr@239 136
mas01cr@239 137 template <class T> void trackAveragingReporter<T>::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) {
mas01cr@242 138 if (!isnan(dist)) {
mas01cr@242 139 NNresult r;
mas01cr@242 140 r.trackID = trackID;
mas01cr@242 141 r.qpos = qpos;
mas01cr@242 142 r.spos = spos;
mas01cr@242 143 r.dist = dist;
mas01cr@242 144 queues[trackID].push(r);
mas01cr@242 145 if(queues[trackID].size() > pointNN) {
mas01cr@242 146 queues[trackID].pop();
mas01cr@242 147 }
mas01cr@239 148 }
mas01cr@239 149 }
mas01cr@239 150
mas01cr@239 151 template <class T> void trackAveragingReporter<T>::report(char *fileTable, adb__queryResponse *adbQueryResponse) {
mas01cr@239 152 std::priority_queue < NNresult, std::vector< NNresult>, T> result;
mas01cr@239 153 for (int i = numFiles-1; i >= 0; i--) {
mas01cr@239 154 unsigned int size = queues[i].size();
mas01cr@239 155 if (size > 0) {
mas01cr@239 156 NNresult r;
mas01cr@239 157 double dist = 0;
mas01cr@239 158 NNresult oldr = queues[i].top();
mas01cr@239 159 for (unsigned int j = 0; j < size; j++) {
mas01cr@239 160 r = queues[i].top();
mas01cr@239 161 dist += r.dist;
mas01cr@239 162 queues[i].pop();
mas01cr@239 163 if (r.dist == oldr.dist) {
mas01cr@239 164 r.qpos = oldr.qpos;
mas01cr@239 165 r.spos = oldr.spos;
mas01cr@239 166 } else {
mas01cr@239 167 oldr = r;
mas01cr@239 168 }
mas01cr@239 169 }
mas01cr@239 170 dist /= size;
mas01cr@239 171 r.dist = dist; // trackID, qpos and spos are magically right already.
mas01cr@239 172 result.push(r);
mas01cr@239 173 if (result.size() > trackNN) {
mas01cr@239 174 result.pop();
mas01cr@239 175 }
mas01cr@239 176 }
mas01cr@239 177 }
mas01cr@239 178
mas01cr@239 179 NNresult r;
mas01cr@239 180 std::vector<NNresult> v;
mas01cr@239 181 unsigned int size = result.size();
mas01cr@239 182 for(unsigned int k = 0; k < size; k++) {
mas01cr@239 183 r = result.top();
mas01cr@239 184 v.push_back(r);
mas01cr@239 185 result.pop();
mas01cr@239 186 }
mas01cr@239 187 std::vector<NNresult>::reverse_iterator rit;
mas01cr@239 188
mas01cr@239 189 if(adbQueryResponse==0) {
mas01cr@239 190 for(rit = v.rbegin(); rit < v.rend(); rit++) {
mas01cr@239 191 r = *rit;
mas01cr@239 192 std::cout << fileTable + r.trackID*O2_FILETABLESIZE << " ";
mas01cr@239 193 std::cout << r.dist << " " << r.qpos << " " << r.spos << std::endl;
mas01cr@239 194 }
mas01cr@239 195 } else {
mas01cr@239 196 adbQueryResponse->result.__sizeRlist=size;
mas01cr@239 197 adbQueryResponse->result.__sizeDist=size;
mas01cr@239 198 adbQueryResponse->result.__sizeQpos=size;
mas01cr@239 199 adbQueryResponse->result.__sizeSpos=size;
mas01cr@239 200 adbQueryResponse->result.Rlist= new char*[size];
mas01cr@239 201 adbQueryResponse->result.Dist = new double[size];
mas01cr@239 202 adbQueryResponse->result.Qpos = new unsigned int[size];
mas01cr@239 203 adbQueryResponse->result.Spos = new unsigned int[size];
mas01cr@239 204 unsigned int k = 0;
mas01cr@239 205 for(rit = v.rbegin(); rit < v.rend(); rit++, k++) {
mas01cr@239 206 r = *rit;
mas01cr@239 207 adbQueryResponse->result.Rlist[k] = new char[O2_MAXFILESTR];
mas01cr@239 208 adbQueryResponse->result.Dist[k] = r.dist;
mas01cr@239 209 adbQueryResponse->result.Qpos[k] = r.qpos;
mas01cr@239 210 adbQueryResponse->result.Spos[k] = r.spos;
mas01cr@239 211 snprintf(adbQueryResponse->result.Rlist[k], O2_MAXFILESTR, "%s", fileTable+r.trackID*O2_FILETABLESIZE);
mas01cr@239 212 }
mas01cr@239 213 }
mas01cr@239 214 }
mas01cr@239 215
mas01cr@239 216 class trackSequenceQueryRadReporter : public Reporter {
mas01cr@239 217 public:
mas01cr@239 218 trackSequenceQueryRadReporter(unsigned int trackNN, unsigned int numFiles);
mas01cr@239 219 ~trackSequenceQueryRadReporter();
mas01cr@239 220 void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist);
mas01cr@239 221 void report(char *fileTable, adb__queryResponse *adbQueryResponse);
mas01mc@249 222 protected:
mas01cr@239 223 unsigned int trackNN;
mas01cr@239 224 unsigned int numFiles;
mas01cr@239 225 std::set<std::pair<unsigned int, unsigned int> > *set;
mas01cr@239 226 unsigned int *count;
mas01cr@239 227 };
mas01cr@239 228
mas01cr@239 229 trackSequenceQueryRadReporter::trackSequenceQueryRadReporter(unsigned int trackNN, unsigned int numFiles):
mas01cr@239 230 trackNN(trackNN), numFiles(numFiles) {
mas01cr@239 231 set = new std::set<std::pair<unsigned int, unsigned int> >;
mas01cr@239 232 count = new unsigned int[numFiles];
mas01cr@239 233 for (unsigned i = 0; i < numFiles; i++) {
mas01cr@239 234 count[i] = 0;
mas01cr@239 235 }
mas01cr@239 236 }
mas01cr@239 237
mas01cr@239 238 trackSequenceQueryRadReporter::~trackSequenceQueryRadReporter() {
mas01cr@239 239 delete set;
mas01cr@239 240 delete [] count;
mas01cr@239 241 }
mas01cr@239 242
mas01cr@239 243 void trackSequenceQueryRadReporter::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) {
mas01cr@239 244 std::set<std::pair<unsigned int, unsigned int> >::iterator it;
mas01cr@239 245 std::pair<unsigned int, unsigned int> pair = std::make_pair(trackID, qpos);
mas01cr@239 246 it = set->find(pair);
mas01cr@239 247 if (it == set->end()) {
mas01cr@239 248 set->insert(pair);
mas01cr@239 249 count[trackID]++;
mas01cr@239 250 }
mas01cr@239 251 }
mas01cr@239 252
mas01cr@239 253 void trackSequenceQueryRadReporter::report(char *fileTable, adb__queryResponse *adbQueryResponse) {
mas01cr@239 254 std::priority_queue < Radresult > result;
mas01cr@239 255 // KLUDGE: doing this backwards in an attempt to get the same
mas01cr@239 256 // tiebreak behaviour as before.
mas01cr@239 257 for (int i = numFiles-1; i >= 0; i--) {
mas01cr@239 258 Radresult r;
mas01cr@239 259 r.trackID = i;
mas01cr@239 260 r.count = count[i];
mas01cr@239 261 if(r.count > 0) {
mas01cr@239 262 result.push(r);
mas01cr@239 263 if (result.size() > trackNN) {
mas01cr@239 264 result.pop();
mas01cr@239 265 }
mas01cr@239 266 }
mas01cr@239 267 }
mas01cr@239 268
mas01cr@239 269 Radresult r;
mas01cr@239 270 std::vector<Radresult> v;
mas01cr@239 271 unsigned int size = result.size();
mas01cr@239 272 for(unsigned int k = 0; k < size; k++) {
mas01cr@239 273 r = result.top();
mas01cr@239 274 v.push_back(r);
mas01cr@239 275 result.pop();
mas01cr@239 276 }
mas01cr@239 277 std::vector<Radresult>::reverse_iterator rit;
mas01cr@239 278
mas01cr@239 279 if(adbQueryResponse==0) {
mas01cr@239 280 for(rit = v.rbegin(); rit < v.rend(); rit++) {
mas01cr@239 281 r = *rit;
mas01cr@239 282 std::cout << fileTable + r.trackID*O2_FILETABLESIZE << " " << r.count << std::endl;
mas01cr@239 283 }
mas01cr@239 284 } else {
mas01cr@239 285 // FIXME
mas01cr@239 286 }
mas01cr@239 287 }
mas01mc@248 288
mas01mc@249 289 // Another type of trackAveragingReporter that reports all pointNN nearest neighbours
mas01mc@249 290 template <class T> class trackSequenceQueryNNReporter : public trackAveragingReporter<T> {
mas01mc@249 291 protected:
mas01mc@249 292 using trackAveragingReporter<T>::numFiles;
mas01mc@249 293 using trackAveragingReporter<T>::queues;
mas01mc@249 294 using trackAveragingReporter<T>::trackNN;
mas01mc@249 295 using trackAveragingReporter<T>::pointNN;
mas01mc@248 296 public:
mas01mc@248 297 trackSequenceQueryNNReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles);
mas01mc@248 298 void report(char *fileTable, adb__queryResponse *adbQueryResponse);
mas01mc@248 299 };
mas01mc@248 300
mas01mc@249 301 template <class T> trackSequenceQueryNNReporter<T>::trackSequenceQueryNNReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles)
mas01mc@249 302 :trackAveragingReporter<T>(pointNN, trackNN, numFiles){}
mas01mc@248 303
mas01mc@248 304 template <class T> void trackSequenceQueryNNReporter<T>::report(char *fileTable, adb__queryResponse *adbQueryResponse) {
mas01mc@248 305 std::priority_queue < NNresult, std::vector< NNresult>, T> result;
mas01mc@248 306 std::priority_queue< NNresult, std::vector< NNresult>, std::greater<NNresult> > *point_queues = new std::priority_queue< NNresult, std::vector< NNresult>, std::greater<NNresult> >[numFiles];
mas01mc@249 307
mas01mc@248 308 for (int i = numFiles-1; i >= 0; i--) {
mas01mc@248 309 unsigned int size = queues[i].size();
mas01mc@248 310 if (size > 0) {
mas01mc@248 311 NNresult r;
mas01mc@248 312 double dist = 0;
mas01mc@248 313 NNresult oldr = queues[i].top();
mas01mc@248 314 for (unsigned int j = 0; j < size; j++) {
mas01mc@248 315 r = queues[i].top();
mas01mc@248 316 dist += r.dist;
mas01mc@248 317 point_queues[i].push(r);
mas01mc@249 318 queues[i].pop();
mas01mc@248 319 if (r.dist == oldr.dist) {
mas01mc@248 320 r.qpos = oldr.qpos;
mas01mc@248 321 r.spos = oldr.spos;
mas01mc@248 322 } else {
mas01mc@248 323 oldr = r;
mas01mc@248 324 }
mas01mc@248 325 }
mas01mc@248 326 dist /= size;
mas01mc@248 327 r.dist = dist; // trackID, qpos and spos are magically right already.
mas01mc@248 328 result.push(r);
mas01mc@248 329 if (result.size() > trackNN) {
mas01mc@248 330 result.pop();
mas01mc@248 331 }
mas01mc@248 332 }
mas01mc@248 333 }
mas01mc@248 334
mas01mc@248 335 NNresult r;
mas01mc@248 336 std::vector<NNresult> v;
mas01mc@248 337 unsigned int size = result.size();
mas01mc@248 338 for(unsigned int k = 0; k < size; k++) {
mas01mc@248 339 r = result.top();
mas01mc@248 340 v.push_back(r);
mas01mc@248 341 result.pop();
mas01mc@248 342 }
mas01mc@248 343 std::vector<NNresult>::reverse_iterator rit;
mas01mc@248 344
mas01mc@248 345 if(adbQueryResponse==0) {
mas01mc@248 346 for(rit = v.rbegin(); rit < v.rend(); rit++) {
mas01mc@248 347 r = *rit;
mas01mc@248 348 std::cout << fileTable + r.trackID*O2_FILETABLESIZE << std::endl;
mas01mc@248 349 for(int k=0; k < (int)pointNN; k++){
mas01mc@248 350 NNresult rk = point_queues[r.trackID].top();
mas01mc@248 351 std::cout << rk.dist << " " << rk.qpos << " " << rk.spos << std::endl;
mas01mc@248 352 point_queues[r.trackID].pop();
mas01mc@248 353 }
mas01mc@248 354 }
mas01mc@248 355 } else {
mas01mc@248 356 adbQueryResponse->result.__sizeRlist=size;
mas01mc@248 357 adbQueryResponse->result.__sizeDist=size;
mas01mc@248 358 adbQueryResponse->result.__sizeQpos=size;
mas01mc@248 359 adbQueryResponse->result.__sizeSpos=size;
mas01mc@248 360 adbQueryResponse->result.Rlist= new char*[size];
mas01mc@248 361 adbQueryResponse->result.Dist = new double[size];
mas01mc@248 362 adbQueryResponse->result.Qpos = new unsigned int[size];
mas01mc@248 363 adbQueryResponse->result.Spos = new unsigned int[size];
mas01mc@248 364 unsigned int k = 0;
mas01mc@248 365 for(rit = v.rbegin(); rit < v.rend(); rit++, k++) {
mas01mc@248 366 r = *rit;
mas01mc@248 367 adbQueryResponse->result.Rlist[k] = new char[O2_MAXFILESTR];
mas01mc@248 368 adbQueryResponse->result.Dist[k] = r.dist;
mas01mc@248 369 adbQueryResponse->result.Qpos[k] = r.qpos;
mas01mc@248 370 adbQueryResponse->result.Spos[k] = r.spos;
mas01mc@248 371 snprintf(adbQueryResponse->result.Rlist[k], O2_MAXFILESTR, "%s", fileTable+r.trackID*O2_FILETABLESIZE);
mas01mc@248 372 }
mas01mc@248 373 }
mas01mc@248 374 // clean up
mas01mc@248 375 delete[] point_queues;
mas01mc@248 376 }