annotate reporter.h @ 307:d1b8b2dec37e

Added reporters radius search via Web Services. The ordering for radius search is degenerate if usingQueryPoint, because the query point can only be counted once. This behaviour is changed by specifying -n 1 to emulate the trackAveragingReporter ordering behaviour
author mas01mc
date Wed, 06 Aug 2008 21:23:14 +0000
parents d9a88cfd4ab6
children 25572f1bd37f
rev   line source
mas01mc@292 1 #ifndef __REPORTER_H
mas01mc@292 2 #define __REPORTER_H
mas01mc@292 3
mas01cr@239 4 #include <utility>
mas01cr@239 5 #include <queue>
mas01cr@239 6 #include <set>
mas01cr@239 7 #include <functional>
mas01mc@292 8 #include <iostream>
mas01mc@292 9 #include "ReporterBase.h"
mas01mc@292 10 #include "audioDB.h"
mas01cr@239 11
mas01cr@239 12 typedef struct nnresult {
mas01cr@239 13 unsigned int trackID;
mas01cr@239 14 double dist;
mas01cr@239 15 unsigned int qpos;
mas01cr@239 16 unsigned int spos;
mas01cr@239 17 } NNresult;
mas01cr@239 18
mas01cr@239 19 typedef struct radresult {
mas01cr@239 20 unsigned int trackID;
mas01cr@239 21 unsigned int count;
mas01cr@239 22 } Radresult;
mas01cr@239 23
mas01cr@239 24 bool operator< (const NNresult &a, const NNresult &b) {
mas01cr@239 25 return a.dist < b.dist;
mas01cr@239 26 }
mas01cr@239 27
mas01cr@239 28 bool operator> (const NNresult &a, const NNresult &b) {
mas01cr@239 29 return a.dist > b.dist;
mas01cr@239 30 }
mas01cr@239 31
mas01cr@239 32 bool operator< (const Radresult &a, const Radresult &b) {
mas01cr@239 33 return a.count < b.count;
mas01cr@239 34 }
mas01cr@239 35
mas01mc@275 36 bool operator> (const Radresult &a, const Radresult &b) {
mas01mc@275 37 return a.count > b.count;
mas01mc@275 38 }
mas01mc@275 39
mas01mc@292 40 class Reporter : public ReporterBase {
mas01cr@239 41 public:
mas01cr@239 42 virtual ~Reporter() {};
mas01cr@239 43 virtual void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) = 0;
mas01cr@239 44 // FIXME: this interface is a bit wacky: a relic of previous, more
mas01cr@239 45 // confused times. Really it might make sense to have separate
mas01cr@239 46 // reporter classes for WS and for stdout, rather than passing this
mas01cr@239 47 // adbQueryResponse thing everywhere; the fileTable argument is
mas01cr@239 48 // there solely for convertion trackIDs into names. -- CSR,
mas01cr@239 49 // 2007-12-10.
mas01mc@292 50 virtual void report(char *fileTable, void* adbQueryResponse) = 0;
mas01cr@239 51 };
mas01cr@239 52
mas01cr@239 53 template <class T> class pointQueryReporter : public Reporter {
mas01cr@239 54 public:
mas01cr@239 55 pointQueryReporter(unsigned int pointNN);
mas01cr@239 56 ~pointQueryReporter();
mas01cr@239 57 void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist);
mas01mc@292 58 void report(char *fileTable, void* adbQueryResponse);
mas01cr@239 59 private:
mas01cr@239 60 unsigned int pointNN;
mas01cr@239 61 std::priority_queue< NNresult, std::vector< NNresult >, T> *queue;
mas01cr@239 62 };
mas01cr@239 63
mas01cr@239 64 template <class T> pointQueryReporter<T>::pointQueryReporter(unsigned int pointNN)
mas01cr@239 65 : pointNN(pointNN) {
mas01cr@239 66 queue = new std::priority_queue< NNresult, std::vector< NNresult >, T>;
mas01cr@239 67 }
mas01cr@239 68
mas01cr@239 69 template <class T> pointQueryReporter<T>::~pointQueryReporter() {
mas01cr@239 70 delete queue;
mas01cr@239 71 }
mas01cr@239 72
mas01cr@239 73 template <class T> void pointQueryReporter<T>::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) {
mas01cr@242 74 if (!isnan(dist)) {
mas01cr@242 75 NNresult r;
mas01cr@242 76 r.trackID = trackID;
mas01cr@242 77 r.qpos = qpos;
mas01cr@242 78 r.spos = spos;
mas01cr@242 79 r.dist = dist;
mas01cr@242 80 queue->push(r);
mas01cr@242 81 if(queue->size() > pointNN) {
mas01cr@242 82 queue->pop();
mas01cr@242 83 }
mas01cr@239 84 }
mas01cr@239 85 }
mas01cr@239 86
mas01mc@292 87 template <class T> void pointQueryReporter<T>::report(char *fileTable, void *adbQueryResponse) {
mas01cr@239 88 NNresult r;
mas01cr@239 89 std::vector<NNresult> v;
mas01cr@239 90 unsigned int size = queue->size();
mas01cr@239 91 for(unsigned int k = 0; k < size; k++) {
mas01cr@239 92 r = queue->top();
mas01cr@239 93 v.push_back(r);
mas01cr@239 94 queue->pop();
mas01cr@239 95 }
mas01cr@239 96 std::vector<NNresult>::reverse_iterator rit;
mas01cr@239 97
mas01cr@239 98 if(adbQueryResponse==0) {
mas01cr@239 99 for(rit = v.rbegin(); rit < v.rend(); rit++) {
mas01cr@239 100 r = *rit;
mas01mc@292 101 if(fileTable)
mas01mc@292 102 std::cout << fileTable + r.trackID*O2_FILETABLE_ENTRY_SIZE << " ";
mas01mc@292 103 else
mas01mc@292 104 std::cout << r.trackID << " ";
mas01cr@239 105 std::cout << r.dist << " " << r.qpos << " " << r.spos << std::endl;
mas01cr@239 106 }
mas01cr@239 107 } else {
mas01mc@292 108 ((adb__queryResponse*)adbQueryResponse)->result.__sizeRlist=size;
mas01mc@292 109 ((adb__queryResponse*)adbQueryResponse)->result.__sizeDist=size;
mas01mc@292 110 ((adb__queryResponse*)adbQueryResponse)->result.__sizeQpos=size;
mas01mc@292 111 ((adb__queryResponse*)adbQueryResponse)->result.__sizeSpos=size;
mas01mc@292 112 ((adb__queryResponse*)adbQueryResponse)->result.Rlist= new char*[size];
mas01mc@292 113 ((adb__queryResponse*)adbQueryResponse)->result.Dist = new double[size];
mas01mc@292 114 ((adb__queryResponse*)adbQueryResponse)->result.Qpos = new unsigned int[size];
mas01mc@292 115 ((adb__queryResponse*)adbQueryResponse)->result.Spos = new unsigned int[size];
mas01cr@239 116 unsigned int k = 0;
mas01cr@239 117 for(rit = v.rbegin(); rit < v.rend(); rit++, k++) {
mas01cr@239 118 r = *rit;
mas01mc@292 119 ((adb__queryResponse*)adbQueryResponse)->result.Rlist[k] = new char[O2_MAXFILESTR];
mas01mc@292 120 ((adb__queryResponse*)adbQueryResponse)->result.Dist[k] = r.dist;
mas01mc@292 121 ((adb__queryResponse*)adbQueryResponse)->result.Qpos[k] = r.qpos;
mas01mc@292 122 ((adb__queryResponse*)adbQueryResponse)->result.Spos[k] = r.spos;
mas01mc@292 123 if(fileTable)
mas01mc@292 124 snprintf(((adb__queryResponse*)adbQueryResponse)->result.Rlist[k], O2_MAXFILESTR, "%s", fileTable+r.trackID*O2_FILETABLE_ENTRY_SIZE);
mas01mc@292 125 else
mas01mc@292 126 snprintf(((adb__queryResponse*)adbQueryResponse)->result.Rlist[k], O2_MAXFILESTR, "%d", r.trackID);
mas01cr@239 127 }
mas01cr@239 128 }
mas01cr@239 129 }
mas01cr@239 130
mas01cr@239 131 template <class T> class trackAveragingReporter : public Reporter {
mas01cr@239 132 public:
mas01cr@239 133 trackAveragingReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles);
mas01cr@239 134 ~trackAveragingReporter();
mas01cr@239 135 void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist);
mas01mc@292 136 void report(char *fileTable, void *adbQueryResponse);
mas01mc@249 137 protected:
mas01cr@239 138 unsigned int pointNN;
mas01cr@239 139 unsigned int trackNN;
mas01cr@239 140 unsigned int numFiles;
mas01cr@239 141 std::priority_queue< NNresult, std::vector< NNresult>, T > *queues;
mas01cr@239 142 };
mas01cr@239 143
mas01cr@239 144 template <class T> trackAveragingReporter<T>::trackAveragingReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles)
mas01cr@239 145 : pointNN(pointNN), trackNN(trackNN), numFiles(numFiles) {
mas01cr@239 146 queues = new std::priority_queue< NNresult, std::vector< NNresult>, T >[numFiles];
mas01cr@239 147 }
mas01cr@239 148
mas01cr@239 149 template <class T> trackAveragingReporter<T>::~trackAveragingReporter() {
mas01cr@239 150 delete [] queues;
mas01cr@239 151 }
mas01cr@239 152
mas01cr@239 153 template <class T> void trackAveragingReporter<T>::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) {
mas01cr@242 154 if (!isnan(dist)) {
mas01cr@242 155 NNresult r;
mas01cr@242 156 r.trackID = trackID;
mas01cr@242 157 r.qpos = qpos;
mas01cr@242 158 r.spos = spos;
mas01cr@242 159 r.dist = dist;
mas01cr@242 160 queues[trackID].push(r);
mas01cr@242 161 if(queues[trackID].size() > pointNN) {
mas01cr@242 162 queues[trackID].pop();
mas01cr@242 163 }
mas01cr@239 164 }
mas01cr@239 165 }
mas01cr@239 166
mas01mc@292 167 template <class T> void trackAveragingReporter<T>::report(char *fileTable, void *adbQueryResponse) {
mas01cr@239 168 std::priority_queue < NNresult, std::vector< NNresult>, T> result;
mas01cr@239 169 for (int i = numFiles-1; i >= 0; i--) {
mas01cr@239 170 unsigned int size = queues[i].size();
mas01cr@239 171 if (size > 0) {
mas01cr@239 172 NNresult r;
mas01cr@239 173 double dist = 0;
mas01cr@239 174 NNresult oldr = queues[i].top();
mas01cr@239 175 for (unsigned int j = 0; j < size; j++) {
mas01cr@239 176 r = queues[i].top();
mas01cr@239 177 dist += r.dist;
mas01cr@239 178 queues[i].pop();
mas01cr@239 179 if (r.dist == oldr.dist) {
mas01cr@239 180 r.qpos = oldr.qpos;
mas01cr@239 181 r.spos = oldr.spos;
mas01cr@239 182 } else {
mas01cr@239 183 oldr = r;
mas01cr@239 184 }
mas01cr@239 185 }
mas01cr@239 186 dist /= size;
mas01cr@239 187 r.dist = dist; // trackID, qpos and spos are magically right already.
mas01cr@239 188 result.push(r);
mas01cr@239 189 if (result.size() > trackNN) {
mas01cr@239 190 result.pop();
mas01cr@239 191 }
mas01cr@239 192 }
mas01cr@239 193 }
mas01cr@239 194
mas01cr@239 195 NNresult r;
mas01cr@239 196 std::vector<NNresult> v;
mas01cr@239 197 unsigned int size = result.size();
mas01cr@239 198 for(unsigned int k = 0; k < size; k++) {
mas01cr@239 199 r = result.top();
mas01cr@239 200 v.push_back(r);
mas01cr@239 201 result.pop();
mas01cr@239 202 }
mas01cr@239 203 std::vector<NNresult>::reverse_iterator rit;
mas01cr@239 204
mas01cr@239 205 if(adbQueryResponse==0) {
mas01cr@239 206 for(rit = v.rbegin(); rit < v.rend(); rit++) {
mas01cr@239 207 r = *rit;
mas01mc@292 208 if(fileTable)
mas01mc@292 209 std::cout << fileTable + r.trackID*O2_FILETABLE_ENTRY_SIZE << " ";
mas01mc@292 210 else
mas01mc@292 211 std::cout << r.trackID << " ";
mas01cr@239 212 std::cout << r.dist << " " << r.qpos << " " << r.spos << std::endl;
mas01cr@239 213 }
mas01cr@239 214 } else {
mas01mc@292 215 ((adb__queryResponse*)adbQueryResponse)->result.__sizeRlist=size;
mas01mc@292 216 ((adb__queryResponse*)adbQueryResponse)->result.__sizeDist=size;
mas01mc@292 217 ((adb__queryResponse*)adbQueryResponse)->result.__sizeQpos=size;
mas01mc@292 218 ((adb__queryResponse*)adbQueryResponse)->result.__sizeSpos=size;
mas01mc@292 219 ((adb__queryResponse*)adbQueryResponse)->result.Rlist= new char*[size];
mas01mc@292 220 ((adb__queryResponse*)adbQueryResponse)->result.Dist = new double[size];
mas01mc@292 221 ((adb__queryResponse*)adbQueryResponse)->result.Qpos = new unsigned int[size];
mas01mc@292 222 ((adb__queryResponse*)adbQueryResponse)->result.Spos = new unsigned int[size];
mas01cr@239 223 unsigned int k = 0;
mas01cr@239 224 for(rit = v.rbegin(); rit < v.rend(); rit++, k++) {
mas01cr@239 225 r = *rit;
mas01mc@292 226 ((adb__queryResponse*)adbQueryResponse)->result.Rlist[k] = new char[O2_MAXFILESTR];
mas01mc@292 227 ((adb__queryResponse*)adbQueryResponse)->result.Dist[k] = r.dist;
mas01mc@292 228 ((adb__queryResponse*)adbQueryResponse)->result.Qpos[k] = r.qpos;
mas01mc@292 229 ((adb__queryResponse*)adbQueryResponse)->result.Spos[k] = r.spos;
mas01mc@292 230 if(fileTable)
mas01mc@292 231 snprintf(((adb__queryResponse*)adbQueryResponse)->result.Rlist[k], O2_MAXFILESTR, "%s", fileTable+r.trackID*O2_FILETABLE_ENTRY_SIZE);
mas01mc@292 232 else
mas01mc@292 233 snprintf(((adb__queryResponse*)adbQueryResponse)->result.Rlist[k], O2_MAXFILESTR, "%d", r.trackID);
mas01cr@239 234 }
mas01cr@239 235 }
mas01cr@239 236 }
mas01cr@239 237
mas01mc@249 238 // Another type of trackAveragingReporter that reports all pointNN nearest neighbours
mas01mc@249 239 template <class T> class trackSequenceQueryNNReporter : public trackAveragingReporter<T> {
mas01mc@249 240 protected:
mas01mc@249 241 using trackAveragingReporter<T>::numFiles;
mas01mc@249 242 using trackAveragingReporter<T>::queues;
mas01mc@249 243 using trackAveragingReporter<T>::trackNN;
mas01mc@249 244 using trackAveragingReporter<T>::pointNN;
mas01mc@248 245 public:
mas01mc@248 246 trackSequenceQueryNNReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles);
mas01mc@292 247 void report(char *fileTable, void *adbQueryResponse);
mas01mc@248 248 };
mas01mc@248 249
mas01mc@249 250 template <class T> trackSequenceQueryNNReporter<T>::trackSequenceQueryNNReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles)
mas01mc@249 251 :trackAveragingReporter<T>(pointNN, trackNN, numFiles){}
mas01mc@248 252
mas01mc@292 253 template <class T> void trackSequenceQueryNNReporter<T>::report(char *fileTable, void *adbQueryResponse) {
mas01mc@248 254 std::priority_queue < NNresult, std::vector< NNresult>, T> result;
mas01mc@292 255 std::priority_queue< NNresult, std::vector< NNresult>, std::less<NNresult> > *point_queues
mas01mc@292 256 = new std::priority_queue< NNresult, std::vector< NNresult>, std::less<NNresult> >[numFiles];
mas01mc@249 257
mas01mc@248 258 for (int i = numFiles-1; i >= 0; i--) {
mas01mc@248 259 unsigned int size = queues[i].size();
mas01mc@248 260 if (size > 0) {
mas01mc@248 261 NNresult r;
mas01mc@248 262 double dist = 0;
mas01mc@248 263 NNresult oldr = queues[i].top();
mas01mc@248 264 for (unsigned int j = 0; j < size; j++) {
mas01mc@248 265 r = queues[i].top();
mas01mc@248 266 dist += r.dist;
mas01mc@248 267 point_queues[i].push(r);
mas01mc@249 268 queues[i].pop();
mas01mc@248 269 if (r.dist == oldr.dist) {
mas01mc@248 270 r.qpos = oldr.qpos;
mas01mc@248 271 r.spos = oldr.spos;
mas01mc@248 272 } else {
mas01mc@248 273 oldr = r;
mas01mc@248 274 }
mas01mc@248 275 }
mas01mc@248 276 dist /= size;
mas01mc@248 277 r.dist = dist; // trackID, qpos and spos are magically right already.
mas01mc@248 278 result.push(r);
mas01mc@248 279 if (result.size() > trackNN) {
mas01mc@248 280 result.pop();
mas01mc@248 281 }
mas01mc@248 282 }
mas01mc@248 283 }
mas01mc@248 284
mas01mc@248 285 NNresult r;
mas01mc@248 286 std::vector<NNresult> v;
mas01mc@248 287 unsigned int size = result.size();
mas01mc@248 288 for(unsigned int k = 0; k < size; k++) {
mas01mc@248 289 r = result.top();
mas01mc@248 290 v.push_back(r);
mas01mc@248 291 result.pop();
mas01mc@248 292 }
mas01mc@248 293 std::vector<NNresult>::reverse_iterator rit;
mas01mc@264 294 std::priority_queue< NNresult, std::vector< NNresult>, std::greater<NNresult> > point_queue;
mas01mc@264 295
mas01mc@248 296 if(adbQueryResponse==0) {
mas01mc@248 297 for(rit = v.rbegin(); rit < v.rend(); rit++) {
mas01mc@248 298 r = *rit;
mas01mc@292 299 if(fileTable)
mas01mc@292 300 std::cout << fileTable + r.trackID*O2_FILETABLE_ENTRY_SIZE << " ";
mas01mc@292 301 else
mas01mc@292 302 std::cout << r.trackID << " ";
mas01mc@292 303 std::cout << r.dist << std::endl;
mas01mc@264 304 unsigned int qsize = point_queues[r.trackID].size();
mas01mc@264 305 // Reverse the order of the points stored in point_queues
mas01mc@264 306 for(unsigned int k=0; k < qsize; k++){
mas01mc@264 307 point_queue.push( point_queues[r.trackID].top() );
mas01mc@264 308 point_queues[r.trackID].pop();
mas01mc@264 309 }
mas01mc@264 310
mas01mc@264 311 for(unsigned int k = 0; k < qsize; k++) {
mas01mc@264 312 NNresult rk = point_queue.top();
mas01mc@248 313 std::cout << rk.dist << " " << rk.qpos << " " << rk.spos << std::endl;
mas01mc@264 314 point_queue.pop();
mas01mc@248 315 }
mas01mc@248 316 }
mas01mc@248 317 } else {
mas01mc@292 318 ((adb__queryResponse*)adbQueryResponse)->result.__sizeRlist=size;
mas01mc@292 319 ((adb__queryResponse*)adbQueryResponse)->result.__sizeDist=size;
mas01mc@292 320 ((adb__queryResponse*)adbQueryResponse)->result.__sizeQpos=size;
mas01mc@292 321 ((adb__queryResponse*)adbQueryResponse)->result.__sizeSpos=size;
mas01mc@292 322 ((adb__queryResponse*)adbQueryResponse)->result.Rlist= new char*[size];
mas01mc@292 323 ((adb__queryResponse*)adbQueryResponse)->result.Dist = new double[size];
mas01mc@292 324 ((adb__queryResponse*)adbQueryResponse)->result.Qpos = new unsigned int[size];
mas01mc@292 325 ((adb__queryResponse*)adbQueryResponse)->result.Spos = new unsigned int[size];
mas01mc@248 326 unsigned int k = 0;
mas01mc@248 327 for(rit = v.rbegin(); rit < v.rend(); rit++, k++) {
mas01mc@248 328 r = *rit;
mas01mc@292 329 ((adb__queryResponse*)adbQueryResponse)->result.Rlist[k] = new char[O2_MAXFILESTR];
mas01mc@292 330 ((adb__queryResponse*)adbQueryResponse)->result.Dist[k] = r.dist;
mas01mc@292 331 ((adb__queryResponse*)adbQueryResponse)->result.Qpos[k] = r.qpos;
mas01mc@292 332 ((adb__queryResponse*)adbQueryResponse)->result.Spos[k] = r.spos;
mas01mc@292 333 if(fileTable)
mas01mc@292 334 snprintf(((adb__queryResponse*)adbQueryResponse)->result.Rlist[k], O2_MAXFILESTR, "%s", fileTable+r.trackID*O2_FILETABLE_ENTRY_SIZE);
mas01mc@292 335 else
mas01mc@292 336 snprintf(((adb__queryResponse*)adbQueryResponse)->result.Rlist[k], O2_MAXFILESTR, "%d", r.trackID);
mas01mc@248 337 }
mas01mc@248 338 }
mas01mc@248 339 // clean up
mas01mc@248 340 delete[] point_queues;
mas01mc@248 341 }
mas01mc@250 342
mas01mc@292 343 /********************** Radius Reporters **************************/
mas01mc@250 344
mas01mc@292 345 class triple{
mas01mc@292 346 public:
mas01mc@292 347 unsigned int a;
mas01mc@292 348 unsigned int b;
mas01mc@292 349 unsigned int c;
mas01mc@292 350
mas01mc@292 351 triple(void);
mas01mc@292 352 triple(unsigned int, unsigned int, unsigned int);
mas01mc@292 353 unsigned int first();
mas01mc@292 354 unsigned int second();
mas01mc@292 355 unsigned int third();
mas01mc@292 356 };
mas01mc@292 357
mas01mc@292 358 triple& make_triple(unsigned int, unsigned int, unsigned int);
mas01mc@292 359
mas01mc@292 360 triple::triple(unsigned int a, unsigned int b, unsigned int c):a(a),b(b),c(c){}
mas01mc@292 361
mas01mc@292 362 unsigned int triple::first(){return a;}
mas01mc@292 363 unsigned int triple::second(){return b;}
mas01mc@292 364 unsigned int triple::third(){return c;}
mas01mc@292 365
mas01mc@292 366 triple::triple():a(0),b(0),c(0){}
mas01mc@292 367
mas01mc@292 368 bool operator< (const triple &t1, const triple &t2) {
mas01mc@292 369 return ((t1.a < t2.a) ||
mas01mc@292 370 ((t1.a == t2.a) && ((t1.b < t2.b) ||
mas01mc@292 371 ((t1.b == t2.b) && (t1.c < t2.c)))));
mas01mc@292 372 }
mas01mc@292 373 bool operator== (const triple &t1, const triple &t2) {
mas01mc@292 374 return ((t1.a == t2.a) && (t1.b == t2.b) && (t1.c == t2.c));
mas01mc@292 375 }
mas01mc@292 376
mas01mc@292 377 triple& make_triple(unsigned int a, unsigned int b, unsigned int c){
mas01mc@292 378 triple* t = new triple(a,b,c);
mas01mc@292 379 return *t;
mas01mc@292 380 }
mas01mc@292 381
mas01mc@292 382 // track Sequence Query Radius Reporter
mas01mc@292 383 // only return tracks and retrieved point counts
mas01mc@292 384 class trackSequenceQueryRadReporter : public Reporter {
mas01mc@250 385 public:
mas01mc@292 386 trackSequenceQueryRadReporter(unsigned int trackNN, unsigned int numFiles);
mas01mc@292 387 ~trackSequenceQueryRadReporter();
mas01mc@250 388 void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist);
mas01mc@292 389 void report(char *fileTable, void *adbQueryResponse);
mas01mc@250 390 protected:
mas01mc@250 391 unsigned int trackNN;
mas01mc@250 392 unsigned int numFiles;
mas01mc@292 393 std::set<std::pair<unsigned int, unsigned int> > *set;
mas01mc@292 394 std::set< triple > *set_triple;
mas01mc@250 395 unsigned int *count;
mas01mc@250 396 };
mas01mc@250 397
mas01mc@292 398 trackSequenceQueryRadReporter::trackSequenceQueryRadReporter(unsigned int trackNN, unsigned int numFiles):
mas01mc@292 399 trackNN(trackNN), numFiles(numFiles) {
mas01mc@292 400 set = new std::set<std::pair<unsigned int, unsigned int> >;
mas01mc@292 401 set_triple = new std::set<triple, std::less<triple> >;
mas01mc@250 402 count = new unsigned int[numFiles];
mas01mc@250 403 for (unsigned i = 0; i < numFiles; i++) {
mas01mc@250 404 count[i] = 0;
mas01mc@250 405 }
mas01mc@250 406 }
mas01mc@250 407
mas01mc@292 408 trackSequenceQueryRadReporter::~trackSequenceQueryRadReporter() {
mas01mc@250 409 delete set;
mas01mc@292 410 delete set_triple;
mas01mc@250 411 delete [] count;
mas01mc@250 412 }
mas01mc@250 413
mas01mc@292 414 void trackSequenceQueryRadReporter::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) {
mas01mc@292 415 std::set<std::pair<unsigned int, unsigned int> >::iterator it;
mas01mc@292 416 std::pair<unsigned int, unsigned int> pair = std::make_pair(trackID, qpos); // only count this once
mas01mc@292 417 std::set<triple>::iterator it2;
mas01mc@292 418 triple triple;
mas01mc@250 419
mas01mc@292 420 triple = make_triple(trackID, qpos, spos); // only count this once
mas01mc@292 421
mas01mc@292 422 // Record unique <trackID,qpos,spos> triples (record one collision from all hash tables)
mas01mc@292 423 it2 = set_triple->find(triple);
mas01mc@250 424
mas01mc@292 425 if(it2 == set_triple->end()){
mas01mc@292 426 set_triple->insert(triple);
mas01mc@292 427
mas01mc@292 428 it = set->find(pair);
mas01mc@292 429 if (it == set->end()) {
mas01mc@292 430 set->insert(pair);
mas01mc@292 431 count[trackID]++; // only count if <tackID,qpos> pair is unique
mas01mc@292 432 }
mas01mc@250 433 }
mas01mc@250 434 }
mas01mc@250 435
mas01mc@292 436 void trackSequenceQueryRadReporter::report(char *fileTable, void *adbQueryResponse) {
mas01mc@275 437 std::priority_queue < Radresult, std::vector<Radresult>, std::greater<Radresult> > result;
mas01mc@250 438 // KLUDGE: doing this backwards in an attempt to get the same
mas01mc@250 439 // tiebreak behaviour as before.
mas01mc@250 440 for (int i = numFiles-1; i >= 0; i--) {
mas01mc@250 441 Radresult r;
mas01mc@250 442 r.trackID = i;
mas01mc@250 443 r.count = count[i];
mas01mc@250 444 if(r.count > 0) {
mas01mc@250 445 result.push(r);
mas01mc@250 446 if (result.size() > trackNN) {
mas01mc@250 447 result.pop();
mas01mc@250 448 }
mas01mc@250 449 }
mas01mc@250 450 }
mas01mc@250 451
mas01mc@250 452 Radresult r;
mas01mc@250 453 std::vector<Radresult> v;
mas01mc@250 454 unsigned int size = result.size();
mas01mc@250 455 for(unsigned int k = 0; k < size; k++) {
mas01mc@250 456 r = result.top();
mas01mc@250 457 v.push_back(r);
mas01mc@250 458 result.pop();
mas01mc@250 459 }
mas01mc@292 460 std::vector<Radresult>::reverse_iterator rit;
mas01mc@292 461
mas01mc@292 462 if(adbQueryResponse==0) {
mas01mc@292 463 for(rit = v.rbegin(); rit < v.rend(); rit++) {
mas01mc@292 464 r = *rit;
mas01mc@292 465 if(fileTable)
mas01mc@292 466 std::cout << fileTable + r.trackID*O2_FILETABLE_ENTRY_SIZE << " ";
mas01mc@292 467 else
mas01mc@292 468 std::cout << r.trackID << " ";
mas01mc@292 469 std::cout << r.count << std::endl;
mas01mc@292 470 }
mas01mc@307 471 }
mas01mc@307 472 else {
mas01mc@307 473 ((adb__queryResponse*)adbQueryResponse)->result.__sizeRlist=size;
mas01mc@307 474 ((adb__queryResponse*)adbQueryResponse)->result.__sizeDist=size;
mas01mc@307 475 ((adb__queryResponse*)adbQueryResponse)->result.__sizeQpos=size;
mas01mc@307 476 ((adb__queryResponse*)adbQueryResponse)->result.__sizeSpos=size;
mas01mc@307 477 ((adb__queryResponse*)adbQueryResponse)->result.Rlist= new char*[size];
mas01mc@307 478 ((adb__queryResponse*)adbQueryResponse)->result.Dist = new double[size];
mas01mc@307 479 ((adb__queryResponse*)adbQueryResponse)->result.Qpos = new unsigned int[size];
mas01mc@307 480 ((adb__queryResponse*)adbQueryResponse)->result.Spos = new unsigned int[size];
mas01mc@307 481 unsigned int k = 0;
mas01mc@307 482 for(rit = v.rbegin(); rit < v.rend(); rit++, k++) {
mas01mc@307 483 r = *rit;
mas01mc@307 484 ((adb__queryResponse*)adbQueryResponse)->result.Rlist[k] = new char[O2_MAXFILESTR];
mas01mc@307 485 ((adb__queryResponse*)adbQueryResponse)->result.Dist[k] = 0;
mas01mc@307 486 ((adb__queryResponse*)adbQueryResponse)->result.Qpos[k] = 0;
mas01mc@307 487 ((adb__queryResponse*)adbQueryResponse)->result.Spos[k] = 0;
mas01mc@307 488 if(fileTable)
mas01mc@307 489 snprintf(((adb__queryResponse*)adbQueryResponse)->result.Rlist[k], O2_MAXFILESTR, "%s", fileTable+r.trackID*O2_FILETABLE_ENTRY_SIZE);
mas01mc@307 490 else
mas01mc@307 491 snprintf(((adb__queryResponse*)adbQueryResponse)->result.Rlist[k], O2_MAXFILESTR, "%d", r.trackID);
mas01mc@307 492 }
mas01mc@292 493 }
mas01mc@292 494 }
mas01mc@292 495
mas01mc@292 496 // track Sequence Query Radius NN Reporter
mas01mc@292 497 // retrieve tracks ordered by query-point matches (one per track per query point)
mas01mc@292 498 //
mas01mc@292 499 // as well as sorted n-NN points per retrieved track
mas01mc@292 500 class trackSequenceQueryRadNNReporter : public Reporter {
mas01mc@292 501 public:
mas01mc@292 502 trackSequenceQueryRadNNReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles);
mas01mc@292 503 ~trackSequenceQueryRadNNReporter();
mas01mc@292 504 void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist);
mas01mc@292 505 void report(char *fileTable, void *adbQueryResponse);
mas01mc@292 506 protected:
mas01mc@292 507 unsigned int pointNN;
mas01mc@292 508 unsigned int trackNN;
mas01mc@292 509 unsigned int numFiles;
mas01mc@292 510 std::set<std::pair<unsigned int, unsigned int> > *set;
mas01mc@292 511 std::set< triple > *set_triple;
mas01mc@292 512 std::priority_queue< NNresult, std::vector< NNresult>, std::less<NNresult> > *point_queues;
mas01mc@292 513 unsigned int *count;
mas01mc@292 514 };
mas01mc@292 515
mas01mc@292 516 trackSequenceQueryRadNNReporter::trackSequenceQueryRadNNReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles):
mas01mc@292 517 pointNN(pointNN), trackNN(trackNN), numFiles(numFiles) {
mas01mc@292 518 // Where to count Radius track matches (one-to-one)
mas01mc@292 519 set = new std::set<std::pair<unsigned int, unsigned int> >;
mas01mc@292 520 set_triple = new std::set<triple, std::less<triple> >;
mas01mc@292 521 // Where to insert individual point matches (one-to-many)
mas01mc@292 522 point_queues = new std::priority_queue< NNresult, std::vector< NNresult>, std::less<NNresult> >[numFiles];
mas01mc@292 523
mas01mc@292 524 count = new unsigned int[numFiles];
mas01mc@292 525 for (unsigned i = 0; i < numFiles; i++) {
mas01mc@292 526 count[i] = 0;
mas01mc@292 527 }
mas01mc@292 528 }
mas01mc@292 529
mas01mc@292 530 trackSequenceQueryRadNNReporter::~trackSequenceQueryRadNNReporter() {
mas01mc@292 531 delete set;
mas01mc@292 532 delete set_triple;
mas01mc@292 533 delete [] count;
mas01mc@292 534 }
mas01mc@292 535
mas01mc@292 536 void trackSequenceQueryRadNNReporter::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) {
mas01mc@292 537 std::set<std::pair<unsigned int, unsigned int> >::iterator it;
mas01mc@292 538 std::set<triple>::iterator it2;
mas01mc@292 539 std::pair<unsigned int, unsigned int> pair;
mas01mc@292 540 triple triple;
mas01mc@292 541 NNresult r;
mas01mc@292 542
mas01mc@292 543 pair = std::make_pair(trackID, qpos); // only count this once
mas01mc@292 544 triple = make_triple(trackID, qpos, spos); // only count this once
mas01mc@292 545 // Record unique <trackID,qpos,spos> triples (record one collision from all hash tables)
mas01mc@292 546 it2 = set_triple->find(triple);
mas01mc@292 547 if(it2 == set_triple->end()){
mas01mc@292 548 set_triple->insert(triple);
mas01mc@292 549 // Record all matching points (within radius)
mas01mc@292 550 // Record counts of <trackID,qpos> pairs
mas01mc@292 551 it = set->find(pair);
mas01mc@292 552 if (it == set->end()) {
mas01mc@292 553 set->insert(pair);
mas01mc@292 554 count[trackID]++;
mas01mc@307 555 }
mas01mc@307 556 if (!isnan(dist)) {
mas01mc@307 557 r.trackID = trackID;
mas01mc@307 558 r.qpos = qpos;
mas01mc@307 559 r.dist = dist;
mas01mc@307 560 r.spos = spos;
mas01mc@307 561 point_queues[trackID].push(r);
mas01mc@307 562 if(point_queues[trackID].size() > pointNN)
mas01mc@307 563 point_queues[trackID].pop();
mas01mc@292 564 }
mas01mc@292 565 }
mas01mc@292 566 }
mas01mc@292 567
mas01mc@292 568 void trackSequenceQueryRadNNReporter::report(char *fileTable, void *adbQueryResponse) {
mas01mc@292 569 std::priority_queue < Radresult, std::vector<Radresult>, std::greater<Radresult> > result;
mas01mc@292 570 // KLUDGE: doing this backwards in an attempt to get the same
mas01mc@292 571 // tiebreak behaviour as before.
mas01mc@292 572 Radresult r;
mas01mc@292 573 NNresult rk;
mas01mc@307 574 std::vector<Radresult> v;
mas01mc@307 575 unsigned int size;
mas01mc@292 576
mas01mc@307 577 if(pointNN>1){
mas01mc@307 578 for (int i = numFiles-1; i >= 0; i--) {
mas01mc@307 579 r.trackID = i;
mas01mc@307 580 r.count = count[i];
mas01mc@307 581 if(r.count > 0) {
mas01mc@307 582 cout.flush();
mas01mc@307 583 result.push(r);
mas01mc@307 584 if (result.size() > trackNN) {
mas01mc@307 585 result.pop();
mas01mc@307 586 }
mas01mc@292 587 }
mas01mc@292 588 }
mas01mc@307 589
mas01mc@307 590 size = result.size();
mas01mc@307 591 for(unsigned int k = 0; k < size; k++) {
mas01mc@307 592 r = result.top();
mas01mc@307 593 v.push_back(r);
mas01mc@307 594 result.pop();
mas01mc@307 595 }
mas01mc@292 596 }
mas01mc@307 597 else{
mas01mc@307 598 // Instantiate a 1-NN trackAveragingNN reporter
mas01mc@307 599 trackSequenceQueryNNReporter<std::less <NNresult> >* rep = new trackSequenceQueryNNReporter<std::less <NNresult> >(1, trackNN, numFiles);
mas01mc@307 600 // Add all the points we've got to the reporter
mas01mc@307 601 for(unsigned int i=0; i<numFiles; i++){
mas01mc@307 602 int qsize = point_queues[i].size();
mas01mc@307 603 while(qsize--){
mas01mc@307 604 rk = point_queues[i].top();
mas01mc@307 605 rep->add_point(i, rk.qpos, rk.spos, rk.dist);
mas01mc@307 606 point_queues[i].pop();
mas01mc@307 607 }
mas01mc@307 608 }
mas01mc@307 609 // Report
mas01mc@307 610 rep->report(fileTable, adbQueryResponse);
mas01mc@307 611 // Exit
mas01mc@307 612 delete[] point_queues;
mas01mc@307 613 return;
mas01mc@292 614 }
mas01mc@264 615
mas01mc@264 616
mas01mc@264 617 // Traverse tracks in descending order of count cardinality
mas01mc@250 618 std::vector<Radresult>::reverse_iterator rit;
mas01mc@264 619 std::priority_queue< NNresult, std::vector< NNresult>, std::greater<NNresult> > point_queue;
mas01mc@264 620
mas01mc@250 621 if(adbQueryResponse==0) {
mas01mc@250 622 for(rit = v.rbegin(); rit < v.rend(); rit++) {
mas01mc@250 623 r = *rit;
mas01mc@292 624 if(fileTable)
mas01mc@292 625 std::cout << fileTable + r.trackID*O2_FILETABLE_ENTRY_SIZE << " ";
mas01mc@292 626 else
mas01mc@292 627 std::cout << r.trackID << " ";
mas01mc@292 628 std::cout << r.count << std::endl;
mas01mc@264 629
mas01mc@264 630 // Reverse the order of the points stored in point_queues
mas01mc@264 631 unsigned int qsize=point_queues[r.trackID].size();
mas01mc@264 632 for(unsigned int k=0; k < qsize; k++){
mas01mc@264 633 point_queue.push(point_queues[r.trackID].top());
mas01mc@264 634 point_queues[r.trackID].pop();
mas01mc@264 635 }
mas01mc@264 636 for(unsigned int k=0; k < qsize; k++){
mas01mc@292 637 rk = point_queue.top();
mas01mc@250 638 std::cout << rk.dist << " " << rk.qpos << " " << rk.spos << std::endl;
mas01mc@264 639 point_queue.pop();
mas01mc@250 640 }
mas01mc@250 641 }
mas01mc@250 642 }
mas01mc@307 643 else {
mas01mc@307 644 ((adb__queryResponse*)adbQueryResponse)->result.__sizeRlist=size;
mas01mc@307 645 ((adb__queryResponse*)adbQueryResponse)->result.__sizeDist=size;
mas01mc@307 646 ((adb__queryResponse*)adbQueryResponse)->result.__sizeQpos=size;
mas01mc@307 647 ((adb__queryResponse*)adbQueryResponse)->result.__sizeSpos=size;
mas01mc@307 648 ((adb__queryResponse*)adbQueryResponse)->result.Rlist= new char*[size];
mas01mc@307 649 ((adb__queryResponse*)adbQueryResponse)->result.Dist = new double[size];
mas01mc@307 650 ((adb__queryResponse*)adbQueryResponse)->result.Qpos = new unsigned int[size];
mas01mc@307 651 ((adb__queryResponse*)adbQueryResponse)->result.Spos = new unsigned int[size];
mas01mc@307 652 unsigned int k = 0;
mas01mc@307 653 // Loop over returned tracks
mas01mc@307 654 for(rit = v.rbegin(); rit < v.rend(); rit++, k++) {
mas01mc@307 655 r = *rit;
mas01mc@307 656 // Reverse the order of the points stored in point_queues
mas01mc@307 657 unsigned int qsize=point_queues[r.trackID].size();
mas01mc@307 658 while(qsize--){
mas01mc@307 659 point_queue.push(point_queues[r.trackID].top());
mas01mc@307 660 point_queues[r.trackID].pop();
mas01mc@307 661 }
mas01mc@307 662 qsize=point_queue.size();
mas01mc@307 663 rk = point_queue.top(); // Take one point from the top of the queue
mas01mc@307 664 ((adb__queryResponse*)adbQueryResponse)->result.Rlist[k] = new char[O2_MAXFILESTR];
mas01mc@307 665 ((adb__queryResponse*)adbQueryResponse)->result.Dist[k] = rk.dist;
mas01mc@307 666 ((adb__queryResponse*)adbQueryResponse)->result.Qpos[k] = rk.qpos;
mas01mc@307 667 ((adb__queryResponse*)adbQueryResponse)->result.Spos[k] = rk.spos;
mas01mc@307 668 if(fileTable)
mas01mc@307 669 snprintf(((adb__queryResponse*)adbQueryResponse)->result.Rlist[k], O2_MAXFILESTR, "%s", fileTable+r.trackID*O2_FILETABLE_ENTRY_SIZE);
mas01mc@307 670 else
mas01mc@307 671 snprintf(((adb__queryResponse*)adbQueryResponse)->result.Rlist[k], O2_MAXFILESTR, "%d", r.trackID);
mas01mc@307 672 while(qsize--) // pop the rest of the points
mas01mc@307 673 point_queue.pop();
mas01mc@307 674 }
mas01mc@307 675 }
mas01mc@264 676 delete[] point_queues;
mas01mc@250 677 }
mas01mc@263 678
mas01mc@264 679 /********** ONE-TO-ONE REPORTERS *****************/
mas01mc@263 680
mas01mc@264 681 // track Sequence Query Radius NN Reporter One-to-One
mas01mc@264 682 // for each query point find the single best matching target point in all database
mas01mc@264 683 // report qpos, spos and trackID
mas01mc@263 684 class trackSequenceQueryRadNNReporterOneToOne : public Reporter {
mas01mc@263 685 public:
mas01mc@263 686 trackSequenceQueryRadNNReporterOneToOne(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles);
mas01mc@263 687 ~trackSequenceQueryRadNNReporterOneToOne();
mas01mc@263 688 void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist);
mas01mc@292 689 void report(char *fileTable, void *adbQueryResponse);
mas01mc@263 690 protected:
mas01mc@263 691 unsigned int pointNN;
mas01mc@263 692 unsigned int trackNN;
mas01mc@263 693 unsigned int numFiles;
mas01mc@263 694 std::set< NNresult > *set;
mas01mc@263 695 std::vector< NNresult> *point_queue;
mas01mc@263 696 unsigned int *count;
mas01mc@263 697
mas01mc@263 698 };
mas01mc@263 699
mas01mc@263 700 trackSequenceQueryRadNNReporterOneToOne::trackSequenceQueryRadNNReporterOneToOne(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles):
mas01mc@263 701 pointNN(pointNN), trackNN(trackNN), numFiles(numFiles) {
mas01mc@263 702 // Where to count Radius track matches (one-to-one)
mas01mc@263 703 set = new std::set< NNresult >;
mas01mc@263 704 // Where to insert individual point matches (one-to-many)
mas01mc@263 705 point_queue = new std::vector< NNresult >;
mas01mc@263 706
mas01mc@263 707 count = new unsigned int[numFiles];
mas01mc@263 708 for (unsigned i = 0; i < numFiles; i++) {
mas01mc@263 709 count[i] = 0;
mas01mc@263 710 }
mas01mc@263 711 }
mas01mc@263 712
mas01mc@263 713 trackSequenceQueryRadNNReporterOneToOne::~trackSequenceQueryRadNNReporterOneToOne() {
mas01mc@263 714 delete set;
mas01mc@263 715 delete [] count;
mas01mc@263 716 }
mas01mc@263 717
mas01mc@263 718 void trackSequenceQueryRadNNReporterOneToOne::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) {
mas01mc@263 719 std::set< NNresult >::iterator it;
mas01mc@263 720 NNresult r;
mas01mc@264 721
mas01mc@263 722 r.qpos = qpos;
mas01mc@263 723 r.trackID = trackID;
mas01mc@263 724 r.spos = spos;
mas01mc@263 725 r.dist = dist;
mas01mc@263 726
mas01mc@263 727 if(point_queue->size() < r.qpos + 1){
mas01mc@263 728 point_queue->resize( r.qpos + 1 );
mas01mc@263 729 (*point_queue)[r.qpos].dist = 1e6;
mas01mc@263 730 }
mas01mc@263 731
mas01mc@263 732 if (r.dist < (*point_queue)[r.qpos].dist)
mas01mc@263 733 (*point_queue)[r.qpos] = r;
mas01mc@263 734
mas01mc@263 735 }
mas01mc@263 736
mas01mc@292 737 void trackSequenceQueryRadNNReporterOneToOne::report(char *fileTable, void *adbQueryResponse) {
mas01mc@263 738 if(adbQueryResponse==0) {
mas01mc@263 739 std::vector< NNresult >::iterator vit;
mas01mc@263 740 NNresult rk;
mas01mc@263 741 for( vit = point_queue->begin() ; vit < point_queue->end() ; vit++ ){
mas01mc@263 742 rk = *vit;
mas01mc@263 743 std::cout << rk.dist << " "
mas01mc@263 744 << rk.qpos << " "
mas01mc@292 745 << rk.spos << " ";
mas01mc@292 746 if(fileTable)
mas01mc@292 747 std::cout << fileTable + rk.trackID*O2_FILETABLE_ENTRY_SIZE << " ";
mas01mc@292 748 else
mas01mc@292 749 std::cout << rk.trackID << " ";
mas01mc@292 750 std::cout << std::endl;
mas01mc@263 751 }
mas01mc@263 752 } else {
mas01mc@263 753 // FIXME
mas01mc@263 754 }
mas01mc@263 755 }
mas01mc@292 756
mas01mc@292 757 #endif