Changes in trunk/python/selector.py [2340:2881]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/python/selector.py
r2340 r2881 1 1 import re 2 import math 3 import string 2 4 from asap._asap import selector as _selector, srctype 3 5 from asap.utils import unique, _to_list … … 200 202 raise TypeError('Unknown row number type. Use lists of integers.') 201 203 204 def set_msselection_field(self, selection): 205 """ 206 Set a field selection in msselection syntax. The msselection 207 suppports the following syntax: 208 209 pattern match: 210 - UNIX style pattern match for source name using '*' 211 (compatible with set_name) 212 213 field id selection: 214 - simple number in string ('0', '1', etc.) 215 - range specification using '~' ('0~1', etc.) 216 - range specification using '>' or '<' in combination 217 with '=' ('>=1', '<3', etc.) 218 219 comma separated multiple selection: 220 - selections can be combined by using ',' ('0,>1', 221 'mysource*,2~4', etc.) 222 """ 223 selection_list = map(string.strip, selection.split(',')) 224 query_list = list(self.generate_query(selection_list)) 225 if len(query_list) > 0: 226 original_query = self.get_query() 227 if len(original_query) == 0 or re.match('.*(SRC|FIELD)NAME.*',original_query): 228 query = 'SELECT FROM $1 WHERE ' + ' || '.join(query_list) 229 else: 230 query = 'SELECT FROM $1 WHERE (' + original_query + ') && (' + ' || '.join(query_list) + ')' 231 self._settaql(query) 232 233 def generate_query(self, selection_list): 234 for s in selection_list: 235 if s.isdigit() or re.match('^[<>]=?[0-9]*$', s) or \ 236 re.match('^[0-9]+~[0-9]+$', s): 237 #print '"%s" is ID selection using < or <='%(s) 238 a = FieldIdRegexGenerator(s) 239 yield '(%s)'%(a.get_regex()) 240 elif len(s) > 0: 241 #print '"%s" is UNIX style pattern match'%(s) 242 yield '(SRCNAME == pattern(\'%s\'))'%(s) 243 202 244 def get_scans(self): 203 245 return list(self._getscans()) … … 275 317 union.set_query(qs) 276 318 return union 319 320 class FieldIdRegexGenerator(object): 321 def __init__(self, pattern): 322 if pattern.isdigit(): 323 self.regex = 'FIELDNAME == regex(\'.+__%s$\')'%(pattern) 324 else: 325 self.regex = None 326 ineq = None 327 if pattern.find('<') >= 0: 328 ineq = '<' 329 s = pattern.strip().lstrip(ineq).lstrip('=') 330 if not s.isdigit(): 331 raise RuntimeError('Invalid syntax: %s'%(pattern)) 332 self.id = int(s) + (-1 if pattern.find('=') < 0 else 0) 333 self.template = string.Template('FIELDNAME == regex(\'.+__${reg}$\')') 334 elif pattern.find('>') >= 0: 335 ineq = '>' 336 s = pattern.strip().lstrip(ineq).lstrip('=') 337 if not s.isdigit(): 338 raise RuntimeError('Invalid syntax: %s'%(pattern)) 339 self.id = int(s) + (-1 if pattern.find('=') >= 0 else 0) 340 self.template = string.Template('FIELDNAME == regex(\'.+__[0-9]+$\') && FIELDNAME != regex(\'.+__${reg}$\')') 341 elif pattern.find('~') >= 0: 342 s = map(string.strip, pattern.split('~')) 343 if len(s) == 2 and s[0].isdigit() and s[1].isdigit(): 344 id0 = int(s[0]) 345 id1 = int(s[1]) 346 if id0 == 0: 347 self.id = id1 348 self.template = string.Template('FIELDNAME == regex(\'.+__${reg}$\')') 349 else: 350 self.id = [id0-1,id1] 351 self.template = string.Template('FIELDNAME == regex(\'.+__${reg}$\') && FIELDNAME != regex(\'.+__${optreg}$\')') 352 else: 353 raise RuntimeError('Invalid syntax: %s'%(pattern)) 354 else: 355 raise RuntimeError('Invalid syntax: %s'%(pattern)) 356 #print 'self.id=',self.id 357 358 def get_regex(self): 359 if self.regex is not None: 360 # 'X' 361 return self.regex 362 elif isinstance(self.id, list): 363 # 'X~Y' 364 return self.template.safe_substitute(reg=self.__compile(self.id[1]), 365 optreg=self.__compile(self.id[0])) 366 else: 367 # '<(=)X' or '>(=)X' 368 return self.template.safe_substitute(reg=self.__compile(self.id)) 369 370 def __compile(self, idx): 371 pattern = '' 372 if idx >= 0: 373 numerics = map(int,list(str(idx))) 374 #numerics.reverse() 375 num_digits = len(numerics) 376 #print 'numerics=',numerics 377 if num_digits == 1: 378 if numerics[0] == 0: 379 pattern = '0' 380 else: 381 pattern = '[0-%s]'%(numerics[0]) 382 elif num_digits == 2: 383 pattern = '(%s)'%('|'.join( 384 list(self.__gen_two_digit_pattern(numerics)))) 385 elif num_digits == 3: 386 pattern = '(%s)'%('|'.join( 387 list(self.__gen_three_digit_pattern(numerics)))) 388 else: 389 raise RuntimeError('ID > 999 is not supported') 390 else: 391 raise RuntimeError('ID must be >= 0') 392 return pattern 393 394 def __gen_two_digit_pattern(self, numerics): 395 assert len(numerics) == 2 396 yield '[0-9]' 397 if numerics[0] == 2: 398 yield '1[0-9]' 399 elif numerics[0] > 2: 400 yield '[1-%s][0-9]'%(numerics[0]-1) 401 if numerics[1] == 0: 402 yield '%s%s'%(numerics[0],numerics[1]) 403 else: 404 yield '%s[0-%s]'%(numerics[0],numerics[1]) 405 406 def __gen_three_digit_pattern(self, numerics): 407 assert len(numerics) == 3 408 yield '[0-9]' 409 yield '[1-9][0-9]' 410 if numerics[0] == 2: 411 yield '1[0-9][0-9]' 412 elif numerics[0] > 2: 413 yield '[1-%s][0-9][0-9]'%(numerics[0]-1) 414 if numerics[1] == 0: 415 if numerics[2] == 0: 416 yield '%s00'%(numerics[0]) 417 else: 418 yield '%s0[0-%s]'%(numerics[0],numerics[2]) 419 else: 420 if numerics[1] > 1: 421 yield '%s[0-%s][0-9]'%(numerics[0],numerics[1]-1) 422 elif numerics[1] == 1: 423 yield '%s0[0-9]'%(numerics[0]) 424 if numerics[0] == 0: 425 yield '%s%s%s'%(numerics[0],numerics[1],numerics[2]) 426 else: 427 yield '%s%s[0-%s]'%(numerics[0],numerics[1],numerics[2])
Note:
See TracChangeset
for help on using the changeset viewer.