Visualize salt bridges.
513361
def show_sbridges(self):
        """"""
        for i, saltb in enumerate(self.plcomplex.saltbridges):
            if saltb.protispos:
                for patom in saltb.positive_atoms:
                    cmd.select('PosCharge-P', 'PosCharge-P or (id %i & %s)' % (patom, self.protname))
                for latom in saltb.negative_atoms:
                    cmd.select('NegCharge-L', 'NegCharge-L or (id %i & %s)' % (latom, self.ligname))
                for sbgroup in [['ps-sbl-1-%i' % i, 'Chargecenter-P', saltb.positive_center],
                                ['ps-sbl-2-%i' % i, 'Chargecenter-L', saltb.negative_center]]:
                    cmd.pseudoatom(sbgroup[0], pos=sbgroup[2])
                    cmd.pseudoatom(sbgroup[1], pos=sbgroup[2])
                cmd.distance('Saltbridges', 'ps-sbl-1-%i' % i, 'ps-sbl-2-%i' % i)
            else:
                for patom in saltb.negative_atoms:
                    cmd.select('NegCharge-P', 'NegCharge-P or (id %i & %s)' % (patom, self.protname))
                for latom in saltb.positive_atoms:
                    cmd.select('PosCharge-L', 'PosCharge-L or (id %i & %s)' % (latom, self.ligname))
                for sbgroup in [['ps-sbp-1-%i' % i, 'Chargecenter-P', saltb.negative_center],
                                ['ps-sbp-2-%i' % i, 'Chargecenter-L', saltb.positive_center]]:
                    cmd.pseudoatom(sbgroup[0], pos=sbgroup[2])
                    cmd.pseudoatom(sbgroup[1], pos=sbgroup[2])
                cmd.distance('Saltbridges', 'ps-sbp-1-%i' % i, 'ps-sbp-2-%i' % i)

        if self.object_exists('Saltbridges'):
            cmd.set('dash_color', 'yellow', 'Saltbridges')
            cmd.set('dash_gap', 0.5, 'Saltbridges')
57761
def plot_results(fout_png, goea_results, *args, **kws):
    """"""
    if "{NS}" not in fout_png:
        plt_goea_results(fout_png, goea_results, *args, **kws)
    else:
        # Plot separately by NS: BP, MF, CC
        ns2goea_results = cx.defaultdict(list)
        for rec in goea_results:
            ns2goea_results[rec.NS].append(rec)
        for ns_name, ns_res in ns2goea_results.items():
            png = fout_png.format(NS=ns_name)
            plt_goea_results(png, ns_res, *args, **kws)
147280
def show_highstate(queue=False, **kwargs):
    '''
    
    '''
    conflict = _check_queue(queue, kwargs)
    if conflict is not None:
        return conflict
    pillar_override = kwargs.get('pillar')
    pillar_enc = kwargs.get('pillar_enc')
    if pillar_enc is None \
            and pillar_override is not None \
            and not isinstance(pillar_override, dict):
        raise SaltInvocationError(
            'Pillar data must be formatted as a dictionary, unless pillar_enc '
            'is specified.'
        )

    opts = salt.utils.state.get_sls_opts(__opts__, **kwargs)
    try:
        st_ = salt.state.HighState(opts,
                                   pillar_override,
                                   pillar_enc=pillar_enc,
                                   proxy=__proxy__,
                                   initial_pillar=_get_initial_pillar(opts))
    except NameError:
        st_ = salt.state.HighState(opts,
                                   pillar_override,
                                   pillar_enc=pillar_enc,
                                   initial_pillar=_get_initial_pillar(opts))

    errors = _get_pillar_errors(kwargs, pillar=st_.opts['pillar'])
    if errors:
        __context__['retcode'] = salt.defaults.exitcodes.EX_PILLAR_FAILURE
        raise CommandExecutionError('Pillar failed to render', info=errors)

    st_.push_active()
    try:
        ret = st_.compile_highstate()
    finally:
        st_.pop_active()
    _set_retcode(ret)
    return ret
477549
def _bsd_brshow(br=None):
    '''
    
    '''
    if __grains__['kernel'] == 'NetBSD':
        return _netbsd_brshow(br)

    ifconfig = _tool_path('ifconfig')

    ifaces = {}

    if br:
        ifaces[br] = br
    else:
        cmd = '{0} -g bridge'.format(ifconfig)
        for line in __salt__['cmd.run'](cmd, python_shell=False).splitlines():
            ifaces[line] = line

    brs = {}

    for iface in ifaces:
        cmd = '{0} {1}'.format(ifconfig, iface)
        for line in __salt__['cmd.run'](cmd, python_shell=False).splitlines():
            brs[iface] = {
                'interfaces': [],
                'stp': 'no'
            }
            line = line.lstrip()
            if line.startswith('member:'):
                brs[iface]['interfaces'].append(line.split(' ')[1])
                if 'STP' in line:
                    brs[iface]['stp'] = 'yes'

    if br:
        return brs[br]
    return brs
78532
def plot_gos(fout_png, goids, obo_dag, *args, **kws):
    """"""
    engine = kws['engine'] if 'engine' in kws else 'pydot'
    godagsmall = OboToGoDagSmall(goids=goids, obodag=obo_dag).godag
    godagplot = GODagSmallPlot(godagsmall, *args, **kws)
    godagplot.plt(fout_png, engine)
39609
def water_bridges(bs_hba, lig_hba, bs_hbd, lig_hbd, water):
    """"""
    data = namedtuple('waterbridge', 'a a_orig_idx atype d d_orig_idx dtype h water water_orig_idx distance_aw '
                                     'distance_dw d_angle w_angle type resnr restype reschain resnr_l restype_l reschain_l protisdon')
    pairings = []
    # First find all acceptor-water pairs with distance within d
    # and all donor-water pairs with distance within d and angle greater theta
    lig_aw, prot_aw, lig_dw, prot_hw = [], [], [], []
    for w in water:
        for acc1 in lig_hba:
            dist = euclidean3d(acc1.a.coords, w.oxy.coords)
            if config.WATER_BRIDGE_MINDIST <= dist <= config.WATER_BRIDGE_MAXDIST:
                lig_aw.append((acc1, w, dist))
        for acc2 in bs_hba:
            dist = euclidean3d(acc2.a.coords, w.oxy.coords)
            if config.WATER_BRIDGE_MINDIST <= dist <= config.WATER_BRIDGE_MAXDIST:
                prot_aw.append((acc2, w, dist))
        for don1 in lig_hbd:
            dist = euclidean3d(don1.d.coords, w.oxy.coords)
            d_angle = vecangle(vector(don1.h.coords, don1.d.coords), vector(don1.h.coords, w.oxy.coords))
            if config.WATER_BRIDGE_MINDIST <= dist <= config.WATER_BRIDGE_MAXDIST \
                    and d_angle > config.WATER_BRIDGE_THETA_MIN:
                lig_dw.append((don1, w, dist, d_angle))
        for don2 in bs_hbd:
            dist = euclidean3d(don2.d.coords, w.oxy.coords)
            d_angle = vecangle(vector(don2.h.coords, don2.d.coords), vector(don2.h.coords, w.oxy.coords))
            if config.WATER_BRIDGE_MINDIST <= dist <= config.WATER_BRIDGE_MAXDIST \
                    and d_angle > config.WATER_BRIDGE_THETA_MIN:
                prot_hw.append((don2, w, dist, d_angle))

    for l, p in itertools.product(lig_aw, prot_hw):
        acc, wl, distance_aw = l
        don, wd, distance_dw, d_angle = p
        if not wl.oxy == wd.oxy:
            continue
        # Same water molecule and angle within omega
        w_angle = vecangle(vector(acc.a.coords, wl.oxy.coords), vector(wl.oxy.coords, don.h.coords))
        if not config.WATER_BRIDGE_OMEGA_MIN < w_angle < config.WATER_BRIDGE_OMEGA_MAX:
            continue
        resnr, reschain, restype = whichresnumber(don.d), whichchain(don.d), whichrestype(don.d)
        resnr_l, reschain_l, restype_l = whichresnumber(acc.a_orig_atom), whichchain(
            acc.a_orig_atom), whichrestype(acc.a_orig_atom)
        contact = data(a=acc.a, a_orig_idx=acc.a_orig_idx, atype=acc.a.type, d=don.d, d_orig_idx=don.d_orig_idx,
                       dtype=don.d.type, h=don.h, water=wl.oxy, water_orig_idx=wl.oxy_orig_idx,
                       distance_aw=distance_aw, distance_dw=distance_dw, d_angle=d_angle, w_angle=w_angle,
                       type='first_deg', resnr=resnr, restype=restype,
                       reschain=reschain, restype_l=restype_l, resnr_l=resnr_l, reschain_l=reschain_l, protisdon=True)
        pairings.append(contact)
    for p, l in itertools.product(prot_aw, lig_dw):
        acc, wl, distance_aw = p
        don, wd, distance_dw, d_angle = l
        if not wl.oxy == wd.oxy:
            continue
        # Same water molecule and angle within omega
        w_angle = vecangle(vector(acc.a.coords, wl.oxy.coords), vector(wl.oxy.coords, don.h.coords))
        if not config.WATER_BRIDGE_OMEGA_MIN < w_angle < config.WATER_BRIDGE_OMEGA_MAX:
            continue
        resnr, reschain, restype = whichresnumber(acc.a), whichchain(acc.a), whichrestype(acc.a)
        resnr_l, reschain_l, restype_l = whichresnumber(don.d_orig_atom), whichchain(
            don.d_orig_atom), whichrestype(don.d_orig_atom)
        contact = data(a=acc.a, a_orig_idx=acc.a_orig_idx, atype=acc.a.type, d=don.d, d_orig_idx=don.d_orig_idx,
                       dtype=don.d.type, h=don.h, water=wl.oxy, water_orig_idx=wl.oxy_orig_idx,
                       distance_aw=distance_aw, distance_dw=distance_dw,
                       d_angle=d_angle, w_angle=w_angle, type='first_deg', resnr=resnr,
                       restype=restype, reschain=reschain,
                       restype_l=restype_l, reschain_l=reschain_l, resnr_l=resnr_l, protisdon=False)
        pairings.append(contact)
    return filter_contacts(pairings)
423205
def salt_cp():
    '''
    
    '''
    import salt.cli.cp
    client = salt.cli.cp.SaltCPCli()
    _install_signal_handlers(client)
    client.run()
267950
def _salt_to_os_path(path):
    '''
    
    '''
    return os.path.normpath(path.replace(posixpath.sep, os.path.sep))
1231075
private SgroupBracket newCrossingBracket(IBond bond, Multimap<IBond,Sgroup> bonds, Map<IBond,Integer> counter, boolean vert) {
        final IAtom beg = bond.getBegin();
        final IAtom end = bond.getEnd();
        final Point2d begXy = beg.getPoint2d();
        final Point2d endXy = end.getPoint2d();
        final Vector2d lenOffset = new Vector2d(endXy.x-begXy.x, endXy.y-begXy.y);
        final Vector2d bndCrossVec = new Vector2d(-lenOffset.y, lenOffset.x);
        lenOffset.normalize();
        bndCrossVec.normalize();
        bndCrossVec.scale(((0.9 * bondLength)) / 2);

        final List<Sgroup> sgroups = new ArrayList<>(bonds.get(bond));

        // bond in sgroup, place it in the middle of the bond
        if (sgroups.size() == 1) {
            lenOffset.scale(0.5 * bondLength);
        }
        // two sgroups, place one near start and one near end
        else if (sgroups.size() == 2) {
            boolean flip = !sgroups.get(counter.get(bond)).getAtoms().contains(beg);
            if (counter.get(bond) == 0) {
                lenOffset.scale(flip ? 0.75 : 0.25 * bondLength); // 75 or 25% along
                counter.put(bond, 1);
            } else {
                lenOffset.scale(flip ? 0.25 : 0.75 * bondLength); // 25 or 75% along
            }
        }
        else {
            double step = bondLength / (1 + sgroups.size());
            int idx = counter.get(bond) + 1;
            counter.put(bond, idx);
            lenOffset.scale((idx * step) * bondLength);
        }

        // vertical bracket
        if (vert) {
            return new SgroupBracket(begXy.x + lenOffset.x, begXy.y + lenOffset.y + bndCrossVec.length(),
                                     begXy.x + lenOffset.x, begXy.y + lenOffset.y - bndCrossVec.length());
        } else {
            return new SgroupBracket(begXy.x + lenOffset.x + bndCrossVec.x, begXy.y + lenOffset.y + bndCrossVec.y,
                                     begXy.x + lenOffset.x - bndCrossVec.x, begXy.y + lenOffset.y - bndCrossVec.y);
        }
    }
270915
def _linux_brshow(br=None):
    '''
    
    '''
    brctl = _tool_path('brctl')

    if br:
        cmd = '{0} show {1}'.format(brctl, br)
    else:
        cmd = '{0} show'.format(brctl)

    brs = {}

    for line in __salt__['cmd.run'](cmd, python_shell=False).splitlines():
        # get rid of first line
        if line.startswith('bridge name'):
            continue
        # get rid of ^\n's
        vals = line.split()
        if not vals:
            continue

        # bridge name bridge id       STP enabled interfaces
        # br0       8000.e4115bac8ddc   no      eth0
        #                                       foo0
        # br1       8000.e4115bac8ddc   no      eth1
        if len(vals) > 1:
            brname = vals[0]

            brs[brname] = {
                'id': vals[1],
                'stp': vals[2],
            }
            if len(vals) > 3:
                brs[brname]['interfaces'] = [vals[3]]

        if len(vals) == 1 and brname:
            brs[brname]['interfaces'].append(vals[0])

    if br:
        try:
            return brs[br]
        except KeyError:
            return None
    return brs
141946
def _plot(self):
        """"""
        squares = self._squares()
        sq_dimensions = self.add_squares(squares)

        for index, serie in enumerate(self.series):
            current_square = self._current_square(squares, index)
            self.gaugify(serie, squares, sq_dimensions, current_square)
894391
def show_halogen(self):
        """"""
        halogen = self.plcomplex.halogen_bonds
        all_don_x, all_acc_o = [], []
        for h in halogen:
            all_don_x.append(h.don_id)
            all_acc_o.append(h.acc_id)
            cmd.select('tmp_bs', 'id %i & %s' % (h.acc_id, self.protname))
            cmd.select('tmp_lig', 'id %i & %s' % (h.don_id, self.ligname))

            cmd.distance('HalogenBonds', 'tmp_bs', 'tmp_lig')
        if not len(all_acc_o) == 0:
            self.select_by_ids('HalogenAccept', all_acc_o, restrict=self.protname)
            self.select_by_ids('HalogenDonor', all_don_x, restrict=self.ligname)
        if self.object_exists('HalogenBonds'):
            cmd.set('dash_color', 'greencyan', 'HalogenBonds')
764512
function ( buffers, geoInfo, facePositionIndexes, materialIndex, faceNormals, faceColors, faceUVs, faceWeights, faceWeightIndices, faceLength ) {

			for ( var i = 2; i < faceLength; i ++ ) {

				buffers.vertex.push( geoInfo.vertexPositions[ facePositionIndexes[ 0 ] ] );
				buffers.vertex.push( geoInfo.vertexPositions[ facePositionIndexes[ 1 ] ] );
				buffers.vertex.push( geoInfo.vertexPositions[ facePositionIndexes[ 2 ] ] );

				buffers.vertex.push( geoInfo.vertexPositions[ facePositionIndexes[ ( i - 1 ) * 3 ] ] );
				buffers.vertex.push( geoInfo.vertexPositions[ facePositionIndexes[ ( i - 1 ) * 3 + 1 ] ] );
				buffers.vertex.push( geoInfo.vertexPositions[ facePositionIndexes[ ( i - 1 ) * 3 + 2 ] ] );

				buffers.vertex.push( geoInfo.vertexPositions[ facePositionIndexes[ i * 3 ] ] );
				buffers.vertex.push( geoInfo.vertexPositions[ facePositionIndexes[ i * 3 + 1 ] ] );
				buffers.vertex.push( geoInfo.vertexPositions[ facePositionIndexes[ i * 3 + 2 ] ] );

				if ( geoInfo.skeleton ) {

					buffers.vertexWeights.push( faceWeights[ 0 ] );
					buffers.vertexWeights.push( faceWeights[ 1 ] );
					buffers.vertexWeights.push( faceWeights[ 2 ] );
					buffers.vertexWeights.push( faceWeights[ 3 ] );

					buffers.vertexWeights.push( faceWeights[ ( i - 1 ) * 4 ] );
					buffers.vertexWeights.push( faceWeights[ ( i - 1 ) * 4 + 1 ] );
					buffers.vertexWeights.push( faceWeights[ ( i - 1 ) * 4 + 2 ] );
					buffers.vertexWeights.push( faceWeights[ ( i - 1 ) * 4 + 3 ] );

					buffers.vertexWeights.push( faceWeights[ i * 4 ] );
					buffers.vertexWeights.push( faceWeights[ i * 4 + 1 ] );
					buffers.vertexWeights.push( faceWeights[ i * 4 + 2 ] );
					buffers.vertexWeights.push( faceWeights[ i * 4 + 3 ] );

					buffers.weightsIndices.push( faceWeightIndices[ 0 ] );
					buffers.weightsIndices.push( faceWeightIndices[ 1 ] );
					buffers.weightsIndices.push( faceWeightIndices[ 2 ] );
					buffers.weightsIndices.push( faceWeightIndices[ 3 ] );

					buffers.weightsIndices.push( faceWeightIndices[ ( i - 1 ) * 4 ] );
					buffers.weightsIndices.push( faceWeightIndices[ ( i - 1 ) * 4 + 1 ] );
					buffers.weightsIndices.push( faceWeightIndices[ ( i - 1 ) * 4 + 2 ] );
					buffers.weightsIndices.push( faceWeightIndices[ ( i - 1 ) * 4 + 3 ] );

					buffers.weightsIndices.push( faceWeightIndices[ i * 4 ] );
					buffers.weightsIndices.push( faceWeightIndices[ i * 4 + 1 ] );
					buffers.weightsIndices.push( faceWeightIndices[ i * 4 + 2 ] );
					buffers.weightsIndices.push( faceWeightIndices[ i * 4 + 3 ] );

				}

				if ( geoInfo.color ) {

					buffers.colors.push( faceColors[ 0 ] );
					buffers.colors.push( faceColors[ 1 ] );
					buffers.colors.push( faceColors[ 2 ] );

					buffers.colors.push( faceColors[ ( i - 1 ) * 3 ] );
					buffers.colors.push( faceColors[ ( i - 1 ) * 3 + 1 ] );
					buffers.colors.push( faceColors[ ( i - 1 ) * 3 + 2 ] );

					buffers.colors.push( faceColors[ i * 3 ] );
					buffers.colors.push( faceColors[ i * 3 + 1 ] );
					buffers.colors.push( faceColors[ i * 3 + 2 ] );

				}

				if ( geoInfo.material && geoInfo.material.mappingType !== 'AllSame' ) {

					buffers.materialIndex.push( materialIndex );
					buffers.materialIndex.push( materialIndex );
					buffers.materialIndex.push( materialIndex );

				}

				if ( geoInfo.normal ) {

					buffers.normal.push( faceNormals[ 0 ] );
					buffers.normal.push( faceNormals[ 1 ] );
					buffers.normal.push( faceNormals[ 2 ] );

					buffers.normal.push( faceNormals[ ( i - 1 ) * 3 ] );
					buffers.normal.push( faceNormals[ ( i - 1 ) * 3 + 1 ] );
					buffers.normal.push( faceNormals[ ( i - 1 ) * 3 + 2 ] );

					buffers.normal.push( faceNormals[ i * 3 ] );
					buffers.normal.push( faceNormals[ i * 3 + 1 ] );
					buffers.normal.push( faceNormals[ i * 3 + 2 ] );

				}

				if ( geoInfo.uv ) {

					geoInfo.uv.forEach( function ( uv, j ) {

						if ( buffers.uvs[ j ] === undefined ) buffers.uvs[ j ] = [];

						buffers.uvs[ j ].push( faceUVs[ j ][ 0 ] );
						buffers.uvs[ j ].push( faceUVs[ j ][ 1 ] );

						buffers.uvs[ j ].push( faceUVs[ j ][ ( i - 1 ) * 2 ] );
						buffers.uvs[ j ].push( faceUVs[ j ][ ( i - 1 ) * 2 + 1 ] );

						buffers.uvs[ j ].push( faceUVs[ j ][ i * 2 ] );
						buffers.uvs[ j ].push( faceUVs[ j ][ i * 2 + 1 ] );

					} );

				}

			}

		}
259810
def lines(self):
        '''

        '''
        if "bonds" not in self.topology:
            return

        bond_start, bond_end = zip(*self.topology['bonds'])
        bond_start = np.array(bond_start)
        bond_end = np.array(bond_end)

        color_array = np.array([get_atom_color(t) for t in self.topology['atom_types']])
        lines = self.add_representation('lines', {'startCoords': self.coordinates[bond_start],
                                                  'endCoords': self.coordinates[bond_end],
                                                  'startColors': color_array[bond_start].tolist(),
                                                  'endColors': color_array[bond_end].tolist()})

        def update(self=self, lines=lines):
            bond_start, bond_end = zip(*self.topology['bonds'])
            bond_start = np.array(bond_start)
            bond_end = np.array(bond_end)

            self.update_representation(lines, {'startCoords': self.coordinates[bond_start],
                                                 'endCoords': self.coordinates[bond_end]})
        self.update_callbacks.append(update)
        self.autozoom(self.coordinates)
793979
def show_top(**kwargs):
    '''
    
    '''
    __opts__['grains'] = __grains__
    opts = salt.utils.state.get_sls_opts(__opts__, **kwargs)
    st_ = salt.client.ssh.state.SSHHighState(
            opts,
            __pillar__,
            __salt__,
            __context__['fileclient'])
    top_data = st_.get_top()
    errors = []
    errors += st_.verify_tops(top_data)
    if errors:
        return errors
    matches = st_.top_matches(top_data)
    return matches
748710
def build_visualization(ontouri, g, viz_index, path=None, title="", theme=""):
    

    this_viz = VISUALIZATIONS_LIST[viz_index]

    if this_viz['ID'] == "html-simple":
        from .viz.viz_html_single import HTMLVisualizer
        v = HTMLVisualizer(g, title)

    elif this_viz['ID'] == "html-complex":
        from .viz.viz_html_multi import KompleteViz
        v = KompleteViz(g, title, theme)

    elif this_viz['ID'] == "markdown":
        from .viz.viz_markdown import MarkdownViz
        v = MarkdownViz(g, title)

    elif this_viz['ID'] == "d3-tree":
        from .viz.viz_d3tree import Dataviz
        v = Dataviz(g, title)

    elif this_viz['ID'] == "d3-bubble-chart":
        from .viz.viz_d3bubbleChart import Dataviz
        v = Dataviz(g, title)

    elif this_viz['ID'] == "d3-pack-hierarchy":
        from .viz.viz_d3packHierarchy import Dataviz
        v = Dataviz(g, title)

    elif this_viz['ID'] == "d3-bar-hierarchy":
        from .viz.viz_d3barHierarchy import Dataviz
        v = Dataviz(g, title)

    elif this_viz['ID'] == "d3-partition-table":
        from .viz.viz_d3partitionTable import Dataviz
        v = Dataviz(g, title)

    elif this_viz['ID'] == "d3-rotating-cluster":
        from .viz.viz_d3rotatingCluster import Dataviz
        v = Dataviz(g, title)

    elif this_viz['ID'] == "sigma-force-directed":
        from .viz.viz_sigmajs import Dataviz
        v = Dataviz(g, title)

    else:
        return False

    url = v.build(path)

    return url
716347
def render(self,
               horizontal_spacing: int = 1,
               vertical_spacing: int = 1,
               crossing_char: str = None,
               use_unicode_characters: bool = True) -> str:
        """"""

        block_diagram = BlockDiagramDrawer()

        w = self.width()
        h = self.height()

        # Communicate padding into block diagram.
        for x in range(0, w - 1):
            block_diagram.set_col_min_width(
                x*2 + 1,
                # Horizontal separation looks narrow, so partials round up.
                int(np.ceil(self.horizontal_padding.get(x, horizontal_spacing)))
            )
            block_diagram.set_col_min_width(x*2, 1)
        for y in range(0, h - 1):
            block_diagram.set_row_min_height(
                y*2 + 1,
                # Vertical separation looks wide, so partials round down.
                int(np.floor(self.vertical_padding.get(y, vertical_spacing)))
            )
            block_diagram.set_row_min_height(y*2, 1)

        # Draw vertical lines.
        for x_b, y1_b, y2_b, emphasize in self.vertical_lines:
            x = int(x_b * 2)
            y1, y2 = int(min(y1_b, y2_b) * 2), int(max(y1_b, y2_b) * 2)
            charset = pick_charset(use_unicode_characters, emphasize)

            # Caps.
            block_diagram.mutable_block(x, y1).draw_curve(
                charset, bottom=True)
            block_diagram.mutable_block(x, y2).draw_curve(
                charset, top=True)

            # Span.
            for y in range(y1 + 1, y2):
                block_diagram.mutable_block(x, y).draw_curve(
                    charset, top=True, bottom=True)

        # Draw horizontal lines.
        for y_b, x1_b, x2_b, emphasize in self.horizontal_lines:
            y = int(y_b * 2)
            x1, x2 = int(min(x1_b, x2_b) * 2), int(max(x1_b, x2_b) * 2)
            charset = pick_charset(use_unicode_characters, emphasize)

            # Caps.
            block_diagram.mutable_block(x1, y).draw_curve(
                charset, right=True)
            block_diagram.mutable_block(x2, y).draw_curve(
                charset, left=True)

            # Span.
            for x in range(x1 + 1, x2):
                block_diagram.mutable_block(x, y).draw_curve(
                    charset, left=True, right=True, crossing_char=crossing_char)

        # Place entries.
        for (x, y), v in self.entries.items():
            x *= 2
            y *= 2
            block_diagram.mutable_block(x, y).content = v.text

        return block_diagram.render()