mas01cr@239: #include mas01cr@239: #include mas01cr@239: #include mas01cr@239: #include mas01cr@239: mas01cr@239: typedef struct nnresult { mas01cr@239: unsigned int trackID; mas01cr@239: double dist; mas01cr@239: unsigned int qpos; mas01cr@239: unsigned int spos; mas01cr@239: } NNresult; mas01cr@239: mas01cr@239: typedef struct radresult { mas01cr@239: unsigned int trackID; mas01cr@239: unsigned int count; mas01cr@239: } Radresult; mas01cr@239: mas01cr@239: bool operator< (const NNresult &a, const NNresult &b) { mas01cr@239: return a.dist < b.dist; mas01cr@239: } mas01cr@239: mas01cr@239: bool operator> (const NNresult &a, const NNresult &b) { mas01cr@239: return a.dist > b.dist; mas01cr@239: } mas01cr@239: mas01cr@239: bool operator< (const Radresult &a, const Radresult &b) { mas01cr@239: return a.count < b.count; mas01cr@239: } mas01cr@239: mas01cr@239: class Reporter { mas01cr@239: public: mas01cr@239: virtual ~Reporter() {}; mas01cr@239: virtual void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) = 0; mas01cr@239: // FIXME: this interface is a bit wacky: a relic of previous, more mas01cr@239: // confused times. Really it might make sense to have separate mas01cr@239: // reporter classes for WS and for stdout, rather than passing this mas01cr@239: // adbQueryResponse thing everywhere; the fileTable argument is mas01cr@239: // there solely for convertion trackIDs into names. -- CSR, mas01cr@239: // 2007-12-10. mas01cr@239: virtual void report(char *fileTable, adb__queryResponse *adbQueryResponse) = 0; mas01cr@239: }; mas01cr@239: mas01cr@239: template class pointQueryReporter : public Reporter { mas01cr@239: public: mas01cr@239: pointQueryReporter(unsigned int pointNN); mas01cr@239: ~pointQueryReporter(); mas01cr@239: void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist); mas01cr@239: void report(char *fileTable, adb__queryResponse *adbQueryResponse); mas01cr@239: private: mas01cr@239: unsigned int pointNN; mas01cr@239: std::priority_queue< NNresult, std::vector< NNresult >, T> *queue; mas01cr@239: }; mas01cr@239: mas01cr@239: template pointQueryReporter::pointQueryReporter(unsigned int pointNN) mas01cr@239: : pointNN(pointNN) { mas01cr@239: queue = new std::priority_queue< NNresult, std::vector< NNresult >, T>; mas01cr@239: } mas01cr@239: mas01cr@239: template pointQueryReporter::~pointQueryReporter() { mas01cr@239: delete queue; mas01cr@239: } mas01cr@239: mas01cr@239: template void pointQueryReporter::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) { mas01cr@242: if (!isnan(dist)) { mas01cr@242: NNresult r; mas01cr@242: r.trackID = trackID; mas01cr@242: r.qpos = qpos; mas01cr@242: r.spos = spos; mas01cr@242: r.dist = dist; mas01cr@242: queue->push(r); mas01cr@242: if(queue->size() > pointNN) { mas01cr@242: queue->pop(); mas01cr@242: } mas01cr@239: } mas01cr@239: } mas01cr@239: mas01cr@239: template void pointQueryReporter::report(char *fileTable, adb__queryResponse *adbQueryResponse) { mas01cr@239: NNresult r; mas01cr@239: std::vector v; mas01cr@239: unsigned int size = queue->size(); mas01cr@239: for(unsigned int k = 0; k < size; k++) { mas01cr@239: r = queue->top(); mas01cr@239: v.push_back(r); mas01cr@239: queue->pop(); mas01cr@239: } mas01cr@239: std::vector::reverse_iterator rit; mas01cr@239: mas01cr@239: if(adbQueryResponse==0) { mas01cr@239: for(rit = v.rbegin(); rit < v.rend(); rit++) { mas01cr@239: r = *rit; mas01cr@239: std::cout << fileTable + r.trackID*O2_FILETABLESIZE << " "; mas01cr@239: std::cout << r.dist << " " << r.qpos << " " << r.spos << std::endl; mas01cr@239: } mas01cr@239: } else { mas01cr@239: adbQueryResponse->result.__sizeRlist=size; mas01cr@239: adbQueryResponse->result.__sizeDist=size; mas01cr@239: adbQueryResponse->result.__sizeQpos=size; mas01cr@239: adbQueryResponse->result.__sizeSpos=size; mas01cr@239: adbQueryResponse->result.Rlist= new char*[size]; mas01cr@239: adbQueryResponse->result.Dist = new double[size]; mas01cr@239: adbQueryResponse->result.Qpos = new unsigned int[size]; mas01cr@239: adbQueryResponse->result.Spos = new unsigned int[size]; mas01cr@239: unsigned int k = 0; mas01cr@239: for(rit = v.rbegin(); rit < v.rend(); rit++, k++) { mas01cr@239: r = *rit; mas01cr@239: adbQueryResponse->result.Rlist[k] = new char[O2_MAXFILESTR]; mas01cr@239: adbQueryResponse->result.Dist[k] = r.dist; mas01cr@239: adbQueryResponse->result.Qpos[k] = r.qpos; mas01cr@239: adbQueryResponse->result.Spos[k] = r.spos; mas01cr@239: snprintf(adbQueryResponse->result.Rlist[k], O2_MAXFILESTR, "%s", fileTable+r.trackID*O2_FILETABLESIZE); mas01cr@239: } mas01cr@239: } mas01cr@239: } mas01cr@239: mas01cr@239: template class trackAveragingReporter : public Reporter { mas01cr@239: public: mas01cr@239: trackAveragingReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles); mas01cr@239: ~trackAveragingReporter(); mas01cr@239: void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist); mas01cr@239: void report(char *fileTable, adb__queryResponse *adbQueryResponse); mas01mc@249: protected: mas01cr@239: unsigned int pointNN; mas01cr@239: unsigned int trackNN; mas01cr@239: unsigned int numFiles; mas01cr@239: std::priority_queue< NNresult, std::vector< NNresult>, T > *queues; mas01cr@239: }; mas01cr@239: mas01cr@239: template trackAveragingReporter::trackAveragingReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles) mas01cr@239: : pointNN(pointNN), trackNN(trackNN), numFiles(numFiles) { mas01cr@239: queues = new std::priority_queue< NNresult, std::vector< NNresult>, T >[numFiles]; mas01cr@239: } mas01cr@239: mas01cr@239: template trackAveragingReporter::~trackAveragingReporter() { mas01cr@239: delete [] queues; mas01cr@239: } mas01cr@239: mas01cr@239: template void trackAveragingReporter::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) { mas01cr@242: if (!isnan(dist)) { mas01cr@242: NNresult r; mas01cr@242: r.trackID = trackID; mas01cr@242: r.qpos = qpos; mas01cr@242: r.spos = spos; mas01cr@242: r.dist = dist; mas01cr@242: queues[trackID].push(r); mas01cr@242: if(queues[trackID].size() > pointNN) { mas01cr@242: queues[trackID].pop(); mas01cr@242: } mas01cr@239: } mas01cr@239: } mas01cr@239: mas01cr@239: template void trackAveragingReporter::report(char *fileTable, adb__queryResponse *adbQueryResponse) { mas01cr@239: std::priority_queue < NNresult, std::vector< NNresult>, T> result; mas01cr@239: for (int i = numFiles-1; i >= 0; i--) { mas01cr@239: unsigned int size = queues[i].size(); mas01cr@239: if (size > 0) { mas01cr@239: NNresult r; mas01cr@239: double dist = 0; mas01cr@239: NNresult oldr = queues[i].top(); mas01cr@239: for (unsigned int j = 0; j < size; j++) { mas01cr@239: r = queues[i].top(); mas01cr@239: dist += r.dist; mas01cr@239: queues[i].pop(); mas01cr@239: if (r.dist == oldr.dist) { mas01cr@239: r.qpos = oldr.qpos; mas01cr@239: r.spos = oldr.spos; mas01cr@239: } else { mas01cr@239: oldr = r; mas01cr@239: } mas01cr@239: } mas01cr@239: dist /= size; mas01cr@239: r.dist = dist; // trackID, qpos and spos are magically right already. mas01cr@239: result.push(r); mas01cr@239: if (result.size() > trackNN) { mas01cr@239: result.pop(); mas01cr@239: } mas01cr@239: } mas01cr@239: } mas01cr@239: mas01cr@239: NNresult r; mas01cr@239: std::vector v; mas01cr@239: unsigned int size = result.size(); mas01cr@239: for(unsigned int k = 0; k < size; k++) { mas01cr@239: r = result.top(); mas01cr@239: v.push_back(r); mas01cr@239: result.pop(); mas01cr@239: } mas01cr@239: std::vector::reverse_iterator rit; mas01cr@239: mas01cr@239: if(adbQueryResponse==0) { mas01cr@239: for(rit = v.rbegin(); rit < v.rend(); rit++) { mas01cr@239: r = *rit; mas01cr@239: std::cout << fileTable + r.trackID*O2_FILETABLESIZE << " "; mas01cr@239: std::cout << r.dist << " " << r.qpos << " " << r.spos << std::endl; mas01cr@239: } mas01cr@239: } else { mas01cr@239: adbQueryResponse->result.__sizeRlist=size; mas01cr@239: adbQueryResponse->result.__sizeDist=size; mas01cr@239: adbQueryResponse->result.__sizeQpos=size; mas01cr@239: adbQueryResponse->result.__sizeSpos=size; mas01cr@239: adbQueryResponse->result.Rlist= new char*[size]; mas01cr@239: adbQueryResponse->result.Dist = new double[size]; mas01cr@239: adbQueryResponse->result.Qpos = new unsigned int[size]; mas01cr@239: adbQueryResponse->result.Spos = new unsigned int[size]; mas01cr@239: unsigned int k = 0; mas01cr@239: for(rit = v.rbegin(); rit < v.rend(); rit++, k++) { mas01cr@239: r = *rit; mas01cr@239: adbQueryResponse->result.Rlist[k] = new char[O2_MAXFILESTR]; mas01cr@239: adbQueryResponse->result.Dist[k] = r.dist; mas01cr@239: adbQueryResponse->result.Qpos[k] = r.qpos; mas01cr@239: adbQueryResponse->result.Spos[k] = r.spos; mas01cr@239: snprintf(adbQueryResponse->result.Rlist[k], O2_MAXFILESTR, "%s", fileTable+r.trackID*O2_FILETABLESIZE); mas01cr@239: } mas01cr@239: } mas01cr@239: } mas01cr@239: mas01cr@239: class trackSequenceQueryRadReporter : public Reporter { mas01cr@239: public: mas01cr@239: trackSequenceQueryRadReporter(unsigned int trackNN, unsigned int numFiles); mas01cr@239: ~trackSequenceQueryRadReporter(); mas01cr@239: void add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist); mas01cr@239: void report(char *fileTable, adb__queryResponse *adbQueryResponse); mas01mc@249: protected: mas01cr@239: unsigned int trackNN; mas01cr@239: unsigned int numFiles; mas01cr@239: std::set > *set; mas01cr@239: unsigned int *count; mas01cr@239: }; mas01cr@239: mas01cr@239: trackSequenceQueryRadReporter::trackSequenceQueryRadReporter(unsigned int trackNN, unsigned int numFiles): mas01cr@239: trackNN(trackNN), numFiles(numFiles) { mas01cr@239: set = new std::set >; mas01cr@239: count = new unsigned int[numFiles]; mas01cr@239: for (unsigned i = 0; i < numFiles; i++) { mas01cr@239: count[i] = 0; mas01cr@239: } mas01cr@239: } mas01cr@239: mas01cr@239: trackSequenceQueryRadReporter::~trackSequenceQueryRadReporter() { mas01cr@239: delete set; mas01cr@239: delete [] count; mas01cr@239: } mas01cr@239: mas01cr@239: void trackSequenceQueryRadReporter::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) { mas01cr@239: std::set >::iterator it; mas01cr@239: std::pair pair = std::make_pair(trackID, qpos); mas01cr@239: it = set->find(pair); mas01cr@239: if (it == set->end()) { mas01cr@239: set->insert(pair); mas01cr@239: count[trackID]++; mas01cr@239: } mas01cr@239: } mas01cr@239: mas01cr@239: void trackSequenceQueryRadReporter::report(char *fileTable, adb__queryResponse *adbQueryResponse) { mas01cr@239: std::priority_queue < Radresult > result; mas01cr@239: // KLUDGE: doing this backwards in an attempt to get the same mas01cr@239: // tiebreak behaviour as before. mas01cr@239: for (int i = numFiles-1; i >= 0; i--) { mas01cr@239: Radresult r; mas01cr@239: r.trackID = i; mas01cr@239: r.count = count[i]; mas01cr@239: if(r.count > 0) { mas01cr@239: result.push(r); mas01cr@239: if (result.size() > trackNN) { mas01cr@239: result.pop(); mas01cr@239: } mas01cr@239: } mas01cr@239: } mas01cr@239: mas01cr@239: Radresult r; mas01cr@239: std::vector v; mas01cr@239: unsigned int size = result.size(); mas01cr@239: for(unsigned int k = 0; k < size; k++) { mas01cr@239: r = result.top(); mas01cr@239: v.push_back(r); mas01cr@239: result.pop(); mas01cr@239: } mas01cr@239: std::vector::reverse_iterator rit; mas01cr@239: mas01cr@239: if(adbQueryResponse==0) { mas01cr@239: for(rit = v.rbegin(); rit < v.rend(); rit++) { mas01cr@239: r = *rit; mas01cr@239: std::cout << fileTable + r.trackID*O2_FILETABLESIZE << " " << r.count << std::endl; mas01cr@239: } mas01cr@239: } else { mas01cr@239: // FIXME mas01cr@239: } mas01cr@239: } mas01mc@248: mas01mc@249: // Another type of trackAveragingReporter that reports all pointNN nearest neighbours mas01mc@249: template class trackSequenceQueryNNReporter : public trackAveragingReporter { mas01mc@249: protected: mas01mc@249: using trackAveragingReporter::numFiles; mas01mc@249: using trackAveragingReporter::queues; mas01mc@249: using trackAveragingReporter::trackNN; mas01mc@249: using trackAveragingReporter::pointNN; mas01mc@248: public: mas01mc@248: trackSequenceQueryNNReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles); mas01mc@248: void report(char *fileTable, adb__queryResponse *adbQueryResponse); mas01mc@248: }; mas01mc@248: mas01mc@249: template trackSequenceQueryNNReporter::trackSequenceQueryNNReporter(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles) mas01mc@249: :trackAveragingReporter(pointNN, trackNN, numFiles){} mas01mc@248: mas01mc@248: template void trackSequenceQueryNNReporter::report(char *fileTable, adb__queryResponse *adbQueryResponse) { mas01mc@248: std::priority_queue < NNresult, std::vector< NNresult>, T> result; mas01mc@248: std::priority_queue< NNresult, std::vector< NNresult>, std::greater > *point_queues = new std::priority_queue< NNresult, std::vector< NNresult>, std::greater >[numFiles]; mas01mc@249: mas01mc@248: for (int i = numFiles-1; i >= 0; i--) { mas01mc@248: unsigned int size = queues[i].size(); mas01mc@248: if (size > 0) { mas01mc@248: NNresult r; mas01mc@248: double dist = 0; mas01mc@248: NNresult oldr = queues[i].top(); mas01mc@248: for (unsigned int j = 0; j < size; j++) { mas01mc@248: r = queues[i].top(); mas01mc@248: dist += r.dist; mas01mc@248: point_queues[i].push(r); mas01mc@249: queues[i].pop(); mas01mc@248: if (r.dist == oldr.dist) { mas01mc@248: r.qpos = oldr.qpos; mas01mc@248: r.spos = oldr.spos; mas01mc@248: } else { mas01mc@248: oldr = r; mas01mc@248: } mas01mc@248: } mas01mc@248: dist /= size; mas01mc@248: r.dist = dist; // trackID, qpos and spos are magically right already. mas01mc@248: result.push(r); mas01mc@248: if (result.size() > trackNN) { mas01mc@248: result.pop(); mas01mc@248: } mas01mc@248: } mas01mc@248: } mas01mc@248: mas01mc@248: NNresult r; mas01mc@248: std::vector v; mas01mc@248: unsigned int size = result.size(); mas01mc@248: for(unsigned int k = 0; k < size; k++) { mas01mc@248: r = result.top(); mas01mc@248: v.push_back(r); mas01mc@248: result.pop(); mas01mc@248: } mas01mc@248: std::vector::reverse_iterator rit; mas01mc@248: mas01mc@248: if(adbQueryResponse==0) { mas01mc@248: for(rit = v.rbegin(); rit < v.rend(); rit++) { mas01mc@248: r = *rit; mas01mc@248: std::cout << fileTable + r.trackID*O2_FILETABLESIZE << std::endl; mas01mc@248: for(int k=0; k < (int)pointNN; k++){ mas01mc@248: NNresult rk = point_queues[r.trackID].top(); mas01mc@248: std::cout << rk.dist << " " << rk.qpos << " " << rk.spos << std::endl; mas01mc@248: point_queues[r.trackID].pop(); mas01mc@248: } mas01mc@248: } mas01mc@248: } else { mas01mc@248: adbQueryResponse->result.__sizeRlist=size; mas01mc@248: adbQueryResponse->result.__sizeDist=size; mas01mc@248: adbQueryResponse->result.__sizeQpos=size; mas01mc@248: adbQueryResponse->result.__sizeSpos=size; mas01mc@248: adbQueryResponse->result.Rlist= new char*[size]; mas01mc@248: adbQueryResponse->result.Dist = new double[size]; mas01mc@248: adbQueryResponse->result.Qpos = new unsigned int[size]; mas01mc@248: adbQueryResponse->result.Spos = new unsigned int[size]; mas01mc@248: unsigned int k = 0; mas01mc@248: for(rit = v.rbegin(); rit < v.rend(); rit++, k++) { mas01mc@248: r = *rit; mas01mc@248: adbQueryResponse->result.Rlist[k] = new char[O2_MAXFILESTR]; mas01mc@248: adbQueryResponse->result.Dist[k] = r.dist; mas01mc@248: adbQueryResponse->result.Qpos[k] = r.qpos; mas01mc@248: adbQueryResponse->result.Spos[k] = r.spos; mas01mc@248: snprintf(adbQueryResponse->result.Rlist[k], O2_MAXFILESTR, "%s", fileTable+r.trackID*O2_FILETABLESIZE); mas01mc@248: } mas01mc@248: } mas01mc@248: // clean up mas01mc@248: delete[] point_queues; mas01mc@248: }