def search_by_label(label): """ search for Sato-Tate group by label and render if found """ if re.match(ST_LABEL_RE, label): return render_by_label(label) if re.match(ST_LABEL_SHORT_RE, label): return redirect(url_for('.by_label',label=label+'a'),301) # check for labels of the form 0.1.n corresponding to mu(n) if re.match(MU_LABEL_RE, label): return render_by_label(label) # check for labels of the form w.2.1.dn corresponding to N(U(1)) x mu(n) if re.match(NU1_MU_LABEL_RE, label): return render_by_label(label) # check for labels of the form w.2.3.cn corresponding to SU(2) x mu(n) if re.match(SU2_MU_LABEL_RE, label): return render_by_label(label) # check for labels of the form 0.1.mu(n) (redirecto to 0.1.n) if re.match(MU_LABEL_NAME_RE, label): return redirect(url_for('.by_label',label='0.1.'+label.split('(')[1].split(')')[0]), 301) # check for general labels of the form w.d.name if re.match(ST_LABEL_NAME_RE,label): slabel = label.split('.') try: label = db.gps_sato_tate.lucky({'weight':int(slabel[0]),'degree':int(slabel[1]),'name':slabel[2]}, 0) except ValueError: label = None if label is None: flash_error("%s is not the label or name of a Sato-Tate group currently in the database", label) return redirect(url_for(".index")) else: return redirect(url_for('.by_label', label=label), 301)
def higher_genus_w_automorphisms_search(info, query): if info.get('signature'): #allow for ; in signature info['signature'] = info['signature'].replace(';',',') parse_bracketed_posints(info,query,'signature',split=False,name='Signature',keepbrackets=True) if query.get('signature'): query['signature'] = info['signature'] = str(sort_sign(ast.literal_eval(query['signature']))).replace(' ','') parse_gap_id(info,query,'group',name='Group',qfield='group') parse_ints(info,query,'genus',name='Genus') parse_ints(info,query,'dim',name='Dimension of the family') if 'inc_hyper' in info: if info['inc_hyper'] == 'exclude': query['hyperelliptic'] = False elif info['inc_hyper'] == 'only': query['hyperelliptic'] = True if 'inc_cyc_trig' in info: if info['inc_cyc_trig'] == 'exclude': query['cyclic_trigonal'] = False elif info['inc_cyc_trig'] == 'only': query['cyclic_trigonal'] = True if 'inc_full' in info: if info['inc_full'] == 'exclude': query['full_auto'] = {'$exists': True} elif info['inc_full'] == 'only': query['full_auto'] = {'$exists': False} query['cc.1'] = 1 if info.get('groupsize'): err, result = add_group_order_range(query, info['groupsize']) if err is not None: flash_error('Parse error on group order field. <font face="Courier New"><br />Given: ' + err + '<br />-------' + result + '</font>') info['group_display'] = sg_pretty info['sign_display'] = sign_display
def search_by_label(label): """ search for Sato-Tate group by label and render if found """ if re.match(ST_LABEL_RE, label): return render_by_label(label) if re.match(ST_LABEL_SHORT_RE, label): return redirect(url_for('.by_label',label=label+'a'),301) # check for labels of the form 0.1.n corresponding to mu(n) if re.match(MU_LABEL_RE, label): return render_by_label(label) # check for labels of the form 0.1.mu(n) (redirecto to 0.1.n) if re.match(MU_LABEL_NAME_RE, label): return redirect(url_for('.by_label',label='0.1.'+label.split('(')[1].split(')')[0]), 301) # check for general labels of the form w.d.name data = {} if re.match(ST_LABEL_NAME_RE,label): slabel = label.split('.') try: data = st_groups().find_one({'weight':int(slabel[0]),'degree':int(slabel[1]),'name':slabel[2]},{'_id':False,'label':True}) except ValueError: data = {} if not data: flash_error("%s is not the label or name of a Sato-Tate group currently in the database", label) return redirect(url_for(".index")) else: return redirect(url_for('.by_label', label=data['label']), 301)
def download_multiple_traces(self, info, spaces=False): lang = info.get(self.lang_key,'text').strip() query = literal_eval(info.get('query', '{}')) if spaces: count = db.mf_newspaces.count(query) else: count = db.mf_newforms.count(query) limit = 1000 if count > limit: msg = "We limit downloads of traces to %d forms" % limit flash_error(msg) return redirect(url_for('.index')) if spaces: res = list(db.mf_newspaces.search(query, projection=['label', 'traces'])) else: res = list(db.mf_newforms.search(query, projection=['label', 'traces'])) s = "" c = self.comment_prefix[lang] s += c + ' Query "%s" returned %d %s.\n\n' % (str(info.get('query')), len(res), 'spaces' if spaces else 'forms') s += c + ' Below are two lists, one called labels, and one called traces (in matching order).\n' s += c + ' Each list of traces starts with a_1 (giving the dimension).\n\n' s += 'labels ' + self.assignment_defn[lang] + self.start_and_end[lang][0] + '\\\n' s += ',\n'.join(rec['label'] for rec in res) s += self.start_and_end[lang][1] + '\n\n' s += 'traces ' + self.assignment_defn[lang] + self.start_and_end[lang][0] + '\\\n' s += ',\n'.join('[' + ', '.join(str(t) for t in rec['traces']) for rec in res) s += self.start_and_end[lang][1] return self._wrap(s, 'mf_newforms_traces', lang=lang)
def rational_elliptic_curves(err_args=None): if err_args is None: if len(request.args) != 0: return elliptic_curve_search(request.args) else: err_args = {} for field in ['conductor', 'jinv', 'torsion', 'rank', 'sha', 'optimal', 'torsion_structure', 'msg']: err_args[field] = '' err_args['count'] = '50' counts = get_stats().counts() conductor_list_endpoints = [1, 100, 1000, 10000, 100000, counts['max_N'] + 1] conductor_list = ["%s-%s" % (start, end - 1) for start, end in zip(conductor_list_endpoints[:-1], conductor_list_endpoints[1:])] rank_list = range(counts['max_rank'] + 1) torsion_list = range(1,11) + [12, 16] info = { 'rank_list': rank_list, 'torsion_list': torsion_list, 'conductor_list': conductor_list, 'counts': counts, 'stats_url': url_for(".statistics") } t = 'Elliptic Curves over $\Q$' bread = [('Elliptic Curves', url_for("ecnf.index")), ('$\Q$', ' ')] if err_args.get("err_msg"): flash_error(err_args.pop("err_msg"),err_args.pop("label")) return redirect(url_for(".rational_elliptic_curves")) return render_template("ec-index.html", info=info, credit=ec_credit(), title=t, bread=bread, learnmore=learnmore_list(), calling_function = "ec.rational_elliptic_curves", **err_args)
def artin_representation_jump(info): label = info['natural'] try: label = parse_artin_label(label) except ValueError as err: flash_error("%s" % (err),label) return redirect(url_for(".index")) return redirect(url_for(".render_artin_representation_webpage", label=label), 307)
def hgm_jump(info): label = clean_input(info['jump_to']) if HGM_LABEL_RE.match(label): return render_hgm_webpage(normalize_motive(label)) if HGM_FAMILY_LABEL_RE.match(label): return render_hgm_family_webpage(normalize_family(label)) flash_error('%s is not a valid label for a hypergeometric motive or family of hypergeometric motives', label) return redirect(url_for(".index"))
def higher_genus_w_automorphisms_jump(info): labs = info['jump_to'] if label_is_one_passport(labs): return render_passport({'passport_label': labs}) elif label_is_one_family(labs): return render_family({'label': labs}) else: flash_error ("The label %s is not a legitimate label for this data.",labs) return redirect(url_for(".index"))
def half_integral_weight_form_search(info, query): parse_ints(info, query, 'weight') parse_ints(info, query, 'level') if info.get('character','').strip(): if re.match('^\d+.\d+$', info['character'].strip()): query['character'] = info['character'].strip() else: flash_error("%s is not a valid Dirichlet character label, it should be of the form q.n", info['character']) raise ValueError
def by_label(label): try: nflabel = nf_string_to_label(clean_input(label)) if label != nflabel: return redirect(url_for(".by_label", label=nflabel), 301) return render_field_webpage({'label': nflabel}) except ValueError as err: flash_error("<span style='color:black'>%s</span> us not a valid input for a <span style='color:black'>label</span>. "+ str(err), label) return redirect(url_for(".number_field_render_webpage"))
def by_label(label): if label_is_one_passport(label): return render_passport({'passport_label': label}) elif label_is_one_family(label): return render_family({'label': label}) else: flash_error( "No family with label %s was found in the database.", label) return redirect(url_for(".index"))
def belyi_jump(info): jump = info["jump"].strip() if re.match(r'^\d+T\d+-\[\d+,\d+,\d+\]-\d+-\d+-\d+-g\d+-[a-z]+$', jump): return redirect(url_for_belyi_galmap_label(jump), 301) else: if re.match(r'^\d+T\d+-\[\d+,\d+,\d+\]-\d+-\d+-\d+-g\d+$', jump): return redirect(url_for_belyi_passport_label(jump), 301) else: errmsg = "%s is not a valid Belyi map or passport label" flash_error (errmsg, jump) return redirect(url_for(".index"))
def __call__(self, info): info = to_dict(info) # I'm not sure why this is required... for key, func in self.shortcuts.items(): if info.get(key,'').strip(): return func(info) query = {} template_kwds = {} for key in self.kwds: template_kwds[key] = info.get(key, self.kwds[key]()) try: errpage = self.f(info, query) except ValueError as err: # Errors raised in parsing info['err'] = str(err) err_title = query.pop('__err_title__', self.err_title) return render_template(self.template, info=info, title=err_title, **template_kwds) if errpage is not None: return errpage if 'result_count' in info: nres = self.table.count(query) return jsonify({"nres":str(nres)}) sort = query.pop('__sort__', None) table = query.pop('__table__', self.table) proj = query.pop('__projection__', self.projection) # We want to pop __title__ even if overridden by info. title = query.pop('__title__', self.title) title = info.get('title', title) template = query.pop('__template__', self.template) count = parse_count(info, self.per_page) start = parse_start(info) try: res = table.search(query, proj, limit=count, offset=start, sort=sort, info=info) except QueryCanceledError as err: ctx = ctx_proc_userdata() flash_error('The search query took longer than expected! Please help us improve by reporting this error <a href="%s" target=_blank>here</a>.' % ctx['feedbackpage']) info['err'] = str(err) info['query'] = dict(query) return render_template(self.template, info=info, title=self.err_title, **template_kwds) else: if self.cleaners: for v in res: for name, func in self.cleaners.items(): v[name] = func(v) if self.postprocess is not None: res = self.postprocess(res, info, query) for key, func in self.longcuts.items(): if info.get(key,'').strip(): return func(res, info, query) info['results'] = res return render_template(template, info=info, title=title, **template_kwds)
def half_integral_weight_form_search(**args): C = getDBConnection() C.halfintegralmf.forms.ensure_index([('level', 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_hiwf_webpage(**args) query = {} try: parse_ints(info, query, 'weight') parse_ints(info, query, 'level') if info.get('character','').strip(): if re.match('^\d+.\d+$', info['character'].strip()): query['character'] = info['character'].strip() else: flash_error("%s is not a valid Dirichlet character label, it should be of the form q.n", info['character']) except: return redirect(url_for(".half_integral_weight_form_render_webpage")) info['query'] = dict(query) res = C.halfintegralmf.forms.find(query).sort([('level', pymongo.ASCENDING), ('label', pymongo.ASCENDING)]) nres = res.count() count = 100 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['level'] = v['level'] v_clean['label'] = v['label'] v_clean['weight'] = v['weight'] v_clean['ch_lab']= v['character'].replace('.','/') v_clean['char']= "\chi_{"+v['character'].split(".")[0]+"}("+v['character'].split(".")[1]+",\cdot)" v_clean['dimension'] = v['dim'] res_clean.append(v_clean) info['forms'] = res_clean t = 'Half Integral Weight Cusp Forms search results' bread = [('Half Integral Weight Cusp Forms', url_for(".half_integral_weight_form_render_webpage")),('Search Results', ' ')] properties = [] return render_template("half_integral_weight_form_search.html", info=info, title=t, properties=properties, bread=bread)
def by_label(label): bread = [("Modular Forms", url_for('mf.modular_form_main_page')), ('Siegel modular forms', url_for('.index'))] slabel = label.split('.') family = get_smf_family (slabel[0]) if family: if len(slabel) == 1: return render_family_page(family, request.args, bread) if len(slabel) == 2: sam = sample.Samples({ 'collection': slabel[0], 'name': slabel[1]}) if len(sam) > 0: bread.append(('$'+family.latex_name+'$', url_for('.by_label',label=slabel[0]))) return render_sample_page(family, sam[0], request.args, bread) flash_error ("No siegel modular form data for %s was found in the database.", label) return redirect(url_for(".index"))
def genus2_jump(info): jump = info["jump"].strip() if re.match(r'^\d+\.[a-z]+\.\d+\.\d+$',jump): return redirect(url_for_curve_label(jump), 301) else: if re.match(r'^\d+\.[a-z]+$', jump): return redirect(url_for_isogeny_class_label(jump), 301) else: # Handle direct Lhash input if re.match(r'^\#\d+$',jump) and ZZ(jump[1:]) < 2**61: c = db.g2c_curves.lucky({'Lhash': jump[1:].strip()}, projection="class") if c: return redirect(url_for_isogeny_class_label(c), 301) else: errmsg = "hash %s not found" else: errmsg = "%s is not a valid genus 2 curve or isogeny class label" flash_error (errmsg, jump) return redirect(url_for(".index"))
def render_Dirichletwebpage(modulus=None, number=None): if modulus is None: return render_DirichletNavigation() modulus = modulus.replace(' ','') if number is None and re.match('^[1-9][0-9]*\.([1-9][0-9]*|[a-z]+)$', modulus): modulus, number = modulus.split('.') return redirect(url_for(".render_Dirichletwebpage", modulus=modulus, number=number), 301) args={} args['type'] = 'Dirichlet' args['modulus'] = modulus args['number'] = number try: modulus = int(modulus) except ValueError: modulus = 0 if modulus <= 0: flash_error ("%s is not a valid modulus for a Dirichlet character. It should be a positive integer.", args['modulus']) return redirect(url_for(".render_Dirichletwebpage")) if modulus > 10**20: flash_error ("specified modulus %s is too large, it should be less than $10^{20}$.", modulus) return redirect(url_for(".render_Dirichletwebpage")) if number is None: if modulus < 10000: info = WebDBDirichletGroup(**args).to_dict() info['show_orbit_label'] = True elif modulus < 100000: info = WebDirichletGroup(**args).to_dict() else: info = WebSmallDirichletGroup(**args).to_dict() info['title'] = 'Group of Dirichlet Characters of Modulus ' + str(modulus) info['bread'] = [('Characters', url_for(".render_characterNavigation")), ('Dirichlet', url_for(".render_Dirichletwebpage")), ('%d'%modulus, url_for(".render_Dirichletwebpage", modulus=modulus))] info['learnmore'] = learn() info['code'] = dict([(k[4:],info[k]) for k in info if k[0:4] == "code"]) info['code']['show'] = { lang:'' for lang in info['codelangs'] } # use default show names if 'gens' in info: info['generators'] = ', '.join([r'<a href="%s">$\chi_{%s}(%s,\cdot)$'%(url_for(".render_Dirichletwebpage",modulus=modulus,number=g),modulus,g) for g in info['gens']]) return render_template('CharGroup.html', **info) number = label_to_number(modulus, number) if number == 0: flash_error("the value %s is invalid. It should be a positive integer coprime to and no greater than the modulus %s.", args['number'],args['modulus']) return redirect(url_for(".render_Dirichletwebpage")) args['number'] = number webchar = make_webchar(args) info = webchar.to_dict() info['bread'] = [('Characters', url_for(".render_characterNavigation")), ('Dirichlet', url_for(".render_Dirichletwebpage")), ('%s'%modulus, url_for(".render_Dirichletwebpage", modulus=modulus)), ('%s'%number, url_for(".render_Dirichletwebpage", modulus=modulus, number=number)) ] info['learnmore'] = learn() info['code'] = dict([(k[4:],info[k]) for k in info if k[0:4] == "code"]) info['code']['show'] = { lang:'' for lang in info['codelangs'] } # use default show names return render_template('Character.html', **info)
def rational_elliptic_curves(err_args=None): if err_args is None: if request.args: return elliptic_curve_search(request.args) else: err_args = {} for field in ['conductor', 'jinv', 'torsion', 'rank', 'sha', 'optimal', 'torsion_structure', 'msg']: err_args[field] = '' err_args['count'] = '50' counts = get_stats().counts() conductor_list_endpoints = [1, 100, 1000, 10000, 100000, counts['max_N'] + 1] conductor_list = ["%s-%s" % (start, end - 1) for start, end in zip(conductor_list_endpoints[:-1], conductor_list_endpoints[1:])] rank_list = list(range(counts['max_rank'] + 1)) torsion_list = list(range(1, 11)) + [12, 16] info = { 'rank_list': rank_list, 'torsion_list': torsion_list, 'conductor_list': conductor_list, 'counts': counts, 'stats_url': url_for(".statistics") } t = r'Elliptic Curves over $\Q$' bread = [('Elliptic Curves', url_for("ecnf.index")), (r'$\Q$', ' ')] if err_args.get("err_msg"): # this comes from elliptic_curve_jump_error flash_error(err_args.pop("err_msg"), err_args.pop("label")) return redirect(url_for(".rational_elliptic_curves")) return render_template("ec-index.html", info=info, credit=ec_credit(), title=t, bread=bread, learnmore=learnmore_list(), calling_function="ec.rational_elliptic_curves", **err_args)
def by_url_belyi_search_url(smthorlabel): split = smthorlabel.split("-") # strip out the last field if empty if split[-1] == "": split = split[:-1] if len(split) == 1: return by_url_belyi_search_group(group=split[0]) elif len(split) == 2: # passport sigma_spl = (split[1]).split('_') return redirect( url_for( ".by_url_belyi_passport_label", group=split[0], sigma0=sigma_spl[0], sigma1=sigma_spl[1], sigmaoo=sigma_spl[2], ), 301, ) elif len(split) == 3: # galmap sigma_spl = (split[1]).split('_') return redirect( url_for( ".by_url_belyi_galmap_label", group=split[0], abc=split[1], sigma0=sigma_spl[0], sigma1=sigma_spl[1], sigmaoo=sigma_spl[2], letnum=split[2], ), 301, ) else: # It could be an old label flash_error("%s is not a valid label for a Belyi map", smthorlabel) return redirect(url_for(".index"))
def search_by_label(label): """ search for Sato-Tate group by label and render if found """ if re.match(ST_LABEL_RE, label): return render_by_label(label) if re.match(ST_LABEL_SHORT_RE, label): return redirect(url_for('.by_label',label=label+'a'),301) if re.match(ST_OLD_LABEL_RE, label): return render_by_label(convert_label(label)) if re.match(ST_OLD_LABEL_SHORT_RE, label): return redirect(url_for('.by_label',label=convert_label(label)+'a'),301) # check for labels of the form 0.1.n corresponding to mu(n) if re.match(MU_LABEL_RE, label): return render_by_label(label) # check for labels of the form w.2.B.dn corresponding to N(U(1)) x mu(n) if re.match(NU1_MU_LABEL_RE, label): return render_by_label(convert_label(label)) # check for labels of the form w.2.A.cn corresponding to SU(2) x mu(n) if re.match(SU2_MU_LABEL_RE, label): return render_by_label(convert_label(label)) # check for labels of the form 0.1.mu(n) (redirecto to 0.1.n) if re.match(MU_LABEL_NAME_RE, label): return redirect(url_for('.by_label',label='0.1.'+label.split('(')[1].split(')')[0]), 301) # check for general labels of the form w.d.name if re.match(ST_LABEL_NAME_RE,label): slabel = label.split('.') rlabel = db.gps_st.lucky({'weight':int(slabel[0]),'degree':int(slabel[1]),'name':slabel[2]}, "label") if not rlabel: flash_error("%s is not the label or name of a Sato-Tate group currently in the database", label) return redirect(url_for(".index")) return redirect(url_for('.by_label', label=rlabel), 301) # check for a straight up name rlabel = db.gps_st.lucky({'name':label}, "label") if not rlabel: flash_error("%s is not the label or name of a Sato-Tate group currently in the database", label) return redirect(url_for(".index")) return redirect(url_for('.by_label', label=rlabel), 301)
def abelian_varieties_by_gqi(g, q, iso): label = abvar_label(g, q, iso) try: validate_label(label) except ValueError as err: flash_error("%s is not a valid label: %s.", label, str(err)) return search_input_error() try: cl = AbvarFq_isoclass.by_label(label) except ValueError as err: flash_error("%s is not in the database.", label) return search_input_error() bread = get_bread((str(g), url_for(".abelian_varieties_by_g", g=g)), (str(q), url_for(".abelian_varieties_by_gq", g=g, q=q)), (iso, url_for(".abelian_varieties_by_gqi", g=g, q=q, iso=iso))) return render_template("show-abvarfq.html", properties2=cl.properties(), credit=abvarfq_credit, title='Abelian Variety Isogeny Class %s over $%s$'%(label, cl.field()), bread=bread, cl=cl, learnmore=learnmore_list(), KNOWL_ID='av.fq.%s'%label)
def abelian_varieties_by_gqi(g, q, iso): label = abvar_label(g, q, iso) try: validate_label(label) except ValueError as err: flash_error("%s is not a valid label: %s.", label, str(err)) return search_input_error() try: cl = AbvarFq_isoclass.by_label(label) except ValueError: return abort(404, "Isogeny class %s is not in the database." % label) bread = get_bread( (str(g), url_for(".abelian_varieties_by_g", g=g)), (str(q), url_for(".abelian_varieties_by_gq", g=g, q=q)), (iso, url_for(".abelian_varieties_by_gqi", g=g, q=q, iso=iso)) ) downloads = [ ('All stored data to text', url_for('.download_all', label=label)) ] if hasattr(cl, "curves") and cl.curves: downloads.append(('Curves to text', url_for('.download_curves', label=label))) downloads.append(("Underlying data", url_for('.AV_data', label=label))) return render_template( "show-abvarfq.html", properties=cl.properties(), friends=cl.friends(), downloads=downloads, title='Abelian variety isogeny class %s over $%s$'%(label, cl.field()), bread=bread, cl=cl, learnmore=learnmore_list(), KNOWL_ID='av.fq.%s'%label )
def allowed_id(ID): if ID.endswith('comment'): main_knowl = ".".join(ID.split(".")[:-2]) return knowldb.knowl_exists(main_knowl) if ID.endswith('top') or ID.endswith('bottom'): if ID.startswith('belyi'): extras = "[],T" elif ID.startswith('hgm'): extras = "AB" elif ID.startswith('ec'): extras = "CM" elif ID.startswith('gg'): extras = "T" else: extras = "" for c in extras: ID = ID.replace(c, '') if not allowed_knowl_id.match(ID): flash_error( """Oops, knowl id '%s' is not allowed. It must consist of lowercase characters, no spaces, numbers or '.', '_' and '-'.""", ID) return False return True
def show_seminar(shortname): # We need organizers to be able to see seminars with display=False seminar = seminars_lucky({"shortname": shortname}, prequery={}) if seminar is None: return abort(404, "Seminar not found") if not seminar.visible(): # There may be a non-API version of the seminar that can be shown seminar = seminars_lucky({"shortname": shortname}) if seminar is None or not seminar.visible(): flash_error("You do not have permission to view %s", seminar.name) return redirect(url_for("search_seminars"), 302) talks = seminar.talks(projection=3) now = get_now() future = [] past = [] for talk in talks: if talk.end_time >= now: future.append(talk) else: past.append(talk) future.sort(key=lambda talk: talk.start_time) past.sort(key=lambda talk: talk.start_time, reverse=True) if current_user.email in seminar.editors() or current_user.is_subject_admin(seminar): section = "Manage" else: section = None return render_template( "seminar.html", title="View series", future=future, past=past, seminar=seminar, section=section, subsection="view", bread=None, )
def show_talk(seminar_id, talkid): token = request.args.get( "token", "") # save the token so user can toggle between view and edit talk = talks_lucky({ "seminar_id": seminar_id, "seminar_ctr": talkid }, include_pending=True) if talk is None: return abort(404, "Talk not found") if not talk.visible(): # There may be a non-API version of the seminar that can be shown talk = talks_lucky({"seminar_id": seminar_id, "seminar_ctr": talkid}) if talk is None or not talk.visible(): flash_error("You do not have permission to view %s/%s", seminar_id, talkid) return redirect(url_for("seminar_series_index")) kwds = dict(title="View talk", talk=talk, seminar=talk.seminar, subsection="viewtalk", token=token) if token: kwds["section"] = "Manage" # Also want to override top menu from seminars.utils import top_menu menu = top_menu() menu[1] = (url_for("create.index"), "", "Manage") kwds["top_menu"] = menu elif (current_user.is_subject_admin(talk) or current_user.email_confirmed and (current_user.email in talk.seminar.editors() or current_user.email == talk.speaker_email)): kwds["section"] = "Manage" return render_template("talk.html", **kwds)
def register_for_talk(seminar_id, talkid): from flask import flash talk = talks_lucky({"seminar_id": seminar_id, "seminar_ctr": talkid}) if talk is None: return abort(404, "Talk not found") # If registration isn't required just send them to the talk page # where the user will see an appropriate livestream link if talk.access_control != 4: return redirect(url_for('show_talk',seminar_id=seminar_id,talkid=talkid)) if current_user.is_anonymous: return redirect(url_for("user.info", next=url_for("register_for_talk", seminar_id=seminar_id, talkid=talkid))) if not current_user.email_confirmed: flash_error("You need to confirm your email before you can register.") return redirect(url_for('show_talk',seminar_id=seminar_id,talkid=talkid)) if not talk.live_link: return abort(404, "Livestream link for talk not found") if talk.register_user(): flash("You have been registered, enjoy the talk!") else: flash("Previous registration confirmed, enjoy the talk!") if talk.is_starting_soon(): return redirect(talk.live_link) else: return redirect(url_for('show_talk',seminar_id=seminar_id,talkid=talkid))
def parse_date(info, query): tz = current_user.tz date = info.get("daterange") if date: sub_query = {} if "-" not in date: # make it into a range date = date + "-" + date start, end = date.split("-") if start.strip(): try: start = tz.localize(parse(start)) except Exception: flash_error("Could not parse date: %s", start) sub_query["$gte"] = start if end.strip(): try: end = tz.localize(parse(end)) except Exception: flash_error("Could not parse date: %s", end) end = end + timedelta(hours=23, minutes=59, seconds=59) sub_query["$lte"] = end if sub_query: query["start_time"] = sub_query
def build_dimension_table(info, fam, args): try: dim_args = dimensions.parse_dim_args(args, fam.dim_args_default) except ValueError: # error message is flashed in parse_dim_args info['error'] = True if not info.get('error'): info['dim_args'] = dim_args kwargs={} try: for arg in fam.dimension_desc()['args']: if (arg == 'wt_range' or arg == 'k_range') and 'k_range' in dim_args: kwargs[arg] = dim_args['k_range'] elif (arg == 'wt' or arg == 'k') and 'k_range' in dim_args: if len(dim_args['k_range']) != 1: raise NotImplementedError("Please specify a single value of <span style='color:black'>$k$</span> rather than a range of values.") kwargs[arg] = dim_args['k_range'][0] elif arg == 'j_range' and 'j_range' in dim_args: kwargs[arg] = dim_args['j_range'] elif arg == 'j' and 'j_range' in dim_args: if len(dim_args['j_range']) != 1: raise NotImplementedError("Please specify a single value of <span style='color:black'>$j$</span> rather than a range of values.") kwargs[arg] = dim_args['j_range'][0] except NotImplementedError as err: flash_error(err) info['error'] = True if not info.get('error'): info['kwargs'] = kwargs try: headers, table = fam.dimension(**kwargs) info['headers'] = headers info['table'] = table except (ValueError, NotImplementedError) as err: flash_error(err) info['error'] = True return
def parse_daterange(info, query, time=True): tz = current_user.tz date = info.get("daterange") if date: sub_query = {} if "-" not in date: # make it into a range date = date + "-" + date start, end = date.split("-") if start.strip(): try: start = tz.localize(parse(start)) sub_query["$gte"] = start if time else start.date() except Exception as e: flash_error("Could not parse start date %s. Error: " + str(e), start) if end.strip(): try: end = tz.localize(parse(end)) end = end + timedelta(hours=23, minutes=59, seconds=59) sub_query["$lte"] = end if time else end.date() except Exception as e: flash_error("Could not parse end date %s. Error: " + str(e), end) if sub_query: query["start_time" if time else "start_date"] = sub_query
def register(): if request.method == "POST": email = request.form["email"] pw1 = request.form["password1"] pw2 = request.form["password2"] try: email = validate_email(email)['email'] except EmailNotValidError as e: flash_error("""Oops, email '%s' is not allowed. %s""", email, str(e)) return make_response( render_template("register.html", title="Register", email=email)) if pw1 != pw2: flash_error("Oops, passwords do not match!") return make_response( render_template("register.html", title="Register", email=email)) if len(pw1) < 8: flash_error( "Oops, password too short. Minimum 8 characters, please!") return make_response( render_template("register.html", title="Register", email=email)) password = pw1 if userdb.user_exists(email=email): flash_error("The email address '%s' is already registered!", email) return make_response( render_template("register.html", title="Register", email=email)) newuser = userdb.new_user( email=email, password=password, ) send_confirmation_email(email) login_user(newuser, remember=True) flask.flash(Markup("Hello! Congratulations, you are a new user!")) logger.info("new user: '******' - '%s'" % (newuser.get_id(), newuser.email)) return redirect(url_for(".info")) return render_template("register.html", title="Register", email="")
def can_edit_talk(seminar_id, seminar_ctr, token): """ INPUT: - ``seminar_id`` -- the identifier of the seminar - ``seminar_ctr`` -- an integer as a string, or the empty string (for new talk) - ``token`` -- a string (allows editing by speaker who might not have account) OUTPUT: - ``resp`` -- a response to return to the user (indicating an error) or None (editing allowed) - ``seminar`` -- a WebSeminar object, as returned by ``seminars_lookup(seminar_id)`` - ``talk`` -- a WebTalk object, as returned by ``talks_lookup(seminar_id, seminar_ctr)``, or ``None`` (if error or talk does not exist) """ new = not seminar_ctr if seminar_ctr: try: seminar_ctr = int(seminar_ctr) except ValueError: flash_error("Invalid talk id") return redirect(url_for("show_seminar", shortname=seminar_id), 301), None, None if token and seminar_ctr != "": talk = talks_lookup(seminar_id, seminar_ctr) if talk is None: flash_error("Talk does not exist") return redirect(url_for("show_seminar", shortname=seminar_id), 301), None, None elif token != talk.token: flash_error("Invalid token for editing talk") return redirect(url_for("show_talk", semid=seminar_id, talkid=seminar_ctr), 301), None, None seminar = seminars_lookup(seminar_id) else: resp, seminar = can_edit_seminar(seminar_id, new=False) if resp is not None: return resp, None, None if seminar.new: # TODO: This is where you might insert the ability to create a talk without first making a seminar flash_error("You must first create the seminar %s" % seminar_id) return redirect(url_for("edit_seminar", shortname=seminar_id), 301) if new: talk = WebTalk(seminar_id, seminar=seminar, editing=True) else: talk = WebTalk(seminar_id, seminar_ctr, seminar=seminar) return None, seminar, talk
def show_ecnf_isoclass(nf, conductor_label, class_label): if not FIELD_RE.fullmatch(nf): flash_error("%s is not a valid number field label", nf) return redirect(url_for(".index")) conductor_label = unquote(conductor_label) conductor_label = convert_IQF_label(nf, conductor_label) try: nf_label, nf_pretty = get_nf_info(nf) except ValueError: flash_error("%s is not a valid number field label", nf_label) return redirect(url_for(".index")) label = "-".join([nf_label, conductor_label, class_label]) if not CLASS_LABEL_RE.fullmatch(label): flash_error("%s is not a valid elliptic curve isogeny class label", label) return redirect(url_for(".index")) full_class_label = "-".join([conductor_label, class_label]) cl = ECNF_isoclass.by_label(label) if not isinstance(cl, ECNF_isoclass): flash_error( "There is no elliptic curve isogeny class with label %s in the database", label) return redirect(url_for(".index")) bread = [("Elliptic curves", url_for(".index"))] title = "Elliptic curve isogeny class %s over number field %s" % ( full_class_label, cl.field_name) bread.append((nf_pretty, url_for(".show_ecnf1", nf=nf))) bread.append((conductor_label, url_for(".show_ecnf_conductor", nf=nf_label, conductor_label=conductor_label))) bread.append((class_label, url_for(".show_ecnf_isoclass", nf=nf_label, conductor_label=quote(conductor_label), class_label=class_label))) return render_template("ecnf-isoclass.html", credit=ecnf_credit, title=title, bread=bread, cl=cl, properties=cl.properties, friends=cl.friends, learnmore=learnmore_list())
def render_by_label(label): """ render html page for Sato-Tate group sepecified by label """ if re.match(MU_LABEL_RE, label): n = ZZ(label.split('.')[2]) if n > 10**20: flash_error("number of components %s is too large, it should be less than 10^{20}$.", n) return redirect(url_for(".index")) return render_st_group(mu_info(n), portrait=mu_portrait(n)) data = st_groups().find_one({'label': label}) info = {} if data is None: flash_error ("%s is not the label of a Sato-Tate group currently in the database.", label) return redirect(url_for(".index")) for attr in ['label','weight','degree','name','pretty','real_dimension','components']: info[attr] = data[attr] info['ambient'] = st_ambient(info['weight'],info['degree']) info['connected']=boolean_name(info['components'] == 1) info['rational']=boolean_name(info.get('rational',True)) st0 = st0_groups().find_one({'name':data['identity_component']}) if not st0: flash_error ("%s is not the label of a Sato-Tate identity component currently in the database.", data['identity_component']) return redirect(url_for(".index")) info['st0_name']=st0['pretty'] info['st0_description']=st0['description'] G = small_groups().find_one({'label':data['component_group']}) if not G: flash_error ("%s is not the label of a Sato-Tate component group currently in the database.", data['component_group']) return redirect(url_for(".index")) info['component_group']=G['pretty'] info['cyclic']=boolean_name(G['cyclic']) info['abelian']=boolean_name(G['abelian']) info['solvable']=boolean_name(G['solvable']) info['gens']=comma_separated_list([string_matrix(m) for m in data['gens']]) info['numgens']=len(info['gens']) info['subgroups'] = comma_separated_list([st_link(sub) for sub in data['subgroups']]) info['supgroups'] = comma_separated_list([st_link(sup) for sup in data['supgroups']]) if data['moments']: info['moments'] = [['x'] + [ '\\mathrm{E}[x^{%d}]'%m for m in range(len(data['moments'][0])-1)]] info['moments'] += data['moments'] if data['counts']: c=data['counts'] info['probabilities'] = [['\\mathrm{P}[%s=%d]=\\frac{%d}{%d}'%(c[i][0],c[i][1][j][0],c[i][1][j][1],data['components']) for j in range(len(c[i][1]))] for i in range(len(c))] return render_st_group(info, portrait=data.get('trace_histogram'))
def endorse_wtoken(token): try: # tokens last forever endoser, email, phd = read_timed_token(token, 'endorser', None) except Exception: flash_error('The link is invalid or has expired.') if current_user.creator: flash_error('Account already has creator privileges.') elif current_user.email != email: flash_error('The link is not valid for this account.') elif not current_user.email_confirmed: flash_error('You must confirm your email first.') else: user.endorser = int(endorser) user.creator = True user.phd = bool(phd) user.save() flask.flash('You can now create seminars. Thanks!', 'success') return redirect(url_for('.info'))
def register_token(token): if not userdb._rw_userdb: flask.abort(401, "no attempt to create user, not enough privileges"); userdb.delete_old_tokens() if not userdb.token_exists(token): flask.abort(401) bread = base_bread() + [('Register', url_for(".register_new"))] if request.method == "GET": return render_template("register.html", title="Register", bread=bread, next=request.referrer or "/", token=token) elif request.method == 'POST': name = request.form['name'] if not allowed_usernames.match(name): flash_error("""Oops, usename '%s' is not allowed. It must consist of lower/uppercase characters, no spaces, numbers or '.', '_' and '-'.""", name) return flask.redirect(url_for(".register_new")) pw1 = request.form['password1'] pw2 = request.form['password2'] if pw1 != pw2: flash_error("Oops, passwords do not match!") return flask.redirect(url_for(".register_new")) if len(pw1) < 8: flash_error("Oops, password too short. Minimum 8 characters please!") return flask.redirect(url_for(".register_new")) full_name = request.form['full_name'] #next = request.form["next"] if userdb.user_exists(name): flash_error("Sorry, user ID '%s' already exists!", name) return flask.redirect(url_for(".register_new")) newuser = userdb.new_user(name, pwd=pw1, full_name=full_name) userdb.delete_token(token) #newuser.full_name = full_name #newuser.save() login_user(newuser, remember=True) flask.flash(Markup("Hello %s! Congratulations, you are a new user!" % newuser.name)) logger.debug("removed login token '%s'" % token) logger.info("new user: '******' - '%s'" % (newuser.get_id(), newuser.name)) return flask.redirect(url_for(".info"))
def show_ecnf(nf, conductor_label, class_label, number): if not FIELD_RE.fullmatch(nf): return abort(404) conductor_label = unquote(conductor_label) conductor_label = convert_IQF_label(nf, conductor_label) try: nf_label = nf_string_to_label(nf) except ValueError: flash_error("%s is not a valid number field label", nf_label) return redirect(url_for(".index")) label = "".join( ["-".join([nf_label, conductor_label, class_label]), str(number)]) if not LABEL_RE.fullmatch(label): flash_error("%s is not a valid elliptic curve label", label) return redirect(url_for(".index")) ec = ECNF.by_label(label) if not isinstance(ec, ECNF): flash_error("There is no elliptic curve with label %s in the database", label) return redirect(url_for(".index")) bread = [("Elliptic curves", url_for(".index"))] title = "Elliptic curve %s over number field %s" % ( ec.short_label, ec.field.field_pretty()) bread = [("Elliptic curves", url_for(".index"))] bread.append((ec.field.field_pretty(), ec.urls['field'])) bread.append((ec.conductor_label, ec.urls['conductor'])) bread.append((ec.iso_label, ec.urls['class'])) bread.append((ec.number, ec.urls['curve'])) code = ec.code() code['show'] = { 'magma': '', 'pari': '', 'sage': '' } # use default show names info = {} return render_template( "ecnf-curve.html", credit=ecnf_credit, title=title, bread=bread, ec=ec, code=code, # properties = ec.properties, properties=ec.properties, friends=ec.friends, downloads=ec.downloads, info=info, KNOWL_ID="ec.%s" % label, learnmore=learnmore_list())
def jump(info): jump_box = info["jump"].strip() # only called when this present try: validate_label(jump_box) except ValueError: # Also accept polynomials try: poly = coeff_to_poly(jump_box) cdict = poly.dict() deg = poly.degree() if deg % 2 == 1: raise ValueError except Exception: flash_error( "%s is not valid input. Expected a label or Weil polynomial.", jump_box) return redirect(url_for(".abelian_varieties")) g = deg // 2 lead = cdict[deg] if lead == 1: # accept monic normalization lead = cdict[0] cdict = {deg - exp: coeff for (exp, coeff) in cdict.items()} if cdict.get(0) != 1: flash_error( "%s is not valid input. Polynomial must have constant or leading coefficient 1", jump_box) return redirect(url_for(".abelian_varieties")) try: q = lead.nth_root(g) if not ZZ(q).is_prime_power(): raise ValueError for i in range(1, g): if cdict.get(2 * g - i, 0) != q**(g - i) * cdict.get(i, 0): raise ValueError except ValueError: flash_error( "%s is not valid input. Expected a label or Weil polynomial.", jump_box) return redirect(url_for(".abelian_varieties")) def extended_code(c): if c < 0: return 'a' + cremona_letter_code(-c) return cremona_letter_code(c) jump_box = "%s.%s.%s" % (g, q, "_".join( extended_code(cdict.get(i, 0)) for i in range(1, g + 1))) return by_label(jump_box)
def confirm_email(token): try: # the users have 24h to confirm their email email = read_timed_token(token, "confirm email", 86400) except Exception: flash_error("The confirmation link is invalid or has expired.") else: if current_user.email.lower() != email.lower(): flash_error("The link is not valid for this account.") elif current_user.email_confirmed: flash_error("Email already confirmed.") else: current_user.email_confirmed = True current_user.save() flask.flash("You have confirmed your email. Thanks!", "success") return redirect(url_for(".info"))
def download_ECNF_all(nf,conductor_label,class_label,number): conductor_label = unquote(conductor_label) try: nf_label = nf_string_to_label(nf) except ValueError: flash_error("%s is not a valid number field label", nf_label) return redirect(url_for(".index")) label = "".join(["-".join([nf_label, conductor_label, class_label]), number]) if not LABEL_RE.fullmatch(label): flash_error("%s is not a valid elliptic curve label.", label) return redirect(url_for(".index")) data = db.ec_nfcurves.lookup(label) if data is None: flash_error("%s is not the label of an elliptic curve in the database.", label) return redirect(url_for(".index")) response = make_response(Json.dumps(data)) response.headers['Content-type'] = 'text/plain' return response
def permdelete_seminar(shortname): seminar = seminars_lookup(shortname, include_deleted=True) if seminar is None: flash_error("Series %s already deleted permanently", shortname) return redirect(url_for(".index"), 302) if not current_user.is_subject_admin( seminar) and seminar.owner != current_user: flash_error("You do not have permission to delete seminar %s", shortname) return redirect(url_for(".index"), 302) if not seminar.deleted: flash_error("You must delete seminar %s first", shortname) return redirect(url_for(".edit_seminar", shortname=shortname), 302) else: db.seminars.delete({"shortname": shortname}) db.talks.delete({"seminar_id": shortname}) flash("Series %s permanently deleted" % shortname) return redirect(url_for(".index"), 302)
def permdelete_talk(semid, semctr): talk = talks_lookup(semid, semctr, include_deleted=True) if talk is None: flash_error("Talk %s/%s already deleted permanently", semid, semctr) return redirect(url_for(".edit_seminar_schedule", shortname=semid), 302) if not current_user.is_subject_admin( talk) and talk.seminar.owner != current_user: flash_error("You do not have permission to delete this seminar") return redirect(url_for(".index"), 302) if not talk.deleted: flash_error("You must delete talk %s/%s first", semid, semctr) return redirect( url_for(".edit_talk", seminar_id=semid, seminar_ctr=semctr), 302) else: db.talks.delete({"seminar_id": semid, "seminar_ctr": semctr}) flash("Talk %s/%s permanently deleted" % (semid, semctr)) return redirect(url_for(".edit_seminar_schedule", shortname=semid), 302)
def change_password(): email = current_user.email pw_old = request.form["oldpwd"] if not current_user.check_password(pw_old): flash_error("Ooops, old password is wrong!") return redirect(url_for(".info")) pw1 = request.form["password1"] pw2 = request.form["password2"] if pw1 != pw2: flash_error("Oops, new passwords do not match!") return redirect(url_for(".info")) if len(pw1) < 8: flash_error("Oops, password too short. Minimum 8 characters please!") return redirect(url_for(".info")) userdb.change_password(email, pw1) flask.flash(Markup("Your password has been changed.")) return redirect(url_for(".info"))
def revive_seminar(shortname): seminar = seminars_lookup(shortname, include_deleted=True) if seminar is None: flash_error("Series %s was deleted permanently", shortname) return redirect(url_for(".index"), 302) if not current_user.is_subject_admin( seminar) and seminar.owner != current_user: flash_error("You do not have permission to revive seminar %s", shortname) return redirect(url_for(".index"), 302) if not seminar.deleted: flash_error("Series %s was not deleted, so cannot be revived", shortname) else: db.seminars.update({"shortname": shortname}, {"deleted": False}) db.talks.update({"seminar_id": shortname}, {"deleted": False}) flash( "Series %s revived. You should reset the organizers, and note that any users that were subscribed no longer are." % shortname) return redirect(url_for(".edit_seminar", shortname=shortname), 302)
def render_dimension_table_page(args, bread): fams = get_smf_families() fam_list = [c for c in fams if c.computes_dimensions() and not c.name in ["Sp4Z","Sp4Z_2"]] # Sp4Z and Sp4Z_2 are sub-families of Sp4Z_j info = { 'family_list': fam_list, 'args': to_dict(args) } family = get_smf_family(args.get('family')) if not family: flash_error("Space %s not found in databsae", args.get('family')) elif not family.computes_dimensions(): flash_error("Dimension table not available for family %s.", args.get('family')) else: info['family'] = family if 'j' in family.latex_name: # if j is not specified (but could be) set it to zero for consistency (overrides defaults in json files) if not 'j' in info['args'] or not info['args']['j']: info['args']['j'] = '0' if not 'j' in family.latex_name and 'j' in info['args'] and info['args']['j'] != '0': flash_error("$j$ = %s should not be specified for the selected space %s", info['args']['j'], '$'+family.latex_name+'$') else: build_dimension_table (info, family, info['args']) bread.append(('dimensions', 'dimensions')) return render_template("ModularForm_GSp4_Q_dimensions.html", title='Siegel modular forms dimension tables', bread=bread, info=info)
def render_dimension_table_page(args, bread): fams = get_smf_families() fam_list = [c for c in fams if c.computes_dimensions() and not c.name in ["Sp4Z","Sp4Z_2"]] # Sp4Z and Sp4Z_2 are sub-families of Sp4Z_j info = { 'family_list': fam_list, 'args': to_dict(args) } family = get_smf_family(args.get('family')) if not family: flash_error("Space %s not found in databsae", args.get('family')) elif not family.computes_dimensions(): flash_error("Dimension table not available for family %s.", args.get('family')) else: info['family'] = family if 'j' in family.latex_name: # if j is not specified (but could be) set it to zero for consistency (overrides defaults in json files) if not 'j' in info['args'] or not info['args']['j']: info['args']['j'] = '0' if not 'j' in family.latex_name and 'j' in info['args'] and info['args']['j'] != '0': flash_error("$j$ = %s should not be specified for the selected space %s", info['args']['j'], '$'+family.latex_name+'$') else: build_dimension_table (info, family, info['args']) bread.append(('Dimensions', 'dimensions')) return render_template("ModularForm_GSp4_Q_dimensions.html", title='Siegel modular forms dimension tables', bread=bread, info=info)
def render_hecke_algebras_webpage_l_adic(**args): data = None if 'orbit_label' in args and 'prime' in args: lab = clean_input(args.get('orbit_label')) if lab != args.get('orbit_label'): base_lab = ".".join([split(lab)[i] for i in [0, 1, 2]]) return redirect( url_for('.render_hecke_algebras_webpage', label=base_lab), 301) try: ell = int(args.get('prime')) except ValueError: base_lab = ".".join([split(lab)[i] for i in [0, 1, 2]]) return redirect( url_for('.render_hecke_algebras_webpage', label=base_lab), 301) data = db.hecke_ladic.lucky({'orbit_label': lab, 'ell': ell}) if data is None: t = "Hecke algebra search error" bread = [('HeckeAlgebra', url_for(".hecke_algebras_render_webpage"))] flash_error( "%s is not a valid label for the ℓ-adic information for an Hecke algebra orbit in the database.", lab) return render_template("hecke_algebras-error.html", title=t, properties=[], bread=bread, learnmore=learnmore_list()) info = {} info.update(data) proj = [ 'index', 'orbit_label', 'ell', 'idempotent', 'field', 'structure', 'properties', 'operators' ] res = list( db.hecke_ladic.search( { 'level': data['level'], 'weight': data['weight'], 'orbit_label': data['orbit_label'], 'ell': data['ell'] }, proj)) for f in res: if f['idempotent'] != "": dim = len(sage_eval(f['idempotent'])) l_max = sage_eval(f['idempotent'])[0][0].ndigits() if dim > 4 or l_max > 5: f['idempotent_display'] = [] elif dim == 1: f['idempotent_display'] = sage_eval(f['idempotent'])[0][0] else: f['idempotent_display'] = latex( matrix(sage_eval(f['idempotent']))) else: f['idempotent_display'] = latex(matrix([[1]])) del f['idempotent'] f['download_id'] = [ (i, url_for(".render_hecke_algebras_webpage_ell_download", orbit_label=f['orbit_label'], index=f['index'], prime=f['ell'], lang=i, obj='idempotents')) for i in ['magma', 'sage'] ] # for 'gp' the code does not work, since p-adics are not implemented field = f.pop('field') if field is not None: f['deg'] = field[1] f['field_poly'] = field[2] structure = f.pop('structure') if structure is not None: f['dim'] = structure[0] f['num_gen'] = structure[1] s2 = sage_eval(structure[2]) f['gens'] = [[int(s2.index(i) + 1), str(i)] for i in s2] f['rel'] = sage_eval(structure[3]) properties = f.pop('properties') if properties is not None: f['grading'] = properties[0] f['gorenstein_def'] = properties[1] f['gorenstein'] = "yes" if properties[1] == 0 else "no" operators = f.pop('operators') if operators is not None: f['operators_mod_l'] = operators f['num_hecke_op'] = len(operators) f['size_op'] = size = sqrt(len(operators[0])) if size > 4: f['operators_mod_l_display'] = [] elif size == 1: f['operators_mod_l_display'] = [[i + 1, operators[i][0]] for i in range(10)] else: f['operators_mod_l_display'] = [[ i + 1, latex(matrix(size, size, operators[i])) ] for i in range(5)] f['download_op'] = [ (lang, url_for(".render_hecke_algebras_webpage_ell_download", orbit_label=f['orbit_label'], index=f['index'], prime=f['ell'], lang=lang, obj='operators')) for lang in ['magma', 'sage'] ] # for 'gp' the code does not work info['num_l_adic_orbits'] = len(res) info['l_adic_orbits'] = res info['level'] = int(data['level']) info['weight'] = int(data['weight']) info['base_lab'] = ".".join( [split(data['orbit_label'])[i] for i in [0, 1, 2]]) info['orbit_label'] = str(data['orbit_label']) info['ell'] = int(data['ell']) bread = [('HeckeAlgebra', url_for(".hecke_algebras_render_webpage")), ('%s' % info['base_lab'], url_for('.render_hecke_algebras_webpage', label=info['base_lab'])), ('%s' % info['ell'], ' ')] credit = hecke_algebras_credit info['properties'] = [('Level', '%s' % info['level']), ('Weight', '%s' % info['weight']), ('Characteristic', '%s' % info['ell']), ('Orbit label', '%s' % info['orbit_label'])] info['friends'] = [('Modular form ' + info['base_lab'], url_for("cmf.by_url_space_label", level=info['level'], weight=info['weight'], char_orbit_label='a'))] t = "%s-adic and mod %s data for the Hecke algebra orbit %s" % ( info['ell'], info['ell'], info['orbit_label']) return render_template("hecke_algebras_l_adic-single.html", info=info, credit=credit, title=t, bread=bread, properties=info['properties'], learnmore=learnmore_list(), friends=info['friends'], KNOWL_ID='hecke_algebra_l_adic.%s' % (info['orbit_label']))
def render_hmf_webpage(**args): if 'data' in args: data = args['data'] label = data['label'] else: label = str(args['label']) data = get_hmf(label) if data is None: flash_error( "%s is not a valid Hilbert modular form label. It must be of the form (number field label) - (level label) - (orbit label) separated by dashes, such as 2.2.5.1-31.1-a", args['label']) return search_input_error() info = {} try: info['count'] = args['count'] except KeyError: info['count'] = 50 hmf_field = get_hmf_field(data['field_label']) gen_name = findvar(hmf_field['ideals']) nf = WebNumberField(data['field_label'], gen_name=gen_name) info['hmf_field'] = hmf_field info['field'] = nf info['base_galois_group'] = nf.galois_string() info['field_degree'] = nf.degree() info['field_disc'] = str(nf.disc()) info['field_poly'] = teXify_pol(str(nf.poly())) info.update(data) info['downloads'] = [('Modular form to Magma', url_for(".render_hmf_webpage_download", field_label=info['field_label'], label=info['label'], download_type='magma')), ('Eigenvalues to Sage', url_for(".render_hmf_webpage_download", field_label=info['field_label'], label=info['label'], download_type='sage'))] # figure out friends # first try to see if there is an instance of this HMF on Lfun db url = 'ModularForm/GL2/TotallyReal/{}/holomorphic/{}'.format( info['field_label'], info['label']) Lfun = get_lfunction_by_url(url) if Lfun: instances = get_instances_by_Lhash_and_trace_hash( Lfun['Lhash'], Lfun['degree'], Lfun['trace_hash']) # This will also add the EC/G2C, as this how the Lfun was computed info['friends'] = names_and_urls(instances, exclude={url}) info['friends'] += [('L-function', url_for("l_functions.l_function_hmf_page", field=info['field_label'], label=info['label'], character='0', number='0'))] else: # if there is no instance # old code if hmf_field['narrow_class_no'] == 1 and nf.disc( )**2 * data['level_norm'] < 40000: info['friends'] = [('L-function', url_for("l_functions.l_function_hmf_page", field=info['field_label'], label=info['label'], character='0', number='0'))] else: info['friends'] = [('L-function not available', "")] if data['dimension'] == 1: # Try to attach associated elliptic curve lab = split_class_label(info['label']) ec_from_hmf = db.ec_nfcurves.lookup(label + '1') if ec_from_hmf is None: info['friends'] += [('Elliptic curve not available', "")] else: info['friends'] += [('Isogeny class ' + info['label'], url_for("ecnf.show_ecnf_isoclass", nf=lab[0], conductor_label=lab[1], class_label=lab[2]))] bread = [("Modular Forms", url_for('modular_forms')), ('Hilbert Modular Forms', url_for(".hilbert_modular_form_render_webpage")), ('%s' % data['label'], ' ')] t = "Hilbert Cusp Form %s" % info['label'] forms_dims = db.hmf_forms.search( { 'field_label': data['field_label'], 'level_ideal': data['level_ideal'] }, projection='dimension') info['newspace_dimension'] = sum(forms_dims) # Get hecke_polynomial, hecke_eigenvalues and AL_eigenvalues try: numeigs = request.args['numeigs'] numeigs = int(numeigs) except: numeigs = 20 info['numeigs'] = numeigs hecke_pol = data['hecke_polynomial'] eigs = map(str, data['hecke_eigenvalues']) eigs = eigs[:min(len(eigs), numeigs)] AL_eigs = data['AL_eigenvalues'] primes = hmf_field['primes'] n = min(len(eigs), len(primes)) info['eigs'] = [{ 'eigenvalue': add_space_if_positive(teXify_pol(eigs[i])), 'prime_ideal': teXify_pol(primes[i]), 'prime_norm': primes[i][1:primes[i].index(',')] } for i in range(n)] try: display_eigs = request.args['display_eigs'] if display_eigs in ['True', 'true', '1', 'yes']: display_eigs = True else: display_eigs = False except KeyError: display_eigs = False if 'numeigs' in request.args: display_eigs = True info['hecke_polynomial'] = "\(" + teXify_pol(hecke_pol) + "\)" if not AL_eigs: # empty list if data['level_norm'] == 1: # OK, no bad primes info['AL_eigs'] = 'none' else: # not OK, AL eigs are missing info['AL_eigs'] = 'missing' else: info['AL_eigs'] = [{ 'eigenvalue': teXify_pol(al[1]), 'prime_ideal': teXify_pol(al[0]), 'prime_norm': al[0][1:al[0].index(',')] } for al in data['AL_eigenvalues']] max_eig_len = max([len(eig['eigenvalue']) for eig in info['eigs']]) display_eigs = display_eigs or (max_eig_len <= 300) info['display_eigs'] = display_eigs if not display_eigs: for eig in info['eigs']: if len(eig['eigenvalue']) > 300: eig['eigenvalue'] = '...' info['level_ideal'] = teXify_pol(info['level_ideal']) if 'is_CM' in data: is_CM = data['is_CM'] else: is_CM = '?' info['is_CM'] = is_CM if 'is_base_change' in data: is_base_change = data['is_base_change'] else: is_base_change = '?' info['is_base_change'] = is_base_change if 'q_expansions' in data: info['q_expansions'] = data['q_expansions'] properties = [('Base field', '%s' % info['field'].field_pretty()), ('Weight', '%s' % data['weight']), ('Level norm', '%s' % data['level_norm']), ('Level', '$' + teXify_pol(data['level_ideal']) + '$'), ('Label', '%s' % data['label']), ('Dimension', '%s' % data['dimension']), ('CM', is_CM), ('Base change', is_base_change)] return render_template("hilbert_modular_form.html", downloads=info["downloads"], info=info, properties=properties, credit=hmf_credit, title=t, bread=bread, friends=info['friends'], learnmore=learnmore_list())
def render_hecke_algebras_webpage(**args): data = None if 'label' in args: lab = clean_input(args.get('label')) if lab != args.get('label'): return redirect( url_for('.render_hecke_algebras_webpage', label=lab), 301) data = db.hecke_algebras.lookup(lab) if data is None: t = "Hecke algebra search error" bread = [('HeckeAlgebra', url_for(".hecke_algebras_render_webpage"))] flash_error( "%s is not a valid label for a Hecke algebra in the database.", lab) return render_template("hecke_algebras-error.html", title=t, properties=[], bread=bread, learnmore=learnmore_list()) info = {} info.update(data) bread = [('HeckeAlgebra', url_for(".hecke_algebras_render_webpage")), ('%s' % data['label'], ' ')] credit = hecke_algebras_credit info['level'] = int(data['level']) info['weight'] = int(data['weight']) info['num_orbits'] = int(data['num_orbits']) dim_count = "not available" proj = [ 'orbit_label', 'hecke_op', 'num_hecke_op', 'Zbasis', 'discriminant', 'disc_fac', 'Qbasis', 'Qalg_gen' ] orb = list(db.hecke_orbits.search({'parent_label': data['label']}, proj)) if orb: #consistency check if len(orb) != int(data['num_orbits']): return search_input_error(info) dim_count = 0 for v in orb: ops = sage_eval(v['hecke_op']) dim = int(matrix(ops[0]).nrows()) dim_count += dim if dim > 4: v['hecke_op_display'] = [] elif dim == 1: v['hecke_op_display'] = [[i + 1, ops[i][0][0]] for i in range(10)] else: v['hecke_op_display'] = [[i + 1, latex(matrix(ops[i]))] for i in range(5)] v['download_op'] = [ (lang, url_for(".render_hecke_algebras_webpage_download", orbit_label=v['orbit_label'], lang=lang, obj='operators')) for lang in ['gp', 'magma', 'sage'] ] if v['Zbasis'] is None: for key in [ 'Zbasis', 'discriminant', 'disc_fac', 'Qbasis', 'Qalg_gen' ]: del v[key] else: v['Zbasis'] = [[int(i) for i in j] for j in v['Zbasis']] v['disc_fac'] = [[int(i) for i in j] for j in v['disc_fac']] if dim > 4: v['gen_display'] = [] elif dim == 1: v['gen_display'] = [v['Zbasis'][0][0]] else: v['gen_display'] = [ latex(matrix(dim, dim, v['Zbasis'][i])) for i in range(dim) ] v['inner_twists'] = "not available" # not yet in the database v['download_gen'] = [ (lang, url_for(".render_hecke_algebras_webpage_download", orbit_label=v['orbit_label'], lang=lang, obj='gen')) for lang in ['gp', 'magma', 'sage'] ] info['orbits'] = orb info['dim_alg'] = dim_count info['l_adic'] = l_range info['properties'] = [('Label', '%s' % info['label']), ('Level', '%s' % info['level']), ('Weight', '%s' % info['weight'])] if info['num_orbits'] != 0: info['friends'] = [('Newforms space ' + info['label'], url_for("cmf.by_url_space_label", level=info['level'], weight=info['weight'], char_orbit_label='a'))] else: info['friends'] = [] t = "Hecke algebra %s" % info['label'] return render_template("hecke_algebras-single.html", info=info, credit=credit, title=t, bread=bread, properties=info['properties'], learnmore=learnmore_list(), friends=info['friends'], KNOWL_ID='hecke_algebra.%s' % (info['label']))
def render_passport(args): info = {} if 'passport_label' in args: label = clean_input(args['passport_label']) dataz = list(db.hgcwa_passports.search({'passport_label': label})) if len(dataz) == 0: bread = get_bread([("Search Error", url_for('.index'))]) flash_error( "No refined passport with label %s was found in the database.", label) return redirect(url_for(".index")) data=dataz[0] g = data['genus'] GG = ast.literal_eval(data['group']) gn = GG[0] gt = GG[1] gp_string=str(gn) + '.' + str(gt) pretty_group=sg_pretty(gp_string) if gp_string == pretty_group: spname=False else: spname=True numb = len(dataz) try: numgenvecs = request.args['numgenvecs'] numgenvecs = int(numgenvecs) except: numgenvecs = 20 info['numgenvecs']=numgenvecs title = 'One Refined Passport of Genus ' + str(g) + ' with Automorphism Group $' + pretty_group +'$' smallgroup="[" + str(gn) + "," +str(gt) +"]" prop2 = [ ('Genus', '\(%d\)' % g), ('Small Group', '\(%s\)' % pretty_group), ('Signature', '\(%s\)' % sign_display(ast.literal_eval(data['signature']))), ('Generating Vectors','\(%d\)' % numb) ] info.update({'genus': data['genus'], 'cc': cc_display(data['con']), 'sign': sign_display(ast.literal_eval(data['signature'])), 'group': pretty_group, 'gpid': smallgroup, 'numb':numb, 'disp_numb':min(numb,numgenvecs) }) if spname: info.update({'specialname': True}) Ldata=[] HypColumn = False Lfriends=[] for i in range (0, min(numgenvecs,numb)): dat= dataz[i] x1=dat['total_label'] if 'full_auto' in dat: x2='No' if dat['full_label'] not in Lfriends: Lfriends.append(dat['full_label']) else: x2='Yes' if 'hyperelliptic' in dat: x3=tfTOyn(dat['hyperelliptic']) HypColumn= True else: x3=' ' x4=[] for perm in dat['gen_vectors']: cycperm=Permutation(perm).cycle_string() x4.append(sep.join(split_perm(cycperm))) Ldata.append([x1,x2,x3,x4]) info.update({'genvects': Ldata, 'HypColumn' : HypColumn}) info.update({'passport_cc': cc_display(ast.literal_eval(data['con']))}) if 'eqn' in data: info.update({'eqns': data['eqn']}) if 'ndim' in data: info.update({'Ndim': data['ndim']}) other_data = False if 'hyperelliptic' in data: info.update({'ishyp': tfTOyn(data['hyperelliptic'])}) other_data = True if 'hyp_involution' in data: inv=Permutation(data['hyp_involution']).cycle_string() info.update({'hypinv': sep.join(split_perm(inv))}) if 'cyclic_trigonal' in data: info.update({'iscyctrig': tfTOyn(data['cyclic_trigonal'])}) other_data = True if 'jacobian_decomp' in data: jcLatex, corrChar = decjac_format(data['jacobian_decomp']) info.update({'corrChar': corrChar, 'jacobian_decomp': jcLatex}) if 'cinv' in data: cinv=Permutation(data['cinv']).cycle_string() info.update({'cinv': sep.join(split_perm(cinv))}) info.update({'other_data': other_data}) if 'full_auto' in data: full_G=ast.literal_eval(data['full_auto']) full_gn = full_G[0] full_gt = full_G[1] full_gp_string=str(full_gn) + '.' + str(full_gt) full_pretty_group=sg_pretty(full_gp_string) info.update({'fullauto': full_pretty_group, 'signH':sign_display(ast.literal_eval(data['signH'])), 'higgenlabel' : data['full_label'] }) urlstrng,br_g, br_gp, br_sign, refined_p = split_passport_label(label) if Lfriends: for Lf in Lfriends: friends = [("Full automorphism " + Lf, Lf),("Family containing this refined passport ", urlstrng) ] else: friends = [("Family containing this refined passport", urlstrng) ] bread_sign = label_to_breadcrumbs(br_sign) bread_gp = label_to_breadcrumbs(br_gp) bread = get_bread([(br_g, './?genus='+br_g),('$'+pretty_group+'$','./?genus='+br_g + '&group='+bread_gp), (bread_sign, urlstrng),(data['cc'][0],' ')]) learnmore =[('Completeness of the data', url_for(".completeness_page")), ('Source of the data', url_for(".how_computed_page")), ('Labeling convention', url_for(".labels_page"))] downloads = [('Download Magma code', url_for(".hgcwa_code_download", label=label, download_type='magma')), ('Download Gap code', url_for(".hgcwa_code_download", label=label, download_type='gap'))] return render_template("hgcwa-show-passport.html", title=title, bread=bread, info=info, properties2=prop2, friends=friends, learnmore=learnmore, downloads=downloads, credit=credit)
def render_family(args): info = {} if 'label' in args: label = clean_input(args['label']) dataz = list(db.hgcwa_passports.search({'label':label})) if len(dataz) == 0: flash_error( "No family with label %s was found in the database.", label) return redirect(url_for(".index")) data=dataz[0] g = data['genus'] GG = ast.literal_eval(data['group']) gn = GG[0] gt = GG[1] gp_string = str(gn) + '.' + str(gt) pretty_group = sg_pretty(gp_string) if gp_string == pretty_group: spname = False else: spname = True title = 'Family of Genus ' + str(g) + ' Curves with Automorphism Group $' + pretty_group +'$' smallgroup="[" + str(gn) + "," +str(gt) + "]" prop2 = [ ('Genus', '\(%d\)' % g), ('Group', '\(%s\)' % pretty_group), ('Signature', '\(%s\)' % sign_display(ast.literal_eval(data['signature']))) ] info.update({'genus': data['genus'], 'sign': sign_display(ast.literal_eval(data['signature'])), 'group': pretty_group, 'g0':data['g0'], 'dim':data['dim'], 'r':data['r'], 'gpid': smallgroup }) if spname: info.update({'specialname': True}) Lcc=[] Lall=[] i=1 for dat in dataz: if ast.literal_eval(dat['con']) not in Lcc: urlstrng=dat['passport_label'] Lcc.append(ast.literal_eval(dat['con'])) Lall.append([cc_display(ast.literal_eval(dat['con'])),dat['passport_label'], urlstrng]) i=i+1 info.update({'passport': Lall}) g2List = ['[2,1]','[4,2]','[8,3]','[10,2]','[12,4]','[24,8]','[48,29]'] if g == 2 and data['group'] in g2List: g2url = "/Genus2Curve/Q/?geom_aut_grp_id=" + data['group'] friends = [("Genus 2 curves over $\Q$", g2url ) ] else: friends = [ ] br_g, br_gp, br_sign = split_family_label(label) bread_sign = label_to_breadcrumbs(br_sign) bread_gp = label_to_breadcrumbs(br_gp) bread = get_bread([(br_g, './?genus='+br_g),('$'+pretty_group+'$','./?genus='+br_g + '&group='+bread_gp), (bread_sign,' ')]) learnmore =[('Completeness of the data', url_for(".completeness_page")), ('Source of the data', url_for(".how_computed_page")), ('Labeling convention', url_for(".labels_page"))] downloads = [('Download Magma code', url_for(".hgcwa_code_download", label=label, download_type='magma')), ('Download Gap code', url_for(".hgcwa_code_download", label=label, download_type='gap'))] return render_template("hgcwa-show-family.html", title=title, bread=bread, info=info, properties2=prop2, friends=friends, learnmore=learnmore, downloads=downloads, credit=credit)
def render_maass_waveforms(level=0, weight=-1, character=-1, r1=0, r2=0, **kwds): info = get_args_mwf(level=level, weight=weight, character=character, r1=r1, r2=r2, **kwds) info["credit"] = "" info["learnmore"] = learnmore_list() mwf_logger.debug("args=%s" % request.args) mwf_logger.debug("method=%s" % request.method) mwf_logger.debug("req.form=%s" % request.form) mwf_logger.debug("info=%s" % info) mwf_logger.debug("level,weight,char={0},{1},{2}".format(level, weight, character)) if info.get('maass_id', None) and info.get('db', None): return render_one_maass_waveform_wp(**info) if info['search'] or (info['browse'] and int(info['weight']) != 0): # This isn't the right place to do input validation, but it is easier to flash errors here (this is a hack to address issue #1820) if info.get('level_range'): if not re.match(POSINT_RE, info['level_range']): if "-" in info['level_range']: info['level_range'] = "..".join(info['level_range'].split("-")) if not re.match(POSINT_RANGE_RE, info['level_range']): flash_error("%s is not a level, please specify a positive integer <span style='color:black'>n</span> or postivie integer range <span style='color:black'>m..n</span>.", info['level_range']) return render_template('mwf_navigate.html', **info) if info['character'] != -1: try: N = int(info.get('level_range','0')) except: flash_error("Character %s cannot be specified in combination with a range of levels.", info['character']) return render_template('mwf_navigate.html', **info) if not re.match(r'^[1-9][0-9]*\.[1-9][0-9]*$', info['character']): flash_error("%s is not a valid label for a Dirichlet character. It should be of the form <span style='color:black'>q.n</span>, where q and n are coprime positive integers with n < q, or q=n=1.", info['character']) return render_template('mwf_navigate.html', **info) s = info['character'].split('.') q,n = int(s[0]), int(s[1]) if n > q or gcd(q,n) != 1 or (N > 0 and q != N): flash_error("%s is not a valid label for a Dirichlet character. It should be of the form <span style='color:black'>q.n</span>, where q and n are coprime positive integers with n < q, or q=n=1.", info['character']) return render_template('mwf_navigate.html', **info) info['level_range'] = str(q) info['character'] = str(n) if info['weight'] != -1: if not re.match(INT_RE, info['weight']): flash_error("%s is not a valid weight. It should be a nonnegative integer.", info['weight']) return render_template('mwf_navigate.html', **info) if info.get('ev_range'): if not re.match(FLOAT_RE,info['ev_range']): if "-" in info['ev_range']: info['ev_range'] = "..".join(info['ev_range'].split("-")) s = info['ev_range'].split("..") if len(s) != 2: flash_error("%s is not a valid eigenvalue range. It should be postive real interval.", info['ev_range']) return render_template('mwf_navigate.html', **info) if not re.match(FLOAT_RE,s[0]) or not re.match(FLOAT_RE,s[1]): flash_error("%s is not a valid eigenvalue range. It should be postive real interval.", info['ev_range']) return render_template('mwf_navigate.html', **info) search = get_search_parameters(info) mwf_logger.debug("search=%s" % search) return render_search_results_wp(info, search) if info['browse']: mwf_logger.debug("browse info=%s" % info) return render_browse_all_eigenvalues(**info) info['cur_character'] = character if level > 0: info['maass_weight'] = maass_db.weights(int(level)) info['cur_level'] = level if weight > -1: info['cur_weight'] = weight if level > 0: info['maass_character'] = maass_db.characters(int(level), float(weight)) if character > - 1: info['cur_character'] = character if level > 0 or weight > -1 or character > -1: search = get_search_parameters(info) mwf_logger.debug("info=%s" % info) mwf_logger.debug("search=%s" % search) return render_search_results_wp(info, search) title = 'Maass Forms' info['list_of_levels'] = maass_db.levels() if info['list_of_levels']: info['max_level'] = max(info['list_of_levels']) else: info['max_level'] = 0 mwf_logger.debug("info3=%s" % info) bread = [('Modular Forms', url_for('mf.modular_form_main_page')), ('Maass Forms', url_for('.render_maass_waveforms'))] info['bread'] = bread info['title'] = title maass_db.set_table() maass_db.table['ncols'] = 10 info['DB'] = maass_db info['dbcount'] = maass_db.count() info['limit'] = maxNumberOfResultsToShow return render_template("mwf_navigate.html", **info)
def higher_genus_w_automorphisms_search(**args): info = to_dict(args) bread = get_bread([("Search Results",'')]) C = base.getDBConnection() query = {} if 'jump_to' in info: labs = info['jump_to'] if label_is_one_passport(labs): return render_passport({'passport_label': labs}) elif label_is_one_family(labs): return render_family({'label': labs}) else: flash_error ("The label %s is not a legitimate label for this data.",labs) return redirect(url_for(".index")) #allow for ; in signature if info.get('signature'): info['signature'] = info['signature'].replace(';',',') try: parse_gap_id(info,query,'group','Group') parse_ints(info,query,'genus',name='Genus') parse_bracketed_posints(info,query,'signature',split=False,name='Signature',keepbrackets=True) if query.get('signature'): query['signature'] = info['signature'] = str(sort_sign(ast.literal_eval(query['signature']))).replace(' ','') parse_ints(info,query,'dim',name='Dimension of the family') if 'inc_hyper' in info: if info['inc_hyper'] == 'exclude': query['hyperelliptic'] = False elif info['inc_hyper'] == 'only': query['hyperelliptic'] = True if 'inc_cyc_trig' in info: if info['inc_cyc_trig'] == 'exclude': query['cyclic_trigonal'] = False elif info['inc_cyc_trig'] == 'only': query['cyclic_trigonal'] = True if 'inc_full' in info: if info['inc_full'] == 'exclude': query['full_auto'] = {'$exists': True} elif info['inc_full'] == 'only': query['full_auto'] = {'$exists': False} query['cc.1'] = 1 except ValueError: return search_input_error(info, bread) count = parse_count(info) start = parse_start(info) if 'groupsize' in info and info['groupsize'] != '': err, result = add_group_order_range(query, info['groupsize'], C) if err != None: flash_error('Parse error on group order field. <font face="Courier New"><br />Given: ' + err + '<br />-------' + result + '</font>') res = C.curve_automorphisms.passports.find(query).sort([( 'genus', pymongo.ASCENDING), ('dim', pymongo.ASCENDING), ('cc'[0],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 L = [ ] for field in res: field['signature'] = ast.literal_eval(field['signature']) L.append(field) if 'download_magma' in info: return hgcwa_code_download_search(L,'magma') #OR RES?????? elif 'download_gap' in info: return hgcwa_code_download_search(L,'gap') #OR L?????? info['fields'] = L info['number'] = nres info['group_display'] = sg_pretty info['show_downloads'] = len(L) > 0 info['sign_display'] = sign_display 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("hgcwa-search.html", info=info, title="Families of Higher Genus Curves with Automorphisms Search Result", credit=credit, bread=bread)
def search(**args): """ query processing for Sato-Tate groups -- returns rendered results page """ info = to_dict(args) if 'jump' in info: return redirect(url_for('.by_label', label=info['jump']), 301) if 'label' in info: return redirect(url_for('.by_label', label=info['label']), 301) template_kwds = {'bread':[('Sato-Tate Groups', url_for('.index')),('Search Results', '.')], 'credit':credit_string, 'learnmore':learnmore_list()} title = 'Sato-Tate Group Search Results' err_title = 'Sato-Tate Groups Search Input Error' count = parse_count(info, 25) start = parse_start(info) # if user clicked refine search always restart at 0 if 'refine' in info: start = 0 ratonly = True if info.get('rational_only','no').strip().lower() == 'yes' else False query = {'rational':True} if ratonly else {} try: parse_ints(info,query,'weight','weight') if 'weight' in query: weight_list = parse_ints_to_list_flash(info.get('weight'),'weight') parse_ints(info,query,'degree','degree') if 'degree' in query: degree_list = parse_ints_to_list_flash(info.get('degree'),'degree') if info.get('identity_component'): query['identity_component'] = info['identity_component'] parse_ints(info,query,'components','components') if 'components' in query: components_list = parse_ints_to_list_flash(info.get('components'), 'components') parse_rational(info,query,'trace_zero_density','trace zero density') except ValueError as err: info['err'] = str(err) return render_template('st_results.html', info=info, title=err_title, **template_kwds) # Check mu(n) groups first (these are not stored in the database) results = [] if (not 'weight' in query or 0 in weight_list) and \ (not 'degree' in query or 1 in degree_list) and \ (not 'identity_component' in query or query['identity_component'] == 'SO(1)') and \ (not 'trace_zero_density' in query or query['trace_zero_density'] == '0'): if not 'components' in query: components_list = xrange(1,3 if ratonly else start+count+1) elif ratonly: components_list = [n for n in range(1,3) if n in components_list] nres = len(components_list) if 'components' in query or ratonly else INFINITY for n in itertools.islice(components_list,start,start+count): results.append(mu_info(n)) else: nres = 0 if 'result_count' in info: nres += db.gps_sato_tate.count(query) return jsonify({"nres":str(nres)}) # Now lookup other (rational) ST groups in database if nres != INFINITY: start2 = start - nres if start > nres else 0 proj = ['label','weight','degree','real_dimension','identity_component','name','pretty','components','component_group','trace_zero_density','moments'] try: res = db.gps_sato_tate.search(query, proj, limit=max(count - len(results), 0), offset=start2, info=info) except QueryCanceledError as err: ctx = ctx_proc_userdata() flash_error('The search query took longer than expected! Please help us improve by reporting this error <a href="%s" target=_blank>here</a>.' % ctx['feedbackpage']) info['err'] = str(err) return render_template('st_results.html', info=info, title=err_title, **template_kwds) info['number'] += nres if start < info['number'] and len(results) < count: for v in res: v['identity_component'] = st0_pretty(v['identity_component']) v['component_group'] = sg_pretty(v['component_group']) v['trace_moments'] = trace_moments(v['moments']) results.append(v) else: info['number'] = 'infinity' info['start'] = start info['count'] = count info['st0_list'] = st0_list info['st0_dict'] = st0_dict info['results'] = results info['stgroup_url'] = lambda dbc: url_for('.by_label', label=dbc['label']) return render_template('st_results.html', info=info, title=title, **template_kwds)
def render_sample_page(family, sam, args, bread): info = { 'args': to_dict(args), 'sam': sam, 'latex': latex, 'type':sam.type(), 'name':sam.name(), 'full_name': sam.full_name(), 'weight':sam.weight(), 'fdeg':sam.degree_of_field(), 'is_eigenform':sam.is_eigenform(), 'field_poly': sam.field_poly()} if sam.is_integral() != None: info['is_integral'] = sam.is_integral() if 'Sp4Z' in sam.collection(): info['space_url'] = url_for('.Sp4Z_j_space', k=info['weight'], j=0) if 'Sp4Z_2' in sam.collection(): info['space_url'] = url_for('.Sp4Z_j_space', k=info['weight'], j=2) info['space'] = '$'+family.latex_name.replace('k', '{' + str(sam.weight()) + '}')+'$' if 'space_url' in info: bread.append((info['space'], info['space_url'])) info['space_href'] = '<a href="%s">%s</d>'%(info['space_url'],info['space']) if 'space_url' in info else info['space'] if info['field_poly'].disc() < 10**10: label = poly_to_field_label(info['field_poly']) if label: info['field_label'] = label info['field_url'] = url_for('number_fields.by_label', label=label) info['field_href'] = '<a href="%s">%s</a>'%(info['field_url'], field_pretty(label)) bread.append((info['name'], '')) title='Siegel modular forms sample ' + info['full_name'] properties = [('Space', info['space_href']), ('Name', info['name']), ('Type', '<br>'.join(info['type'].split(','))), ('Weight', str(info['weight'])), ('Hecke eigenform', str(info['is_eigenform'])), ('Field degree', str(info['fdeg']))] try: evs_to_show = parse_ints_to_list_flash(args.get('ev_index'), 'list of $l$') fcs_to_show = parse_ints_to_list_flash(args.get('fc_det'), 'list of $\\det(F)$') except ValueError: evs_to_show = [] fcs_to_show = [] info['evs_to_show'] = sorted([n for n in (evs_to_show if len(evs_to_show) else sam.available_eigenvalues()[:10])]) info['fcs_to_show'] = sorted([n for n in (fcs_to_show if len(fcs_to_show) else sam.available_Fourier_coefficients()[1:6])]) info['evs_avail'] = [n for n in sam.available_eigenvalues()] info['fcs_avail'] = [n for n in sam.available_Fourier_coefficients()] # Do not attempt to constuct a modulus ideal unless the field has a reasonably small discriminant # otherwise sage may not even be able to factor the discriminant info['field'] = sam.field() if info['field_poly'].disc() < 10**80: null_ideal = sam.field().ring_of_integers().ideal(0) info['modulus'] = null_ideal modulus = args.get('modulus','').strip() m = 0 if modulus: try: O = sam.field().ring_of_integers() m = O.ideal([O(str(b)) for b in modulus.split(',')]) except Exception: info['error'] = True flash_error("Unable to construct modulus ideal from specified generators %s.", modulus) if m == 1: info['error'] = True flash_error("The ideal %s is the unit ideal, please specify a different modulus.", '('+modulus+')') m = 0 info['modulus'] = m # Hack to reduce polynomials and to handle non integral stuff def redc(c): return m.reduce(c*c.denominator())/m.reduce(c.denominator()) def redp(f): c = f.dict() return f.parent()(dict((e,redc(c[e])) for e in c)) def safe_reduce(f): if not m: return latex(f) try: if f in sam.field(): return latex(redc(f)) else: return latex(redp(f)) except ZeroDivisionError: return '\\textrm{Unable to reduce} \\bmod\\mathfrak{m}' info['reduce'] = safe_reduce else: info['reduce'] = latex # check that explicit formula is not ridiculously big if sam.explicit_formula(): info['explicit_formula_bytes'] = len(sam.explicit_formula()) if len(sam.explicit_formula()) < 100000: info['explicit_formula'] = sam.explicit_formula() return render_template("ModularForm_GSp4_Q_sample.html", title=title, bread=bread, properties2=properties, info=info)
def render_DirichletNavigation(): args = to_dict(request.args) info = {'args':args} info['bread'] = [ ('Characters',url_for(".render_characterNavigation")), ('Dirichlet', url_for(".render_Dirichletwebpage")) ] info['learnmore'] = learn() if 'modbrowse' in args: arg = args['modbrowse'] arg = arg.split('-') modulus_start = int(arg[0]) modulus_end = int(arg[1]) info['title'] = 'Dirichlet Characters of Modulus ' + str(modulus_start) + '-' + str(modulus_end) info['credit'] = 'Sage' h, c, rows, cols = ListCharacters.get_character_modulus(modulus_start, modulus_end) info['contents'] = c info['headers'] = h info['rows'] = rows info['cols'] = cols return render_template("ModulusList.html", **info) elif 'condbrowse' in args: arg = args['condbrowse'] arg = arg.split('-') conductor_start = int(arg[0]) conductor_end = int(arg[1]) info['conductor_start'] = conductor_start info['conductor_end'] = conductor_end info['title'] = 'Dirichlet Characters of Conductor ' + str(conductor_start) + '-' + str(conductor_end) info['credit'] = "Sage" info['contents'] = ListCharacters.get_character_conductor(conductor_start, conductor_end + 1) return render_template("ConductorList.html", **info) elif 'ordbrowse' in args: arg = args['ordbrowse'] arg = arg.split('-') order_start = int(arg[0]) order_end = int(arg[1]) info['order_start'] = order_start info['order_end'] = order_end info['title'] = 'Dirichlet Characters of Orders ' + str(order_start) + '-' + str(order_end) info['credit'] = 'SageMath' info['contents'] = ListCharacters.get_character_order(order_start, order_end + 1) return render_template("OrderList.html", **info) elif 'label' in args: label = args['label'].replace(' ','') if re.match(r'^[1-9][0-9]*\.[1-9][0-9]*$', label): slabel = label.split('.') m,n = int(slabel[0]), int(slabel[1]) if m==n==1 or n < m and gcd(m,n) == 1: return redirect(url_for(".render_Dirichletwebpage", modulus=slabel[0], number=slabel[1])) if re.match(r'^[1-9][0-9]*$', label): return redirect(url_for(".render_Dirichletwebpage", modulus=label), 301) flash_error("%s is not a valid label for a Dirichlet character. It should be of the form <span style='color:black'>q.n</span>, where q and n are coprime positive integers with n < q, or q=n=1.", label) return render_template('CharacterNavigate.html', **info) #FIXME, delete line below? #return redirect(url_for(".render_Dirichletwebpage"), 301) if args: # if user clicked refine search, reset start to 0 if args.get('refine'): args['start'] = '0' try: search = ListCharacters.CharacterSearch(args) except ValueError as err: info['err'] = str(err) return render_template("CharacterNavigate.html" if "search" in args else "character_search_results.html" , **info) info['info'] = search.results() info['title'] = 'Dirichlet Character Search Results' info['bread'] = [('Characters', url_for(".render_characterNavigation")), ('Dirichlet', url_for(".render_Dirichletwebpage")), ('Search Results', '') ] info['credit'] = 'SageMath' return render_template("character_search_results.html", **info) else: info['title'] = 'Dirichlet Characters' return render_template('CharacterNavigate.html', **info)
# executing the query "q" and replacing the _id in the result list api_logger.info("API query: q = '%s', fields = '%s', sort = '%s', offset = %s" % (q, fields, sort, offset)) try: data = list(coll.search(q, projection=fields, sort=sort, limit=100, offset=offset)) except QueryCanceledError: flash_error("Query %s exceeded time limit.", q) return flask.redirect(url_for(".api_query", table=table)) except KeyError, err: flash_error("No key %s in table %s", err, table) return flask.redirect(url_for(".api_query", table=table)) if single_object and not data: if format != 'html': flask.abort(404) else: flash_error("no document with id %s found in table %s.", id, table) return flask.redirect(url_for(".api_query", table=table)) # fixup data for display and json/yaml encoding if 'bytea' in coll.col_type.values(): for row in data: for key, val in row.iteritems(): if type(val) == buffer: row[key] = "[binary data]" #data = [ dict([ (key, val if coll.col_type[key] != 'bytea' else "binary data") for key, val in row.iteritems() ]) for row in data] data = Json.prep(data) # preparing the datastructure start = offset next_req = dict(request.args) next_req["_offset"] = offset
def api_query(table, id = None): #if censored_table(table): # return flask.abort(404) # parsing the meta parameters _format and _offset format = request.args.get("_format", "html") offset = int(request.args.get("_offset", 0)) DELIM = request.args.get("_delim", ",") fields = request.args.get("_fields", None) sortby = request.args.get("_sort", None) if fields: fields = ['id'] + fields.split(DELIM) else: fields = 1.1 if sortby: sortby = sortby.split(DELIM) if offset > 10000: if format != "html": flask.abort(404) else: flash_error("offset %s too large, please refine your query.", offset) return flask.redirect(url_for(".api_query", table=table)) # preparing the actual database query q try: coll = getattr(db, table) except AttributeError: if format != "html": flask.abort(404) else: flash_error("table %s does not exist", table) return flask.redirect(url_for(".index")) q = {} # if id is set, just go and get it, ignore query parameeters if id is not None: if offset: return flask.abort(404) single_object = True api_logger.info("API query: id = '%s', fields = '%s'" % (id, fields)) if re.match(r'^\d+$', id): id = int(id) data = coll.lucky({'id':id}, projection=fields) data = [data] if data else [] else: single_object = False for qkey, qval in request.args.iteritems(): from ast import literal_eval try: if qkey.startswith("_"): continue elif qval.startswith("s"): qval = qval[1:] elif qval.startswith("i"): qval = int(qval[1:]) elif qval.startswith("f"): qval = float(qval[1:]) elif qval.startswith("o"): qval = ObjectId(qval[1:]) elif qval.startswith("ls"): # indicator, that it might be a list of strings qval = qval[2].split(DELIM) elif qval.startswith("li"): print qval qval = [int(_) for _ in qval[2:].split(DELIM)] print qval elif qval.startswith("lf"): qval = [float(_) for _ in qval[2:].split(DELIM)] elif qval.startswith("py"): # literal evaluation qval = literal_eval(qval[2:]) elif qval.startswith("cs"): # containing string in list qval = { "$contains" : [qval[2:]] } elif qval.startswith("ci"): qval = { "$contains" : [int(qval[2:])] } elif qval.startswith("cf"): qval = { "contains" : [float(qval[2:])] } elif qval.startswith("cpy"): qval = { "$contains" : [literal_eval(qval[3:])] } except: # no suitable conversion for the value, keep it as string pass # update the query q[qkey] = qval # assure that one of the keys of the query is indexed # however, this doesn't assure that the query will be fast... #if q != {} and len(set(q.keys()).intersection(collection_indexed_keys(coll))) == 0: # flash_error("no key in the query %s is indexed.", q) # return flask.redirect(url_for(".api_query", table=table)) # sort = [('fieldname1', 1 (ascending) or -1 (descending)), ...] if sortby is not None: sort = [] for key in sortby: if key.startswith("-"): sort.append((key[1:], -1)) else: sort.append((key, 1)) else: sort = None # executing the query "q" and replacing the _id in the result list api_logger.info("API query: q = '%s', fields = '%s', sort = '%s', offset = %s" % (q, fields, sort, offset)) try: data = list(coll.search(q, projection=fields, sort=sort, limit=100, offset=offset)) except QueryCanceledError: flash_error("Query %s exceeded time limit.", q) return flask.redirect(url_for(".api_query", table=table)) except KeyError, err: flash_error("No key %s in table %s", err, table) return flask.redirect(url_for(".api_query", table=table))
def genus2_curve_search(info): if 'jump' in info: jump = info["jump"].strip() if re.match(r'^\d+\.[a-z]+\.\d+\.\d+$',jump): return redirect(url_for_curve_label(jump), 301) else: if re.match(r'^\d+\.[a-z]+$', jump): return redirect(url_for_isogeny_class_label(jump), 301) else: # Handle direct Lhash input if re.match(r'^\#\d+$',jump) and ZZ(jump[1:]) < 2**61: c = g2c_db_curves().find_one({'Lhash': jump[1:].strip()}) if c: return redirect(url_for_isogeny_class_label(c["class"]), 301) else: errmsg = "hash %s not found" else: errmsg = "%s is not a valid genus 2 curve or isogeny class label" flash_error (errmsg, jump) return redirect(url_for(".index")) if info.get('download','').strip() == '1': return download_search(info) info["st_group_list"] = st_group_list info["st_group_dict"] = st_group_dict info["real_geom_end_alg_list"] = real_geom_end_alg_list info["real_geom_end_alg_to_ST0_dict"] = real_geom_end_alg_to_ST0_dict info["aut_grp_list"] = aut_grp_list info["aut_grp_dict"] = aut_grp_dict info["geom_aut_grp_list"] = geom_aut_grp_list info["geom_aut_grp_dict"] = geom_aut_grp_dict bread = info.get('bread',(('Genus 2 Curves', url_for(".index")), ('$\Q$', url_for(".index_Q")), ('Search Results', '.'))) query = {} try: parse_ints(info,query,'abs_disc','absolute discriminant') parse_bool(info,query,'is_gl2_type','is of GL2-type') parse_bool(info,query,'has_square_sha','has square Sha') parse_bool(info,query,'locally_solvable','is locally solvable') parse_bool(info,query,'is_simple_geom','is geometrically simple') parse_ints(info,query,'cond','conductor') parse_ints(info,query,'num_rat_wpts','rational Weierstrass points') parse_bracketed_posints(info, query, 'torsion', 'torsion structure', maxlength=4,check_divisibility="increasing") parse_ints(info,query,'torsion_order','torsion order') if 'torsion' in query and not 'torsion_order' in query: query['torsion_order'] = reduce(mul,[int(n) for n in query['torsion']],1) if 'torsion' in query: query['torsion_subgroup'] = str(query['torsion']).replace(" ","") query.pop('torsion') # search using string key, not array of ints parse_ints(info,query,'two_selmer_rank','2-Selmer rank') parse_ints(info,query,'analytic_rank','analytic rank') # G2 invariants and drop-list items don't require parsing -- they are all strings (supplied by us, not the user) if 'g20' in info and 'g21' in info and 'g22' in info: query['g2_inv'] = "['%s','%s','%s']"%(info['g20'], info['g21'], info['g22']) if 'class' in info: query['class'] = info['class'] for fld in ('st_group', 'real_geom_end_alg', 'aut_grp_id', 'geom_aut_grp_id'): if info.get(fld): query[fld] = info[fld] except ValueError as err: info['err'] = str(err) return render_template("g2c_search_results.html", info=info, title='Genus 2 Curves Search Input Error', bread=bread, credit=credit_string) # Database query happens here info["query"] = query # save query for reuse in download_search cursor = g2c_db_curves().find(query, {'_id':False, 'label':True, 'eqn':True, 'st_group':True, 'is_gl2_type':True, 'is_simple_geom':True, 'analytic_rank':True}) count = parse_count(info, 50) start = parse_start(info) nres = cursor.count() if(start >= nres): start -= (1 + (start - nres) / count) * count if(start < 0): start = 0 res = cursor.sort([("cond", ASCENDING), ("class", ASCENDING), ("disc_key", ASCENDING), ("label", ASCENDING)]).skip(start).limit(count) nres = res.count() 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 res_clean = [] for v in res: v_clean = {} v_clean["label"] = v["label"] v_clean["class"] = class_from_curve_label(v["label"]) v_clean["is_gl2_type"] = v["is_gl2_type"] v_clean["is_simple_geom"] = v["is_simple_geom"] v_clean["equation_formatted"] = list_to_min_eqn(literal_eval(v["eqn"])) v_clean["st_group_link"] = st_link_by_name(1,4,v['st_group']) v_clean["analytic_rank"] = v["analytic_rank"] res_clean.append(v_clean) info["curves"] = res_clean info["curve_url"] = lambda label: url_for_curve_label(label) info["class_url"] = lambda label: url_for_isogeny_class_label(label) info["start"] = start info["count"] = count info["more"] = int(start+count<nres) title = info.get('title','Genus 2 Curve search results') credit = credit_string return render_template("g2c_search_results.html", info=info, credit=credit,learnmore=learnmore_list(), bread=bread, title=title)
def __call__(self, info, random=False): # If random is True, returns a random label info = to_dict(info, exclude =['bread']) # I'm not sure why this is required... for key, func in self.shortcuts.items(): if info.get(key,'').strip(): return func(info) query = {} template_kwds = {} for key in self.kwds: template_kwds[key] = info.get(key, self.kwds[key]()) try: errpage = self.f(info, query) except ValueError as err: # Errors raised in parsing info['err'] = str(err) err_title = query.pop('__err_title__', self.err_title) return render_template(self.template, info=info, title=err_title, **template_kwds) else: err_title = query.pop('__err_title__', self.err_title) if errpage is not None: return errpage if 'result_count' in info: nres = self.table.count(query) return jsonify({"nres":str(nres)}) sort = query.pop('__sort__', None) table = query.pop('__table__', self.table) # We want to pop __title__ even if overridden by info. title = query.pop('__title__', self.title) title = info.get('title', title) template = query.pop('__template__', self.template) if random: query.pop('__projection__', None) proj = query.pop('__projection__', self.projection) count = parse_count(info, self.per_page) start = parse_start(info) try: if random: # Ignore __projection__: it's intended for searches label = table.random(query, projection=0) if label is None: res = [] # ugh; we have to set these manually info['query'] = dict(query) info['number'] = 0 info['count'] = count info['start'] = start info['exact_count'] = True else: return redirect(self.url_for_label(label), 307) else: res = table.search(query, proj, limit=count, offset=start, sort=sort, info=info) except QueryCanceledError as err: ctx = ctx_proc_userdata() flash_error('The search query took longer than expected! Please help us improve by reporting this error <a href="%s" target=_blank>here</a>.' % ctx['feedbackpage']) info['err'] = str(err) info['query'] = dict(query) return render_template(self.template, info=info, title=self.err_title, **template_kwds) else: try: if self.cleaners: for v in res: for name, func in self.cleaners.items(): v[name] = func(v) if self.postprocess is not None: res = self.postprocess(res, info, query) except ValueError as err: # Errors raised in postprocessing flash_error(str(err)) info['err'] = str(err) return render_template(self.template, info=info, title=err_title, **template_kwds) for key, func in self.longcuts.items(): if info.get(key,'').strip(): return func(res, info, query) info['results'] = res return render_template(template, info=info, title=title, **template_kwds)