# HG changeset patch # User mas01mc # Date 1213039239 0 # Node ID 210b2f661b8898f7b14d1e73dbaafcadcd0f7e72 # Parent 34ce7f7a177d0f33adee9c5cbeb2c6d7c364301b Added new query type "onetoonensequence" for matching each query sequence to the single closest match in the database. Most useful if query is not also in the database. diff -r 34ce7f7a177d -r 210b2f661b88 audioDB.cpp --- a/audioDB.cpp Mon May 19 16:25:12 2008 +0000 +++ b/audioDB.cpp Mon Jun 09 19:20:39 2008 +0000 @@ -330,6 +330,8 @@ queryType=O2_SEQUENCE_QUERY; else if(strncmp(args_info.QUERY_arg, "nsequence", MAXSTR)==0) queryType=O2_N_SEQUENCE_QUERY; + else if(strncmp(args_info.QUERY_arg, "onetoonensequence", MAXSTR)==0) + queryType=O2_ONE_TO_ONE_N_SEQUENCE_QUERY; else error("unsupported query type",args_info.QUERY_arg); @@ -341,12 +343,12 @@ } pointNN = args_info.pointnn_arg; - if(pointNN < 1 || pointNN > 1000) { - error("pointNN out of range: 1 <= pointNN <= 1000"); + if(pointNN < 1 || pointNN > O2_MAXNN) { + error("pointNN out of range: 1 <= pointNN <= 1000000"); } trackNN = args_info.resultlength_arg; - if(trackNN < 1 || trackNN > 1000) { - error("resultlength out of range: 1 <= resultlength <= 1000"); + if(trackNN < 1 || trackNN > O2_MAXNN) { + error("resultlength out of range: 1 <= resultlength <= 1000000"); } sequenceLength = args_info.sequencelength_arg; if(sequenceLength < 1 || sequenceLength > 1000) { diff -r 34ce7f7a177d -r 210b2f661b88 audioDB.h --- a/audioDB.h Mon May 19 16:25:12 2008 +0000 +++ b/audioDB.h Mon Jun 09 19:20:39 2008 +0000 @@ -68,7 +68,7 @@ #define O2_HEADERSIZE (sizeof(dbTableHeaderT)) #define O2_MEANNUMVECTORS (1000U) #define O2_MAXDIM (1000U) -#define O2_MAXNN (10000U) +#define O2_MAXNN (1000000U) // Flags #define O2_FLAG_L2NORM (0x1U) @@ -81,6 +81,7 @@ #define O2_SEQUENCE_QUERY (0x8U) #define O2_TRACK_QUERY (0x10U) #define O2_N_SEQUENCE_QUERY (0x20U) +#define O2_ONE_TO_ONE_N_SEQUENCE_QUERY (0x40U) // Error Codes diff -r 34ce7f7a177d -r 210b2f661b88 gengetopt.in --- a/gengetopt.in Mon May 19 16:25:12 2008 +0000 +++ b/gengetopt.in Mon Jun 09 19:20:39 2008 +0000 @@ -42,7 +42,7 @@ section "Database Search" sectiondesc="Thse commands control the retrieval behaviour.\n" -option "QUERY" Q "content-based search on --database using --features as a query. Optionally restrict the search to those tracks identified in a --keyList." values="point","track","sequence", "nsequence" typestr="searchtype" dependon="database" dependon="features" optional +option "QUERY" Q "content-based search on --database using --features as a query. Optionally restrict the search to those tracks identified in a --keyList." values="point","track","sequence","nsequence","onetoonensequence" typestr="searchtype" dependon="database" dependon="features" optional option "qpoint" p "ordinal position of query start point in --features file." int typestr="position" default="0" optional option "exhaustive" e "exhaustive search: iterate through all query vectors in search. Overrides --qpoint." flag off optional hidden option "pointnn" n "number of point nearest neighbours to use in retrieval." int typestr="numpoints" default="10" optional diff -r 34ce7f7a177d -r 210b2f661b88 query.cpp --- a/query.cpp Mon May 19 16:25:12 2008 +0000 +++ b/query.cpp Mon Jun 09 19:20:39 2008 +0000 @@ -44,6 +44,13 @@ r = new trackSequenceQueryRadNNReporter(pointNN,trackNN, dbH->numFiles); } break; + case O2_ONE_TO_ONE_N_SEQUENCE_QUERY : + if(radius == 0) { + error("query-type not yet supported"); + } else { + r = new trackSequenceQueryRadNNReporterOneToOne(pointNN,trackNN, dbH->numFiles); + } + break; default: error("unrecognized queryType in query()"); } diff -r 34ce7f7a177d -r 210b2f661b88 reporter.h --- a/reporter.h Mon May 19 16:25:12 2008 +0000 +++ b/reporter.h Mon Jun 09 19:20:39 2008 +0000 @@ -3,8 +3,6 @@ #include #include -#define MIN_ARG(a,b) a *set; + std::vector< NNresult> *point_queue; + unsigned int *count; + +}; + +trackSequenceQueryRadNNReporterOneToOne::trackSequenceQueryRadNNReporterOneToOne(unsigned int pointNN, unsigned int trackNN, unsigned int numFiles): +pointNN(pointNN), trackNN(trackNN), numFiles(numFiles) { + // Where to count Radius track matches (one-to-one) + set = new std::set< NNresult >; + // Where to insert individual point matches (one-to-many) + point_queue = new std::vector< NNresult >; + + count = new unsigned int[numFiles]; + for (unsigned i = 0; i < numFiles; i++) { + count[i] = 0; + } +} + +trackSequenceQueryRadNNReporterOneToOne::~trackSequenceQueryRadNNReporterOneToOne() { + delete set; + delete [] count; +} + +void trackSequenceQueryRadNNReporterOneToOne::add_point(unsigned int trackID, unsigned int qpos, unsigned int spos, double dist) { + std::set< NNresult >::iterator it; + NNresult r; + r.qpos = qpos; + r.trackID = trackID; + + // Track insertion count pairs + it = set->find(r); + if ( it == set->end() ) { + set->insert(r); + count[trackID]++; + } + + // Point insertion + // Keep the result with the smallest value (greedy local one-to-one algorithm) + r.spos = spos; + r.dist = dist; + + if(point_queue->size() < r.qpos + 1){ + point_queue->resize( r.qpos + 1 ); + (*point_queue)[r.qpos].dist = 1e6; + } + + if (r.dist < (*point_queue)[r.qpos].dist) + (*point_queue)[r.qpos] = r; + +} + +void trackSequenceQueryRadNNReporterOneToOne::report(char *fileTable, adb__queryResponse *adbQueryResponse) { + if(adbQueryResponse==0) { + std::vector< NNresult >::iterator vit; + NNresult rk; + for( vit = point_queue->begin() ; vit < point_queue->end() ; vit++ ){ + rk = *vit; + std::cout << rk.dist << " " + << rk.qpos << " " + << rk.spos << " " + << fileTable + rk.trackID*O2_FILETABLE_ENTRY_SIZE + << std::endl; + } + } else { + // FIXME + } +}