mas01mc@354: #!/usr/bin/python
mas01mc@354:
mas01mc@354: # Python code/library to query the audioDB via the SOAP web interface.
mas01mc@354: # by Malcolm Slaney, August/September 2008
mas01mc@354: # malcolm@ieee.org
mas01mc@354:
mas01mc@354: import sys, socket
mas01mc@354: from xml.dom.minidom import parseString
mas01mc@354:
mas01mc@354: global debug
mas01mc@354: debug = False
mas01mc@354: global dbName
mas01mc@354: dbName = 'tutorial.adb'
mas01mc@354:
mas01mc@354: # From: http://www.informit.com/articles/article.aspx?p=686162&seqNum=2
mas01mc@354: #serverHost = 'research-hm3.corp.sk1.yahoo.com'
mas01mc@354: serverHost = 'localhost'
mas01mc@354: serverPort = 14475
mas01mc@354:
mas01mc@354: # Start the server on serverHost with
mas01mc@354: # ./audioDB -s 14475
mas01mc@354:
mas01mc@354: # Here are the templates used for the different kinds of queries. We'll fill in the
mas01mc@354: # desired parameters are we go.
mas01mc@354: LIST_TEMPLATE = """
mas01mc@354:
mas01mc@354:
-1.0
-1.0
' # one power feature per row mas01mc@354: queryPos = '0' # where in the feature sequence to start the shingle query mas01mc@354: pointNN = '10' # how many near points to return per track mas01mc@354: trackNN = '10' # how many near tracks to return mas01mc@354: radius = '1.0' # search radius mas01mc@354: absoluteThreshold = '-4.5' # absolute silence threshold in Bels (query and database shingles) mas01mc@354: relativeThreshold = '0' # relative silence threshold in Bels between features, 0 = ignore mas01mc@354: exhaustive = '0' # 1 = perform query using all subsequences of features of length sequenceLength mas01mc@354: lshExact = '0' # if using an index then compute exact distances after LSH retrieval mas01mc@354: message = SHINGLE_QUERY_TEMPLATE mas01mc@354: message = SHINGLE_QUERY_TEMPLATE%(dbName, featureDim, queryVector, powerVector, queryPos, pointNN, trackNN, radius, absoluteThreshold, relativeThreshold, exhaustive, lshExact); mas01mc@354: # print message mas01mc@354: print message mas01mc@354: response = SendXMLCommand(message) mas01mc@354: ParseShingleXML(response) mas01mc@354: mas01mc@354: mas01mc@354: ############### Sequence Query - Show the data closest to one query ########### mas01mc@354: def RunSequenceQuery(argv): mas01mc@354: global debug, dbName mas01mc@354: if len(argv) > 2: mas01mc@354: dbKey = argv[2] mas01mc@354: qType = '32' # nSequence mas01mc@354: qPos = argv[3] mas01mc@354: pointNN = '10' mas01mc@354: trackNN = '5' mas01mc@354: seqLen = argv[4] mas01mc@354: queryRadius = '0.5' mas01mc@354: else: mas01mc@354: dbKey = 'tmp/3.chr' mas01mc@354: qType = '32' # nSequence mas01mc@354: qPos = '110' mas01mc@354: pointNN = '10' mas01mc@354: trackNN = '5' mas01mc@354: seqLen = '20' mas01mc@354: queryRadius = '0.4' mas01mc@354: mas01mc@354: message = SEQUENCE_TEMPLATE mas01mc@354: message = SEQUENCE_TEMPLATE%(dbName, dbKey, qType, qPos, pointNN, trackNN, seqLen, queryRadius) mas01mc@354: # print message mas01mc@354: response = SendXMLCommand(message) mas01mc@354: ParseShingleXML(response) mas01mc@354: mas01mc@354: def ParseShingleXML(response): mas01mc@354: # Grab all the responses mas01mc@354: # See http://diveintopython.org/xml_processing/parsing_xml.html mas01mc@354: dom = parseString(response) mas01mc@354: resultList = [] mas01mc@354: for node in dom.getElementsByTagName('Rlist'): mas01mc@354: # print node.toxml() mas01mc@354: resultList.append(node.firstChild.data.encode('latin-1')) mas01mc@354: mas01mc@354: distanceList = [] mas01mc@354: for node in dom.getElementsByTagName('Dist'): mas01mc@354: # print node.toxml() mas01mc@354: distanceList.append(node.firstChild.data.encode('latin-1')) mas01mc@354: mas01mc@354: positionList = [] mas01mc@354: for node in dom.getElementsByTagName('Spos'): mas01mc@354: # print node.toxml() mas01mc@354: positionList.append(node.firstChild.data.encode('latin-1')) mas01mc@354: mas01mc@354: # print resultList mas01mc@354: # print distanceList mas01mc@354: # print positionList mas01mc@354: mas01mc@354: # Print out a summary of the most similar results mas01mc@354: for i in range(0,len(resultList)): mas01mc@354: if i > 0 and resultList[i] != resultList[i-1]: mas01mc@354: print mas01mc@354: print positionList[i], distanceList[i], resultList[i] mas01mc@354: mas01mc@354: dom.unlink() mas01mc@354: mas01mc@354: ############### XML and Network Utilities ########### mas01mc@354: # Send one XML SOAP command to the server. Get back the response. mas01mc@354: mas01mc@354: def SendXMLCommand(message): mas01mc@354: global debug mas01mc@354: if debug: mas01mc@354: print message mas01mc@354: print mas01mc@354: mas01mc@354: #Create a socket mas01mc@354: sSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) mas01mc@354: mas01mc@354: #Connect to server mas01mc@354: sSock.connect((serverHost, serverPort)) mas01mc@354: mas01mc@354: #Send messages mas01mc@354: sSock.send(message) mas01mc@354: data = "" mas01mc@354: # Now loop, while getting all the data we can get from the socket. mas01mc@354: while True: mas01mc@354: c = sSock.recv(4096) mas01mc@354: if c == "": mas01mc@354: break mas01mc@354: data += c mas01mc@354: if data == "": mas01mc@354: print "No response from the audioDB server" mas01mc@354: sys.exit(0) mas01mc@354: # Split off the HTTP header and the data mas01mc@354: header,response = data.split("\r\n\r\n", 1) mas01mc@354: if debug: mas01mc@354: print 'Client received: ',response mas01mc@354: mas01mc@354: sSock.close() mas01mc@354: return response mas01mc@354: mas01mc@354: mas01mc@354: ############### Main Program - Figure out which query we want ########### mas01mc@354: mas01mc@354: # Argument processing scheme described at: http://docs.python.org/lib/module-getopt.html mas01mc@354: mas01mc@354: import sys mas01mc@354: if __name__=="__main__": mas01mc@354: cmdname = sys.argv[0] mas01mc@354: if len(sys.argv) == 1: mas01mc@354: print "Syntax: " + sys.argv[0] + " -q feature_file pos len" mas01mc@354: sys.exit(1) mas01mc@354: mas01mc@354: queryType = sys.argv[1] mas01mc@354: if queryType == '-s' or queryType == 'status': mas01mc@354: response = RunStatusQuery() mas01mc@354: for k, v in response.iteritems(): mas01mc@354: print k, v mas01mc@354: elif queryType == '-q' or queryType == 'query': mas01mc@354: RunSequenceQuery(sys.argv) mas01mc@354: elif queryType == '-l' or queryType == 'list': mas01mc@354: response = RunListQuery() mas01mc@354: # print response mas01mc@354: results = ParseListXML(response) mas01mc@354: for (f,l) in results: mas01mc@354: print "%s\t%s" % (f,l) mas01mc@354: elif queryType == '-v' or queryType == 'vector': mas01mc@354: response = RunShingleQuery() mas01mc@354: mas01mc@354: