[I tried to send this last night, but I don't think it worked, and even 
if it did, this is different!]

You will see some pretty major code changes in Jmol 11.1.14. I wasn't 
really planning on this, but I needed a parseFloat() command and 
realized that I could with (ahem) a BIT of work (like, 6 hours) change 
Parser to all-static methods. This allows it to be used in any class 
without having to create a parser object. The only reason it wasn't 
static already is that it tracks the current line position in the global 
variable "ichNextParse". I making Parser methods all static, that 
variable is gone. In its place is the parameter int[] next, which is 
really just

int[] next = new int[1];

so that it can be passed by reference to the static methods. This 
allowed for some economy of code in just about all of the adapter 
methods as well as isosurface (for reading CUBE files) and pmesh (for 
reading pmesh files).

The place I wanted this was the context of mixed-type variable 
arithmetic. It's interesting to me how this has developed --- In sorting 
out all the scattered global settings, I created StateManager and the 
GlobalSettings class. That allowed for saving variables in Hashtables, 
which allowed for user-defined variables.

myvar = 3

Of course, you couldn't do very much with this -- so I added simple math 
and IF/ELSE/ENDIF so that we could at least have a counter:

myvar = myvar - 1
if (myvar = 0);....;else;....;endif;

I was borrowing from the atom expression processor to do the IF logic:

if (myvar = 3 or yourvar = 2)...

and realized it would be helpful to add regular atom expressions:

if ({oxygen} > 2).....

So that forced the need for braces around these expressions. That's when 
I realized that %{...} would be helpful in messages and echo text:

 echo "there are %{{oxygen}} oxygen atoms in this model"

But this was problematic with set, because there we already use {x y z} 
for unitcell definition.

So today I sat down and determined to reconcile IF and SET. I threw out 
both arithmetic processors and wrote a nice little Reverse Polish 
Notation operand/operator stack class (Eval.Rpn).

(Believe it or not, this was sort of nostalgic for me. I loved RPN in 
high school -- What was that little HP calculator that came out in the 
early 70s that used RPN, HP-21? I loved that calculator and later 
incorporated RPN in a FORTRAN compiler I wrote as a senior project in 
high school. -- Ah, back when 16K was all you got. Period.)


This of course took all day, but I think it was well worth it. We can 
now do the full range of operator math in IF and SET -- parentheses, 
+-*/% < > <= >= = != AND/OR/XOR/NOT.

if {oxygen} > 2 and ({carbon} > {oxygen} or {carbon} > 3) ....

unsaturation = (2 * {_C} + 2  + {_N} - {_H})/2


Both commands use the same method to do the job. The only difference is 
that IF always returns a boolean in the end and SET can return boolean, 
int, float, String, or Point3f. That's still not fully worked out, and 
suggestions are definitely in order here. So the if command now just 
looks like this:


 boolean ifCmd() throws ScriptException {
   return parameterExpression(1, true).booleanValue();
 }

and the SET command doesn't look much different:

        Object v = parameterExpression((getToken(2).tok == Token.opEQ ? 3 : 2),
            false);
        if (isSyntaxCheck)
          return;
        if (v instanceof Boolean) {
          setBooleanProperty(key, ((Boolean) v).booleanValue());
        } else if (v instanceof Integer) {
          setIntProperty(key, ((Integer) v).intValue());
        } else if (v instanceof Float) {
          setFloatProperty(key, ((Float) v).floatValue());
        } else if (v instanceof String) {
          setStringProperty(key, (String) v);
        } else if (v instanceof Point3f) {
          drawPoint(key, (Point3f) v, false);
          showString("draw " + key + " " + StateManager.escape((Point3f) v)
              + " off;");
          return;
        }

That last one is kind of interesting. I was thinking, "What's the best 
way to return a point?" We don't have a generic "setPointProperty()" 
method. So I thought, well, why not just draw the point. It will be 
saved as part of the state that way, and you might even want to see it. 
So this leads to constructs such as the following:

c1 = {O5}.xyz
c2 = {N6}.xyz
draw line1 @c1 @c2

That ".xyz" is one of a set of new atom properties designed just for 
these purposes. The new set includes:

.x
.y
.z
.xyz
.ident

All the other atom properties are there as well:

.temperature
.atomno
.elemno
.radius
.phi
.psi
.surfacedistance
.partialcharge
.model
.file
.bondcount
._structure
._groupid
.resno
.symop
.site
.formalcharge
.file
.model

LOTS of these -- this is only a partial list. Just let me know if 
something isn't there that you want. These are very easy to add.

OK, so this is getting too long. I wanted to run one more idea past you. 
OK, if you do this:

x = {oxygen}

you get the number "2" for caffeine, because there are two oxygens. If 
you use:

x = {oxygen}.xyz

you get the average position. Actually, you get a POINT at the actual 
position, and if the next command is draw on:

x = {oxygen}.xyz; draw on

then you actually SEE that point. (I thought it would be better to leave 
these OFF by default.)

OK, but I thought it might be nice to be able to address each of the 
oxygens. I tried:

x = {oxygen}.1.xyz

But that gets messed up in the Compiler. So then I tried:

x1 = {oxygen}_1.xyz

but that was seemed strange. So I settled on:

x1 = {oxygen}[1].xyz

which has varients:

x1 = {oxygen}[1-].xyz
x1 = {oxygen}[1-2].xyz
x1 = {oxygen}[-2].xyz

with the obvious meaning.

What's nice about this is that I know I have two oxygens, so it is just 
as simple to address them as "1" and "2" rather than their full numbers. 
Of course, I could do:

message %{{oxygen}[1].ident} %{{oxygen[2].ident}

(OH, by the way, since it wouldn't make sense to average .ident, doing 
this on an atom set with more than one atom just makes a list:

message %{{oxygen}.ident}

gives for caffeine

O9 #9, O11 #11

and for 1crn.pdb:

[THR]1.O #4, [THR]1.OG1 #6, [THR]2.O #11, [THR]2.OG1 #13, [CYS]3.O #18, 
[CYS]4.O #24, [PRO]5.O #30, [SER]6.O #37, [SER]6.OG #39, [ILE]7.O #43, 
[VAL]8.O #51, [ALA]9.O #58, [ARG]10.O #63, [SER]11.O #74, [SER]11.OG 
#76, [ASN]12.O #80, [ASN]12.OD1 #83, [PHE]13.O #88, [ASN]14.O #99, 
[ASN]14.OD1 #102, [VAL]15.O #107, [CYS]16.O #114, [ARG]17.O #120, 
[LEU]18.O #131, [PRO]19.O #139, [GLY]20.O #146, [THR]21.O #150, 
[THR]21.OG1 #152, [PRO]22.O #157, [GLU]23.O #164, [GLU]23.OE1 #168, 
[GLU]23.OE2 #169, [ALA]24.O #173, [ILE]25.O #178, [CYS]26.O #186, 
[ALA]27.O #192, [THR]28.O #197, [THR]28.OG1 #199, [TYR]29.O #204, 
[TYR]29.OH #212, [THR]30.O #216, [THR]30.OG1 #218, [GLY]31.O #223, 
[CYS]32.O #227, [ILE]33.O #233, [ILE]34.O #241, [ILE]35.O #249, 
[PRO]36.O #257, [GLY]37.O #264, [ALA]38.O #268, [THR]39.O #273, 
[THR]39.OG1 #275, [CYS]40.O #280, [PRO]41.O #286, [GLY]42.O #293, 
[ASP]43.O #297, [ASP]43.OD1 #300, [ASP]43.OD2 #301, [TYR]44.O #305, 
[TYR]44.OH #313, [ALA]45.O #317, [ASN]46.O #322, [ASN]46.OD1 #325, 
[ASN]46.OXT #327

I can imagine that this could be quite handy.

OK, enough for now.

Well, one more thing: Think about what you might want to do with 
point-based math.

You can do, for example:

x = {oxygen}[1].xyz - {oxygen}[2].xyz

which gives a vector and, interestingly, I think, mixing floats and points is 
NOT commutative.

x = 0.0 + {oxygen}[1].xyz - {oxygen}[2].xyz   ==> MAGNITUDE of the vector

x = {oxygen}[1].xyz - {oxygen}[2].xyz + 1.0  ==>  vector + {1 1 1}

I've added some more mixed-type ideas today. 

x = 13.5432 % 3  ===> 12.543
x = 13.5432 % -3  ===> 1.35E+1
x = "testing" % 3 ==> "tes"
x = "testing" % -3 ==> "ing"

for example. Mostly the rule I'm going with is that the left-side operand sets 
the generated type.

x = 4.5 + "3.0"   ==> 7.5
x = "3.0" + 4.5   ==> 3.04.5

This way we get much more flexibility than the standard Java "anything plus a 
string is a string"

    
Bob




-------------------------------------------------------------------------
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