I have just committed an upgrade of Jmol that will allow indication and 
selection of isotopes. Since this is a fairly complex upgrade, I thought 
I would describe what I have done. For my own sake and for others, here 
is a rundown of how it works. If you see a flaw, do let me know.

Underlying Structure
--------------------

(byte) Atom.elementNumber is now (short) Atom.atomicAndIsotopeNumber. 
This is defined as:

  atomicNumber + isotopeNumber*256

or

  atomicNumber + (isotopeNumber << 8)

This basically transforms the former single-byte "elementNumber" into a 
two-byte representation, one being the atomic number 
(atomAndIsotopeNumber % 256) and the other the isotope number 
(atomAndIsotopeNumber >> 8) -- the number of protons+neutrons.

I added the isotope numbers to the already present 
JmolConstants.alternateElementNumbers array, renaming it 
altElementNumbers() so I could catch every occurance of its use and also 
made it private:
 
  private final static short[] altElementNumbers = {
    0,
    13,
    16,
    55,
    1 + (2 << 8), // D = 1 + 2*256  <-- firstIsotope
    1 + (3 << 8), // T = 1 + 3*256
  };

  private final static String[] altElementSymbols = {
    "Xx",
    "Al",
    "S",
    "Cs",
    "D",
    "T"
  };

  private final static String[] altElementNames = {
    "dummy",
    "aluminium",
    "sulphur",
    "caesium",
    "deuterium",
    "tritium"
  };

So we could certainly add on to this if we wanted to.

Notice that these are all private now. The elementSymbols and 
elementNames arrays are also private.
One additional array is public, because it is not private, because it is 
just copied by ColorManager, not accessed as a lookup table itself. The 
first four numbers here are placeholders only.

  public final static int[] altArgbsCpk = {
    0xFFFF1493, // Xx 0
    0xFFBFA6A6, // Al 13
    0xFFFFFF30, // S  16
    0xFF57178F, // Cs 55
    0xFFD9FFFF, // D 2H (He color)  <-- firstIsotope is entry 4
    0xFFCC80FF, // T 3H (Li color)
  };


All references in the project to JmolConstants.alternateElementNumbers 
or elementNames are modified to go through public methods that properly 
access these arrays instead:

  public final static short altElementNumberFromIndex(int i) {
    return altElementNumbers[i];
  }

  public final static String altElementNameFromIndex(int i) {
    return altElementNames[i];
  }
 
  public final static int altElementIndexFromNumber(int 
atomicAndIsotopeNumber) {
    for (int i = 0; i < altElementMax; i++)
      if (altElementNumbers[i] == atomicAndIsotopeNumber)
        return i;
    return 0;
  }

The public methods to use to get ANY atom's element name, number, or 
symbol, then, become:

  public final static short elementNumberFromSymbol(String elementSymbol)
  public final static String elementSymbolFromNumber(int elementNumber)
  public final static String elementNameFromNumber(int elementNumber)

where "elementNumber" is atNo + isotopeNo*256.


methods accessing Atom.elementNumber
------------------------------------

I modified all methods accessing Atom.elementNumber to access the 
already present Atom.getElementNumber(). This method removes the isotope 
number using % 256 (maybe & 0xFF would be marginally better?). In any 
case, the effect is that any method that was using an element number for 
an actual element still gets "1" for any isotope of hydrogen. But 
actually, some methods this is appropriate for, and some not. So we have 
two Atom methods:

  short getElementNumber() {
    return (short) (atomicAndIsotopeNumber % 256);
  }
 
  short getAtomicAndIsotopeNumber() {
    return atomicAndIsotopeNumber;
  }

The first of these, which would return deuterium as having element 
number 1, is accessed by:

Atom.getCovalentHydrogenCount() so as to treat them as hydrogen for 
bonding purposes
Balls.setVisibilityFlags()      for "showHydrogens"
Bond()                          for identifying S-S bonds
Eval.comparatorInstruction()    for select elemno=1 returning all 
isotopes of hydrogen
FrameExportJmolAdapter.AtomIterator.getElementNumber()  for no change to 
current functionality
Frame.autoHbond()               for identifying DN and DO as well as HN 
and HO
Frame.getAdditionalHydrogens()  for identifying hybridization and adding 
needed hydrogens
Frame.getHydrogenSet()          for select (hydrogen) including all 
isotopes of hydrogen
Frame.getVisibleElementBitset() for user picking
Isosurface.setupSolvent()       for identifying hydrogens needed for 
"addHydrogens" flag
ModelManager.getElementNumber() for getting the element number for 
getProperty atomInfo and
                                select within(ELEMENT, ...)

I selected these others to use the full isotope number, distinguishing 
"D" and "T" or "deuterium" and "tritium":

Atom.getElementSymbol()             for formatLabel(), getAtomName(), 
getIdentity(),
                                       and PatternMatcher.searchMatch() 
giving "D" "T" or "H"
ColorManager.getColixAtomPalette()  for coloring specific isotopes a 
changeable color
ColorManager.setElementArgb()       for setting the default 
element/isotope color
Eval.comparatorInstruction()        for select deuterium or tritium 
returning specific isotopes
Frame.getElementsPresent()          used in the dynamic popup element list
Frame.Molecule.getElementAndAtomCount() for constructing a molecular formula
Isosurface.SetupQMOrbital()         for generating a JVXL file that 
preserves isotope numbers
ModelManager.getElementName()       for getProperty atomInfo


Q: Should the smiles matcher get "H" or "D" for deuterium -- or 
something completely different -- 2H?


Well, that's more than anyone wants to know. Is there more to implement 
on this?


Bob
   





File reading
------------

Some file readers read element symbols (e.g. XYZ, MOL), while some read 
atomic numbers (e.g. Gaussian, Cube/JVXL). Element-symbol readers simply 
read the symbol and store it for later conversion; atomic number readers 
currently cast this as a (byte), but if desired, this could be cast as a 
(short). I have enabled the Cube/JVXL reader to read (short) 
atomicAndIsotopeNumber, but I haven't gone after any other readers, 
which presumably don't support isotopes anyway. (Or do they?)

For those readers that
JmolAdapter API
---------------

-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys -- and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Jmol-developers mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/jmol-developers

Reply via email to