ngl icon indicating copy to clipboard operation
ngl copied to clipboard

Help: Colouring

Open DustBytes opened this issue 4 years ago • 8 comments

Hi,

I need to put colors on each chain, which can be done with colorScheme: "chainid" but I also need to put custom colors on certain residues, which is possible via color: My_schemeId. Imagine it like 4 chains colored via colorScheme and 10 residues from each chain are in let's say orange color. If I put both, only "color" is active and colorScheme is ignored. In My_schemeId, the " * " coloring is not added but still no effect. I tried changing order but still color is active.

Writing custom colors for each chain is not a practical solution as chain number varies. How can we do both?

Eg: https://jsfiddle.net/ku1fhgrn/1/

Thank You

DustBytes avatar Dec 17 '20 07:12 DustBytes

You could provide a custom Colormaker which implements atomColor itself, using the logic you described.

 function generateCustomSchemeID() {
        	
          return NGL.ColormakerRegistry.addScheme(function(params) {
            
            var chainColors = [0xff0000, 0x00ff00, 0x0000ff] // Or whatever logic you want for these
            var residueColors = {
            	3: 0xffff00, // yellow
            	15: 0xffffff, // white.. 
            	14: 0xffff00,
                454: 0xffff00,
          	}
           
            this.atomColor = function(ap) {
              var resColor = residueColors[ap.resno]
            	if (resColor !== undefined) { 

                return resColor 
              }
              return chainColors[ap.chainIndex % chainColors.length] || 'grey'
            }
          })
        }

Other examples of this here: https://github.com/nglviewer/ngl/blob/master/examples/scripts/color/custom.js

fredludlow avatar Jan 23 '21 09:01 fredludlow

Thank You. It's missing one important part. I think I didn't put my question correctly. You solution is great but it is coloring residues 3, 15, 14 , 454 from all chains. This is not what I need. I need let's say 3, 15 from chain A, 14 from chain B, 454 from chain C and so on. Chain A, B, C will have colors from "chainColors()" and color of the residue will be chain+residue.

Couldn't figure out how to add chain + residue combination.

NGL.ColormakerRegistry.addSelectionScheme() can take input as 3:A, 15:A, 14:B, 454:C but that's now what is used here

Thank You

DustBytes avatar Mar 16 '21 10:03 DustBytes

Something like (untested)

 function generateCustomSchemeID() {
        	
  return NGL.ColormakerRegistry.addScheme(function(params) {
            
    var chainColors = [0xff0000, 0x00ff00, 0x0000ff] // Or whatever logic you want for these
    var residueColors = { 
      A: {
        3: 0xffff00, // yellow
        15: 0xffffff, // white.. 
      },
      B: {
        14: 0xffff00
      },
      C: {
        454: 0xffff00,
      }
    }           
    this.atomColor = function(ap) {
    var resDict = residueColors[ap.chainname]
 
    var resColor = resDict && resDict[ap.resno]
    if (resColor !== undefined) { 
      return resColor 
    }
    return chainColors[ap.chainIndex % chainColors.length] || 'grey'
    }
  })
}

fredludlow avatar Mar 26 '21 10:03 fredludlow

I think that the performance issue is around speed of testing a large selection object, this side-steps that by replacing the (very general, complex) selection testing code with a minimal hard-coded bit of javascript for your specific use-case. Something like the above should be pretty performant.

fredludlow avatar Mar 26 '21 10:03 fredludlow

Yes. I selected bigger structure so that if this works other structures will definitely work. With your function , changing color is without any performance issue.

I can understand what you did here, but the color is not changing. https://jsfiddle.net/bophregz/4/

And on mousehover the chain colors are lost.

This is the main question.

How to color chain wise and highlight certain residues with different colors.

The topmost question here seems to be misleading. That's why I posted in other issue.

DustBytes avatar Mar 26 '21 11:03 DustBytes

Right, so I think this is a bit confusing because there are two different ways to do this, and you can only have 1 colormaker assigned to the structure. When your example loads it uses my snippet above (custom atomColor), but when you mouseover it switches to selection based approach (which completely replaces the previous colormaker)

So, you need to choose one of the following:

  1. Use selection colormaker (optionally including the getAtomSet for improved performance)
  2. Completely custom colormaker where you implement atomColor yourself (in whatever way you choose)

1: The link above (https://jsfiddle.net/bophregz/4/) implements the first of these, but as you say only applies the info in colorData, you can add further rules (you currently specify rules for red and blue). If you look at this example: https://github.com/nglviewer/ngl/blob/master/examples/scripts/color/selection.js you can see rules get applied first to last and the first match applies the color, so you can have your red and blue rules followed by chain rules (i.e. default colors for those not explicitly set).

2: To do it with custom colormakers you'd have to rewrite my above snippet (https://github.com/nglviewer/ngl/issues/822#issuecomment-808106933) to take colorData as an argument and use it approriately in the logic in the colorMaker. This will give you the best performance, but it requires a bit more work on your part

fredludlow avatar Mar 26 '21 11:03 fredludlow

OK. Will try.

But please keep this as TODO in mol* or maybe next version of ngl (if still developing). This kind of user case is really common in my lab, and other labs we collaborate with.

Thank You

DustBytes avatar Mar 26 '21 11:03 DustBytes

ps - I'm not associated with the mol* project at all (though it is a great product) but you can try asking on their issue tracker - I'm not familiar with their API so can't comment on how much easier or harder it would be to do there.

The TODO here I think is to fix performance in the selection mode (it's a simpler way to write the rules than implementing atomColor in your own Colormaker)

fredludlow avatar Mar 26 '21 13:03 fredludlow