'Raise or lower indices with the metric ``g``
Parameters
g : metric
Notes
see the ``TensorIndexType`` docstring for the contraction conventions
Examples
>>> from sympy.tensor.tensor import TensorIndexType, tensor_indices, tensorhead
>>> Lorentz = TensorIndexType(\'Lorentz\', dummy_fmt=\'L\')
>>> m0, m1, m2 = tensor_indices(\'m0,m1,m2\', Lorentz)
>>> g = Lorentz.metric
>>> p, q = tensorhead(\'p,q\', [Lorentz], [[1]])
>>> t = p(m0)*q(m1)*g(-m0, -m1)
>>> t.canon_bp()
metric(L_0, L_1)*p(-L_0)*q(-L_1)
>>> t.contract_metric(g).canon_bp()
p(L_0)*q(-L_0)'

def contract_metric(self, g):

    pos_map = self._get_indices_to_args_pos()
    args = list(self.args)
    antisym = g.index_types[0].metric_antisym
    gpos = [i for (i, x) in enumerate(self.args) if (isinstance(x, Tensor) and (x.component == g))]
    if (not gpos):
        return self
    sign = 1
    dum = self.dum[:]
    free = self.free[:]
    elim = set()
    for gposx in gpos:
        if (gposx in elim):
            continue
        free1 = [x for x in free if (pos_map[x[1]] == gposx)]
        dum1 = [x for x in dum if ((pos_map[x[0]] == gposx) or (pos_map[x[1]] == gposx))]
        if (not dum1):
            continue
        elim.add(gposx)
        args[gposx] = 1
        if (len(dum1) == 2):
            if (not antisym):
                (dum10, dum11) = dum1
                if (pos_map[dum10[1]] == gposx):
                    p0 = dum10[0]
                else:
                    p0 = dum10[1]
                if (pos_map[dum11[1]] == gposx):
                    p1 = dum11[0]
                else:
                    p1 = dum11[1]
                dum.append((p0, p1))
            else:
                (dum10, dum11) = dum1
                if (pos_map[dum10[1]] == gposx):
                    p0 = dum10[0]
                    if (dum10[1] == 1):
                        sign = (- sign)
                else:
                    p0 = dum10[1]
                    if (dum10[0] == 0):
                        sign = (- sign)
                if (pos_map[dum11[1]] == gposx):
                    p1 = dum11[0]
                    sign = (- sign)
                else:
                    p1 = dum11[1]
                dum.append((p0, p1))
        elif (len(dum1) == 1):
            if (not antisym):
                (dp0, dp1) = dum1[0]
                if (pos_map[dp0] == pos_map[dp1]):
                    typ = g.index_types[0]
                    if (typ._dim is None):
                        raise ValueError('dimension    not    assigned')
                    sign = (sign * typ._dim)
                else:
                    if (pos_map[dp0] == gposx):
                        p1 = dp1
                    else:
                        p1 = dp0
                    (ind, p) = free1[0]
                    free.append((ind, p1))
            else:
                (dp0, dp1) = dum1[0]
                if (pos_map[dp0] == pos_map[dp1]):
                    typ = g.index_types[0]
                    if (typ._dim is None):
                        raise ValueError('dimension    not    assigned')
                    sign = (sign * typ._dim)
                    if (dp0 < dp1):
                        sign = (- sign)
                else:
                    if (pos_map[dp0] == gposx):
                        p1 = dp1
                        if (dp0 == 0):
                            sign = (- sign)
                    else:
                        p1 = dp0
                    (ind, p) = free1[0]
                    free.append((ind, p1))
        dum = [x for x in dum if (x not in dum1)]
        free = [x for x in free if (x not in free1)]
    shift = 0
    shifts = ([0] * len(args))
    for i in range(len(args)):
        if (i in elim):
            shift += 2
            continue
        shifts[i] = shift
    free = [(ind, (p - shifts[pos_map[p]])) for (ind, p) in free if (pos_map[p] not in elim)]
    dum = [((p0 - shifts[pos_map[p0]]), (p1 - shifts[pos_map[p1]])) for (i, (p0, p1)) in enumerate(dum) if ((pos_map[p0] not in elim) and (pos_map[p1] not in elim))]
    res = (sign * TensMul(*args))
    if (not isinstance(res, TensExpr)):
        return res
    im = _IndexStructure.from_components_free_dum(res.components, free, dum)
    return res._set_new_index_structure(im)
