예제 #1
0
파일: main.py 프로젝트: koffie/lmfdb
def st0_group_format(name):
    return "\("+st0_group_name(name)+"\)"
예제 #2
0
def st0_group_format(name):
    return "\(" + st0_group_name(name) + "\)"
예제 #3
0
class G2C_stats(StatsDisplay):
    """
    Class for creating and displaying statistics for genus 2 curves over Q
    """
    def __init__(self):
        self.ncurves = comma(db.g2c_curves.count())
        self.max_D = comma(db.g2c_curves.max('abs_disc'))
        self.disc_knowl = display_knowl('g2c.abs_discriminant',
                                        title="absolute discriminant")

    @property
    def short_summary(self):
        stats_url = url_for(".statistics")
        g2c_knowl = display_knowl('g2c.g2curve', title='genus 2 curves')
        return r'The database currently contains %s %s over $\Q$ of %s up to %s.  Here are some <a href="%s">further statistics</a>.' % (
            self.ncurves, g2c_knowl, self.disc_knowl, self.max_D, stats_url)

    @property
    def summary(self):
        nclasses = comma(db.lfunc_instances.count({'type': 'G2Q'}))
        return 'The database currently contains %s genus 2 curves in %s isogeny classes, with %s at most %s.' % (
            self.ncurves, nclasses, self.disc_knowl, self.max_D)

    table = db.g2c_curves
    baseurl_func = ".index_Q"
    knowls = {
        'num_rat_pts': 'g2c.num_rat_pts',
        'num_rat_wpts': 'g2c.num_rat_wpts',
        'aut_grp_id': 'g2c.aut_grp',
        'geom_aut_grp_id': 'g2c.geom_aut_grp',
        'analytic_rank': 'g2c.analytic_rank',
        'two_selmer_rank': 'g2c.two_selmer_rank',
        'analytic_sha': 'g2c.analytic_sha',
        'has_square_sha': 'g2c.has_square_sha',
        'locally_solvable': 'g2c.locally_solvable',
        'is_gl2_type': 'g2c.gl2type',
        'real_geom_end_alg': 'g2c.st_group_identity_component',
        'st_group': 'g2c.st_group',
        'torsion_order': 'g2c.torsion_order'
    }
    short_display = {
        'num_rat_pts': 'rational points',
        'num_rat_wpts': 'Weierstrass points',
        'aut_grp_id': 'automorphism group',
        'geom_aut_grp_id': 'automorphism group',
        'two_selmer_rank': '2-Selmer rank',
        'analytic_sha': 'analytic order of &#1064;',
        'has_square_sha': 'has square &#1064;',
        'is_gl2_type': 'is of GL2-type',
        'real_geom_end_alg': 'identity component',
        'st_group': 'Sato-Tate group',
        'torsion_order': 'torsion order'
    }
    top_titles = {
        'num_rat_pts': 'rational points',
        'num_rat_wpts': 'rational Weierstrass points',
        'aut_grp_id': r'$\mathrm{Aut}(X)$',
        'geom_aut_grp_id': r'$\mathrm{Aut}(X_{\overline{\mathbb{Q}}})$',
        'analytic_sha': 'analytic order of &#1064;',
        'has_square_sha': 'squareness of &#1064;',
        'locally_solvable': 'local solvability',
        'is_gl2_type': r'$\mathrm{GL}_2$-type',
        'real_geom_end_alg': 'Sato-Tate group identity components',
        'st_group': 'Sato-Tate groups',
        'torsion_order': 'torsion subgroup orders'
    }
    formatters = {
        'aut_grp_id': lambda x: aut_grp_dict_pretty[x],
        'geom_aut_grp_id': lambda x: geom_aut_grp_dict_pretty[x],
        'has_square_sha': formatters.boolean,
        'is_gl2_type': formatters.boolean,
        'real_geom_end_alg': lambda x: "\\(" + st0_group_name(x) + "\\)",
        'st_group': lambda x: st_link_by_name(1, 4, x)
    }
    query_formatters = {
        'aut_grp_id': lambda x: 'aut_grp_id=%s' % x,
        'geom_aut_grp_id': lambda x: 'geom_aut_grp_id=%s' % x,
        'real_geom_end_alg': lambda x: 'real_geom_end_alg=%s' % x,
        'st_group': lambda x: 'st_group=%s' % x,
    }

    stat_list = [
        {
            'cols': 'num_rat_pts',
            'totaler': {
                'avg': True
            }
        },
        {
            'cols': 'num_rat_wpts',
            'totaler': {
                'avg': True
            }
        },
        {
            'cols': 'aut_grp_id'
        },
        {
            'cols': 'geom_aut_grp_id'
        },
        {
            'cols': 'analytic_rank',
            'totaler': {
                'avg': True
            }
        },
        {
            'cols': 'two_selmer_rank',
            'totaler': {
                'avg': True
            }
        },
        {
            'cols': 'has_square_sha'
        },
        {
            'cols': 'analytic_sha',
            'totaler': {
                'avg': True
            }
        },
        {
            'cols': 'locally_solvable'
        },
        {
            'cols': 'is_gl2_type'
        },
        {
            'cols': 'real_geom_end_alg'
        },
        {
            'cols': 'st_group'
        },
        {
            'cols': 'torsion_order',
            'totaler': {
                'avg': True
            }
        },
    ]
예제 #4
0
    def make_class(self):
        curves_data = db_g2c().curves.find({"class" : self.label}).sort([("disc_key", pymongo.ASCENDING), ("label", pymongo.ASCENDING)])
        self.curves = [ {"label" : c['label'], "equation_formatted" : list_to_min_eqn(c['min_eqn']), "url": url_for_label(c['label'])} for c in curves_data ]
        self.ncurves = curves_data.count()
        self.bad_lfactors = [ [c[0], list_to_factored_poly_otherorder(c[1])] for c in self.bad_lfactors]
        ## duplication of get_end_alg.  need to clean up!
        end_alg_title_dict = {'end_ring': r'\End(J)', 
                              'rat_end_alg': r'\End(J) \otimes \Q',
                              'real_end_alg': r'\End(J) \otimes \R',
                              'geom_end_ring': r'\End(J_{\overline{\Q}})', 
                              'rat_geom_end_alg': r'\End(J_{\overline{\Q}}) \otimes \Q',
                              'real_geom_end_alg':'\End(J_{\overline{\Q}}) \otimes \R'}
        for endalgtype in ['end_ring', 'rat_end_alg', 'real_end_alg', 'geom_end_ring', 'rat_geom_end_alg', 'real_geom_end_alg']:
            if hasattr(self, endalgtype):
                setattr(self,endalgtype + '_name',[end_alg_title_dict[endalgtype],end_alg_name(getattr(self,endalgtype))])
            else:
                setattr(self,endalgtype + '_name',[end_alg_title_dict[endalgtype],''])
        
        if hasattr(self, 'geom_end_field') and self.geom_end_field <> '':
            self.geom_end_field_name = field_pretty(self.geom_end_field)
        else:
            self.geom_end_field_name = ''
        self.st_group_name = st_group_name(self.st_group)
        self.st0_group_name = st0_group_name(self.real_geom_end_alg)
        if self.is_gl2_type:
            self.is_gl2_type_name = 'yes'
            gl2_statement = 'of \(\GL_2\)-type'
        else:
            self.is_gl2_type_name = 'no'
            gl2_statement = 'not of \(\GL_2\)-type'
        if hasattr(self, 'is_simple') and hasattr(self, 'is_geom_simple'):
            if self.is_geom_simple:
                simple_statement = "simple over \(\overline{\Q}\), "
            elif self.is_simple:
                simple_statement = "simple over \(\Q\) but not simple over \(\overline{\Q}\), "
            else:
                simple_statement = "not simple over \(\Q\), "
        else:
            simple_statement = ""  # leave empty since not computed.
        self.endomorphism_statement = simple_statement + gl2_statement

        x = self.label.split('.')[1]
        
        self.friends = [('L-function', url_for("l_functions.l_function_genus2_page", cond=self.cond,x=x))]

        self.ecproduct_wurl = []
        if hasattr(self, 'ecproduct'):
            for i in range(2):
                curve_label = self.ecproduct[i]
                crv_url = url_for("ec.by_ec_label", label=curve_label)
                if i == 1 or len(set(self.ecproduct)) <> 1:
                    self.friends.append(('Elliptic curve ' + curve_label, crv_url))
                self.ecproduct_wurl.append({'label' : curve_label, 'url' : crv_url})

        self.ecquadratic_wurl = []
        if hasattr(self, 'ecquadratic'):
            for i in range(len(self.ecquadratic)):
                curve_label = self.ecquadratic[i]
                crv_spl = curve_label.split('-')
                crv_url = url_for("ecnf.show_ecnf_isoclass", nf = crv_spl[0], conductor_label = crv_spl[1], class_label = crv_spl[2])
                self.friends.append(('Elliptic curve ' + curve_label, crv_url))
                self.ecquadratic_wurl.append({'label' : curve_label, 'url' : crv_url, 'nf' : crv_spl[0]})

        if hasattr(self, 'mfproduct'):
            for i in range(len(self.mfproduct)):
                mf_label = self.mfproduct[i]
                mf_spl = mf_label.split('.')
                mf_spl.append(mf_spl[2][-1])
                mf_spl[2] = mf_spl[2][:-1] # Need a splitting function
                mf_url = url_for("emf.render_elliptic_modular_forms", level=mf_spl[0], weight=mf_spl[1], character=mf_spl[2], label=mf_spl[3])
                self.friends.append(('Modular form ' + mf_label, mf_url))

        if hasattr(self, 'mfhilbert'):
            for i in range(len(self.mfhilbert)):
                mf_label = self.mfhilbert[i]
                mf_spl = mf_label.split('-')
                mf_url = url_for("hmf.render_hmf_webpage", field_label=mf_spl[0], label=mf_label)
                self.friends.append(('Hilbert modular form ' + mf_label, mf_url))

        self.properties = [('Label', self.label),
                           ('Number of curves', str(self.ncurves)),
                           ('Conductor','%s' % self.cond),
                           ('Sato-Tate group', '\(%s\)' % self.st_group_name),
                           ('\(%s\)' % self.real_geom_end_alg_name[0],'\(%s\)' % self.real_geom_end_alg_name[1]),
                           ('\(\mathrm{GL}_2\)-type','%s' % self.is_gl2_type_name)]

        self.title = "Genus 2 Isogeny Class %s" % (self.label)
        self.downloads = [
                          ('Download Euler factors', ".")] # url_for(".download_g2c_eulerfactors", label=self.label)),
#                          ('Download stored data for all curves', url_for(".download_g2c_all", label=self.label))]
        
        self.bread = [
                       ('Genus 2 Curves', url_for(".index")),
                       ('$\Q$', url_for(".index_Q")),
                       ('%s' % self.cond, url_for(".by_conductor", conductor=self.cond)),
                       ('%s' % self.label, ' ')
                     ]
예제 #5
0
    def make_class(self):
        from lmfdb.genus2_curves.genus2_curve import url_for_curve_label

        # Data
        curves_data = g2cdb().curves.find({"class" : self.label},{'_id':int(0),'label':int(1),'min_eqn':int(1),'disc_key':int(1)}).sort([("disc_key", ASCENDING), ("label", ASCENDING)])
        assert curves_data
        self.curves = [ {"label" : c['label'], "equation_formatted" : list_to_min_eqn(c['min_eqn']),
            "url": url_for_curve_label(c['label'])} for c in curves_data ]
        self.ncurves = curves_data.count()
        self.bad_lfactors = [ [c[0], list_to_factored_poly_otherorder(c[1])]
            for c in self.bad_lfactors]

        # Data derived from Sato-Tate group
        self.st_group_name = st_group_name(self.st_group)
        self.st_group_href = st_group_href(self.st_group)
        self.st0_group_name = st0_group_name(self.real_geom_end_alg)
        # Later used in Lady Gaga box:
        self.real_geom_end_alg_disp = [r'\End(J_{\overline{\Q}}) \otimes \R',
                end_alg_name(self.real_geom_end_alg)]
        if self.is_gl2_type:
            self.is_gl2_type_name = 'yes'
        else:
            self.is_gl2_type_name = 'no'

        # Endomorphism data
        endodata = g2cdb().endomorphisms.find_one({"label" :
            self.curves[0]['label']})
        self.gl2_statement_base = \
            gl2_statement_base(endodata['factorsRR_base'], r'\(\Q\)')
        self.endo_statement_base = \
            """Endomorphism algebra over \(\Q\):<br>""" + \
            endo_statement_isog(endodata['factorsQQ_base'],
                endodata['factorsRR_base'], r'')
        endodata['fod_poly'] = intlist_to_poly(endodata['fod_coeffs'])
        self.fod_statement = fod_statement(endodata['fod_label'],
            endodata['fod_poly'])
        if endodata['fod_label'] != '1.1.1.1':
            self.endo_statement_geom = \
                """Endomorphism algebra over \(\overline{\Q}\):<br>""" + \
                endo_statement_isog(endodata['factorsQQ_geom'],
                    endodata['factorsRR_geom'], r'\overline{\Q}')
        else:
            self.endo_statement_geom = ''

        # Title
        self.title = "Genus 2 Isogeny Class %s" % (self.label)

        # Lady Gaga box
        self.properties = (
                ('Label', self.label),
                ('Number of curves', str(self.ncurves)),
                ('Conductor','%s' % self.cond),
                ('Sato-Tate group', self.st_group_href),
                ('\(%s\)' % self.real_geom_end_alg_disp[0],
                 '\(%s\)' % self.real_geom_end_alg_disp[1]),
                ('\(\mathrm{GL}_2\)-type','%s' % self.is_gl2_type_name)
                )
        x = self.label.split('.')[1]
        self.friends = [('L-function', url_for("l_functions.l_function_genus2_page", cond=self.cond,x=x))]
        #self.downloads = [('Download Euler factors', ".")]
        #self.downloads = [
        #        ('Download Euler factors', "."),
        #            url_for(".download_g2c_eulerfactors", label=self.label)),
        #        ('Download stored data for all curves',
        #            url_for(".download_g2c_all", label=self.label))
        #        ]

        # Breadcrumbs
        self.bread = (
                       ('Genus 2 Curves', url_for(".index")),
                       ('$\Q$', url_for(".index_Q")),
                       ('%s' % self.cond, url_for(".by_conductor", cond=self.cond)),
                       ('%s' % self.label, ' ')
                     )

        # More friends (NOTE: to be improved)
        self.ecproduct_wurl = []
        if hasattr(self, 'ecproduct'):
            for i in range(2):
                curve_label = self.ecproduct[i]
                crv_url = url_for("ec.by_ec_label", label=curve_label)
                if i == 1 or len(set(self.ecproduct)) != 1:
                    self.friends.append(('Elliptic curve ' + curve_label,
                        crv_url))
                self.ecproduct_wurl.append({'label' : curve_label, 'url' :
                    crv_url})

        self.ecquadratic_wurl = []
        if hasattr(self, 'ecquadratic'):
            for i in range(len(self.ecquadratic)):
                curve_label = self.ecquadratic[i]
                crv_spl = curve_label.split('-')
                crv_url = url_for("ecnf.show_ecnf_isoclass", nf = crv_spl[0],
                        conductor_label = crv_spl[1], class_label = crv_spl[2])
                self.friends.append(('Elliptic curve ' + curve_label, crv_url))
                self.ecquadratic_wurl.append({'label' : curve_label, 'url' :
                    crv_url, 'nf' : crv_spl[0]})

        if hasattr(self, 'mfproduct'):
            for i in range(len(self.mfproduct)):
                mf_label = self.mfproduct[i]
                mf_spl = mf_label.split('.')
                mf_spl.append(mf_spl[2][-1])
                mf_spl[2] = mf_spl[2][:-1] # Need a splitting function
                mf_url = url_for("emf.render_elliptic_modular_forms",
                        level=mf_spl[0], weight=mf_spl[1], character=mf_spl[2],
                        label=mf_spl[3])
                self.friends.append(('Modular form ' + mf_label, mf_url))

        if hasattr(self, 'mfhilbert'):
            for i in range(len(self.mfhilbert)):
                mf_label = self.mfhilbert[i]
                mf_spl = mf_label.split('-')
                mf_url = url_for("hmf.render_hmf_webpage",
                        field_label=mf_spl[0], label=mf_label)
                self.friends.append(('Hilbert modular form ' + mf_label, mf_url))
예제 #6
0
class G2C_stats(StatsDisplay):
    """
    Class for creating and displaying statistics for genus 2 curves over Q
    """
    def __init__(self):
        self.ncurves = comma(db.g2c_curves.count())
        self.max_D = comma(db.g2c_curves.max("abs_disc"))
        self.disc_knowl = display_knowl("g2c.abs_discriminant",
                                        title="absolute discriminant")

    @property
    def short_summary(self):
        stats_url = url_for(".statistics")
        g2c_knowl = display_knowl("g2c.g2curve", title="genus 2 curves")
        return (
            r'The database currently contains %s %s over $\Q$ of %s up to %s.  Here are some <a href="%s">further statistics</a>.'
            %
            (self.ncurves, g2c_knowl, self.disc_knowl, self.max_D, stats_url))

    @property
    def summary(self):
        nclasses = comma(db.lfunc_instances.count({"type": "G2Q"}))
        return (
            "The database currently contains %s genus 2 curves in %s isogeny classes, with %s at most %s."
            % (self.ncurves, nclasses, self.disc_knowl, self.max_D))

    table = db.g2c_curves
    baseurl_func = ".index_Q"
    knowls = {
        "num_rat_pts": "g2c.num_rat_pts",
        "num_rat_wpts": "g2c.num_rat_wpts",
        "aut_grp_label": "g2c.aut_grp",
        "geom_aut_grp_label": "g2c.geom_aut_grp",
        "analytic_rank": "g2c.analytic_rank",
        "two_selmer_rank": "g2c.two_selmer_rank",
        "analytic_sha": "g2c.analytic_sha",
        "has_square_sha": "g2c.has_square_sha",
        "locally_solvable": "g2c.locally_solvable",
        "is_gl2_type": "g2c.gl2type",
        "real_geom_end_alg": "g2c.st_group_identity_component",
        "st_group": "g2c.st_group",
        "torsion_order": "g2c.torsion_order",
    }
    short_display = {
        "num_rat_pts": "rational points",
        "num_rat_wpts": "Weierstrass points",
        "aut_grp_label": "automorphism group",
        "geom_aut_grp_label": "automorphism group",
        "two_selmer_rank": "2-Selmer rank",
        "analytic_sha": "analytic order of &#1064;",
        "has_square_sha": "has square &#1064;",
        "is_gl2_type": "is of GL2-type",
        "real_geom_end_alg": "identity component",
        "st_group": "Sato-Tate group",
        "torsion_order": "torsion order",
    }
    top_titles = {
        "num_rat_pts": "rational points",
        "num_rat_wpts": "rational Weierstrass points",
        "aut_grp_label": r"$\mathrm{Aut}(X)$",
        "geom_aut_grp_label": r"$\mathrm{Aut}(X_{\overline{\mathbb{Q}}})$",
        "analytic_sha": "analytic order of &#1064;",
        "has_square_sha": "squareness of &#1064;",
        "locally_solvable": "local solvability",
        "is_gl2_type": r"$\mathrm{GL}_2$-type",
        "real_geom_end_alg": "Sato-Tate group identity components",
        "st_group": "Sato-Tate groups",
        "torsion_order": "torsion subgroup orders",
    }
    formatters = {
        "aut_grp_label": lambda x: aut_grp_dict_pretty.get(x, x),
        "geom_aut_grp_label": lambda x: geom_aut_grp_dict_pretty[x],
        "has_square_sha": formatters.boolean,
        "is_gl2_type": formatters.boolean,
        "real_geom_end_alg": lambda x: "\\(" + st0_group_name(x) + "\\)",
        "st_group": lambda x: st_link_by_name(1, 4, x),
    }
    query_formatters = {
        "aut_grp_label": lambda x: "aut_grp_label=%s" % x,
        "geom_aut_grp_label": lambda x: "geom_aut_grp_label=%s" % x,
        "real_geom_end_alg": lambda x: "real_geom_end_alg=%s" % x,
        "st_group": lambda x: "st_group=%s" % x,
    }

    stat_list = [
        {
            "cols": "num_rat_pts",
            "totaler": {
                "avg": True
            }
        },
        {
            "cols": "num_rat_wpts",
            "totaler": {
                "avg": True
            }
        },
        {
            "cols": "aut_grp_label"
        },
        {
            "cols": "geom_aut_grp_label"
        },
        {
            "cols": "analytic_rank",
            "totaler": {
                "avg": True
            }
        },
        {
            "cols": "two_selmer_rank",
            "totaler": {
                "avg": True
            }
        },
        {
            "cols": "has_square_sha"
        },
        {
            "cols": "analytic_sha",
            "totaler": {
                "avg": True
            }
        },
        {
            "cols": "locally_solvable"
        },
        {
            "cols": "is_gl2_type"
        },
        {
            "cols": "real_geom_end_alg"
        },
        {
            "cols": "st_group"
        },
        {
            "cols": "torsion_order",
            "totaler": {
                "avg": True
            }
        },
    ]
예제 #7
0
파일: isog_class.py 프로젝트: paulhus/lmfdb
    def make_class(self):
        curves_data = db_g2c().curves.find({"class" : self.label}).sort([("disc_key", pymongo.ASCENDING), ("label", pymongo.ASCENDING)])
        self.curves = [ {"label" : c['label'], "equation_formatted" : list_to_min_eqn(c['min_eqn']), "url": url_for_label(c['label'])} for c in curves_data ]
        self.ncurves = curves_data.count()
        self.bad_lfactors = [ [c[0], list_to_factored_poly_otherorder(c[1])] for c in self.bad_lfactors]
        ## duplication of get_end_alg.  need to clean up!
        end_alg_title_dict = {'end_ring': r'\End(J)', 
                              'rat_end_alg': r'\End(J) \otimes \Q',
                              'real_end_alg': r'\End(J) \otimes \R',
                              'geom_end_ring': r'\End(J_{\overline{\Q}})', 
                              'rat_geom_end_alg': r'\End(J_{\overline{\Q}}) \otimes \Q',
                              'real_geom_end_alg':'\End(J_{\overline{\Q}}) \otimes \R'}
        for endalgtype in ['end_ring', 'rat_end_alg', 'real_end_alg', 'geom_end_ring', 'rat_geom_end_alg', 'real_geom_end_alg']:
            if hasattr(self, endalgtype):
                setattr(self,endalgtype + '_name',[end_alg_title_dict[endalgtype],end_alg_name(getattr(self,endalgtype))])
            else:
                setattr(self,endalgtype + '_name',[end_alg_title_dict[endalgtype],''])
        
        if hasattr(self, 'geom_end_field') and self.geom_end_field != '':
            self.geom_end_field_name = field_pretty(self.geom_end_field)
        else:
            self.geom_end_field_name = ''
        self.st_group_name = st_group_name(self.st_group)
        self.st0_group_name = st0_group_name(self.real_geom_end_alg)
        if self.is_gl2_type:
            self.is_gl2_type_name = 'yes'
            gl2_statement = 'of \(\GL_2\)-type'
        else:
            self.is_gl2_type_name = 'no'
            gl2_statement = 'not of \(\GL_2\)-type'
        if hasattr(self, 'is_simple') and hasattr(self, 'is_geom_simple'):
            if self.is_geom_simple:
                simple_statement = "simple over \(\overline{\Q}\), "
            elif self.is_simple:
                simple_statement = "simple over \(\Q\) but not simple over \(\overline{\Q}\), "
            else:
                simple_statement = "not simple over \(\Q\), "
        else:
            simple_statement = ""  # leave empty since not computed.
        self.endomorphism_statement = simple_statement + gl2_statement

        x = self.label.split('.')[1]
        
        self.friends = [('L-function', url_for("l_functions.l_function_genus2_page", cond=self.cond,x=x))]

        self.ecproduct_wurl = []
        if hasattr(self, 'ecproduct'):
            for i in range(2):
                curve_label = self.ecproduct[i]
                crv_url = url_for("ec.by_ec_label", label=curve_label)
                if i == 1 or len(set(self.ecproduct)) != 1:
                    self.friends.append(('Elliptic curve ' + curve_label, crv_url))
                self.ecproduct_wurl.append({'label' : curve_label, 'url' : crv_url})

        self.ecquadratic_wurl = []
        if hasattr(self, 'ecquadratic'):
            for i in range(len(self.ecquadratic)):
                curve_label = self.ecquadratic[i]
                crv_spl = curve_label.split('-')
                crv_url = url_for("ecnf.show_ecnf_isoclass", nf = crv_spl[0], conductor_label = crv_spl[1], class_label = crv_spl[2])
                self.friends.append(('Elliptic curve ' + curve_label, crv_url))
                self.ecquadratic_wurl.append({'label' : curve_label, 'url' : crv_url, 'nf' : crv_spl[0]})

        if hasattr(self, 'mfproduct'):
            for i in range(len(self.mfproduct)):
                mf_label = self.mfproduct[i]
                mf_spl = mf_label.split('.')
                mf_spl.append(mf_spl[2][-1])
                mf_spl[2] = mf_spl[2][:-1] # Need a splitting function
                mf_url = url_for("emf.render_elliptic_modular_forms", level=mf_spl[0], weight=mf_spl[1], character=mf_spl[2], label=mf_spl[3])
                self.friends.append(('Modular form ' + mf_label, mf_url))

        if hasattr(self, 'mfhilbert'):
            for i in range(len(self.mfhilbert)):
                mf_label = self.mfhilbert[i]
                mf_spl = mf_label.split('-')
                mf_url = url_for("hmf.render_hmf_webpage", field_label=mf_spl[0], label=mf_label)
                self.friends.append(('Hilbert modular form ' + mf_label, mf_url))

        self.properties = [('Label', self.label),
                           ('Number of curves', str(self.ncurves)),
                           ('Conductor','%s' % self.cond),
                           ('Sato-Tate group', '\(%s\)' % self.st_group_name),
                           ('\(%s\)' % self.real_geom_end_alg_name[0],'\(%s\)' % self.real_geom_end_alg_name[1]),
                           ('\(\mathrm{GL}_2\)-type','%s' % self.is_gl2_type_name)]

        self.title = "Genus 2 Isogeny Class %s" % (self.label)
        self.downloads = [
                          ('Download Euler factors', ".")] # url_for(".download_g2c_eulerfactors", label=self.label)),
#                          ('Download stored data for all curves', url_for(".download_g2c_all", label=self.label))]
        
        self.bread = [
                       ('Genus 2 Curves', url_for(".index")),
                       ('$\Q$', url_for(".index_Q")),
                       ('%s' % self.cond, url_for(".by_conductor", conductor=self.cond)),
                       ('%s' % self.label, ' ')
                     ]