def download_EC_all(label): CDB = lmfdb.base.getDBConnection().elliptic_curves.curves N, iso, number = split_lmfdb_label(label) if number: data = CDB.find_one({'lmfdb_label': label}) if data is None: return elliptic_curve_jump_error(label, {}) data_list = [data] else: data_list = sorted(list(CDB.find({'lmfdb_iso': label})), key=lambda E: E['number']) if len(data_list) == 0: return elliptic_curve_jump_error(label, {}) # titles of all entries of curves dump_data = [] titles = [str(c) for c in data_list[0]] titles = [t for t in titles if t[0] != '_'] titles.sort() dump_data.append(titles) for data in data_list: data1 = [] for t in titles: d = data[t] if t == 'ainvs': data1.append(format_ainvs(d)) elif t in ['torsion_generators', 'torsion_structure']: data1.append([eval(g) for g in d]) elif t == 'x-coordinates_of_integral_points': data1.append(parse_list(d)) elif t == 'gens': data1.append(parse_points(d)) elif t in ['iso', 'label', 'lmfdb_iso', 'lmfdb_label']: data1.append(str(d)) else: data1.append(d) dump_data.append(data1) response = make_response('\n'.join(str(an) for an in dump_data)) response.headers['Content-type'] = 'text/plain' return response
def elliptic_curve_search(**args): info = to_dict(args) query = {} bread = [('Elliptic Curves', url_for(".rational_elliptic_curves")), ('Search Results', '.')] if 'jump' in args: label = info.get('label', '').replace(" ", "") m = lmfdb_label_regex.match(label) if m: try: return by_ec_label(label) except ValueError: return elliptic_curve_jump_error(label, info, wellformed_label=True) elif label.startswith("Cremona:"): label = label[8:] m = cremona_label_regex.match(label) if m: try: return by_ec_label(label) except ValueError: return elliptic_curve_jump_error(label, info, wellformed_label=True) elif cremona_label_regex.match(label): return elliptic_curve_jump_error(label, info, cremona_label=True) elif label: # Try to parse a string like [1,0,3,2,4] lab = re.sub(r'\s', '', label) lab = re.sub(r'^\[', '', lab) lab = re.sub(r']$', '', lab) try: labvec = lab.split(',') labvec = [QQ(str(z)) for z in labvec] # Rationals allowed E = EllipticCurve(labvec) ainvs = [str(c) for c in E.minimal_model().ainvs()] C = lmfdb.base.getDBConnection() data = C.elliptic_curves.curves.find_one({'ainvs': ainvs}) if data is None: return elliptic_curve_jump_error(label, info) return by_ec_label(data['lmfdb_label']) except (ValueError, ArithmeticError): return elliptic_curve_jump_error(label, info) else: query['label'] = '' if info.get('jinv'): j = clean_input(info['jinv']) j = j.replace('+', '') if not QQ_RE.match(j): info[ 'err'] = 'Error parsing input for the j-invariant. It needs to be a rational number.' return search_input_error(info, bread) query['jinv'] = j for field in ['conductor', 'torsion', 'rank', 'sha_an']: if info.get(field): info[field] = clean_input(info[field]) ran = info[field] ran = ran.replace('..', '-').replace(' ', '') if not LIST_RE.match(ran): names = { 'conductor': 'conductor', 'torsion': 'torsion order', 'rank': 'rank', 'sha_an': 'analytic order of Ш' } info[ 'err'] = 'Error parsing input for the %s. It needs to be an integer (such as 5), a range of integers (such as 2-10 or 2..10), or a comma-separated list of these (such as 2,3,8 or 3-5, 7, 8-11).' % names[ field] return search_input_error(info, bread) # Past input check tmp = parse_range2(ran, field) # work around syntax for $or # we have to foil out multiple or conditions if tmp[0] == '$or' and '$or' in query: newors = [] for y in tmp[1]: oldors = [dict.copy(x) for x in query['$or']] for x in oldors: x.update(y) newors.extend(oldors) tmp[1] = newors if field == 'sha_an': # database sha_an values are not all exact! query[tmp[0]] = {'$gt': tmp[1] - 0.1, '$lt': tmp[1] + 0.1} else: query[tmp[0]] = tmp[1] if 'optimal' in info and info['optimal'] == 'on': # fails on 990h3 query['number'] = 1 if 'torsion_structure' in info and info['torsion_structure']: info['torsion_structure'] = clean_input(info['torsion_structure']) if not TORS_RE.match(info['torsion_structure']): info[ 'err'] = 'Error parsing input for the torsion structure. It needs to be one or more integers in square brackets, such as [6], [2,2], or [2,4]. Moreover, each integer should be bigger than 1, and each divides the next.' return search_input_error(info, bread) query['torsion_structure'] = [ str(a) for a in parse_list(info['torsion_structure']) ] if info.get('surj_primes'): info['surj_primes'] = clean_input(info['surj_primes']) format_ok = LIST_POSINT_RE.match(info['surj_primes']) if format_ok: surj_primes = [int(p) for p in info['surj_primes'].split(',')] format_ok = all([ZZ(p).is_prime(proof=False) for p in surj_primes]) if format_ok: query['non-surjective_primes'] = {"$nin": surj_primes} else: info[ 'err'] = 'Error parsing input for surjective primes. It needs to be a prime (such as 5), or a comma-separated list of primes (such as 2,3,11).' return search_input_error(info, bread) if info.get('nonsurj_primes'): info['nonsurj_primes'] = clean_input(info['nonsurj_primes']) format_ok = LIST_POSINT_RE.match(info['nonsurj_primes']) if format_ok: nonsurj_primes = [ int(p) for p in info['nonsurj_primes'].split(',') ] format_ok = all( [ZZ(p).is_prime(proof=False) for p in nonsurj_primes]) if format_ok: if info['surj_quantifier'] == 'exactly': nonsurj_primes.sort() query['non-surjective_primes'] = nonsurj_primes else: if 'non-surjective_primes' in query: query['non-surjective_primes'] = { "$nin": surj_primes, "$all": nonsurj_primes } else: query['non-surjective_primes'] = {"$all": nonsurj_primes} else: info[ 'err'] = 'Error parsing input for nonsurjective primes. It needs to be a prime (such as 5), or a comma-separated list of primes (such as 2,3,11).' return search_input_error(info, bread) info['query'] = query count_default = 100 if info.get('count'): try: count = int(info['count']) except: count = count_default else: count = count_default info['count'] = count start_default = 0 if info.get('start'): try: start = int(info['start']) if (start < 0): start += (1 - (start + 1) / count) * count except: start = start_default else: start = start_default cursor = lmfdb.base.getDBConnection().elliptic_curves.curves.find(query) nres = cursor.count() if (start >= nres): start -= (1 + (start - nres) / count) * count if (start < 0): start = 0 res = cursor.sort([('conductor', ASCENDING), ('lmfdb_iso', ASCENDING), ('lmfdb_number', ASCENDING)]).skip(start).limit(count) info['curves'] = res info['format_ainvs'] = format_ainvs info['number'] = nres info['start'] = start if nres == 1: info['report'] = 'unique match' else: if nres > count or start != 0: info['report'] = 'displaying matches %s-%s of %s' % ( start + 1, min(nres, start + count), nres) else: info['report'] = 'displaying all %s matches' % nres credit = 'John Cremona' if 'non-surjective_primes' in query: credit += 'and Andrew Sutherland' t = 'Elliptic Curves' return render_template("search_results.html", info=info, credit=credit, bread=bread, title=t)
def hgm_search(**args): info = to_dict(args) bread = get_bread([("Search results", url_for('.search'))]) C = base.getDBConnection() query = {} if 'jump_to' in info: return render_hgm_webpage({'label': info['jump_to']}) # t, generic, irreducible # 'A', 'B', 'hodge' for param in ['t', 'A', 'B']: if (param == 't' and PAIR_RE.match(info['t'])) or (param == 'A' and IF_RE.match(info[param])) or (param == 'B' and IF_RE.match(info[param])): query[param] = parse_list(info[param]) else: print "Bad input" for param in ['degree','weight','sign']: if info.get(param): info[param] = clean_input(info[param]) if param == 'gal': try: gcs = complete_group_codes(info[param]) if len(gcs) == 1: tmp = ['gal', list(gcs[0])] if len(gcs) > 1: tmp = [{'gal': list(x)} for x in gcs] tmp = ['$or', tmp] except NameError as code: info['err'] = 'Error parsing input for A: unknown group label %s. It needs to be a <a title = "Galois group labels" knowl="nf.galois_group.name">group label</a>, such as C5 or 5T1, or comma separated list of labels.' % code return search_input_error(info, bread) else: ran = info[param] ran = ran.replace('..', '-') if LIST_RE.match(ran): tmp = parse_range2(ran, param) else: names = {'weight': 'weight', 'degree': 'degree', 'sign': 'sign'} info['err'] = 'Error parsing input for the %s. It needs to be an integer (such as 5), a range of integers (such as 2-10 or 2..10), or a comma-separated list of these (such as 2,3,8 or 3-5, 7, 8-11).' % names[param] return search_input_error(info, bread) # work around syntax for $or # we have to foil out multiple or conditions if tmp[0] == '$or' and '$or' in query: newors = [] for y in tmp[1]: oldors = [dict.copy(x) for x in query['$or']] for x in oldors: x.update(y) newors.extend(oldors) tmp[1] = newors query[tmp[0]] = tmp[1] count_default = 20 if info.get('count'): try: count = int(info['count']) except: count = count_default else: count = count_default info['count'] = count start_default = 0 if info.get('start'): try: start = int(info['start']) if(start < 0): start += (1 - (start + 1) / count) * count except: start = start_default else: start = start_default if info.get('paging'): try: paging = int(info['paging']) if paging == 0: start = 0 except: pass # logger.debug(query) res = C.hgm.motives.find(query).sort([('degree', pymongo.ASCENDING), ('label', pymongo.ASCENDING)]) nres = res.count() res = res.skip(start).limit(count) if(start >= nres): start -= (1 + (start - nres) / count) * count if(start < 0): start = 0 info['motives'] = res info['number'] = nres info['start'] = start if nres == 1: info['report'] = 'unique match' else: if nres > count or start != 0: info['report'] = 'displaying matches %s-%s of %s' % (start + 1, min(nres, start + count), nres) else: info['report'] = 'displaying all %s matches' % nres return render_template("hgm-search.html", info=info, title="Hypergeometric Motive over $\Q$ Search Result", bread=bread, credit=HGM_credit)
def hilbert_modular_form_search(**args): C = getDBConnection() # C.hmfs.forms.ensure_index([('level_norm', pymongo.ASCENDING), ('label', pymongo.ASCENDING)]) info = to_dict(args) # what has been entered in the search boxes if 'label' in info: args = {'label': info['label']} return render_hmf_webpage(**args) query = {} for field in ['field_degree', 'field_disc', 'field_label', 'weight', 'level_norm', 'dimension']: if info.get(field): if field == 'weight': try: parallelweight = int(info[field]) query['parallel_weight'] = parallelweight except: query[field] = str(parse_list(info[field])) elif field == 'field_label': query[field] = parse_field_string(info[field]) elif field == 'field_degree': query['deg'] = parse_range(info[field]) elif field == 'field_disc': query['disc'] = parse_range(info[field]) elif field == 'label': query[field] = info[field] elif field == 'dimension': query[field] = parse_range(str(info[field])) elif field == 'level_norm': query[field] = parse_range(info[field]) else: query[field] = info[field] count_default = 100 if info.get('count'): try: count = int(info['count']) except: count = count_default else: info['count'] = count_default count = count_default start_default = 0 if info.get('start'): try: start = int(info['start']) if(start < 0): start += (1 - (start + 1) / count) * count except: start = start_default else: start = start_default info['query'] = dict(query) res = C.hmfs.forms.find( query).sort([('deg', pymongo.ASCENDING), ('disc', pymongo.ASCENDING), ('level_norm', pymongo.ASCENDING), ('level_label', pymongo.ASCENDING), ('label_nsuffix', pymongo.ASCENDING)]).skip(start).limit(count) nres = res.count() if(start >= nres): start -= (1 + (start - nres) / count) * count if(start < 0): start = 0 info['number'] = nres info['start'] = start info['more'] = int(start + count < nres) if nres == 1: info['report'] = 'unique match' else: if nres == 0: info['report'] = 'no matches' else: if nres > count or start != 0: info['report'] = 'displaying matches %s-%s of %s' % (start + 1, min(nres, start + count), nres) else: info['report'] = 'displaying all %s matches' % nres res_clean = [] for v in res: v_clean = {} v_clean['field_label'] = v['field_label'] v_clean['short_label'] = v['short_label'] v_clean['label'] = v['label'] v_clean['level_ideal'] = teXify_pol(v['level_ideal']) v_clean['dimension'] = v['dimension'] res_clean.append(v_clean) info['forms'] = res_clean t = 'Hilbert Modular Form search results' bread = [('Hilbert Modular Forms', url_for(".hilbert_modular_form_render_webpage")), ( 'Search results', ' ')] properties = [] return render_template("hilbert_modular_form_search.html", info=info, title=t, credit=hmf_credit, properties=properties, bread=bread)
def hilbert_modular_form_search(**args): C = getDBConnection() C.hmfs.forms.ensure_index([("level_norm", pymongo.ASCENDING), ("label", pymongo.ASCENDING)]) info = to_dict(args) # what has been entered in the search boxes if "label" in info: args = {"label": info["label"]} return render_hmf_webpage(**args) query = {} for field in ["field_label", "weight", "level_norm", "dimension"]: if info.get(field): if field == "weight": try: parallelweight = int(info[field]) query["parallel_weight"] = parallelweight except: query[field] = str(parse_list(info[field])) elif field == "field_label": query[field] = parse_field_string(info[field]) elif field == "label": query[field] = info[field] elif field == "dimension": query[field] = parse_range(str(info[field])) elif field == "level_norm": query[field] = parse_range(info[field]) else: query[field] = info[field] if info.get("count"): try: count = int(info["count"]) except: count = 100 else: info["count"] = 100 count = 100 info["query"] = dict(query) res = C.hmfs.forms.find(query).sort([("level_norm", pymongo.ASCENDING), ("label", pymongo.ASCENDING)]).limit(count) nres = res.count() if nres > 0: info["field_pretty_name"] = field_pretty(res[0]["field_label"]) else: info["field_pretty_name"] = "" info["number"] = nres if nres == 1: info["report"] = "unique match" else: if nres > count: info["report"] = "displaying first %s of %s matches" % (count, nres) else: info["report"] = "displaying all %s matches" % nres res_clean = [] for v in res: v_clean = {} v_clean["field_label"] = v["field_label"] v_clean["short_label"] = v["short_label"] v_clean["label"] = v["label"] v_clean["level_ideal"] = teXify_pol(v["level_ideal"]) v_clean["dimension"] = v["dimension"] res_clean.append(v_clean) info["forms"] = res_clean t = "Hilbert Modular Form search results" bread = [("Hilbert Modular Forms", url_for(".hilbert_modular_form_render_webpage")), ("Search results", " ")] properties = [] return render_template("hilbert_modular_form_search.html", info=info, title=t, properties=properties, bread=bread)
def hilbert_modular_form_search(**args): C = getDBConnection() C.hmfs.forms.ensure_index([('level_norm', pymongo.ASCENDING), ('label', pymongo.ASCENDING)]) info = to_dict(args) # what has been entered in the search boxes if 'label' in info: args = {'label': info['label']} return render_hmf_webpage(**args) query = {} for field in ['field_label', 'weight', 'level_norm', 'dimension']: if info.get(field): if field == 'weight': try: parallelweight = int(info[field]) query['parallel_weight'] = parallelweight except: query[field] = str(parse_list(info[field])) elif field == 'field_label': query[field] = parse_field_string(info[field]) elif field == 'label': query[field] = info[field] elif field == 'dimension': query[field] = parse_range(str(info[field])) elif field == 'level_norm': query[field] = parse_range(info[field]) else: query[field] = info[field] if info.get('count'): try: count = int(info['count']) except: count = 100 else: info['count'] = 100 count = 100 info['query'] = dict(query) res = C.hmfs.forms.find( query).sort([('level_norm', pymongo.ASCENDING), ('label', pymongo.ASCENDING)]).limit(count) nres = res.count() if nres > 0: info['field_pretty_name'] = field_pretty(res[0]['field_label']) else: info['field_pretty_name'] = '' info['number'] = nres if nres == 1: info['report'] = 'unique match' else: if nres > count: info['report'] = 'displaying first %s of %s matches' % (count, nres) else: info['report'] = 'displaying all %s matches' % nres res_clean = [] for v in res: v_clean = {} v_clean['field_label'] = v['field_label'] v_clean['short_label'] = v['short_label'] v_clean['label'] = v['label'] v_clean['level_ideal'] = teXify_pol(v['level_ideal']) v_clean['dimension'] = v['dimension'] res_clean.append(v_clean) info['forms'] = res_clean t = 'Hilbert Modular Form search results' bread = [('Hilbert Modular Forms', url_for(".hilbert_modular_form_render_webpage")), ( 'Search results', ' ')] properties = [] return render_template("hilbert_modular_form_search.html", info=info, title=t, properties=properties, bread=bread)
def hgm_search(**args): info = to_dict(args) bread = get_bread([("Search results", url_for('.search'))]) C = base.getDBConnection() query = {} if 'jump_to' in info: return render_hgm_webpage({'label': info['jump_to']}) family_search = False if info.get('Submit Family') or info.get('family'): family_search = True # generic, irreducible not in DB yet for param in [ 'A', 'B', 'hodge', 'a2', 'b2', 'a3', 'b3', 'a5', 'b5', 'a7', 'b7' ]: if info.get(param): info[param] = clean_input(info[param]) if IF_RE.match(info[param]): query[param] = parse_list(info[param]) query[param].sort() else: name = param if field == 'hodge': name = 'Hodge vector' info[ 'err'] = 'Error parsing input for %s. It needs to be a list of integers in square brackets, such as [2,3] or [1,1,1]' % name return search_input_error(info, bread) if info.get('t') and not family_search: info['t'] = clean_input(info['t']) try: tsage = QQ(str(info['t'])) tlist = [int(tsage.numerator()), int(tsage.denominator())] query['t'] = tlist except: info[ 'err'] = 'Error parsing input for t. It needs to be a rational number, such as 2/3 or -3' # sign can only be 1, -1, +1 if info.get('sign') and not family_search: sign = info['sign'] sign = re.sub(r'\s', '', sign) sign = clean_input(sign) if sign == '+1': sign = '1' if not (sign == '1' or sign == '-1'): info[ 'err'] = 'Error parsing input %s for sign. It needs to be 1 or -1' % sign return search_input_error(info, bread) query['sign'] = int(sign) for param in ['degree', 'weight', 'conductor']: # We don't look at conductor in family searches if info.get(param) and not (param == 'conductor' and family_search): if param == 'conductor': cond = info['conductor'] try: cond = re.sub(r'(\d)\s+(\d)', r'\1 * \2', cond) # implicit multiplication of numbers cond = cond.replace(r'..', r'-') # all ranges use - cond = re.sub(r'[a..zA..Z]', '', cond) cond = clean_input(cond) tmp = parse_range2(cond, 'cond', myZZ) except: info[ 'err'] = 'Error parsing input for conductor. It needs to be an integer (e.g., 8), a range of integers (e.g. 10-100), or a list of such (e.g., 5,7,8,10-100). Integers may be given in factored form (e.g. 2^5 3^2) %s' % cond return search_input_error(info, bread) else: # not conductor info[param] = clean_input(info[param]) ran = info[param] ran = ran.replace(r'..', r'-') if LIST_RE.match(ran): tmp = parse_range2(ran, param) else: names = {'weight': 'weight', 'degree': 'degree'} info[ 'err'] = 'Error parsing input for the %s. It needs to be an integer (such as 5), a range of integers (such as 2-10 or 2..10), or a comma-separated list of these (such as 2,3,8 or 3-5, 7, 8-11).' % names[ param] return search_input_error(info, bread) # work around syntax for $or # we have to foil out multiple or conditions if tmp[0] == '$or' and '$or' in query: newors = [] for y in tmp[1]: oldors = [dict.copy(x) for x in query['$or']] for x in oldors: x.update(y) newors.extend(oldors) tmp[1] = newors query[tmp[0]] = tmp[1] #print query count_default = 20 if info.get('count'): try: count = int(info['count']) except: count = count_default else: count = count_default info['count'] = count start_default = 0 if info.get('start'): try: start = int(info['start']) if (start < 0): start += (1 - (start + 1) / count) * count except: start = start_default else: start = start_default if info.get('paging'): try: paging = int(info['paging']) if paging == 0: start = 0 except: pass # logger.debug(query) if family_search: res = C.hgm.families.find(query).sort([('label', pymongo.ASCENDING)]) else: res = C.hgm.motives.find(query).sort([('cond', pymongo.ASCENDING), ('label', pymongo.ASCENDING)]) nres = res.count() res = res.skip(start).limit(count) if (start >= nres): start -= (1 + (start - nres) / count) * count if (start < 0): start = 0 info['motives'] = res info['number'] = nres info['start'] = start if nres == 1: info['report'] = 'unique match' else: if nres > count or start != 0: info['report'] = 'displaying matches %s-%s of %s' % ( start + 1, min(nres, start + count), nres) else: info['report'] = 'displaying all %s matches' % nres info['make_label'] = make_abt_label info['make_t_label'] = make_t_label info['ab_label'] = ab_label info['display_t'] = display_t info['family'] = family_search info['factorint'] = factorint if family_search: return render_template( "hgm-search.html", info=info, title="Hypergeometric Family over $\Q$ Search Result", bread=bread, credit=HGM_credit) else: return render_template( "hgm-search.html", info=info, title="Hypergeometric Motive over $\Q$ Search Result", bread=bread, credit=HGM_credit)
def hilbert_modular_form_search(**args): C = getDBConnection() # C.hmfs.forms.ensure_index([('level_norm', pymongo.ASCENDING), ('label', pymongo.ASCENDING)]) info = to_dict(args) # what has been entered in the search boxes if 'label' in info: args = {'label': info['label']} return render_hmf_webpage(**args) query = {} for field in [ 'field_degree', 'field_disc', 'field_label', 'weight', 'level_norm', 'dimension' ]: if info.get(field): if field == 'weight': try: parallelweight = int(info[field]) query['parallel_weight'] = parallelweight except: query[field] = str(parse_list(info[field])) elif field == 'field_label': query[field] = parse_field_string(info[field]) elif field == 'field_degree': query['deg'] = parse_range(info[field]) elif field == 'field_disc': query['disc'] = parse_range(info[field]) elif field == 'label': query[field] = info[field] elif field == 'dimension': query[field] = parse_range(str(info[field])) elif field == 'level_norm': query[field] = parse_range(info[field]) else: query[field] = info[field] count_default = 100 if info.get('count'): try: count = int(info['count']) except: count = count_default else: info['count'] = count_default count = count_default start_default = 0 if info.get('start'): try: start = int(info['start']) if (start < 0): start += (1 - (start + 1) / count) * count except: start = start_default else: start = start_default info['query'] = dict(query) res = C.hmfs.forms.find(query).sort([('deg', pymongo.ASCENDING), ('disc', pymongo.ASCENDING), ('level_norm', pymongo.ASCENDING), ('level_label', pymongo.ASCENDING), ('label_nsuffix', pymongo.ASCENDING) ]).skip(start).limit(count) nres = res.count() if (start >= nres): start -= (1 + (start - nres) / count) * count if (start < 0): start = 0 info['number'] = nres info['start'] = start info['more'] = int(start + count < nres) if nres == 1: info['report'] = 'unique match' else: if nres == 0: info['report'] = 'no matches' else: if nres > count or start != 0: info['report'] = 'displaying matches %s-%s of %s' % ( start + 1, min(nres, start + count), nres) else: info['report'] = 'displaying all %s matches' % nres res_clean = [] for v in res: v_clean = {} v_clean['field_label'] = v['field_label'] v_clean['short_label'] = v['short_label'] v_clean['label'] = v['label'] v_clean['level_ideal'] = teXify_pol(v['level_ideal']) v_clean['dimension'] = v['dimension'] res_clean.append(v_clean) info['forms'] = res_clean t = 'Hilbert Modular Form search results' bread = [('Hilbert Modular Forms', url_for(".hilbert_modular_form_render_webpage")), ('Search results', ' ')] properties = [] return render_template("hilbert_modular_form_search.html", info=info, title=t, credit=hmf_credit, properties=properties, bread=bread)
def hilbert_modular_form_search(**args): C = getDBConnection() C.hmfs.forms.ensure_index([('level_norm', pymongo.ASCENDING), ('label', pymongo.ASCENDING)]) info = to_dict(args) # what has been entered in the search boxes if 'label' in info: args = {'label': info['label']} return render_hmf_webpage(**args) query = {} for field in ['field_label', 'weight', 'level_norm', 'dimension']: if info.get(field): if field == 'weight': try: parallelweight = int(info[field]) query['parallel_weight'] = parallelweight except: query[field] = str(parse_list(info[field])) elif field == 'field_label': query[field] = parse_field_string(info[field]) elif field == 'label': query[field] = info[field] elif field == 'dimension': query[field] = parse_range(str(info[field])) elif field == 'level_norm': query[field] = parse_range(info[field]) else: query[field] = info[field] if info.get('count'): try: count = int(info['count']) except: count = 100 else: info['count'] = 100 count = 100 info['query'] = dict(query) res = C.hmfs.forms.find(query).sort([('level_norm', pymongo.ASCENDING), ('label', pymongo.ASCENDING) ]).limit(count) nres = res.count() if nres > 0: info['field_pretty_name'] = field_pretty(res[0]['field_label']) else: info['field_pretty_name'] = '' info['number'] = nres if nres == 1: info['report'] = 'unique match' else: if nres > count: info['report'] = 'displaying first %s of %s matches' % (count, nres) else: info['report'] = 'displaying all %s matches' % nres res_clean = [] for v in res: v_clean = {} v_clean['field_label'] = v['field_label'] v_clean['short_label'] = v['short_label'] v_clean['label'] = v['label'] v_clean['level_ideal'] = teXify_pol(v['level_ideal']) v_clean['dimension'] = v['dimension'] res_clean.append(v_clean) info['forms'] = res_clean t = 'Hilbert Modular Form search results' bread = [('Hilbert Modular Forms', url_for(".hilbert_modular_form_render_webpage")), ('Search results', ' ')] properties = [] return render_template("hilbert_modular_form_search.html", info=info, title=t, properties=properties, bread=bread)
def elliptic_curve_search(**args): info = to_dict(args['data']) if 'jump' in info: label = info.get('label', '').replace(" ", "") # This label should be a full isogeny class label or a full # curve label (including the field_label component) try: nf, cond_label, iso_label, number = split_full_label(label) except IndexError: if not 'query' in info: info['query'] = {} bread = [("Elliptic Curves", url_for(".index"))] info['err'] = 'No elliptic curve in the database has label %s.' % label return search_input_error(info, bread) return show_ecnf(nf, cond_label, iso_label, number) query = {} bread = [('Elliptic Curves', url_for(".index")), ('Search Results', '.')] if 'conductor_norm' in info: Nnorm = clean_input(info['conductor_norm']) Nnorm = Nnorm.replace('..', '-').replace(' ', '') tmp = parse_range2(Nnorm, 'conductor_norm') if tmp[0] == '$or' and '$or' in query: newors = [] for y in tmp[1]: oldors = [dict.copy(x) for x in query['$or']] for x in oldors: x.update(y) newors.extend(oldors) tmp[1] = newors query[tmp[0]] = tmp[1] if 'conductor_label' in info: query['conductor_label'] = info['conductor_label'] if 'jinv' in info: query['jinv'] = info['jinv'] if info.get('torsion'): ran = info['torsion'] = clean_input(info['torsion']) ran = ran.replace('..', '-').replace(' ', '') if not LIST_RE.match(ran): info['err'] = 'Error parsing input for the torsion order. It needs to be an integer (such as 5), a range of integers (such as 2-10 or 2..10), or a comma-separated list of these (such as 4,9,16 or 4-25, 81-121).' return search_input_error(info, bread) # Past input check tmp = parse_range2(ran, 'torsion_order') # work around syntax for $or # we have to foil out multiple or conditions if tmp[0] == '$or' and '$or' in query: newors = [] for y in tmp[1]: oldors = [dict.copy(x) for x in query['$or']] for x in oldors: x.update(y) newors.extend(oldors) tmp[1] = newors query[tmp[0]] = tmp[1] if 'torsion_structure' in info and info['torsion_structure']: info['torsion_structure'] = clean_input(info['torsion_structure']) if not TORS_RE.match(info['torsion_structure']): info['err'] = 'Error parsing input for the torsion structure. It needs to be one or more integers in square brackets, such as [6], [2,2], or [2,4]. Moreover, each integer should be bigger than 1, and each divides the next.' return search_input_error(info, bread) query['torsion_structure'] = parse_list(info['torsion_structure']) if 'include_isogenous' in info and info['include_isogenous'] == 'off': query['number'] = 1 if 'include_base_change' in info and info['include_base_change'] == 'off': query['base_change'] = [] else: info['include_base_change'] = "on" if 'field' in info: query['field_label'] = parse_field_string(info['field']) info['query'] = query # process count and start if not default: count_default = 50 if info.get('count'): try: count = int(info['count']) except: count = count_default else: count = count_default start_default = 0 if info.get('start'): try: start = int(info['start']) if(start < 0): start += (1 - (start + 1) / count) * count except: start = start_default else: start = start_default # make the query and trim results according to start/count: cursor = db_ecnf().find(query) nres = cursor.count() if(start >= nres): start -= (1 + (start - nres) / count) * count if(start < 0): start = 0 res = cursor.sort([('field_label', ASC), ('conductor_norm', ASC), ('conductor_label', ASC), ('iso_label', ASC), ('number', ASC)]).skip(start).limit(count) res = list(res) for e in res: e['numb'] = str(e['number']) e['field_knowl'] = nf_display_knowl(e['field_label'], getDBConnection(), e['field_label']) info['curves'] = res # [ECNF(e) for e in res] info['number'] = nres info['start'] = start info['count'] = count info['more'] = int(start + count < nres) info['field_pretty'] = field_pretty info['web_ainvs'] = web_ainvs if nres == 1: info['report'] = 'unique match' else: if nres > count or start != 0: info['report'] = 'displaying matches %s-%s of %s' % (start + 1, min(nres, start + count), nres) else: info['report'] = 'displaying all %s matches' % nres t = 'Elliptic Curve search results' return render_template("ecnf-search-results.html", info=info, credit=ecnf_credit, bread=bread, title=t)
def elliptic_curve_search(**args): info = to_dict(args) query = {} bread = [('Elliptic Curves', url_for("ecnf.index")), ('$\Q$', url_for(".rational_elliptic_curves")), ('Search Results', '.')] if 'SearchAgain' in args: return rational_elliptic_curves() if 'jump' in args: label = info.get('label', '').replace(" ", "") m = match_lmfdb_label(label) if m: try: return by_ec_label(label) except ValueError: return elliptic_curve_jump_error(label, info, wellformed_label=True) elif label.startswith("Cremona:"): label = label[8:] m = match_cremona_label(label) if m: try: return by_ec_label(label) except ValueError: return elliptic_curve_jump_error(label, info, wellformed_label=True) elif match_cremona_label(label): return elliptic_curve_jump_error(label, info, cremona_label=True) elif label: # Try to parse a string like [1,0,3,2,4] as valid # Weistrass coefficients: lab = re.sub(r'\s','',label) lab = re.sub(r'^\[','',lab) lab = re.sub(r']$','',lab) try: labvec = lab.split(',') labvec = [QQ(str(z)) for z in labvec] # Rationals allowed E = EllipticCurve(labvec) # Now we do have a valid curve over Q, but it might # not be in the database. ainvs = [str(c) for c in E.minimal_model().ainvs()] data = db_ec().find_one({'ainvs': ainvs}) if data is None: info['conductor'] = E.conductor() return elliptic_curve_jump_error(label, info, missing_curve=True) return by_ec_label(data['lmfdb_label']) except (TypeError, ValueError, ArithmeticError): return elliptic_curve_jump_error(label, info) else: query['label'] = '' if info.get('jinv'): j = clean_input(info['jinv']) j = j.replace('+', '') if not QQ_RE.match(j): info['err'] = 'Error parsing input for the j-invariant. It needs to be a rational number.' return search_input_error(info, bread) query['jinv'] = str(QQ(j)) # to simplify e.g. 1728/1 for field in ['conductor', 'torsion', 'rank', 'sha']: if info.get(field): info[field] = clean_input(info[field]) ran = info[field] ran = ran.replace('..', '-').replace(' ', '') if not LIST_RE.match(ran): names = {'conductor': 'conductor', 'torsion': 'torsion order', 'rank': 'rank', 'sha': 'analytic order of Ш'} info['err'] = 'Error parsing input for the %s. It needs to be an integer (such as 25), a range of integers (such as 2-10 or 2..10), or a comma-separated list of these (such as 4,9,16 or 4-25, 81-121).' % names[field] return search_input_error(info, bread) # Past input check tmp = parse_range2(ran, field) # work around syntax for $or # we have to foil out multiple or conditions if tmp[0] == '$or' and '$or' in query: newors = [] for y in tmp[1]: oldors = [dict.copy(x) for x in query['$or']] for x in oldors: x.update(y) newors.extend(oldors) tmp[1] = newors query[tmp[0]] = tmp[1] if 'optimal' in info and info['optimal'] == 'on': # fails on 990h3 query['number'] = 1 if 'torsion_structure' in info and info['torsion_structure']: info['torsion_structure'] = clean_input(info['torsion_structure']) if not TORS_RE.match(info['torsion_structure']): info['err'] = 'Error parsing input for the torsion structure. It needs to be one or more integers in square brackets, such as [6], [2,2], or [2,4]. Moreover, each integer should be bigger than 1, and each divides the next.' return search_input_error(info, bread) query['torsion_structure'] = [str(a) for a in parse_list(info['torsion_structure'])] if info.get('surj_primes'): info['surj_primes'] = clean_input(info['surj_primes']) format_ok = LIST_POSINT_RE.match(info['surj_primes']) if format_ok: surj_primes = [int(p) for p in info['surj_primes'].split(',')] format_ok = all([ZZ(p).is_prime(proof=False) for p in surj_primes]) if format_ok: query['non-surjective_primes'] = {"$nin": surj_primes} else: info['err'] = 'Error parsing input for surjective primes. It needs to be a prime (such as 5), or a comma-separated list of primes (such as 2,3,11).' return search_input_error(info, bread) if info.get('nonsurj_primes'): info['nonsurj_primes'] = clean_input(info['nonsurj_primes']) format_ok = LIST_POSINT_RE.match(info['nonsurj_primes']) if format_ok: nonsurj_primes = [int(p) for p in info['nonsurj_primes'].split(',')] format_ok = all([ZZ(p).is_prime(proof=False) for p in nonsurj_primes]) if format_ok: if info['surj_quantifier'] == 'exactly': nonsurj_primes.sort() query['non-surjective_primes'] = nonsurj_primes else: if 'non-surjective_primes' in query: query['non-surjective_primes'] = { "$nin": surj_primes, "$all": nonsurj_primes } else: query['non-surjective_primes'] = { "$all": nonsurj_primes } else: info['err'] = 'Error parsing input for nonsurjective primes. It needs to be a prime (such as 5), or a comma-separated list of primes (such as 2,3,11).' return search_input_error(info, bread) info['query'] = query count_default = 100 if info.get('count'): try: count = int(info['count']) except: count = count_default else: count = count_default info['count'] = count start_default = 0 if info.get('start'): try: start = int(info['start']) if(start < 0): start += (1 - (start + 1) / count) * count except: start = start_default else: start = start_default cursor = db_ec().find(query) nres = cursor.count() if(start >= nres): start -= (1 + (start - nres) / count) * count if(start < 0): start = 0 res = cursor.sort([('conductor', ASCENDING), ('lmfdb_iso', ASCENDING), ('lmfdb_number', ASCENDING) ]).skip(start).limit(count) info['curves'] = res info['format_ainvs'] = format_ainvs info['curve_url'] = lambda dbc: url_for(".by_triple_label", conductor=dbc['conductor'], iso_label=split_lmfdb_label(dbc['lmfdb_iso'])[1], number=dbc['lmfdb_number']) info['iso_url'] = lambda dbc: url_for(".by_double_iso_label", conductor=dbc['conductor'], iso_label=split_lmfdb_label(dbc['lmfdb_iso'])[1]) info['number'] = nres info['start'] = start if nres == 1: info['report'] = 'unique match' elif nres == 2: info['report'] = 'displaying both matches' else: if nres > count or start != 0: info['report'] = 'displaying matches %s-%s of %s' % (start + 1, min(nres, start + count), nres) else: info['report'] = 'displaying all %s matches' % nres credit = 'John Cremona' if 'non-surjective_primes' in query: credit += 'and Andrew Sutherland' t = 'Elliptic Curves search results' return render_template("search_results.html", info=info, credit=credit, bread=bread, title=t)
def elliptic_curve_search(**args): info = to_dict(args) query = {} bread = [('Elliptic Curves', url_for("rational_elliptic_curves")), ('Search Results', '.')] if 'jump' in args: label = info.get('label', '').replace(" ", "") m = lmfdb_label_regex.match(label) if m: try: return by_ec_label(label) except ValueError: return elliptic_curve_jump_error(label, info, wellformed_label=True) elif label.startswith("Cremona:"): label = label[8:] m = cremona_label_regex.match(label) if m: try: return by_ec_label(label) except ValueError: return elliptic_curve_jump_error(label, info, wellformed_label=True) elif cremona_label_regex.match(label): return elliptic_curve_jump_error(label, info, cremona_label=True) elif label: # Try to parse a string like [1,0,3,2,4] lab = re.sub(r'\s','',label) lab = re.sub(r'^\[','',lab) lab = re.sub(r']$','',lab) try: labvec = lab.split(',') labvec = [QQ(str(z)) for z in labvec] # Rationals allowed E = EllipticCurve(labvec) ainvs = [str(c) for c in E.minimal_model().ainvs()] C = lmfdb.base.getDBConnection() data = C.elliptic_curves.curves.find_one({'ainvs': ainvs}) if data is None: return elliptic_curve_jump_error(label, info) return by_ec_label(data['lmfdb_label']) except (ValueError, ArithmeticError): return elliptic_curve_jump_error(label, info) else: query['label'] = '' if info.get('jinv'): j = clean_input(info['jinv']) j = j.replace('+', '') if not QQ_RE.match(j): info['err'] = 'Error parsing input for the j-invariant. It needs to be a rational number.' return search_input_error(info, bread) query['jinv'] = j for field in ['conductor', 'torsion', 'rank', 'sha_an']: if info.get(field): info[field] = clean_input(info[field]) ran = info[field] ran = ran.replace('..', '-').replace(' ', '') if not LIST_RE.match(ran): names = {'conductor': 'conductor', 'torsion': 'torsion order', 'rank': 'rank', 'sha_an': 'analytic order of Ш'} info['err'] = 'Error parsing input for the %s. It needs to be an integer (such as 5), a range of integers (such as 2-10 or 2..10), or a comma-separated list of these (such as 2,3,8 or 3-5, 7, 8-11).' % names[field] return search_input_error(info, bread) # Past input check tmp = parse_range2(ran, field) # work around syntax for $or # we have to foil out multiple or conditions if tmp[0] == '$or' and '$or' in query: newors = [] for y in tmp[1]: oldors = [dict.copy(x) for x in query['$or']] for x in oldors: x.update(y) newors.extend(oldors) tmp[1] = newors if field=='sha_an': # database sha_an values are not all exact! query[tmp[0]] = { '$gt': tmp[1]-0.1, '$lt': tmp[1]+0.1} else: query[tmp[0]] = tmp[1] if 'optimal' in info and info['optimal'] == 'on': # fails on 990h3 query['number'] = 1 if 'torsion_structure' in info and info['torsion_structure']: info['torsion_structure'] = clean_input(info['torsion_structure']) if not TORS_RE.match(info['torsion_structure']): info['err'] = 'Error parsing input for the torsion structure. It needs to be one or more integers in square brackets, such as [6], [2,2], or [2,4]. Moreover, each integer should be bigger than 1, and each divides the next.' return search_input_error(info, bread) query['torsion_structure'] = [str(a) for a in parse_list(info['torsion_structure'])] if info.get('surj_primes'): info['surj_primes'] = clean_input(info['surj_primes']) if LIST_POSINT_RE.match(info['surj_primes']): surj_primes = [int(p) for p in info['surj_primes'].split(',')] query['non-surjective_primes'] = {"$nin": surj_primes} else: info['err'] = 'Error parsing input for surjective primes. It needs to be an integer (such as 5), or a comma-separated list of integers (such as 2,3,11).' return search_input_error(info, bread) if info.get('nonsurj_primes'): info['nonsurj_primes'] = clean_input(info['nonsurj_primes']) if LIST_POSINT_RE.match(info['nonsurj_primes']): nonsurj_primes = [int(p) for p in info['nonsurj_primes'].split(',')] if info['surj_quantifier'] == 'exactly': query['non-surjective_primes'] = nonsurj_primes else: if 'non-surjective_primes' in query: query['non-surjective_primes'] = { "$nin": surj_primes, "$all": nonsurj_primes } else: query['non-surjective_primes'] = { "$all": nonsurj_primes } else: info['err'] = 'Error parsing input for nonsurjective primes. It needs to be an integer (such as 5), or a comma-separated list of integers (such as 2,3,11).' return search_input_error(info, bread) info['query'] = query count_default = 100 if info.get('count'): try: count = int(info['count']) except: count = count_default else: count = count_default info['count'] = count start_default = 0 if info.get('start'): try: start = int(info['start']) if(start < 0): start += (1 - (start + 1) / count) * count except: start = start_default else: start = start_default cursor = lmfdb.base.getDBConnection().elliptic_curves.curves.find(query) nres = cursor.count() if(start >= nres): start -= (1 + (start - nres) / count) * count if(start < 0): start = 0 res = cursor.sort([('conductor', ASCENDING), ('lmfdb_iso', ASCENDING), ('lmfdb_number', ASCENDING) ]).skip(start).limit(count) info['curves'] = res info['format_ainvs'] = format_ainvs info['number'] = nres info['start'] = start if nres == 1: info['report'] = 'unique match' else: if nres > count or start != 0: info['report'] = 'displaying matches %s-%s of %s' % (start + 1, min(nres, start + count), nres) else: info['report'] = 'displaying all %s matches' % nres credit = 'John Cremona' t = 'Elliptic Curves' return render_template("elliptic_curve_search.html", info=info, credit=credit, bread=bread, title=t)
def elliptic_curve_search(**args): info = to_dict(args['data']) if 'jump' in info: label = info.get('label', '').replace(" ", "") # This label should be a full isogeny class label or a full # curve label (including the field_label component) try: nf, cond_label, iso_label, number = split_full_label(label) except IndexError: if not 'query' in info: info['query'] = {} bread = [("Elliptic Curves", url_for(".index"))] info[ 'err'] = 'No elliptic curve in the database has label %s.' % label return search_input_error(info, bread) return show_ecnf(nf, cond_label, iso_label, number) query = {} bread = [('Elliptic Curves', url_for(".index")), ('Search Results', '.')] if 'conductor_norm' in info: Nnorm = clean_input(info['conductor_norm']) Nnorm = Nnorm.replace('..', '-').replace(' ', '') tmp = parse_range2(Nnorm, 'conductor_norm') if tmp[0] == '$or' and '$or' in query: newors = [] for y in tmp[1]: oldors = [dict.copy(x) for x in query['$or']] for x in oldors: x.update(y) newors.extend(oldors) tmp[1] = newors query[tmp[0]] = tmp[1] if 'conductor_label' in info: query['conductor_label'] = info['conductor_label'] if 'jinv' in info: query['jinv'] = info['jinv'] if info.get('torsion'): ran = info['torsion'] = clean_input(info['torsion']) ran = ran.replace('..', '-').replace(' ', '') if not LIST_RE.match(ran): info[ 'err'] = 'Error parsing input for the torsion order. It needs to be an integer (such as 5), a range of integers (such as 2-10 or 2..10), or a comma-separated list of these (such as 4,9,16 or 4-25, 81-121).' return search_input_error(info, bread) # Past input check tmp = parse_range2(ran, 'torsion_order') # work around syntax for $or # we have to foil out multiple or conditions if tmp[0] == '$or' and '$or' in query: newors = [] for y in tmp[1]: oldors = [dict.copy(x) for x in query['$or']] for x in oldors: x.update(y) newors.extend(oldors) tmp[1] = newors query[tmp[0]] = tmp[1] if 'torsion_structure' in info and info['torsion_structure']: info['torsion_structure'] = clean_input(info['torsion_structure']) if not TORS_RE.match(info['torsion_structure']): info[ 'err'] = 'Error parsing input for the torsion structure. It needs to be one or more integers in square brackets, such as [6], [2,2], or [2,4]. Moreover, each integer should be bigger than 1, and each divides the next.' return search_input_error(info, bread) query['torsion_structure'] = parse_list(info['torsion_structure']) if 'include_isogenous' in info and info['include_isogenous'] == 'off': query['number'] = 1 if 'include_base_change' in info and info['include_base_change'] == 'off': query['base_change'] = [] else: info['include_base_change'] = "on" if 'field' in info: query['field_label'] = parse_field_string(info['field']) info['query'] = query # process count and start if not default: count_default = 50 if info.get('count'): try: count = int(info['count']) except: count = count_default else: count = count_default start_default = 0 if info.get('start'): try: start = int(info['start']) if (start < 0): start += (1 - (start + 1) / count) * count except: start = start_default else: start = start_default # make the query and trim results according to start/count: cursor = db_ecnf().find(query) nres = cursor.count() if (start >= nres): start -= (1 + (start - nres) / count) * count if (start < 0): start = 0 res = cursor.sort([('field_label', ASC), ('conductor_norm', ASC), ('conductor_label', ASC), ('iso_label', ASC), ('number', ASC)]).skip(start).limit(count) res = list(res) for e in res: e['numb'] = str(e['number']) e['field_knowl'] = nf_display_knowl(e['field_label'], getDBConnection(), e['field_label']) info['curves'] = res # [ECNF(e) for e in res] info['number'] = nres info['start'] = start info['count'] = count info['more'] = int(start + count < nres) info['field_pretty'] = field_pretty info['web_ainvs'] = web_ainvs if nres == 1: info['report'] = 'unique match' else: if nres > count or start != 0: info['report'] = 'displaying matches %s-%s of %s' % ( start + 1, min(nres, start + count), nres) else: info['report'] = 'displaying all %s matches' % nres t = 'Elliptic Curve search results' return render_template("ecnf-search-results.html", info=info, credit=ecnf_credit, bread=bread, title=t)
def hgm_search(**args): info = to_dict(args) bread = get_bread([("Search results", url_for('.search'))]) C = base.getDBConnection() query = {} if 'jump_to' in info: return render_hgm_webpage({'label': info['jump_to']}) family_search = False if info.get('Submit Family') or info.get('family'): family_search = True # generic, irreducible not in DB yet for param in ['A', 'B', 'hodge', 'a2', 'b2', 'a3', 'b3', 'a5', 'b5', 'a7', 'b7']: if info.get(param): info[param] = clean_input(info[param]) if IF_RE.match(info[param]): query[param] = parse_list(info[param]) query[param].sort() else: name = param if field == 'hodge': name = 'Hodge vector' info['err'] = 'Error parsing input for %s. It needs to be a list of integers in square brackets, such as [2,3] or [1,1,1]' % name return search_input_error(info, bread) if info.get('t') and not family_search: info['t'] = clean_input(info['t']) try: tsage = QQ(str(info['t'])) tlist = [int(tsage.numerator()), int(tsage.denominator())] query['t'] = tlist except: info['err'] = 'Error parsing input for t. It needs to be a rational number, such as 2/3 or -3' # sign can only be 1, -1, +1 if info.get('sign') and not family_search: sign = info['sign'] sign = re.sub(r'\s','',sign) sign = clean_input(sign) if sign == '+1': sign = '1' if not (sign == '1' or sign == '-1'): info['err'] = 'Error parsing input %s for sign. It needs to be 1 or -1' % sign return search_input_error(info, bread) query['sign'] = int(sign) for param in ['degree','weight','conductor']: # We don't look at conductor in family searches if info.get(param) and not (param=='conductor' and family_search): if param=='conductor': cond = info['conductor'] try: cond = re.sub(r'(\d)\s+(\d)', r'\1 * \2', cond) # implicit multiplication of numbers cond = cond.replace(r'..', r'-') # all ranges use - cond = re.sub(r'[a..zA..Z]', '', cond) cond = clean_input(cond) tmp = parse_range2(cond, 'cond', myZZ) except: info['err'] = 'Error parsing input for conductor. It needs to be an integer (e.g., 8), a range of integers (e.g. 10-100), or a list of such (e.g., 5,7,8,10-100). Integers may be given in factored form (e.g. 2^5 3^2) %s' % cond return search_input_error(info, bread) else: # not conductor info[param] = clean_input(info[param]) ran = info[param] ran = ran.replace(r'..', r'-') if LIST_RE.match(ran): tmp = parse_range2(ran, param) else: names = {'weight': 'weight', 'degree': 'degree'} info['err'] = 'Error parsing input for the %s. It needs to be an integer (such as 5), a range of integers (such as 2-10 or 2..10), or a comma-separated list of these (such as 2,3,8 or 3-5, 7, 8-11).' % names[param] return search_input_error(info, bread) # work around syntax for $or # we have to foil out multiple or conditions if tmp[0] == '$or' and '$or' in query: newors = [] for y in tmp[1]: oldors = [dict.copy(x) for x in query['$or']] for x in oldors: x.update(y) newors.extend(oldors) tmp[1] = newors query[tmp[0]] = tmp[1] #print query count_default = 20 if info.get('count'): try: count = int(info['count']) except: count = count_default else: count = count_default info['count'] = count start_default = 0 if info.get('start'): try: start = int(info['start']) if(start < 0): start += (1 - (start + 1) / count) * count except: start = start_default else: start = start_default if info.get('paging'): try: paging = int(info['paging']) if paging == 0: start = 0 except: pass # logger.debug(query) if family_search: res = C.hgm.families.find(query).sort([('label', pymongo.ASCENDING)]) else: res = C.hgm.motives.find(query).sort([('cond', pymongo.ASCENDING), ('label', pymongo.ASCENDING)]) nres = res.count() res = res.skip(start).limit(count) if(start >= nres): start -= (1 + (start - nres) / count) * count if(start < 0): start = 0 info['motives'] = res info['number'] = nres info['start'] = start if nres == 1: info['report'] = 'unique match' else: if nres > count or start != 0: info['report'] = 'displaying matches %s-%s of %s' % (start + 1, min(nres, start + count), nres) else: info['report'] = 'displaying all %s matches' % nres info['make_label'] = make_abt_label info['make_t_label'] = make_t_label info['ab_label'] = ab_label info['display_t'] = display_t info['family'] = family_search info['factorint'] = factorint if family_search: return render_template("hgm-search.html", info=info, title="Hypergeometric Family over $\Q$ Search Result", bread=bread, credit=HGM_credit) else: return render_template("hgm-search.html", info=info, title="Hypergeometric Motive over $\Q$ Search Result", bread=bread, credit=HGM_credit)