Skip to content
Snippets Groups Projects
Commit 1cb93e23 authored by Brian Moe's avatar Brian Moe
Browse files

Query on event attributes. #933

parent ae2e1f04
No related branches found
No related tags found
No related merge requests found
...@@ -6,7 +6,8 @@ from models import Event, Group, Label ...@@ -6,7 +6,8 @@ from models import Event, Group, Label
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core.exceptions import FieldError from django.core.exceptions import FieldError
from query import parseQuery, ParseException from query import parseQuery
from pyparsing import ParseException
htmlEntityStar = "★" htmlEntityStar = "★"
htmlEntityRightPointingHand = "☞" htmlEntityRightPointingHand = "☞"
...@@ -31,7 +32,7 @@ class GraceQueryField(forms.CharField): ...@@ -31,7 +32,7 @@ class GraceQueryField(forms.CharField):
raise forms.ValidationError(mark_safe(err)) raise forms.ValidationError(mark_safe(err))
except Exception, e: except Exception, e:
# What could this be and how can we handle it better? XXX # What could this be and how can we handle it better? XXX
raise forms.ValidationError(str(e)) raise forms.ValidationError(str(e)+str(type(e)))
class SimpleSearchForm(forms.Form): class SimpleSearchForm(forms.Form):
query = GraceQueryField(required=False, widget=forms.TextInput(attrs={'size':60})) query = GraceQueryField(required=False, widget=forms.TextInput(attrs={'size':60}))
......
...@@ -23,7 +23,7 @@ from pyparsing import \ ...@@ -23,7 +23,7 @@ from pyparsing import \
Word, nums, Literal, CaselessLiteral, delimitedList, Suppress, QuotedString, \ Word, nums, Literal, CaselessLiteral, delimitedList, Suppress, QuotedString, \
Keyword, Combine, Or, Optional, OneOrMore, alphas, Regex, \ Keyword, Combine, Or, Optional, OneOrMore, alphas, Regex, \
opAssoc, operatorPrecedence, oneOf, \ opAssoc, operatorPrecedence, oneOf, \
stringStart, stringEnd, ParseException stringStart, stringEnd
def maybeRange(name, dbname=None): def maybeRange(name, dbname=None):
dbname = dbname or name dbname = dbname or name
...@@ -170,41 +170,59 @@ labelQ.setParseAction(lambda toks: ("label", toks[0])) ...@@ -170,41 +170,59 @@ labelQ.setParseAction(lambda toks: ("label", toks[0]))
########################### ###########################
# Query on event attributes # Query on event attributes
attrNumExprOperators = { "<" : "__lt", lparen = Suppress('(')
"<=": "__lte", rparen = Suppress(')')
"=" : "",
">" : "__gt",
">=": "__gte",
}
attrNumExprLhs = Keyword("far") | Keyword("gpstime") exprOperators = { "<" : "__lt",
"<=": "__lte",
"=" : "",
">" : "__gt",
">=": "__gte",
}
tableTranslations = {
'si': 'singleinspiral',
'ci': 'coincinspiralevent',
'mb': 'multiburstevent',
'coincinspiral': 'coincinspiralevent',
'multiburst': 'multiburstevent',
}
def buildDjangoQueryField(toks):
toks = [name.lower() for name in toks]
return "__".join([tableTranslations.get(name, name) for name in toks])
exponent = Combine(Word("Ee") + Optional(Word("+-"))+Word(nums)) exponent = Combine(Word("Ee") + Optional(Word("+-"))+Word(nums))
afloat = Combine( Word(nums) + Optional(Combine(Literal(".") + Word(nums))) )
attrNumExprRhs = Combine( Optional(Word("+-")) + afloat + Optional(exponent) ) afloat = Combine( Word(nums) + \
attrNumExprRhs.setParseAction(lambda toks: float(toks[0])) Optional(Combine(Literal(".") + Word(nums))) ) + \
Optional(exponent)
afloat.setParseAction(lambda toks: float(toks[0]))
lhs = delimitedList(Word(alphas+'_'), '.')
lhs.setParseAction(buildDjangoQueryField)
attrNumExprOp = Or(map(Literal, attrNumExprOperators.keys())) rhs = afloat | QuotedString('"')
attrNumExprOp.setParseAction(lambda toks: attrNumExprOperators[toks[0]])
attrNumExpr = attrNumExprLhs + attrNumExprOp + attrNumExprRhs op = Or(map(Literal, exprOperators.keys()))
attrNumExpr.setParseAction(lambda toks: Q(**{toks[0]+toks[1]: toks[2]})) op.setParseAction(lambda toks: exprOperators[toks[0]])
#attrIfoExpr = Keyword("ifos").suppress() + Literal("=").suppress() + Word("LVH12,") simpleTerm = lhs + op + rhs
#attrIfoExpr.setParseAction(lambda toks: Q(instruments=toks[0])) simpleTerm.setParseAction(lambda toks: Q(**{toks[0]+toks[1]: toks[2]}))
#attrExpr = attrIfoExpr | attrNumExpr rangeTerm = lhs + Suppress('in') + rhs + Suppress(",") + rhs
attrExpr = attrNumExpr rangeTerm.setParseAction(lambda toks: Q(**{toks[0]+"__range": toks[1:]}))
attrExprs = operatorPrecedence(attrExpr, term = simpleTerm | rangeTerm
attrExpressions = operatorPrecedence(term,
[(minusop, 1, opAssoc.RIGHT, lambda a,b,toks: ~toks[0][0]), [(minusop, 1, opAssoc.RIGHT, lambda a,b,toks: ~toks[0][0]),
(orop, 2, opAssoc.LEFT, lambda a,b,toks: reduce(Q.__or__, toks[0].asList(), Q())), (orop, 2, opAssoc.LEFT, lambda a,b,toks: reduce(Q.__or__, toks[0].asList(), Q())),
(andop, 2, opAssoc.LEFT, lambda a,b,toks: reduce(Q.__and__, toks[0].asList(), Q())), (andop, 2, opAssoc.LEFT, lambda a,b,toks: reduce(Q.__and__, toks[0].asList(), Q())),
]).setParseAction(lambda toks: toks[0]) ]).setParseAction(lambda toks: toks[0])
#attributeQ = lparen + attrExpressions + rparen
attributeQ = Optional(Suppress(Keyword('attr:'))) + attrExprs.copy() attributeQ = attrExpressions.copy()
attributeQ.setParseAction(lambda toks: ("attr", toks[0])) attributeQ.setParseAction(lambda toks: ("attr", toks[0]))
......
<div id="hints" style="display: none;"> <div id="hints" style="display: none;">
<h4>By Event Attributes</h4>
Relational and range queries can be made on event attributes.
<ul>
<li><code>instruments = "H1,L1,V1" &amp; far &lt; 1e-7</code></li>
<li><code>singleinspiral.mchirp &gt;= 1.6 &amp; eff_distance in 40.5,55 </code></li>
<li><code>(si.channel = "DMT-STRAIN" | si.channel = "DMT-PAIN") &amp; si.snr &lt; 5</code></li>
<li><code>mb.snr in 1,3 &amp; mb.central_freq &gt; 1000</code></li>
</ul>
Attributes in the common event object (eg gpstime, far, instruments) do not need qualifiers. Attributes specific to inspiral or burst events, for example, require qualification. Abbreviations are available: <code>si</code> for singleinspiral, <code>ci</code> for coincinspiral and <code>mb</code> for multiburst.
<h4>By GPS Time</h4> <h4>By GPS Time</h4>
Specifiy an exact GPS time, or a range. Specifiy an exact GPS time, or a range.
Integers will be assumed to be GPS times, making the <code>gpstime:</code> Integers will be assumed to be GPS times, making the <code>gpstime:</code>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment