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