annotate reporter.h @ 458:913a95f06998 api-inversion

Start using the query state structure. Actually using it means moving it around in the source code a little bit, thanks to entanglements. It'll all be alright on the night. Now the accumulator, allowed_keys and exact_evaluation_queue are all part of the query state, and can therefore be passed around with minimal effort (and deleted in the appropriate place). Now a whole bunch of static methods (the callbacks, basically) in index.cpp can be rewritten as plain old C functions. The callbacks need both an adb_t and a query state structure to function (the adb_t to get at things like lsh_n_point_bits and the track->key table; the qstate to get at the accumulator and allowed_keys list). Rearrange audioDB::query a little bit, and mark the beginning and the end of the putative audiodb_query_spec() API function implementation.
author mas01cr
date Sun, 28 Dec 2008 18:44:08 +0000
parents 447f1cf2c276
children d3afc91d205d
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 {
mas01cr@415 108 adb__queryResponse *response = (adb__queryResponse *) adbQueryResponse;
mas01cr@415 109 response->result.__sizeRlist=size;
mas01cr@415 110 response->result.__sizeDist=size;
mas01cr@415 111 response->result.__sizeQpos=size;
mas01cr@415 112 response->result.__sizeSpos=size;
mas01cr@415 113 response->result.Rlist= new char*[size];
mas01cr@415 114 response->result.Dist = new double[size];
mas01cr@415 115 response->result.Qpos = new unsigned int[size];
mas01cr@415 116 response->result.Spos = new unsigned int[size];
mas01cr@239 117 unsigned int k = 0;
mas01cr@239 118 for(rit = v.rbegin(); rit < v.rend(); rit++, k++) {
mas01cr@239 119 r = *rit;
mas01cr@415 120 response->result.Rlist[k] = new char[O2_MAXFILESTR];
mas01cr@415 121 response->result.Dist[k] = r.dist;
mas01cr@415 122 response->result.Qpos[k] = r.qpos;
mas01cr@415 123 response->result.Spos[k] = r.spos;
mas01mc@292 124 if(fileTable)
mas01cr@415 125 snprintf(response->result.Rlist[k], O2_MAXFILESTR, "%s", fileTable+r.trackID*O2_FILETABLE_ENTRY_SIZE);
mas01mc@292 126 else
mas01cr@415 127 snprintf(response->result.Rlist[k], O2_MAXFILESTR, "%d", r.trackID);
mas01cr@239 128 }
mas01cr@239 129 }
mas01cr@239 130 }
mas01cr@239 131
mas01cr@239 132 template <class T> class trackAveragingReporter : public Reporter {
mas01cr@239 133 public:
mas01cr@239 134 trackAveragingReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles);
mas01cr@239 135 ~trackAveragingReporter();
mas01cr@239 136 void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist);
mas01mc@292 137 void report(char *fileTable, void *adbQueryResponse);
mas01mc@249 138 protected:
mas01cr@239 139 unsigned int pointNN;
mas01cr@239 140 unsigned int trackNN;
mas01cr@239 141 unsigned int numFiles;
mas01cr@239 142 std::priority_queue< NNresult, std::vector< NNresult>, T > *queues;
mas01cr@239 143 };
mas01cr@239 144
mas01cr@239 145 template <class T> trackAveragingReporter<T>::trackAveragingReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles)
mas01cr@239 146 : pointNN(pointNN), trackNN(trackNN), numFiles(numFiles) {
mas01cr@239 147 queues = new std::priority_queue< NNresult, std::vector< NNresult>, T >[numFiles];
mas01cr@239 148 }
mas01cr@239 149
mas01cr@239 150 template <class T> trackAveragingReporter<T>::~trackAveragingReporter() {
mas01cr@239 151 delete [] queues;
mas01cr@239 152 }
mas01cr@239 153
mas01cr@239 154 template <class T> void trackAveragingReporter<T>::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) {
mas01cr@242 155 if (!isnan(dist)) {
mas01cr@242 156 NNresult r;
mas01cr@242 157 r.trackID = trackID;
mas01cr@242 158 r.qpos = qpos;
mas01cr@242 159 r.spos = spos;
mas01cr@242 160 r.dist = dist;
mas01cr@242 161 queues[trackID].push(r);
mas01cr@242 162 if(queues[trackID].size() > pointNN) {
mas01cr@242 163 queues[trackID].pop();
mas01cr@242 164 }
mas01cr@239 165 }
mas01cr@239 166 }
mas01cr@239 167
mas01mc@292 168 template <class T> void trackAveragingReporter<T>::report(char *fileTable, void *adbQueryResponse) {
mas01cr@239 169 std::priority_queue < NNresult, std::vector< NNresult>, T> result;
mas01cr@239 170 for (int i = numFiles-1; i >= 0; i--) {
mas01cr@239 171 unsigned int size = queues[i].size();
mas01cr@239 172 if (size > 0) {
mas01cr@239 173 NNresult r;
mas01cr@239 174 double dist = 0;
mas01cr@239 175 NNresult oldr = queues[i].top();
mas01cr@239 176 for (unsigned int j = 0; j < size; j++) {
mas01cr@239 177 r = queues[i].top();
mas01cr@239 178 dist += r.dist;
mas01cr@239 179 queues[i].pop();
mas01cr@239 180 if (r.dist == oldr.dist) {
mas01cr@239 181 r.qpos = oldr.qpos;
mas01cr@239 182 r.spos = oldr.spos;
mas01cr@239 183 } else {
mas01cr@239 184 oldr = r;
mas01cr@239 185 }
mas01cr@239 186 }
mas01cr@239 187 dist /= size;
mas01cr@239 188 r.dist = dist; // trackID, qpos and spos are magically right already.
mas01cr@239 189 result.push(r);
mas01cr@239 190 if (result.size() > trackNN) {
mas01cr@239 191 result.pop();
mas01cr@239 192 }
mas01cr@239 193 }
mas01cr@239 194 }
mas01cr@239 195
mas01cr@239 196 NNresult r;
mas01cr@239 197 std::vector<NNresult> v;
mas01cr@239 198 unsigned int size = result.size();
mas01cr@239 199 for(unsigned int k = 0; k < size; k++) {
mas01cr@239 200 r = result.top();
mas01cr@239 201 v.push_back(r);
mas01cr@239 202 result.pop();
mas01cr@239 203 }
mas01cr@239 204 std::vector<NNresult>::reverse_iterator rit;
mas01cr@239 205
mas01cr@239 206 if(adbQueryResponse==0) {
mas01cr@239 207 for(rit = v.rbegin(); rit < v.rend(); rit++) {
mas01cr@239 208 r = *rit;
mas01mc@292 209 if(fileTable)
mas01mc@292 210 std::cout << fileTable + r.trackID*O2_FILETABLE_ENTRY_SIZE << " ";
mas01mc@292 211 else
mas01mc@292 212 std::cout << r.trackID << " ";
mas01cr@239 213 std::cout << r.dist << " " << r.qpos << " " << r.spos << std::endl;
mas01cr@239 214 }
mas01cr@239 215 } else {
mas01cr@415 216 adb__queryResponse *response = (adb__queryResponse *) adbQueryResponse;
mas01cr@415 217 response->result.__sizeRlist=size;
mas01cr@415 218 response->result.__sizeDist=size;
mas01cr@415 219 response->result.__sizeQpos=size;
mas01cr@415 220 response->result.__sizeSpos=size;
mas01cr@415 221 response->result.Rlist= new char*[size];
mas01cr@415 222 response->result.Dist = new double[size];
mas01cr@415 223 response->result.Qpos = new unsigned int[size];
mas01cr@415 224 response->result.Spos = new unsigned int[size];
mas01cr@239 225 unsigned int k = 0;
mas01cr@239 226 for(rit = v.rbegin(); rit < v.rend(); rit++, k++) {
mas01cr@239 227 r = *rit;
mas01cr@415 228 response->result.Rlist[k] = new char[O2_MAXFILESTR];
mas01cr@415 229 response->result.Dist[k] = r.dist;
mas01cr@415 230 response->result.Qpos[k] = r.qpos;
mas01cr@415 231 response->result.Spos[k] = r.spos;
mas01mc@292 232 if(fileTable)
mas01cr@415 233 snprintf(response->result.Rlist[k], O2_MAXFILESTR, "%s", fileTable+r.trackID*O2_FILETABLE_ENTRY_SIZE);
mas01mc@292 234 else
mas01cr@415 235 snprintf(response->result.Rlist[k], O2_MAXFILESTR, "%d", r.trackID);
mas01cr@239 236 }
mas01cr@239 237 }
mas01cr@239 238 }
mas01cr@239 239
mas01mc@249 240 // Another type of trackAveragingReporter that reports all pointNN nearest neighbours
mas01mc@249 241 template <class T> class trackSequenceQueryNNReporter : public trackAveragingReporter<T> {
mas01mc@249 242 protected:
mas01mc@249 243 using trackAveragingReporter<T>::numFiles;
mas01mc@249 244 using trackAveragingReporter<T>::queues;
mas01mc@249 245 using trackAveragingReporter<T>::trackNN;
mas01mc@249 246 using trackAveragingReporter<T>::pointNN;
mas01mc@248 247 public:
mas01mc@248 248 trackSequenceQueryNNReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles);
mas01mc@292 249 void report(char *fileTable, void *adbQueryResponse);
mas01mc@248 250 };
mas01mc@248 251
mas01mc@249 252 template <class T> trackSequenceQueryNNReporter<T>::trackSequenceQueryNNReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles)
mas01mc@249 253 :trackAveragingReporter<T>(pointNN, trackNN, numFiles){}
mas01mc@248 254
mas01mc@292 255 template <class T> void trackSequenceQueryNNReporter<T>::report(char *fileTable, void *adbQueryResponse) {
mas01mc@248 256 std::priority_queue < NNresult, std::vector< NNresult>, T> result;
mas01mc@292 257 std::priority_queue< NNresult, std::vector< NNresult>, std::less<NNresult> > *point_queues
mas01mc@292 258 = new std::priority_queue< NNresult, std::vector< NNresult>, std::less<NNresult> >[numFiles];
mas01mc@249 259
mas01mc@248 260 for (int i = numFiles-1; i >= 0; i--) {
mas01mc@248 261 unsigned int size = queues[i].size();
mas01mc@248 262 if (size > 0) {
mas01mc@248 263 NNresult r;
mas01mc@248 264 double dist = 0;
mas01mc@248 265 NNresult oldr = queues[i].top();
mas01mc@248 266 for (unsigned int j = 0; j < size; j++) {
mas01mc@248 267 r = queues[i].top();
mas01mc@248 268 dist += r.dist;
mas01mc@248 269 point_queues[i].push(r);
mas01mc@249 270 queues[i].pop();
mas01mc@248 271 if (r.dist == oldr.dist) {
mas01mc@248 272 r.qpos = oldr.qpos;
mas01mc@248 273 r.spos = oldr.spos;
mas01mc@248 274 } else {
mas01mc@248 275 oldr = r;
mas01mc@248 276 }
mas01mc@248 277 }
mas01mc@248 278 dist /= size;
mas01mc@248 279 r.dist = dist; // trackID, qpos and spos are magically right already.
mas01mc@248 280 result.push(r);
mas01mc@248 281 if (result.size() > trackNN) {
mas01mc@248 282 result.pop();
mas01mc@248 283 }
mas01mc@248 284 }
mas01mc@248 285 }
mas01mc@248 286
mas01mc@248 287 NNresult r;
mas01mc@248 288 std::vector<NNresult> v;
mas01mc@248 289 unsigned int size = result.size();
mas01mc@248 290 for(unsigned int k = 0; k < size; k++) {
mas01mc@248 291 r = result.top();
mas01mc@248 292 v.push_back(r);
mas01mc@248 293 result.pop();
mas01mc@248 294 }
mas01mc@248 295 std::vector<NNresult>::reverse_iterator rit;
mas01mc@264 296 std::priority_queue< NNresult, std::vector< NNresult>, std::greater<NNresult> > point_queue;
mas01mc@324 297 NNresult rk;
mas01mc@264 298
mas01mc@248 299 if(adbQueryResponse==0) {
mas01mc@248 300 for(rit = v.rbegin(); rit < v.rend(); rit++) {
mas01mc@248 301 r = *rit;
mas01mc@292 302 if(fileTable)
mas01mc@292 303 std::cout << fileTable + r.trackID*O2_FILETABLE_ENTRY_SIZE << " ";
mas01mc@292 304 else
mas01mc@292 305 std::cout << r.trackID << " ";
mas01mc@292 306 std::cout << r.dist << std::endl;
mas01mc@264 307 unsigned int qsize = point_queues[r.trackID].size();
mas01mc@264 308 // Reverse the order of the points stored in point_queues
mas01mc@264 309 for(unsigned int k=0; k < qsize; k++){
mas01mc@264 310 point_queue.push( point_queues[r.trackID].top() );
mas01mc@264 311 point_queues[r.trackID].pop();
mas01mc@264 312 }
mas01mc@264 313
mas01mc@264 314 for(unsigned int k = 0; k < qsize; k++) {
mas01mc@324 315 rk = point_queue.top();
mas01mc@248 316 std::cout << rk.dist << " " << rk.qpos << " " << rk.spos << std::endl;
mas01mc@264 317 point_queue.pop();
mas01mc@248 318 }
mas01mc@248 319 }
mas01mc@248 320 } else {
mas01cr@415 321 adb__queryResponse *response = (adb__queryResponse *) adbQueryResponse;
mas01cr@415 322 response->result.__sizeRlist=size*pointNN;
mas01cr@415 323 response->result.__sizeDist=size*pointNN;
mas01cr@415 324 response->result.__sizeQpos=size*pointNN;
mas01cr@415 325 response->result.__sizeSpos=size*pointNN;
mas01cr@415 326 response->result.Rlist= new char*[size*pointNN];
mas01cr@415 327 response->result.Dist = new double[size*pointNN];
mas01cr@415 328 response->result.Qpos = new unsigned int[size*pointNN];
mas01cr@415 329 response->result.Spos = new unsigned int[size*pointNN];
mas01mc@248 330 unsigned int k = 0;
mas01mc@324 331 // Loop over returned tracks
mas01mc@324 332 for(rit = v.rbegin(); rit < v.rend(); rit++) {
mas01mc@248 333 r = *rit;
mas01mc@324 334 // Reverse the order of the points stored in point_queues
mas01mc@324 335 unsigned int qsize=point_queues[r.trackID].size();
mas01mc@324 336 while(qsize--){
mas01mc@324 337 point_queue.push(point_queues[r.trackID].top());
mas01mc@324 338 point_queues[r.trackID].pop();
mas01mc@324 339 }
mas01mc@324 340 qsize=point_queue.size();
mas01mc@324 341 unsigned int numReports = pointNN;
mas01mc@324 342 while(numReports--){ // pop the rest of the points
mas01mc@324 343 if(qsize)
mas01mc@324 344 rk = point_queue.top(); // Take one point from the top of the queue
mas01mc@324 345 else{
mas01mc@324 346 rk.dist = 1000000000.0;
mas01mc@324 347 rk.qpos = 0xFFFFFFFF;
mas01mc@324 348 rk.spos = 0xFFFFFFFF;
mas01mc@324 349 }
mas01mc@324 350
mas01cr@415 351 response->result.Rlist[k] = new char[O2_MAXFILESTR];
mas01cr@415 352 response->result.Dist[k] = rk.dist;
mas01cr@415 353 response->result.Qpos[k] = rk.qpos;
mas01cr@415 354 response->result.Spos[k] = rk.spos;
mas01mc@324 355 if(qsize){
mas01mc@324 356 if(fileTable)
mas01cr@415 357 snprintf(response->result.Rlist[k], O2_MAXFILESTR, "%s", fileTable+r.trackID*O2_FILETABLE_ENTRY_SIZE);
mas01mc@324 358 else
mas01cr@415 359 snprintf(response->result.Rlist[k], O2_MAXFILESTR, "%d", r.trackID);
mas01mc@324 360 point_queue.pop();
mas01mc@324 361 qsize--;
mas01mc@324 362 }
mas01mc@324 363 else
mas01cr@415 364 snprintf(response->result.Rlist[k], O2_MAXFILESTR, "NULL");
mas01mc@324 365 k++;
mas01mc@324 366 }
mas01mc@248 367 }
mas01mc@248 368 }
mas01mc@248 369 // clean up
mas01mc@248 370 delete[] point_queues;
mas01mc@248 371 }
mas01mc@250 372
mas01mc@292 373 /********************** Radius Reporters **************************/
mas01mc@250 374
mas01mc@292 375 class triple{
mas01mc@292 376 public:
mas01mc@292 377 unsigned int a;
mas01mc@292 378 unsigned int b;
mas01mc@292 379 unsigned int c;
mas01mc@292 380
mas01mc@292 381 triple(void);
mas01mc@292 382 triple(unsigned int, unsigned int, unsigned int);
mas01mc@292 383 unsigned int first();
mas01mc@292 384 unsigned int second();
mas01mc@292 385 unsigned int third();
mas01mc@292 386 };
mas01mc@292 387
mas01mc@292 388 triple& make_triple(unsigned int, unsigned int, unsigned int);
mas01mc@292 389
mas01mc@292 390 triple::triple(unsigned int a, unsigned int b, unsigned int c):a(a),b(b),c(c){}
mas01mc@292 391
mas01mc@292 392 unsigned int triple::first(){return a;}
mas01mc@292 393 unsigned int triple::second(){return b;}
mas01mc@292 394 unsigned int triple::third(){return c;}
mas01mc@292 395
mas01mc@292 396 triple::triple():a(0),b(0),c(0){}
mas01mc@292 397
mas01mc@292 398 bool operator< (const triple &t1, const triple &t2) {
mas01mc@292 399 return ((t1.a < t2.a) ||
mas01mc@292 400 ((t1.a == t2.a) && ((t1.b < t2.b) ||
mas01mc@292 401 ((t1.b == t2.b) && (t1.c < t2.c)))));
mas01mc@292 402 }
mas01mc@292 403 bool operator== (const triple &t1, const triple &t2) {
mas01mc@292 404 return ((t1.a == t2.a) && (t1.b == t2.b) && (t1.c == t2.c));
mas01mc@292 405 }
mas01mc@292 406
mas01mc@292 407 triple& make_triple(unsigned int a, unsigned int b, unsigned int c){
mas01mc@292 408 triple* t = new triple(a,b,c);
mas01mc@292 409 return *t;
mas01mc@292 410 }
mas01mc@292 411
mas01mc@292 412 // track Sequence Query Radius Reporter
mas01mc@292 413 // only return tracks and retrieved point counts
mas01mc@292 414 class trackSequenceQueryRadReporter : public Reporter {
mas01mc@250 415 public:
mas01mc@292 416 trackSequenceQueryRadReporter(unsigned int trackNN, unsigned int numFiles);
mas01mc@292 417 ~trackSequenceQueryRadReporter();
mas01mc@250 418 void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist);
mas01mc@292 419 void report(char *fileTable, void *adbQueryResponse);
mas01mc@250 420 protected:
mas01mc@250 421 unsigned int trackNN;
mas01mc@250 422 unsigned int numFiles;
mas01mc@292 423 std::set<std::pair<unsigned int, unsigned int> > *set;
mas01mc@292 424 std::set< triple > *set_triple;
mas01mc@250 425 unsigned int *count;
mas01mc@250 426 };
mas01mc@250 427
mas01mc@292 428 trackSequenceQueryRadReporter::trackSequenceQueryRadReporter(unsigned int trackNN, unsigned int numFiles):
mas01mc@292 429 trackNN(trackNN), numFiles(numFiles) {
mas01mc@292 430 set = new std::set<std::pair<unsigned int, unsigned int> >;
mas01mc@292 431 set_triple = new std::set<triple, std::less<triple> >;
mas01mc@250 432 count = new unsigned int[numFiles];
mas01mc@250 433 for (unsigned i = 0; i < numFiles; i++) {
mas01mc@250 434 count[i] = 0;
mas01mc@250 435 }
mas01mc@250 436 }
mas01mc@250 437
mas01mc@292 438 trackSequenceQueryRadReporter::~trackSequenceQueryRadReporter() {
mas01mc@250 439 delete set;
mas01mc@292 440 delete set_triple;
mas01mc@250 441 delete [] count;
mas01mc@250 442 }
mas01mc@250 443
mas01mc@292 444 void trackSequenceQueryRadReporter::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) {
mas01mc@292 445 std::set<std::pair<unsigned int, unsigned int> >::iterator it;
mas01mc@292 446 std::pair<unsigned int, unsigned int> pair = std::make_pair(trackID, qpos); // only count this once
mas01mc@292 447 std::set<triple>::iterator it2;
mas01mc@292 448 triple triple;
mas01mc@250 449
mas01mc@292 450 triple = make_triple(trackID, qpos, spos); // only count this once
mas01mc@292 451
mas01mc@292 452 // Record unique <trackID,qpos,spos> triples (record one collision from all hash tables)
mas01mc@292 453 it2 = set_triple->find(triple);
mas01mc@250 454
mas01mc@292 455 if(it2 == set_triple->end()){
mas01mc@292 456 set_triple->insert(triple);
mas01mc@292 457
mas01mc@292 458 it = set->find(pair);
mas01mc@292 459 if (it == set->end()) {
mas01mc@292 460 set->insert(pair);
mas01mc@292 461 count[trackID]++; // only count if <tackID,qpos> pair is unique
mas01mc@292 462 }
mas01mc@250 463 }
mas01mc@250 464 }
mas01mc@250 465
mas01mc@292 466 void trackSequenceQueryRadReporter::report(char *fileTable, void *adbQueryResponse) {
mas01mc@275 467 std::priority_queue < Radresult, std::vector<Radresult>, std::greater<Radresult> > result;
mas01mc@250 468 // KLUDGE: doing this backwards in an attempt to get the same
mas01mc@250 469 // tiebreak behaviour as before.
mas01mc@250 470 for (int i = numFiles-1; i >= 0; i--) {
mas01mc@250 471 Radresult r;
mas01mc@250 472 r.trackID = i;
mas01mc@250 473 r.count = count[i];
mas01mc@250 474 if(r.count > 0) {
mas01mc@250 475 result.push(r);
mas01mc@250 476 if (result.size() > trackNN) {
mas01mc@250 477 result.pop();
mas01mc@250 478 }
mas01mc@250 479 }
mas01mc@250 480 }
mas01mc@250 481
mas01mc@250 482 Radresult r;
mas01mc@250 483 std::vector<Radresult> v;
mas01mc@250 484 unsigned int size = result.size();
mas01mc@250 485 for(unsigned int k = 0; k < size; k++) {
mas01mc@250 486 r = result.top();
mas01mc@250 487 v.push_back(r);
mas01mc@250 488 result.pop();
mas01mc@250 489 }
mas01mc@292 490 std::vector<Radresult>::reverse_iterator rit;
mas01mc@292 491
mas01mc@292 492 if(adbQueryResponse==0) {
mas01mc@292 493 for(rit = v.rbegin(); rit < v.rend(); rit++) {
mas01mc@292 494 r = *rit;
mas01mc@292 495 if(fileTable)
mas01mc@292 496 std::cout << fileTable + r.trackID*O2_FILETABLE_ENTRY_SIZE << " ";
mas01mc@292 497 else
mas01mc@292 498 std::cout << r.trackID << " ";
mas01mc@292 499 std::cout << r.count << std::endl;
mas01mc@292 500 }
mas01cr@415 501 } else {
mas01cr@415 502 adb__queryResponse *response = (adb__queryResponse *) adbQueryResponse;
mas01cr@415 503 response->result.__sizeRlist=size;
mas01cr@415 504 response->result.__sizeDist=size;
mas01cr@415 505 response->result.__sizeQpos=size;
mas01cr@415 506 response->result.__sizeSpos=size;
mas01cr@415 507 response->result.Rlist= new char*[size];
mas01cr@415 508 response->result.Dist = new double[size];
mas01cr@415 509 response->result.Qpos = new unsigned int[size];
mas01cr@415 510 response->result.Spos = new unsigned int[size];
mas01mc@307 511 unsigned int k = 0;
mas01mc@307 512 for(rit = v.rbegin(); rit < v.rend(); rit++, k++) {
mas01mc@307 513 r = *rit;
mas01cr@415 514 response->result.Rlist[k] = new char[O2_MAXFILESTR];
mas01cr@415 515 response->result.Dist[k] = 0;
mas01cr@415 516 response->result.Qpos[k] = 0;
mas01cr@415 517 response->result.Spos[k] = r.count;
mas01mc@307 518 if(fileTable)
mas01cr@415 519 snprintf(response->result.Rlist[k], O2_MAXFILESTR, "%s", fileTable+r.trackID*O2_FILETABLE_ENTRY_SIZE);
mas01mc@307 520 else
mas01cr@415 521 snprintf(response->result.Rlist[k], O2_MAXFILESTR, "%d", r.trackID);
mas01mc@307 522 }
mas01mc@292 523 }
mas01mc@292 524 }
mas01mc@292 525
mas01mc@292 526 // track Sequence Query Radius NN Reporter
mas01mc@292 527 // retrieve tracks ordered by query-point matches (one per track per query point)
mas01mc@292 528 //
mas01mc@292 529 // as well as sorted n-NN points per retrieved track
mas01mc@292 530 class trackSequenceQueryRadNNReporter : public Reporter {
mas01mc@292 531 public:
mas01mc@292 532 trackSequenceQueryRadNNReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles);
mas01mc@292 533 ~trackSequenceQueryRadNNReporter();
mas01mc@292 534 void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist);
mas01mc@292 535 void report(char *fileTable, void *adbQueryResponse);
mas01mc@292 536 protected:
mas01mc@292 537 unsigned int pointNN;
mas01mc@292 538 unsigned int trackNN;
mas01mc@292 539 unsigned int numFiles;
mas01mc@292 540 std::set<std::pair<unsigned int, unsigned int> > *set;
mas01mc@292 541 std::set< triple > *set_triple;
mas01mc@292 542 std::priority_queue< NNresult, std::vector< NNresult>, std::less<NNresult> > *point_queues;
mas01mc@292 543 unsigned int *count;
mas01mc@292 544 };
mas01mc@292 545
mas01mc@292 546 trackSequenceQueryRadNNReporter::trackSequenceQueryRadNNReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles):
mas01mc@292 547 pointNN(pointNN), trackNN(trackNN), numFiles(numFiles) {
mas01mc@292 548 // Where to count Radius track matches (one-to-one)
mas01mc@292 549 set = new std::set<std::pair<unsigned int, unsigned int> >;
mas01mc@292 550 set_triple = new std::set<triple, std::less<triple> >;
mas01mc@292 551 // Where to insert individual point matches (one-to-many)
mas01mc@292 552 point_queues = new std::priority_queue< NNresult, std::vector< NNresult>, std::less<NNresult> >[numFiles];
mas01mc@292 553
mas01mc@292 554 count = new unsigned int[numFiles];
mas01mc@292 555 for (unsigned i = 0; i < numFiles; i++) {
mas01mc@292 556 count[i] = 0;
mas01mc@292 557 }
mas01mc@292 558 }
mas01mc@292 559
mas01mc@292 560 trackSequenceQueryRadNNReporter::~trackSequenceQueryRadNNReporter() {
mas01mc@292 561 delete set;
mas01mc@292 562 delete set_triple;
mas01mc@292 563 delete [] count;
mas01mc@292 564 }
mas01mc@292 565
mas01mc@292 566 void trackSequenceQueryRadNNReporter::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) {
mas01mc@292 567 std::set<std::pair<unsigned int, unsigned int> >::iterator it;
mas01mc@292 568 std::set<triple>::iterator it2;
mas01mc@292 569 std::pair<unsigned int, unsigned int> pair;
mas01mc@292 570 triple triple;
mas01mc@292 571 NNresult r;
mas01mc@292 572
mas01mc@292 573 pair = std::make_pair(trackID, qpos); // only count this once
mas01mc@292 574 triple = make_triple(trackID, qpos, spos); // only count this once
mas01mc@292 575 // Record unique <trackID,qpos,spos> triples (record one collision from all hash tables)
mas01mc@292 576 it2 = set_triple->find(triple);
mas01mc@292 577 if(it2 == set_triple->end()){
mas01mc@292 578 set_triple->insert(triple);
mas01mc@292 579 // Record all matching points (within radius)
mas01mc@292 580 // Record counts of <trackID,qpos> pairs
mas01mc@292 581 it = set->find(pair);
mas01mc@292 582 if (it == set->end()) {
mas01mc@292 583 set->insert(pair);
mas01mc@292 584 count[trackID]++;
mas01mc@307 585 }
mas01mc@307 586 if (!isnan(dist)) {
mas01mc@307 587 r.trackID = trackID;
mas01mc@307 588 r.qpos = qpos;
mas01mc@307 589 r.dist = dist;
mas01mc@307 590 r.spos = spos;
mas01mc@307 591 point_queues[trackID].push(r);
mas01mc@307 592 if(point_queues[trackID].size() > pointNN)
mas01mc@307 593 point_queues[trackID].pop();
mas01mc@292 594 }
mas01mc@292 595 }
mas01mc@292 596 }
mas01mc@292 597
mas01mc@292 598 void trackSequenceQueryRadNNReporter::report(char *fileTable, void *adbQueryResponse) {
mas01mc@292 599 std::priority_queue < Radresult, std::vector<Radresult>, std::greater<Radresult> > result;
mas01mc@292 600 // KLUDGE: doing this backwards in an attempt to get the same
mas01mc@292 601 // tiebreak behaviour as before.
mas01mc@292 602 Radresult r;
mas01mc@292 603 NNresult rk;
mas01mc@307 604 std::vector<Radresult> v;
mas01mc@307 605 unsigned int size;
mas01mc@292 606
mas01mc@307 607 if(pointNN>1){
mas01mc@307 608 for (int i = numFiles-1; i >= 0; i--) {
mas01mc@307 609 r.trackID = i;
mas01mc@307 610 r.count = count[i];
mas01mc@307 611 if(r.count > 0) {
mas01mc@307 612 cout.flush();
mas01mc@307 613 result.push(r);
mas01mc@307 614 if (result.size() > trackNN) {
mas01mc@307 615 result.pop();
mas01mc@307 616 }
mas01mc@292 617 }
mas01mc@292 618 }
mas01mc@307 619
mas01mc@307 620 size = result.size();
mas01mc@307 621 for(unsigned int k = 0; k < size; k++) {
mas01mc@307 622 r = result.top();
mas01mc@307 623 v.push_back(r);
mas01mc@307 624 result.pop();
mas01mc@307 625 }
mas01mc@292 626 }
mas01mc@307 627 else{
mas01mc@307 628 // Instantiate a 1-NN trackAveragingNN reporter
mas01mc@307 629 trackSequenceQueryNNReporter<std::less <NNresult> >* rep = new trackSequenceQueryNNReporter<std::less <NNresult> >(1, trackNN, numFiles);
mas01mc@307 630 // Add all the points we've got to the reporter
mas01mc@307 631 for(unsigned int i=0; i<numFiles; i++){
mas01mc@307 632 int qsize = point_queues[i].size();
mas01mc@307 633 while(qsize--){
mas01mc@307 634 rk = point_queues[i].top();
mas01mc@307 635 rep->add_point(i, rk.qpos, rk.spos, rk.dist);
mas01mc@307 636 point_queues[i].pop();
mas01mc@307 637 }
mas01mc@307 638 }
mas01mc@307 639 // Report
mas01mc@307 640 rep->report(fileTable, adbQueryResponse);
mas01mc@307 641 // Exit
mas01mc@307 642 delete[] point_queues;
mas01mc@307 643 return;
mas01mc@292 644 }
mas01mc@264 645
mas01mc@264 646
mas01mc@264 647 // Traverse tracks in descending order of count cardinality
mas01mc@250 648 std::vector<Radresult>::reverse_iterator rit;
mas01mc@264 649 std::priority_queue< NNresult, std::vector< NNresult>, std::greater<NNresult> > point_queue;
mas01mc@264 650
mas01mc@250 651 if(adbQueryResponse==0) {
mas01mc@250 652 for(rit = v.rbegin(); rit < v.rend(); rit++) {
mas01mc@250 653 r = *rit;
mas01mc@292 654 if(fileTable)
mas01mc@292 655 std::cout << fileTable + r.trackID*O2_FILETABLE_ENTRY_SIZE << " ";
mas01mc@292 656 else
mas01mc@292 657 std::cout << r.trackID << " ";
mas01mc@292 658 std::cout << r.count << std::endl;
mas01mc@264 659
mas01mc@264 660 // Reverse the order of the points stored in point_queues
mas01mc@264 661 unsigned int qsize=point_queues[r.trackID].size();
mas01mc@264 662 for(unsigned int k=0; k < qsize; k++){
mas01mc@264 663 point_queue.push(point_queues[r.trackID].top());
mas01mc@264 664 point_queues[r.trackID].pop();
mas01mc@264 665 }
mas01mc@264 666 for(unsigned int k=0; k < qsize; k++){
mas01mc@292 667 rk = point_queue.top();
mas01mc@250 668 std::cout << rk.dist << " " << rk.qpos << " " << rk.spos << std::endl;
mas01mc@264 669 point_queue.pop();
mas01mc@250 670 }
mas01mc@250 671 }
mas01cr@415 672 } else {
mas01cr@415 673 adb__queryResponse *response = (adb__queryResponse *) adbQueryResponse;
mas01cr@415 674 response->result.__sizeRlist=size*pointNN;
mas01cr@415 675 response->result.__sizeDist=size*pointNN;
mas01cr@415 676 response->result.__sizeQpos=size*pointNN;
mas01cr@415 677 response->result.__sizeSpos=size*pointNN;
mas01cr@415 678 response->result.Rlist= new char*[size*pointNN];
mas01cr@415 679 response->result.Dist = new double[size*pointNN];
mas01cr@415 680 response->result.Qpos = new unsigned int[size*pointNN];
mas01cr@415 681 response->result.Spos = new unsigned int[size*pointNN];
mas01mc@307 682 unsigned int k = 0;
mas01mc@307 683 // Loop over returned tracks
mas01mc@324 684 for(rit = v.rbegin(); rit < v.rend(); rit++) {
mas01mc@307 685 r = *rit;
mas01mc@307 686 // Reverse the order of the points stored in point_queues
mas01mc@307 687 unsigned int qsize=point_queues[r.trackID].size();
mas01mc@307 688 while(qsize--){
mas01mc@307 689 point_queue.push(point_queues[r.trackID].top());
mas01mc@307 690 point_queues[r.trackID].pop();
mas01mc@307 691 }
mas01mc@307 692 qsize=point_queue.size();
mas01mc@324 693 unsigned int numReports = pointNN;
mas01mc@324 694 while(numReports--){ // pop the rest of the points
mas01mc@324 695 if(qsize)
mas01mc@324 696 rk = point_queue.top(); // Take one point from the top of the queue
mas01mc@324 697 else{
mas01mc@324 698 rk.dist = 1000000000.0;
mas01mc@324 699 rk.qpos = 0xFFFFFFFF;
mas01mc@324 700 rk.spos = 0xFFFFFFFF;
mas01mc@324 701 }
mas01mc@324 702
mas01cr@415 703 response->result.Rlist[k] = new char[O2_MAXFILESTR];
mas01cr@415 704 response->result.Dist[k] = rk.dist;
mas01cr@415 705 response->result.Qpos[k] = rk.qpos;
mas01cr@415 706 response->result.Spos[k] = rk.spos;
mas01mc@324 707 if(qsize){
mas01mc@324 708 if(fileTable)
mas01cr@415 709 snprintf(response->result.Rlist[k], O2_MAXFILESTR, "%s", fileTable+r.trackID*O2_FILETABLE_ENTRY_SIZE);
mas01mc@324 710 else
mas01cr@415 711 snprintf(response->result.Rlist[k], O2_MAXFILESTR, "%d", r.trackID);
mas01mc@324 712 point_queue.pop();
mas01mc@324 713 qsize--;
mas01mc@324 714 }
mas01mc@324 715 else
mas01cr@415 716 snprintf(response->result.Rlist[k], O2_MAXFILESTR, "NULL");
mas01mc@324 717 k++;
mas01mc@324 718 }
mas01mc@307 719 }
mas01mc@307 720 }
mas01mc@264 721 delete[] point_queues;
mas01mc@250 722 }
mas01mc@263 723
mas01mc@264 724 /********** ONE-TO-ONE REPORTERS *****************/
mas01mc@263 725
mas01mc@264 726 // track Sequence Query Radius NN Reporter One-to-One
mas01mc@264 727 // for each query point find the single best matching target point in all database
mas01mc@264 728 // report qpos, spos and trackID
mas01mc@263 729 class trackSequenceQueryRadNNReporterOneToOne : public Reporter {
mas01mc@263 730 public:
mas01mc@263 731 trackSequenceQueryRadNNReporterOneToOne(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles);
mas01mc@263 732 ~trackSequenceQueryRadNNReporterOneToOne();
mas01mc@263 733 void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist);
mas01mc@292 734 void report(char *fileTable, void *adbQueryResponse);
mas01mc@263 735 protected:
mas01mc@263 736 unsigned int pointNN;
mas01mc@263 737 unsigned int trackNN;
mas01mc@263 738 unsigned int numFiles;
mas01mc@263 739 std::set< NNresult > *set;
mas01mc@263 740 std::vector< NNresult> *point_queue;
mas01mc@263 741 unsigned int *count;
mas01mc@263 742
mas01mc@263 743 };
mas01mc@263 744
mas01mc@263 745 trackSequenceQueryRadNNReporterOneToOne::trackSequenceQueryRadNNReporterOneToOne(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles):
mas01mc@263 746 pointNN(pointNN), trackNN(trackNN), numFiles(numFiles) {
mas01mc@263 747 // Where to count Radius track matches (one-to-one)
mas01mc@263 748 set = new std::set< NNresult >;
mas01mc@263 749 // Where to insert individual point matches (one-to-many)
mas01mc@263 750 point_queue = new std::vector< NNresult >;
mas01mc@263 751
mas01mc@263 752 count = new unsigned int[numFiles];
mas01mc@263 753 for (unsigned i = 0; i < numFiles; i++) {
mas01mc@263 754 count[i] = 0;
mas01mc@263 755 }
mas01mc@263 756 }
mas01mc@263 757
mas01mc@263 758 trackSequenceQueryRadNNReporterOneToOne::~trackSequenceQueryRadNNReporterOneToOne() {
mas01mc@263 759 delete set;
mas01mc@263 760 delete [] count;
mas01mc@263 761 }
mas01mc@263 762
mas01mc@263 763 void trackSequenceQueryRadNNReporterOneToOne::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) {
mas01mc@263 764 std::set< NNresult >::iterator it;
mas01mc@263 765 NNresult r;
mas01mc@264 766
mas01mc@263 767 r.qpos = qpos;
mas01mc@263 768 r.trackID = trackID;
mas01mc@263 769 r.spos = spos;
mas01mc@263 770 r.dist = dist;
mas01mc@263 771
mas01mc@263 772 if(point_queue->size() < r.qpos + 1){
mas01mc@263 773 point_queue->resize( r.qpos + 1 );
mas01mc@263 774 (*point_queue)[r.qpos].dist = 1e6;
mas01mc@263 775 }
mas01mc@263 776
mas01mc@263 777 if (r.dist < (*point_queue)[r.qpos].dist)
mas01mc@263 778 (*point_queue)[r.qpos] = r;
mas01mc@263 779
mas01mc@263 780 }
mas01mc@263 781
mas01mc@292 782 void trackSequenceQueryRadNNReporterOneToOne::report(char *fileTable, void *adbQueryResponse) {
mas01mc@263 783 if(adbQueryResponse==0) {
mas01mc@263 784 std::vector< NNresult >::iterator vit;
mas01mc@263 785 NNresult rk;
mas01mc@263 786 for( vit = point_queue->begin() ; vit < point_queue->end() ; vit++ ){
mas01mc@263 787 rk = *vit;
mas01mc@263 788 std::cout << rk.dist << " "
mas01mc@263 789 << rk.qpos << " "
mas01mc@292 790 << rk.spos << " ";
mas01mc@292 791 if(fileTable)
mas01mc@292 792 std::cout << fileTable + rk.trackID*O2_FILETABLE_ENTRY_SIZE << " ";
mas01mc@292 793 else
mas01mc@292 794 std::cout << rk.trackID << " ";
mas01mc@292 795 std::cout << std::endl;
mas01mc@263 796 }
mas01mc@263 797 } else {
mas01mc@263 798 // FIXME
mas01mc@263 799 }
mas01mc@263 800 }
mas01mc@292 801
mas01mc@292 802 #endif