예제 #1
0
def loadInterfacePDB(file,name=None,native=None,wt=None):

	print " Loading interface PDB %s"%(file)

	if name is None:
		name = name = os.path.basename(file)
	if name.endswith('.pdb'):
		name = name[:-4] 

	# Call Will's packing PDB loading function
	# Note: proteins will be cartoons, cavities will be spheres
	# Rosetta radii will be enabled
	name = loadPackingPDB(file,name,native)

	cavselname  = name+"cavities"
	protselname = name+"protein"
	cmd.hide("lines",protselname)

	backbone_colorlist = ['green', 'yellow', 'violet', 'cyan',    \
		   'salmon', 'lime', 'slate', 'magenta', 'orange', 'marine', \
		   'olive', 'forest', 'firebrick', 'chocolate' ]
	curr_bb_color = 0

 	carbon_colorlist = ['teal', 'wheat', 'grey', 'pink' ]
	curr_carbon_color = 0

	# Derive selections for the interface, color by chain
	cmd.select("interface", "none")
	cmd.select("heavy_interface", "none")
	selectPolarProtons("polar_protons")
	selectApolarProtons("apolar_protons")
	alphabet = list(('abcdefghijklmnopqrstuvwxyz').upper())
	for letter in alphabet:
		chainname = "chain"+letter
		cmd.select( chainname, "chain %s and not hetatm and not symbol w"%(letter) )

		# Check whether any protein atoms exist with this chain ID
		# JK Later, put in a special "non-interface" case for L/H antibody chains
		if cmd.count_atoms("chain%s"%(letter))>0:
			interfacename = "interface"+letter
			cmd.select("not_this_chain", "not hetatm and not symbol w and not %s"%(chainname) )
			cmd.select(interfacename, "byres %s and (not_this_chain around 4.0)"%(chainname) )
			cmd.select("heavy_%s"%(interfacename), "%s and not apolar_protons"%(interfacename))
			cmd.select("interface", "interface or %s"%(interfacename) )
			cmd.select("heavy_interface", "heavy_interface or heavy_%s"%(interfacename) )
			cmd.delete("not_this_chain")

			cmd.color(backbone_colorlist[curr_bb_color], chainname)
			curr_bb_color = curr_bb_color+1
			if(curr_bb_color == len(backbone_colorlist)):
				curr_bb_color = 0

			colorCPK(interfacename,carbon_colorlist[curr_carbon_color])
			curr_carbon_color = curr_carbon_color+1
			if(curr_carbon_color == len(carbon_colorlist)):
				curr_carbon_color = 0
			cmd.color("white", "%s and polar_protons"%(interfacename))

		else:
			cmd.delete(chainname)

	cmd.delete("apolar_protons")
	cmd.delete("polar_protons")

	# Show the interface in sticks, colored cpk
	#cmd.hide( "cartoon", "interface" )
	cmd.show( "sticks", "heavy_interface" )
	cmd.zoom("interface")

	cmd.show( "cartoon", "(not interface) or byres(neighbor(interface)) or byres(neighbor(byres(neighbor(interface))))" )

	# Show interface waters as small purple spheres
	cmd.select( "interface_water", "(symbol w or resn HOH) and (interface around 8.0)")
	if cmd.count_atoms("interface_water")>0:
		# Put the waters in a separate object, so that we can scale their radii
		newwatername = name+"waters"
		cmd.create(newwatername, "interface_water")
		cmd.remove("interface_water")
		cmd.color("purple", newwatername)
		cmd.show( "spheres", newwatername )
		#cmd.set( "sphere_scale", 0.5, newwatername )
		cmd.set( "sphere_scale", 0.1, newwatername )
	else:
		cmd.delete("interface_water")

	# Show interface ligands as pink sticks
	cmd.select( "interface_hetero", "(not symbol w and not resn HOH) and (hetatm and not symbol w and not resn WSS) and (interface around 4.5)")
	if cmd.count_atoms("interface_hetero")>0:
		cmd.color("pink", "interface_hetero")
		cmd.show( "sticks", "interface_hetero" )
	else:
		cmd.delete("interface_hetero")

	cmd.select("none")
   	cmd.load( wt, "wt" ) 
   	cmd.create( "wt_A", "wt and chain A" ) 
   	cmd.create( "wt_B", "wt and chain B" ) 
   	cmd.select("none") 
   	cmd.create( "des_A", "not wt and chain A" ) 
   	cmd.show( "surface", "des_A" ) 
   	cmd.create( "des_B", "not wt and chain B") 
   	cmd.show( "surface", "des_B" ) 
   	cmd.align( "wt_A", "des_A" ) 
   	cmd.align( "wt_B", "des_B" ) 
#   cmd.show( "lines", "wt_A" ) 
#   cmd.show( "lines", "wt_B" ) 
  	cmd.set( "transparency", 1 ) 
	cmd.zoom("interface") 
	return name
def loadInterfacePDB(file, name=None, native=None, wt=None):

    print " Loading interface PDB %s" % (file)

    if name is None:
        name = name = os.path.basename(file)
    if name.endswith('.pdb'):
        name = name[:-4]

    # Call Will's packing PDB loading function
    # Note: proteins will be cartoons, cavities will be spheres
    # Rosetta radii will be enabled
    name = loadPackingPDB(file, name, native)

    cavselname = name + "cavities"
    protselname = name + "protein"
    cmd.hide("lines", protselname)

    backbone_colorlist = ['green', 'yellow', 'violet', 'cyan',    \
        'salmon', 'lime', 'slate', 'magenta', 'orange', 'marine', \
        'olive', 'forest', 'firebrick', 'chocolate' ]
    curr_bb_color = 0

    carbon_colorlist = ['teal', 'wheat', 'grey', 'pink']
    curr_carbon_color = 0

    # Derive selections for the interface, color by chain
    cmd.select("interface", "none")
    cmd.select("heavy_interface", "none")
    selectPolarProtons("polar_protons")
    selectApolarProtons("apolar_protons")
    alphabet = list(('abcdefghijklmnopqrstuvwxyz').upper())
    for letter in alphabet:
        chainname = "chain" + letter
        cmd.select(chainname,
                   "chain %s and not hetatm and not symbol w" % (letter))

        # Check whether any protein atoms exist with this chain ID
        # JK Later, put in a special "non-interface" case for L/H antibody chains
        if cmd.count_atoms("chain%s" % (letter)) > 0:
            interfacename = "interface" + letter
            cmd.select("not_this_chain",
                       "not hetatm and not symbol w and not %s" % (chainname))
            cmd.select(
                interfacename,
                "byres %s and (not_this_chain around 4.0)" % (chainname))
            cmd.select("heavy_%s" % (interfacename),
                       "%s and not apolar_protons" % (interfacename))
            cmd.select("interface", "interface or %s" % (interfacename))
            cmd.select("heavy_interface",
                       "heavy_interface or heavy_%s" % (interfacename))
            cmd.delete("not_this_chain")

            cmd.color(backbone_colorlist[curr_bb_color], chainname)
            curr_bb_color = curr_bb_color + 1
            if (curr_bb_color == len(backbone_colorlist)):
                curr_bb_color = 0

            colorCPK(interfacename, carbon_colorlist[curr_carbon_color])
            curr_carbon_color = curr_carbon_color + 1
            if (curr_carbon_color == len(carbon_colorlist)):
                curr_carbon_color = 0
            cmd.color("white", "%s and polar_protons" % (interfacename))

        else:
            cmd.delete(chainname)

    cmd.delete("apolar_protons")
    cmd.delete("polar_protons")

    # Show the interface in sticks, colored cpk
    #cmd.hide( "cartoon", "interface" )
    cmd.show("sticks", "heavy_interface")
    cmd.zoom("interface")

    cmd.show(
        "cartoon",
        "(not interface) or byres(neighbor(interface)) or byres(neighbor(byres(neighbor(interface))))"
    )

    # Show interface waters as small purple spheres
    cmd.select("interface_water",
               "(symbol w or resn HOH) and (interface around 8.0)")
    if cmd.count_atoms("interface_water") > 0:
        # Put the waters in a separate object, so that we can scale their radii
        newwatername = name + "waters"
        cmd.create(newwatername, "interface_water")
        cmd.remove("interface_water")
        cmd.color("purple", newwatername)
        cmd.show("spheres", newwatername)
        #cmd.set( "sphere_scale", 0.5, newwatername )
        cmd.set("sphere_scale", 0.1, newwatername)
    else:
        cmd.delete("interface_water")

    # Show interface ligands as pink sticks
    cmd.select(
        "interface_hetero",
        "(not symbol w and not resn HOH) and (hetatm and not symbol w and not resn WSS) and (interface around 4.5)"
    )
    if cmd.count_atoms("interface_hetero") > 0:
        cmd.color("pink", "interface_hetero")
        cmd.show("sticks", "interface_hetero")
    else:
        cmd.delete("interface_hetero")

    cmd.select("none")
    cmd.load(wt, "wt")
    cmd.create("wt_A", "wt and chain A")
    cmd.create("wt_B", "wt and chain B")
    cmd.select("none")
    cmd.create("des_A", "not wt and chain A")
    cmd.show("surface", "des_A")
    cmd.create("des_B", "not wt and chain B")
    cmd.show("surface", "des_B")
    cmd.align("wt_A", "des_A")
    cmd.align("wt_B", "des_B")
    #   cmd.show( "lines", "wt_A" )
    #   cmd.show( "lines", "wt_B" )
    cmd.set("transparency", 1)
    cmd.zoom("interface")
    return name
예제 #3
0
def colorInterface(name="(all)"):
    """
    colorInterfacePDB [<name>] 

    Color by chain and show interface features.
    """

    cmd.hide("lines",name)

    backbone_colorlist = ['green', 'yellow', 'violet', 'cyan',    \
           'salmon', 'lime', 'slate', 'magenta', 'orange', 'marine', \
           'olive', 'forest', 'firebrick', 'chocolate' ]
    curr_bb_color = 1

    carbon_colorlist = ['teal', 'wheat', 'grey', 'pink' ]
    curr_carbon_color = 1

    # Derive selections for the interface, color by chain
    cmd.select("interface", "none")
    cmd.select("heavy_interface", "none")
    selectPolarProtons("polar_protons")
    selectApolarProtons("apolar_protons")
    alphabet = list(('abcdefghijklmnopqrstuvwxyz').upper())
    for letter in alphabet:
        chainname = "chain"+letter
        cmd.select( chainname, "chain %s and not hetatm and not symbol w and %s" % (letter, name) )

        # Check whether any protein atoms exist with this chain ID
        # JK Later, put in a special "non-interface" case for L/H antibody chains
        if cmd.count_atoms("chain%s"%(letter))>0:
            interfacename = "interface"+letter
            cmd.select("not_this_chain", "not hetatm and not symbol w and not %s and %s" % (chainname, name) )
            cmd.select(interfacename, "byres %s and (not_this_chain around 6.0)"%(chainname) )
            cmd.select("heavy_%s"%(interfacename), "%s and not apolar_protons"%(interfacename))
            cmd.select("interface", "interface or %s"%(interfacename) )
            cmd.select("heavy_interface", "heavy_interface or heavy_%s"%(interfacename) )
            cmd.delete("not_this_chain")

            cmd.color(backbone_colorlist[curr_bb_color], chainname)
            colorCPK(interfacename,backbone_colorlist[curr_bb_color])
            curr_bb_color = curr_bb_color+1
            if(curr_bb_color == len(backbone_colorlist)):
                curr_bb_color = 0

            curr_carbon_color = curr_carbon_color+1
            if(curr_carbon_color == len(carbon_colorlist)):
                curr_carbon_color = 0
            cmd.color("white", "%s and polar_protons"%(interfacename))

        else:
            cmd.delete(chainname)

    cmd.delete("apolar_protons")
    cmd.delete("polar_protons")

    # Show the interface in sticks, colored cpk
#   cmd.hide( "cartoon", "interface" )
    cmd.show( "sticks", "heavy_interface" )

    #cmd.show( "cartoon", "(not interface) or byres(neighbor(interface)) or byres(neighbor(byres(neighbor(interface))))" )
    cmd.show( "cartoon", name )

    # Show interface waters as small purple spheres
    cmd.select( "interface_water", "(symbol w or resn HOH) and (interface around 8.0)")
    if cmd.count_atoms("interface_water")>0:
        # Put the waters in a separate object, so that we can scale their radii
        newwatername = name+"waters"
        cmd.create(newwatername, "interface_water")
        cmd.remove("interface_water")
        cmd.color("purple", newwatername)
        cmd.show( "spheres", newwatername )
        cmd.set( "sphere_scale", 0.1, newwatername )

    else:
        cmd.delete("interface_water")

    # Show interface ligands as pink sticks
    cmd.select( "interface_hetero", "(not symbol w and not resn HOH) and (hetatm and not symbol w and not resn WSS) and (interface around 4.5)")
    if cmd.count_atoms("interface_hetero")>0:
        cmd.color("pink", "interface_hetero")
        cmd.show( "sticks", "interface_hetero" )
    else:
        cmd.delete("interface_hetero")

    cmd.set( "transparency", 1 )
    cmd.zoom("interface")
    return name
def stix():

	backbone_colorlist = ['plutonium','wheat','green', 'yellow', 'violet', 'cyan',    \
		   'salmon', 'lime', 'slate', 'magenta', 'orange', 'marine', \
		   'olive', 'forest', 'firebrick', 'chocolate' ]
	curr_bb_color = 0

 	carbon_colorlist = ['teal', 'wheat', 'grey', 'pink' ]
	curr_carbon_color = 0

	# Derive selections for the interface, color by chain
	cmd.select("interface", "none")
	cmd.select("heavy_interface", "none")
	selectPolarProtons("polar_protons")
	selectApolarProtons("apolar_protons")
	alphabet = list(('abcdefghijklmnopqrstuvwxyz').upper())
	for letter in alphabet:
		chainname = "chain"+letter
		cmd.select( chainname, "chain %s and not hetatm and not symbol w"%(letter) )

		# Check whether any protein atoms exist with this chain ID
		# JK Later, put in a special "non-interface" case for L/H antibody chains
		if cmd.count_atoms("chain%s"%(letter))>0:
			interfacename = "interface"+letter
			cmd.select("not_this_chain", "not hetatm and not symbol w and not %s"%(chainname) )
			cmd.select(interfacename, "byres %s and (not_this_chain around 4.0)"%(chainname) )
			cmd.select("heavy_%s"%(interfacename), "%s and not apolar_protons"%(interfacename))
			cmd.select("interface", "interface or %s"%(interfacename) )
			cmd.select("heavy_interface", "heavy_interface or heavy_%s"%(interfacename) )
			cmd.delete("not_this_chain")

			cmd.color(backbone_colorlist[curr_bb_color], chainname)
			colorCPK(chainname,backbone_colorlist[curr_bb_color])
			curr_bb_color = curr_bb_color+1
			if(curr_bb_color == len(backbone_colorlist)):
				curr_bb_color = 0

			#colorCPK(interfacename,carbon_colorlist[curr_carbon_color])
			curr_carbon_color = curr_carbon_color+1
			if(curr_carbon_color == len(carbon_colorlist)):
				curr_carbon_color = 0
			cmd.color("white", "%s and polar_protons"%(interfacename))

		else:
			cmd.delete(chainname)

	cmd.delete("apolar_protons")
	cmd.delete("polar_protons")

	# Show the interface in sticks, colored cpk
	#cmd.hide( "cartoon", "interface" )
	cmd.show( "sticks", "not hydro" )
	cmd.zoom("interface")

	cmd.show( "cartoon", "(not interface) or byres(neighbor(interface)) or byres(neighbor(byres(neighbor(interface))))" )

	# Show interface waters as small purple spheres
	cmd.select( "interface_water", "(symbol w or resn HOH) and (interface around 8.0)")
	if cmd.count_atoms("interface_water")>0:
		# Put the waters in a separate object, so that we can scale their radii
		newwatername = name+"waters"
		cmd.create(newwatername, "interface_water")
		cmd.remove("interface_water")
		cmd.color("purple", newwatername)
		cmd.show( "spheres", newwatername )
		cmd.set( "sphere_scale", 0.1, newwatername )

	else:
		cmd.delete("interface_water")

	# Show interface ligands as pink sticks
	cmd.select( "interface_hetero", "(not symbol w and not resn HOH) and (hetatm and not symbol w and not resn WSS) and (interface around 4.5)")
	if cmd.count_atoms("interface_hetero")>0:
		cmd.color("pink", "interface_hetero")
		cmd.show( "sticks", "interface_hetero" )
	else:
		cmd.delete("interface_hetero")
	
	    # Show polar contacts
        #cmd.distance("hbonds","interfaceA","interfaceB",3.2,mode=1)
        cmd.distance("hbonds","interfaceA","interfaceB",4.5,mode=2)
        #cmd.distance("hbonds","interfaceA","interfaceB",3.2,mode=3)


        cmd.hide("labels")
        cmd.hide("lines")
	cmd.select("none")
def surfaceInterfacePDB():
        cmd.hide("lines")

        backbone_colorlist = [ 'forest','gold', 'violet', 'cyan',    \
                   'salmon', 'lime', 'slate', 'magenta', 'orange', 'marine', \
                   'olive', 'forest', 'firebrick', 'chocolate' ]
        curr_bb_color = 0

        carbon_colorlist = ['titanium', 'wheat', 'grey', 'pink' ]
        curr_carbon_color = 0

        # Derive selections for the interface, color by chain
        cmd.select("interface", "none")
        cmd.select("heavy_interface", "none")
        selectPolarProtons("polar_protons")
        selectApolarProtons("apolar_protons")
        alphabet = list(('abcdefghijklmnopqrstuvwxyz').upper())
        for letter in alphabet:
                chainname = "chain"+letter
                cmd.select( chainname, "chain %s and not hetatm and not symbol w"%(letter) )

                # Check whether any protein atoms exist with this chain ID
                # JK Later, put in a special "non-interface" case for L/H antibody chains
                if cmd.count_atoms("chain%s"%(letter))>0:
                        interfacename = "interface"+letter
                        cmd.select("not_this_chain", "not hetatm and not symbol w and not %s"%(chainname) )
                        cmd.select(interfacename, "byres %s and (not_this_chain around 4.0)"%(chainname) )
                        cmd.select("heavy_%s"%(interfacename), "%s and not apolar_protons"%(interfacename))
                        cmd.select("interface", "interface or %s"%(interfacename) )
                        cmd.select("heavy_interface", "heavy_interface or heavy_%s"%(interfacename) )
                        cmd.delete("not_this_chain")

                        cmd.color(backbone_colorlist[curr_bb_color], chainname)
                        #changing....
			colorCPK(interfacename,backbone_colorlist[curr_bb_color]) 
			curr_bb_color = curr_bb_color+1
                        if(curr_bb_color == len(backbone_colorlist)):
                                curr_bb_color = 0

                        #colorCPK(interfacename,carbon_colorlist[curr_carbon_color])
                        curr_carbon_color = curr_carbon_color+1
                        if(curr_carbon_color == len(carbon_colorlist)):
                                curr_carbon_color = 0
                        cmd.color("white", "%s and polar_protons"%(interfacename))

                else:
                        cmd.delete(chainname)

        cmd.delete("apolar_protons")
        cmd.delete("polar_protons")

        # Show the interface in sticks, colored cpk
        #cmd.hide( "cartoon", "interface" )
        cmd.show( "sticks", "heavy_interface" )

        cmd.create("design", "chain B")
        cmd.create("target", "chain A")
        cmd.show( "surface", "target" )
        cmd.show( "surface", "design" )

        cmd.set( "transparency", 0 )

        cmd.show( "cartoon", "(not interface) or byres(neighbor(interface)) or byres(neighbor(byres(neighbor(interface))))" )

        # Show interface waters as small purple spheres
        cmd.select( "interface_water", "(symbol w or resn HOH) and (interface around 8.0)")
        if cmd.count_atoms("interface_water")>0:
                # Put the waters in a separate object, so that we can scale their radii
                newwatername = name+"waters"
                cmd.create(newwatername, "interface_water")
                cmd.remove("interface_water")
                cmd.color("purple", newwatername)
                cmd.show( "spheres", newwatername )
                cmd.set( "sphere_scale", 0.1, newwatername )

        else:
                cmd.delete("interface_water")

        # Show interface ligands as pink sticks
        cmd.select( "interface_hetero", "(not symbol w and not resn HOH) and (hetatm and not symbol w and not resn WSS) and (interface around 4.5)")
        if cmd.count_atoms("interface_hetero")>0:
                cmd.color("pink", "interface_hetero")
                cmd.show( "sticks", "interface_hetero" )
        else:
                cmd.delete("interface_hetero")
        
        # Show polar contacts
        cmd.distance("hbonds","interfaceA","interfaceB",3.2,mode=2)
        cmd.hide("labels")
        
        # Show vacuum electrostatics
        cmd.util.protein_vacuum_esp("design", mode=2, quiet=0)
        cmd.util.protein_vacuum_esp("target", mode=2, quiet=0)

        cmd.disable("design_e_chg")
        cmd.disable("design_e_map")
        cmd.disable("design_e_pot")

        cmd.disable("target_e_chg")
        cmd.disable("target_e_map")
        cmd.disable("target_e_pot")

        cmd.disable("design")
        cmd.disable("target")

        cmd.zoom("interface")
        cmd.remove("sele")
        cmd.select("none")
예제 #6
0
def inner_lddt(interface=False):

    # Save the camera
    save_view = cmd.get_view(output=1, quiet=1)

    pdbname = cmd.get_object_list()[0]

    file_path = os.path.join(my_lddt_path, pdbname + ".npz")

    if ( not os.path.exists(file_path) ):
        print("Could not find npz file: %s"%file_path)
        return

    dat = np.load(file_path)

    ### Stuff from Nao

    digitizations = [-20.0, -15.0, -10.0, -4.0, -2.0, -1.0, -0.5, 0.5, 1.0, 2.0, 4.0, 10.0, 15.0, 20.0]
    masses = [digitizations[0]]+[(digitizations[i]+digitizations[i+1])/2 for i in range(len(digitizations)-1)]+[digitizations[-1]]

    def get_lddt(estogram, mask, center=7, weights=[1,1,1,1]):  
        # Remove diagonal from the mask.
        mask = np.multiply(mask, np.ones(mask.shape)-np.eye(mask.shape[0]))
        # Masking the estogram except for the last cahnnel
        masked = np.transpose(np.multiply(np.transpose(estogram, [2,0,1]), mask), [1,2,0])

        p0 = np.sum(masked[:,:,center], axis=-1)
        p1 = np.sum(masked[:,:,center-1]+masked[:,:,center+1], axis=-1)
        p2 = np.sum(masked[:,:,center-2]+masked[:,:,center+2], axis=-1)
        p3 = np.sum(masked[:,:,center-3]+masked[:,:,center+3], axis=-1)
        p4 = np.sum(mask, axis=-1)

        p4[p4==0] = 1
        # Only work on parts where interaction happen
        output = np.divide((weights[0]*p0 + weights[1]*(p0+p1) + weights[2]*(p0+p1+p2) + weights[3]*(p0+p1+p2+p3))/np.sum(weights), p4)
        return output

    #####

    # if interface, mask out the binder and the target to get individual lddts
    if ( interface ):

        blen = len(cmd.get_coords('name CA and chain A', 1))

        mask2 = np.zeros(dat['mask'].shape)
        mask2[:blen, blen:] = 1
        mask2[blen:, :blen] = 1

        my_lddt = get_lddt(dat['estogram'].transpose([1,2,0]), np.multiply(dat['mask'], mask2))

    else:

        my_lddt = get_lddt(dat['estogram'].transpose([1,2,0]), dat['mask'])


    print("========== Mean LDDT: %.2f"%np.mean(my_lddt))


    # colorspace for lddt visualization
    max_color = 121
    min_color = 0

    # interpolate on RGB so we don't see every color in between
    # set saturation to 0.5 so that we can distinguish from cylinders
    max_rgb = colorsys.hsv_to_rgb(max_color/360, 0.5, 1)
    min_rgb = colorsys.hsv_to_rgb(min_color/360, 0.5, 1)

    max_lddt = 1.0
    min_lddt = 0.5

    # color each residue the corresponding lddt color
    for seqpos in range(1, len(dat['mask'])):
        this_lddt = my_lddt[seqpos-1]
     
        r = np.interp(this_lddt, [min_lddt, max_lddt], [min_rgb[0], max_rgb[0]]) * 255
        g = np.interp(this_lddt, [min_lddt, max_lddt], [min_rgb[1], max_rgb[1]]) * 255
        b = np.interp(this_lddt, [min_lddt, max_lddt], [min_rgb[2], max_rgb[2]]) * 255

        color = "0x%02x%02x%02x"%(int(r), int(g), int(b))

        colorCPK("resi %i"%seqpos, color)

        # cmd.color(color, "resi %i"%seqpos,)


    # get 1 indexed ca positions
    cas = np.r_[ [[0, 0, 0]], cmd.get_coords('name CA', 1)]

    # max radius of cylinders (A)
    max_rad = 0.25

    # standard cylinder drawing function. color in HSV
    def get_cyl(start, end, rad_frac=1.0, color=[360, 0, 1]):

        rgb = colorsys.hsv_to_rgb(color[0]/360, color[1], color[2])

        radius = max_rad * rad_frac
        cyl = [
            # Tail of cylinder
            cgo.CYLINDER, start[0], start[1], start[2]
            , end[0], end[1], end[2]
            , radius, rgb[0], rgb[1], rgb[2], rgb[0], rgb[1], rgb[2]  # Radius and RGB for each cylinder tail
        ]

        return cyl


    def obj_exists(sele):
       return sele in cmd.get_names("objects")


    # clear out the old ones if we ran this twice
    for name in cmd.get_names("objects"):
        if (name.startswith("esto_res")):
            cmd.delete(name)


    estogram = np.transpose(dat['estogram'], [1, 2, 0])

    # parameters for cylinder colors
    # Since the lddt calculation maxes out at 4, we do so too
    # Also, fade near-0 to white so that we don't see sharp edges
    close_range_colors = [58, 0]
    far_range_colors = [167, 296]
    max_range = 4
    white_fade = 0.2

    # interpolate in hue space so that we do see all colors in-between
    def dist_to_color(dist):
        dist = np.clip(dist, -max_range, max_range)
        # dist = 2
        if ( dist < 0 ):
            bounds = close_range_colors
            dist = - dist
        else:
            bounds = far_range_colors

        hue = np.interp(dist, [0, max_range], bounds)
        sat = np.interp(dist, [0, white_fade], [0, 1])

        return [hue, sat, 1]

    # Mask is how likely the model things two residues are within 15A of each other
    # Don't draw cylinders for super distant residues
    min_mask = 0.1

    # actually draw the cylinders
    for seqpos in range(1, len(cas)):

        # pull out the estogram and mask for this position
        esto = estogram[seqpos-1] # shape (N x 15)
        mask = dat['mask'][seqpos-1] # shape (N)

        this_cgo = []

        for other in range(1, len(cas)):
            mask_edge = mask[other-1]
            if ( mask_edge < min_mask ):
                continue

            # estogram is a histogram of distances
            # this method comes directly from nao and takes the "center_of_mass" of that histogram
            esto_dist = np.sum(esto[other-1]*masses)

            color = dist_to_color(esto_dist)

            this_cgo += get_cyl(cas[seqpos], cas[other], rad_frac=mask_edge, color=color)

        if ( len(this_cgo) > 0):

            name = "esto_res%i"%seqpos
            cmd.load_cgo(this_cgo, name)
            cmd.disable(name)


    # disables all estograms and then enables the ones you've selected
    def enable_selected():
        selected = list(set([int(x.resi) for x in cmd.get_model("sele").atom]))

        for name in cmd.get_names("objects"):
            if (name.startswith("esto_res")):
                cmd.disable(name)

        for seqpos in selected:
            name = "esto_res%i"%seqpos
            cmd.enable(name)

        cmd.delete("sele")


    cmd.set_key( 'CTRL-C' , enable_selected )

    # restore the camera
    cmd.set_view(save_view)