From: Bob H. <ha...@st...> - 2006-03-08 12:25:20
|
Topic: scripts Re: animated measurements I'm happy to report that this is now possible in the prototype. I've implemented a new mechanism for designating measurements that I think might be very useful. Comments are welcome. These changes are only available in the prototype at this point. http://www.stolaf.edu/people/hansonr/jmol/test/json/measure.htm Modified command: measure/monitor Current status (Version 10.00.48): measure [atom-number] [atom-number] Two atoms specify a distance measurement. measure [atom-number] [atom-number] [atom-number] Three atoms specify an angle measurement. measure [atom-number] [atom-number] [atom-number] [atom-number] Four atoms specify a dihedral angle measurement. where [atom-number] is the sequential number assigned to the atom -- (integer, >=1) Proposed: In addition to the forms above, one can use atom expressions such as (carbon) or (oxygen and within(1.5, nitrogen)). So one might have: measure (atomno=2) (oxygen) which would display the distance from atom 2 to an oxygen atom. By default, the atom expressions evaluate to the FIRST MATCHING atom in each case. If instead all matching atoms are desired, then the ALL keyword must be added: measure ALL (carbon) (oxygen and within(1.5, carbon)) This form is particularly useful if an animated measurement is desired as models are displayed using the "frame play" command. So, for example, in an animation model set, one might use: measure ALL (atomno=3) (atomno=5) to display that measurement in all frames. Note that all matching measurements in one particular frame could be designated as follows: measure ALL (carbon and */2) (oxygen and */2) The ALL keyword specifies that the displayed atoms must all be within the same model, not in two or more different models. The */2 here indicates that we only want to do this for the second model. Note that cross-model measurements are possible so as, perhaps, to compare the difference in position between two related conformations, one in each frame. In that case, you must be specific and not use the ALL keyword. frame 0;restrict */1,*/2 measure (atomno=3 and */1) (atomno=3 and */2); The following is allowed: measure ALL (carbon) (carbon) But, of course, that is likely to be a mess. One problem with this formulation is that the following: measure ALL (carbon and within(1.3, oxygen) (oxygen and within(1.3, carbon)) will indicate more than just C-O bonds. Instead, ALL carbons within 1.3 Angstroms of any oxygen will be measured to ALL oxygens within 1.3 Angstroms of any carbon. To address this problem, the measure command now accepts minimum and maximum distances for ALL-type displays, along the lines of the new CONNECT command. This allows for: measure 1.0 1.3 (carbon) (oxygen) which would display only C-C measurements in the 1.0-1.3 angstrom range. The minimum can be omitted: measure 1.3 (carbon) (carbon) indicates all C-C bonds shorter than 1.3 angstroms. Similarly, measure 104.0 108.0 (carbon) (carbon) (carbon) would display all C-C-C angles in the 104.0-104.8 range. Obviously one does not want to go overboard with the monitor command. measure ALL (all) (all) will do just that. You might think your browser has crashed; but probably not. It's just using ever bit of virtual memory it can grab. :) Finally, wouldn't it be nice to be able to get a list of the displayed measurements? No problem: var strInfo = applet.getPropertyAsJSON("measurementInfo") does the trick. Or, with the proposed changes to Jmol.js: measurementInfo = jmolGetPropertyAsArray("measurementInfo") which returns an array of the sort: measurementInfo[0]=new Array() measurementInfo[0].atoms=new Array() measurementInfo[0].atoms[0]=new Array() measurementInfo[0].atoms[0].atomno=17 measurementInfo[0].atoms[0]._ipt=16 measurementInfo[0].atoms[0].info="H 17/1 #17" measurementInfo[0].atoms[1]=new Array() measurementInfo[0].atoms[1].atomno=17 measurementInfo[0].atoms[1]._ipt=160 measurementInfo[0].atoms[1].info="H 17/9 #17" measurementInfo[0].index=0 measurementInfo[0].strMeasurement="0.107 nm" measurementInfo[0].count=2 measurementInfo[0].value=1.0710598 There will be one such array element for each calculated measurement. This command can be used effectively along with the new applet.scriptWait() command to run a script and wait until it completes. One might, for example use: applet.scriptWait("measure off;measure 1.3 ALL (carbon) (oxygen)") strJSON= applet.getProperty("measurementInfo") and then process the JSON string into an array. Or, as proposed with modifications to Jmol.js: jmolScriptWait("measure off;measure 1.3 ALL (carbon) (oxygen)") myArray = jmolGetPropertyAsArray("measurementInfo") Note that the following WILL NOT WORK: jmolScript("measure off;measure 1.3 ALL (carbon) (oxygen)") myArray = jmolGetPropertyAsArray("measurementInfo") because jmolScript() uses applet.script(), which returns BEFORE it completes. The contents of myArray would be unpredictable. Bob Hanson |