The Ribosome Builder Project
Home - Design - User Manual - Index
[ Up ] [ Top ]

Project Log

Created framework from files in

Added CCube object, adding lighting.
Got normals working

Added CRbApp::MoveSelection().
Added CRuler
Added "ins ruler" command and menu item. Added ambient lighting.

Fixed ruler width so arrowheads point to start and endpoints.
Added root pointer, vColor, vSelectionColor to CGraphicsObject.
Added mouse selection of graphics objects.

Added CBlock object, "ins bl" command. Added "set volsize" command.
Added translate and zoom acceleration.
Added rendering of inside faces of Block polygons, but they are bleeding
through to the outside at far distances.
Added CRbDoc, adding File "Save" methods.
Still adding file read and write methods to CGraphicObject.

Yet still more.
Added CRbFile object.
File 'save' and 'open' are working for CBlock and CVolume objects.
Added File 'close' command.
Added Edit 'delete' command.
Added z-order hit-testing for object selection.

Adding CBase.
Added View menu, 'wireframe' command.
Added CStatusLine object, support routines to CTextConsole.

Adding Rotate Selection mode, CPolygon::Rotate() method.

Added RotateVectors(), MultiplyVectorAndMatrix() functions to Vector.cpp
RotateMatrixAboutVector() to glutils.cpp.
Adding Selection Rotation Origin.
Have good rotation of selection (for single block).

Debugging picking bug - getting a hit when clicking on
empty space. Fixed things somewhat by doing glLoadName(-1)
just before glFlush() and glutSwapBuffers() in CRbWindow::Draw().
Added Base menu. Added selection move factor.
Added CPolygon Write() and Read() methods (when rotating, need
to write individual vertices, not just CBlock position).
Added CBase Write() and Read() methods.

Added CSelection object.

Having working translation and rotation of a selected base.

Have working translation and rotation of selected base blocks.

Fixed uninitialized vars in CApp.
Created CChain object, 'insert sequence' command.

Changed movement and extent code so that all vertices
are in absolute coordinates (calculating coordinates relative to
position in object hierarchy was too cumbersome).

Added 'Add to selection' function.
Added second help screen.
Added 'select all,none' command
Fixing problems with extents updating -
selection movement and rotation seems to be working for all
objects and sub-objects.

Added 'insert sequence from file'

Added 'file new' command.
Added file i/o for CChain object.
Added 'set rotation origin' command.
Added Options menu.

Added CBase::Timestep(), CBase::CalcForces(), CGraphicsObject::CalcForces
Added Run menu.
Note: wireframe rendering is causing a major performance
drop because of calling glDisable(GL_LIGHTING) using glPushAttrib()/glPopAttrib.
inside of the CPolygon Draw() method. Why?
I am now just turning lighting off and back on (instead of pushing and popping)
and the performance is back to normal (I can create my own lighting state flag if need be).
Added volume bounce for moving bases.

Working on SetVolume(), chain and base force and movement calcs.
Need to create a Volume child list containing all bases in model.

Created CFFVolume object (needed a object list distinct from CGraphicsObject child list).
Have working steric force interaction for 256 Base objects, performance is good.

Added CBase::m_pBondList, CBase::CalcBondForce.
We have nice spring-like interaction between bases
in a chain.

Added Torque and rotation to base forces.

Added CBond, CSpringBond objects.
Added CBase::CalcStericForce, CSpringBond::CalcForce.
Added CGraphicsObject::GetVertex().
Added 4 spring bonds to adjacent corners of two riboses
in an A-helix, ran timesteps from 0.1 to 0.01. The
springs are not properly constraining the bases.

Added 'set timestep' command, 'running' status.
Added CRuler::SetScale(), CSelection axis update during run mode.
Added sub-object selection to the polygon level.

Added vertex selection.

Created CForceObject (derived from CGraphicsObject),
derived CBase and CBlock from CForceObject.
Moved CalcForces(), CalcStericForce() and Timestep() from CBase to CForceObject.
Force interactions are now working for CBlock.

Added 'ins sbond' command. Have two blocks connected by
a spring bouncing around.

Added bond selection.
Made CBond derived from CGraphicsObject. Incurs an overhead, but
I think it's necessary to keep things from getting too messy.
Removed object CCube.

Added removal from FFVol->m_pFFList for deleted objects.
Added color to CAxis, extended legend offsets.
Added initialization check to CGraphicsWindow::Redraw().
Added selection poly to CSpringBond, made CBond a part of the
Root Graphics Object hierarchy. Selection of CBond is now
working for CForceObjects (still need to do CBase::AddBond).

CBase::AddBond(CBase*) now calls CForceObject::AddBond(CBond *pBond),
Note: currently, there is a potential for serious bugs because
of the dual references to objects throught (1) the root graphics
object child list hierarchy (CGraphicsObject::m_pChildList) and
(2) internal pointer lists such as
This can be dealt with to some extent by overriding
CGraphicsObject::RemoveChild() to remove the reference from
the internal list in the derived class.
Another option is to try to eliminate the internal pointer lists
entirely and just use wrapper methods which refer to the
CGraphicsObject child list.
Currently, CBlock::m_rgPoly and CBase::m_rgBlock are only
used during initialization and read methods (ie. when the graphics
child list should be empty), and so they shouldn't be a problem at
this time.
Fixing bond deletion bug where CForceObject::m_pBondList is
updated upon removal of CBond from the Root Graphics hierarchy.
This was done by overriding CGraphicsObject::RemoveChild() with
Inserted 2 bases and ran forcefield on them with initial 4 spring
bond connections. Deleted bonds 1 and 2 at a time and everything
worked fine on subsequent forcefield runs.

Added single-step mode, timestep display.
Removed CBond from UpdateExtents() calcs.
Added CSelection::IsOnlyBondSelected().

Added CForceObject::SetOption(iGOInitFFCreateBonds).
Added CForceObject::SetOption(iGOInitFFAddToVolume).
Changed CBase, CBlock Read() methods to
read tags from file in any order (file can also have missing tags).

Added CSpringBond::Write(), Read().
Added CForceObject::AddChild() to update m_pBondList when CBond children
are added.
Added CRbFile::m_iFileId, an id generated from rand() (srand() also is called).
Added utils.cpp GetRandomInt()
Added CBlock, CSpringBond::ScanTagInt(), Float() and Vector().
Got writing and reading of spring bonds working finally! Whew!!

Added "set move off" command.
Changed steric force interaction from Fk*Intersect^2 to
Fk*Intersect, made Fk=10.
A block of size 2,2,2 connected to another fixed block of size 2,2,2
by a spring eventually ends up orbiting the second block with
a distance which gradually varies between a large and a small value.
Changed "set rot" to "set cen" for set rotation center.
Added "set trans on/off" command.
Added "set rot on/off" command.
Added CRbCommand::GetOnOffToggle()
Added torque calculation to CSpringBond::CalcForce()
Added bond deletion when deleting an object which was part of a bond.
(CFFVolume::DeleteBondsToObject() and CForceObject::DeleteBondsToObject())

Set Block mass proportional to volume.
Added CSpringBond::GetBondVertex().
Added Spring bond friction.
Added fTimestep param to CalcForce() (needed for spring friction calc).
Added 'set maxmove' command
Created TimestepParam, CalcForceParam structs to avoid multiple params.
Added 'set springfriction on/off' command
Friction is working, but object still rotate too much.
Also, frictional forces between bases gets out of control.
Setting the timstep to 0.001 helps that, but we can't keep
going down that road.
Need to add "fat" spring bonds to cure the rotation problem.

One problem with the rotation: spring bond friction is
currently only being applied to translation.
Added command 'set avel' (angular velocity)
Added commmand 'set maxrot' (max rotation)
Second problem: the way the spring force is applied to
the force objects. The force along the spring vector is being
applied directly between the center of masses. It needs to
be projected along the cm vector first (dot product).
See file "2blocks1Bond.rbd" for demonstration.

Added 'set color' command
Added 'sho/hid' command, CRbCommand::ShowObject().
Made sure all attributes in CGraphicsObject were initialized in its constructor.
Changed 'set center' command to 'cen' command.

Fixed spring torque after realizing that torque on object 2
is not always equal and opposite to torque on object 1
(ex: two sticks connected by spring: |\| : both have cw torque).
Question: is this also true for torque from steric collision?

Added linear and rotational atmospheric friction.

Added transverse spring torque, counter-force on opposite object and
reaction counter-force on torqued object.
Get good stable structures for 4 blocks connected in a rectangle (see 4Blocks.rbd)
excepting common orientation along the spring axis.
The only thing that should be needed to fix this is a torque
along the spring axis (torsion force).
In implementing this, a spring "up vector" will be added to the existing
EqOrientation "look" vector. Then it should be possible to
get an arbitrary spring eq orientation relative to object orientation
instead of defining the spring eq vector (as done currently)
along the polygon normal (or, in the near future, for corner vertices,
along the vector from block center to spring vertex).
Note: the counter-force as currently computed is arbitrarily scaled
to 1/10th of the transverse spring torque.

Fixed torque direction bug in spring transverse torque for object 2.
Created a chain of 6 blocks, connected them in a ring, then cut
the ring bond and they sprang back to the initial linear chain
Wired up a cube and it works great! Without torsion forces!
Yahoo!!! Saved to Cube.rbd.
Added CBase::GetVertexPolygon().
Adding CBase objects to force calculations.
Since the actual interactions (such as steric forces) should
be calculated between CBlock objects, this raises the question
of how higher level objects such as Bases and Chains should
iterate through their child objects to do the actual interactions.
The top-level force object, CFFVolume, contains a top-level list of
force objects which interact by having each of them iterate
through the top-level list. If we add a "container" attribute
to each force object, then we should be able to get multiply-nested
iteration by an object until the target object resolves to one
which doesn't contain any force objects.
This can be done by passing a target object into the CalcForces() method,
and calling the function recursively for each child object of this
CForceObject, or, if no children, just calculating forces for this
CForceObject. This would include the following:
1. Target interactions, via CalcTargetInteractions(), currently only
steric interactions. The target object will be recursively called
until the bottom-level child is reaced.
2. Additional forces specific to each source object, currently just
bond forces and atomspheric friction.
Transfer of forces from child force objects to their parents
is currently implemented in AddForceVector and AddTorqueVector().
Inserted 2 bases and steric interactions between blocks are working.
Spring force between blocks in different bases is kind of working
but not quite right yet (doesn't move to correct orientation).
Note: added CForceObject::GetTotalForceChildren() which
is an non-ideal optimization which assume CBlocks have no force children and
all other CForceObjects have ONLY force children

The problem with the bases appears to be the incorrect calculation
of spring torque. For a Block with a Base as a parent, the Block
is using it's own center of mass, wheareas the cm of the toplevel
parent needs to be used. To do this, the function
CForceObject::GetCenterOfMass() has been added.
Note: tried compiling with optimization flag /Og to find
uninitialized data begin used and didn't find anything of
Fixed bug where the program started crashing on deletion
of objects, This came about because of the old CFFVolume::Add(CChain *pChain)
function which manually added bases to the m_pFFList. instead of
adding the Chain object. Now, the parent chain object is the only
thing that is added to the top-level m_pFFList and so will references
will be removed correctly prior to deletion.
Made CChain derive from CForceObject instead of CGraphicsObject.
BUG ALERT!! IsForceObject() (a macro) must be updated for every new
derived force object which is added (note: CFFVolume is intentionally excluded).
Still working on base spring torque problem.
To check the block spring torque, ran "2plates.rbd" and it works
as expected.

Added 'sho torque' command, implemented CProperty methods.
Debugging Base spring torque.
Note: the applied torque causes rotation according to the
left hand rule.
This makes sense if we consider the following:
OpenGL defines a positive rotation as a counter-clockwise
one, where one is looking from the base of a vector down
towards the arrow. For example, a rotation of glRotate(10,1,0,0)
of a person lying along the x axis with their feet at the origin
and their head at (1,0,0) and looking up in the +y direction
would rotate ccw 10 degrees and end up looking more in the -z direction.
Now, according to the right-hand rule, if you apply a torque
in the direction of (1,0,0), your thumb will point down the +x axis
and your fingers will curl in the opposite direction
to which the person was rotated, showing that a torque applied
using the right-hand rule results in a rotation opposite to
the OpenGL direction. If you use the left hand to apply the
torque, the direction agrees with OpenGL.

Fixed ptr initialization for objects read from file by
adding CGraphicsObject::GetObjectFromFileId().

Added 'afr on/off' command (atomspheric friction).
Fixed steric interaction bug between blocks in a base.
Bases still not stably attachable by springs.

Added Timestep flag "bZeroVelocity" to help in debugging
Base dynamics. Sets velocity to zero after every timestep.
Added 'sho bbox' command (bounding box).
After displaying the bounding box, it was found that
steric collision was occurring where it didn't appear to
be and this was interfering with the transverse torque.
There were also some sign corrections made in the force and torque
calculations in CSpringBond::CalcForce().
Zero-velocity conditions verify that the spring forces
are now being applied correctly, and will move towards
the desired orientation (as long as steric collisions are
not happening). However, if in non-zero velocity mode,
the bases will still orbit each other and not stabilize
as desired. Hopefully, the proper combination of
spring and torque constants, as well as implementation of
axial torque, will make this possible.

Final fixes to torque and force signs in CSpringBond::CalcForce(),
Cube.rbd object is stable to distortions.

Added 3D insertion cursor (CSelection::m_pCursor).

Created CAtom object. Improving collision detection between
blocks needs to be implemented at some point with geometrical
methods, but at this time, the fast and simple bounding-box
method may be effective if blocks are defined in terms of
smaller "atom" blocks of cubical dimensions. This will
increase the vertex, polygon and object counts, but hopefully
ribosome-scale models can still be run with adequate performance.
Also, the atomic resolution of blocks is probably necessary
for effective hydrogen-bonding simulation.
Added 'ins ato' command (insert atom).

Added CRbCommand::MoveObjectToInsertionPoint().
In looking at the bounding box of an atom as it is rotated,
it becomes clear that the extents attributes m_vMin and m_vMax
need to be modified or extended to show the maximum extent
resulting from all possible orientations.
This actually only needs to be done in the function
CGraphicsObject::HaveIntersection(), and implemented by
calculating the longest diagonal as it exends from the center point
(which is always the same as calculated by m_vMax-m_vMin regardless
of the orientation).
Added CAtom wire sphere.

Added 'insert atom' menu item.
Changed file i/o to do hierarchical object read/write.
Consolidated helper functions ScanTagInt,Float,Vector into CForceObject.
Added CAtom::Read,Write() methods.
Note: CAtom::Read/WriteChildObjects() had to be skipped because of
conflicts with CBlock children (the 6 polygons). This needs to be
improved at some point.
Reading and writing atom objects is working.

Added App version string to rbd file header.
Added insertion cursor update for changed selection.
Add spacebar select/deselect for object in cursor.

Added fast/slow move mode, 'set fastmove' command.
Added 'bonding mode' flag, adding cursor bonding mode.

Added CRbApp::DoCursorBonding(). EndCursorBonding().
Added second connection poly to dest end of spring bond.
Cursor bonding works!
However, aligning bottom front left corner of
cursor (hot spot) with desired block vertex is awkward.

Added CForceObject::HaveIntersection().
Added commands 'set spring force,transforce,eqdist',
after tweaking various params, the pyruvate.rbd molecule
is fairly stable, though not impressively so.

Added command "set atom wiresphere [on | off]",
Added class CRbOptions,

Changed default spring transverse force constant to 5,
Pyruvate.rbd looks much "springier".
Added CBlock::GetInsideRadius() (length of longest side).
Added radius check to CForceObject::CalcStericForce()
for Block objects where sum of inside radii is less
than actual distance (this provides better orientation
invariance than CBlock::GetMaxExtents()).
BUG ALERT!!! Added macro IsBlockObject() which must be
updated for all classes derived from CBlock
With new block collision radii and updated eqdist,
pyruvate2.rbd is more stable than ever but the blocks
in the main chain are pulling closer than the eqdist for
some reason.
Added CForceObject::GetTopForceParent().
Adding 'group' command

Note: in CGraphicsObject::RemoveChild(), set removed child's parent to NULL.
Debugging CRbCommand::GroupObjects().
Removed file, ChildList() assumptions about CBlock::m_rgPolys.

group command is working.

Changed cursor bonding to do only center vertices at this time.
Built several test molecules:
Citrate.rbd, Isocitrate.rbd, aketoglutarate.rbd, Succinyl-CoA.rbd,

Added code in cursor bonding to set bonds between vertices
closest to line between objects.
Added vector.cpp GetDistanceFromPointToLine().

Changed CGraphicsObject::m_bSelected to m_iSelected,
Added secondary selection level (shift-s) (accumulation selection).
Added transfer from secondary to primary selection.
Adding 'copy selection' command.
Added CSelection::Copy(),Paste(),
Adding CSelection::Duplicate().

Adding CGraphicsObject,CPolygon, CForceObject::Duplicate(), CopyAttributes(),
Adding CBlock::Duplicate(), CopyAttributes().

Removed Duplicate(), CopyAttributes(), DuplicateChildren() methods.
Clipboard Copy() and Paste() are now implemented by
writing and reading to clipboard file (gives more consistent
object creation and pointer initialization).
Replaced CFFVolume::CreateBonds(),
CBond::SetObjectPointers(CFFVolume *pFFVol)
CSpringBond::InitFileReferences(CStatus *pStatus)
File reference initialization is now more general and
independent of CFFVolume,
Reading and running "pyruvate.rbd" still works ok.

Added 'copy', 'paste' commands, menu items.
They work great. Copied and pasted until a few hundred
force objects were running, it got pretty slow. It will
be optimization time soon.
Moved m_pFFVolume, m_pSelection, AddGraphicsObject()
from CRbApp to CRbDoc.
Removed CRbDoc::m_pApp.
Changed CSelection::Copy() and Paste() to use CRbDoc to
write and read contents to clipboard file.

Added force display to CProperty.

Adding intersection volume to CProperty.

Added saving of velocity, angular velocity.
Added saving, loading of current timestep.
Moving RbApp state info to RbDoc.
This was done to allow for saving of all relevant state
info in the RbDoc file.

Still moving stuff from RbApp to RbDoc.

Compileable and mostly working.

Doc save and read working. Forcefield is working.
Fixed bug in CForceObject::CalcStericForce()
by moving intersection calc to CForceObject::HaveIntersection().

Debugging grouped-object selection bug.
Added CGraphicsObject::m_szName.
Added debug info to CForceObject::Write().
Moved tag scanning helper functions from CForceObject to CGraphicsObject.
Added CGraphicsObject::Write(), Read() to file i/o hierarchy,
Moved debug info to CGraphicsObject::WriteRead.
Moved Write/ReadChildObjects() to CGraphicsObject::Write/Read.
File i/o appears to be working.
Note: file format is now incompatible with previous rb docs.

Fixed clipboard copy bug by doing manual copy of child object
pointers from selection child list to clipboard doc root child list
in CSelection::Copy() (original way using CRbDoc::AddGraphicsObjectList() caused
the parent to be changed to the temp clipboard doc root object).
Can successfully copy and paste 'ribose.rbd', but the resulting
grouped force objects do not interact.

Added CGraphicsObject::SetOptionIfSelected(), SetOptionForChildrenIfSelected().
Made CForceObject::m_bTransferForceToParent true by default.
Fixed torque calculations for steric interaction of children of force objects
so that parent cm is used if m_bTransferForceToParent is set.
Re-enabled spring torque calcs.
Spring forces on test blocks (2b.rbd, 2bb.rbd) appear to work as expected.
Collision between 2 ribose blocks (2ribose.rbd) does not work
as expected (2nd block doesn't rebound properly on collision)
This may be due to length of timestep as significant force
is only exerted for 1 timestep.

Added "ins fil" command.
We are getting access violations due to some memory bug.
(have been for a few builds now).

Found memory bug thanks to BoundsChecker (CGraphicsObject::m_szName
was being used before being initialized).
Fixed all memory leaks.

In CForceObject::CalcForces(), made steric force and frictional force calcs
happen only if no force children.
Changed spring bond creation code in CRbCommand::InsertObject().
Adding spring bond torsion.

Adding GetPointProjectionOnPlane() in CSpringBond::CSpringBond().

Added Vector.cpp::GetPointProjectionOnPlane().
Added CSpringBond::CalcAxialOrientation(), CSpringBond::SetEqParams().
Adding spring axial torque.

Added CSpringBond axial torque calculations.
Added CSpringBond::m_dAxialTorqueConstant, m_dEqAxialTheta, and their file i/o tags.
Made CPolygon part of hierarchical file i/o (old file format incompatibility occurs again).
File i/o is working for '2blocks.rbd'.

Working on spring axial torque, having sign problems.

Got spring axial torque working ('2axial.rbd') !!!

Adding arbitrary spring eq orientation using
extra vertices (not ideal, but no time to do it
Added CSpringBond::m_vEqVertex1,2,
Added CForceObject move and rotate methods,
Added CForceObject m_pBondRx list
Added CBond, CSpringBond move, rotate, moverx, rotaterx methods.
Added drawing of spring bond eq vertices and eq normals.
Added removal of bond from target object bondrx list on bond deletion
Spring bonding and file i/o still work ok in '2beq.rbd'.

Added use of spring eq vertex normals to bond orientation calcs.
Arbitrary spring eq normals are working (see '2beqAng.rbd'.

Added 'ungroup' cmd, CRbCommand::UnGroupObjects(),BootForceChildren().
Added 'set mass' cmd.
Added 'set atm lfr, rfr' cmds (atmospheric linear and rotational friction)
Fixed friction calc so it's done for top-level force objects.
Created bonds bet 3 nt's, they stabilize fairly quickly!
There is a bug in deleting objects though.

Building chains from group building blocks.
Made CBase, Chain derive from CBlock.
Insert base, insert sequence is working,
except for CChain extents.
Created building block files

Added CBlock::ResizeToChildren().
Added CBlock::m_bHideUnlessSelected (to hide parent block containing child forceobjects)
Changed CBlock::SetColor to set color on child polys only.
Added command 'sho/hid atoms'
Fixed CChain's extents and initial positioning.
Added selected depth offset to center command.
Can create chains of 11 bases in length and collide them,
but it's slow. Need to add parent boundary checks
in CForceObject::CalcForces() and CalcTargetInteractions().

Fixed direction of helix.
Added CForceObject::TimestepChildren().
Added bonds between the purine blocks of 4 bases in a sequence
and they worked pretty good! (4nt.rbd).

Added command 'set name'.
Fixed base-bonding between bases in chain.
We have something approaching an a-form helix.

Added command 'set atom sphere on/off'
Added hack for parent block to toggle m_bHideUnlessSelected when
atom sphere state changes.

Removed fCounterforceReduction in CSpringBond::CalcForce().
Added 'set steric' cmd (steric force factor).
Gave demo to Ribolab.

Removed 'CreateMenus' from mode update because menus stop working
after a while (too many creations/destructions?)
Added Timestep stats 'iTotalCalcForces, iTotalIntersectChecks, iTotalStericInteractions'
For 10 adenines in a chain, we get 181 force calcs, 22,350 intersection checks,
and around 480 steric interactions per timestep.
Moved intersection check from CalcStericForce() to CalcTargetInteractions()
so interactions with children are skipped if no interaction with parent.
For the 10 adenines, reduced number of intersection checks to around 11,000!
Rand 30 bases at pretty good speed except for occaisional annoying
pauses which are occurring for some reason.
Found cause of pausing: I was printing debug info to stdout. Duh.

Added command 'set spring eqparams' (get fairly noticeable errors
when loading spring params from file floating point value).
Added command 'set spring axialtorq'.
Fixed broken vertex selection by adding CPolygon::Select(iSelect, bSelectChildren).
Created a spring bond between corners of two blocks.
A very small transverse displacement (theta=2 degrees) competes
with a linear displacement of 2 angstroms so that movement back towards
the equilibrium distance takes a long time, especially for small timesteps
(see 'SpringForceVsTransForce.rbd').
Fixed rotation clamp bug.
Experimenting with exponential steric and spring force.
No luck in getting good helices.
It's kind of screwed right now.

Creating GraphicsObject lib for compatibility with dradder app.
Created CGoFile as base class for CRbFile, CDrFile.
Created CGoDoc as base class for CRbDoc, CDrDoc.
Currently non-compilable.

Created CRbSelection (derived from CSelection).
Program compiles, but still need to resolve GraphicsWindow
handling between base classes CApp, CWindow, and
CRbApp, CRbWindow for getting graphics window ptr to CTextConsole.
(define CRbTextConsole?).

Added CRbApp::m_pRbWindow.
Program is working (minimal block and spring test).

Moved graphics objects into gobj.lib, framework objs into gframe.lib

Fixed CPolygon transparency bug where CPolygon uninitialized variable
m_bTransparent was shadowing CGraphicsObject::m_bTransparent.
TODO: write or find utility to scan for derived class vars which overshadow
base class vars.
gobj and gframe libraries are working for rb and dradder apps.

Added command 'sho prop'.
Changed CBlock::GetSelectedVertex() to use block vertex ordering.
Added CBlock::PolyToBlockVertex().
Changing CBlock::GetVertex() to use block vertex ordering.

Removed CBlock::m_dOutsideRadius, changed m_dInsideRadius to m_dRadius
(equals half the diagonal, collision test is only really valid for cubical blocks).
Finished CBlock::GetVertex().
Working on CSpringBond::CalcAxialOrientation() (broke after changing
CBlock vertex definition).

Added helper function GetVertexAtMaxAngle() in CSpringBond.

Spring torsion fixed.
Added CGraphicsObject::FindObjectFromName(), selection of object by name.
Added CGraphicsObject::GetMemberObject, selection of member object by name.
Added CBlock::GetMemberObject, selection of block poly by number ("sel BlockName.m_rgPoly[n]").
Changed polygon creation order in CBlock::CreateBlockPolygons() so
top poly is created last (matches block vertex ordering).
Fixed polygon ordering bug by deleting any existing block polys
in CBlock::Read() before reading child polys from file.
Added (bool bCreateChildPolys) option to CBlock() default constructor.
to skip default creation of child polys for CBlocks reading them from file.
Added CBlock::m_bDrawBlockPolys so CAtom::Draw() can call CBlock::Draw()
and just skip drawing of block polys when CAtom::m_bDrawSphere is on.
Created 'glucose.rbd'.

Added command 'set atom sym [on|off]

Added command 'sho/hid block polys'
Adding hierarchical selection to CRbDoc::GetObjectInCursor().
Discovered picking bug where picking is off when in 640x480 mode.
I believe this comes about when the viewport is larger than the screen size.
(initial window width and height default to 780x570)
When the window is resized, the error goes away.
However, still getting picking errors where object at nearest
z depth is not returned because hit record gets 0 value.
May have to investigate using Mesa.

Adding CGoText object.
Added "ins text <string>" command.

Debugging picking problem.
Finally got around to calling glGetError() at
end of CRbWindow::Draw(), found error GL_STACK_UNDERFLOW!!
Added function glutils:PrintGlErrors().
Yahoo!!!! I finally fixed it!!!
Added code to skip CTextConsole::Draw() during GL_SELECT
(it messes with the projection matrix).

Translation and rotation of CGoText is working.

Changed CGraphicsObject::Select() method to use more flexible SelectionParam.
(needed for secondary accumulating selection).
Got sub-object secondary selection by mouse working.

Added CRbDoc::GetHierarchySelection(),
Got sub-object selection by keyboard working.
Added 'size' param to 'set atom sphere' command.

Added CCovalentBond object.
Added command 'set bondmode <mode>'.
Added CRbDoc::BeginCursorCovalentBonding(),
Added CRbDoc::EndCursorCovalentBonding().
Spring and covalent bonding not quite working yet.

Added CPdbFile, CConectList, CPdbRecord, CAtomList objects (with mods from mol project).
Added CAtom::GetCovalentBondList().
Added CAtom::GetCovalentBondCount().
Added CAtom::GetCovalentBondedAtom(int iBond).
Added CAtom::AddCovalentBond(CAtom *pAtom).

Added CRbDoc::OpenPdbFile().
Loading of pdb files works.

Getting some conect record errs because of conects to HETATOMs
which are not yet supported.

Created CBaseList object, CBaseList::CreateBases().

Added command 'add child'.
Added file i/o to CGoTextObject.
Got CGoText rotation working.

Added reset of graphics id counter to CRbCommand::NewFile(), CRbCommand::OpenFile()
(loading of trna.pdb a few times was resulting in very large ids for new files).

Added CMolecule, CEnzyme, CReactionRule objects.

Working on reactant to product conversion methods.

Added CGraphicsObject::GetDoc() (so CEnzyme::DoReaction() can call
Added "sho stats ff" command.
Added CRbApp::ShowStatusLine().
Added CGoText::SetScale();
Added "set size" command.
Added "set text" command.
Adding CBlock::ResizeBlockPolygons().

Added "move <n,n,n>" command.
Added "trans <n,n,n>" command.
Added "ins mol" command

Added CMolecule file i/o,
Added CMolecule child text label, sizing of block to label length.
Added CEnzyme file i/o.
Added "ins enz" command.
Added "set bgcolor" command.

Added "scale" command
Added "set parent" command
Added "cen <id> | <name>" camera centering options.

Added CEnzyme::Timestep(), RecruitReactants(), RecruitMolecule(), DockMolecules().
Added CMolecule::EngageEnzyme().
Changed CAnicon name to CAvicon.
Added CAvicon::Timestep().
Created CSubstrateInfo class.
Createdd enzyme reaction rul file 'PyruvateCarboxylase.rul'

Added command "set enz rul" command.
Added CForceObject::m_bSetCalcChildForcesOnly,
Added command "set fcon [on|off]" to toggle
CForceObjects as containers only.
When on, the following vars are set:
CForceObject::m_bSetCalcChildForcesOnly = true
CForceObject::m_bTransferForceToParent = false
CForceObject::m_bTimestepChildren = true
Added CForceObject::SetForceContainer(), file i/o,
CEnzyme file i/o for reaction rule file name.
Yahoo!!! Molecules are finally engaging an enzyme!!!

Added CEnzyme::DockMolecules(), DockMolecule(), HaveAllReactants(), KickReactants(),
BeginReaction(), EndReaction(), FlashEnzyme().
Enzyme reaction cycle is working but reactants are kicked out
at extreme velocity and take a long time to get back in a large

Added boundary bounce to force containers.
Removing bugs in pDoc->Add/RemoveGraphicsObject() in CEnzyme::EndReaction().
BUG ALERT!!! CFFVolume::Remove() is only removing top level force objects.
This needs to be updated to remove an object (and it's references) at any level in the hierarchy.
Products are being created and reactants destroyed in Pyruvate Carboxylase

Fixed one more bug in CEnzyme::EndReaction() (pDoc->AddGraphicsObject() is not
needed and just causes problems. New mols are added just by setting to enzyme parent).
Built 7 enzymes in the gluconeogenesis pathway, seems to be working well.

Built Beta-oxidation cycle in Chapter 24.

Added reaction direction arrow to CEnzyme.

Added command "set enz dir"
Added CBlock::SetDefaultOrientation().
BUG ALERT!!! added IsTextObject() macro which must be updated for all classes derived from CGoText.
Skipping CGoText objects in CGraphicsObject::UpdateExtents().
Fixed bug in CGraphicsObject::MoveChildren() in which extents
were not being updated properly because it was assumed that
the first object in the child list would always be used as the
initial extents object, but this assumption is incorrect as
child objects such as CBond objects and CGoText objects are
skipped in extents calcs. Fixed by using a flag to catch
first actual child used for extent update.
CBlock::SetDefaultOrientation() is nearly working (some blocks
are not at right angle wrt y axis sometimes.

Fixing CEnzyme color bug during CMolecule::Write() (inactive color is being saved as default).
Added CMolecule docked color.
Added CMolecule::DockWithEnzyme().
Fixed docking bugs. Partial cycle of gluconeogenesis and glycolysis is working.

Debugging misc bugs.
Moved saving of graphics object id from CForceObject to
Fixed bug which resulted from uninitialized CSelection extents.
Some bugs result from duplicate object names - need to add code to check
for this.

Created CPdbObject for lightweight display and file i/o of large pdb files.
Adding CPdbObject::Read().

Turned off block poly creation in CAtom(CPdbRecord*) constructor,
Added CAtom::Move() override to handle CAtom extents when there are no block polys.
Added glutils::Draw3DCircles(), trig lookup table to speed up drawing of large atom counts
(lookup table makes a big difference).
Added Element wiresphere display lists, didn't make that much performance difference.

Re-enabled glLoadName() for generic CGraphicsObject::Draw().
Added CPdbObject::Read()/Write().
Added CPdbObject::CreateDisplayList(),
Added command "show stats fr" (frame rate stats)
Added command "set dl [on/off]" (toggle use of display list).
When running with trna.pdb loaded (~1600 atoms), the difference between
using a display list and drawing every atom is only a few frames per second
(approx 5.5 vs 3.5 frames per sec).

Adding CBase::CreateBlocksFromAtoms(), GetAtomFromPdbName().

Added CBlock::RotateToOrientation(), MoveBlockPolygons(),
Added command 'set hus' (set 'hide unless selected' flag).
Added command 'set zsel' (toggle nearest/farthest z in picking to deal with picking bug)
Base ribose block creation and alignment almost there.

Added Vector.cpp::ConvertToFrame(),
Finished ribose block in CBase::CreateBaseBlocksFromAtoms().
Got adenine and guanine blocks working.

Added cytosine, thymine, and uracil blocks.

Added support for 10 modified trna residues to be rendered
as blocks. All trna residues except wyebutosine in trnaPhe (1tn2.pdb)
are rendered as blocks.

Added 'sho ribbon' command.

Added CPolySet object to handle drawing of ribbons.
Almost done creating ribbon base rung block.

Changed Vector.cpp::CalcNormal3v() so the correct direction for the normal
vector calculated assuming ccw order for vertices.
Fixed CPolySet CalcNormal() bug.
Base rungs now working.

Fixing covalent cursor bonding.
Added hack code in CAtom::Read() to set block and color from element.
Added CRbDoc::GetAtomInCursor().
Added CRbSelection::m_pCursorAtom
Cursor covalent bonding mode is working.

Added code in CPdbFile::Read() to get Pdb header info.
Fixed internal CBase::m_rgBlock init in CBase::Read().
Fixed color bug in CPolygon::Write() (wasn't saving properly if selected).
Fixing alignment of CBase base block with hbonding edge,
finished cytosine.

Finished realignment of remaining bases: adenine, guanine, uracil, thymine.

Aligned ribbon base rungs transverse to hbonding edges.

Researching NURBS.
Created Uik, CRbApp::UikTest, CGoCurve object to see if simpler
interpolation will work for ribbons.
It works!

Working on Uik pipeline in CBaseList::CreateBases() and CBase::CreateRibbon().
Changed name of CBase::CreateRibbon() to CreateBaseRung().
Fixed secondary selection bug in CRbApp::Keyboard().
There is a bug in base block orientation for trna residue A62.

Finished uik pipeline code, preliminary curves along ribbon
path look pretty good.

Uiks don't look good when interpolating all 4 points of a polygon.
Drawing a single line between base rung backs is the easiest,
most efficient, provides the least obscurement, and works just fine.

Created CResidue, CAminoAcid objects.
Made CBase inherit from CResiude, CResidue from CBlock.
Ribbons working for EF-Tu.pdb.

Added CPdbObject::GetMemberObject(),
Modified CGraphicsObject::GetMemberObject(szName) to return
child object matching name.
(allows selection with command "sel objname.childobjname").
Added CPdbObject::FindResidue() to allow selection by
"sel pdbobjname.n" to select residue n in pdbobject.
BUG ALERT!!! Added macro IsResidueObject(pObject)
(must be updated for all new classes derived from CResidue).
Removed CBase::m_chBase, changed all type references to use
Selection of residues by number is working.

Added CreateBaseBlocksFromAtoms() to CBase::Read().
Added CAtom::m_szPdbName (for lightening atom info to skip
saving of all PdbRecord info).
Base rungs are now being created from a trna.rbd file.

Added command 'sho/hid base blocks'.
Added CBase::ShowBaseBlocks().
Created CChainList object,
Added CChainList::CreateChains(CResidueList *pResidueList)
(creates chains from sequences of bases and amino acids).

Added CChain::CreateRibbon() (initializes *pNextBase
ribbon pointers for CBase residues in chain, Base ribbons
are drawn dynamically at Draw() time as line segments).
In contrast, CAminoAcid::CreateRibbon() precalculates
the protein backbone triangles during CChain::CreateRibbon().
This allows CBases to be moved around without doing a
ribbon recalc each time.
Added CBase,CAminoAcid::Move,Rotate overrides to update
ribbon CPolySets.
Added CPolySet::Move(), Rotate().
Added CBase::Select() override to select base rung CPolySet.
Base rung and backbone updates are working for translation
and rotation.
Debugging mis-aligned base blocks and rungs in ahelix.pdb.

Created utils::LogFile() function.
Added rb::startup,shutdown() functions to init LogFile.
Added CChain::CreateChainFromChildResidues()
(needed to reorganize child residues in an internal
array based on pdb res sequence id).
In debugging the "residue-out-of-order" bug in
CChain::CreateChainFromChildResidues() and defining
CResidue::GetItem(), I discovered that the inline GetItem()
functions are not being inlined. After researching inline
function implementation in Stroustrup's C++, the C++ FAQ Lite online,
and Visual C++ documentation, I realized that inline expansion is
disabled by default in Visual C++.
To verify that this possibly important optimization will be inlined,
the program was compiled with the /Ob1 switch. After looking at the
disassembly code, I verified that the code for GetItem() is actually inlined.
Need to make sure that it gets enabled when scaling up to the actual
Ribosome simulation.
Residue ribbons are in correct sequence now for ahelix.pdb.
Observed a few disturbing intermittent lockups. Ran in BoundsChecker,
didn't see anything.

Added CBase::SelectAndWireBaseBlocksIfHidden(),
CBlock::SetWireframe(bool bSet),
Changed sub-object selection to inclusive for children,
all done in order to do dynamic highlighting of blocks for a selected base.
Debugging mis-oriented base block in ahelix.pdb

Found the base block mis-alignment bug:
Primary cause was due to using different atoms in
the definition of the X and Z normals for the cytosine base.
This resulted in non-orthogonal x and z normals, causing
a rotation error in CBlock::RotateToOrientation().
The problem was exacerbated by using the m_vMin points of
the atoms instead of the center points in CBase::GetBlockParams().
Made CGraphicsObject::GetCenter() virtual to have CAtom use
pdb record for center if available (will this incur a performance hit?
CAtom::GetCenter() was made inline by including CPdbRecord.h in CAtom.h).
Added alignment checks to CBlock::RotateToOrientation().
Tested ahelix.pdb, trna.pdb, alignment problem appears fixed.

Added "sel child [on|off|toggle(both|children only|parent only)]" command to toggle selection of children
for currently selected object.
Fixing block show states.

Fixing rbd file i/o for saved pdb objects.
Added Show file tag to CGraphicsObject::Write/Read.
Removed child type checking from CCChain::Read().
Removed SetBaseBonds() from CChain::Read().
Added CAtom::Rotate() override for cases where there are no atom block polys.
Removed virtual declaration from function CGraphicsObject::GetCenter()
(for more consistent and simpler calculation of CAtom extents).

Prior addition of CreateBaseBlocksFromAtoms() to CBase::Read() is
overriding saved Base block info. The purpose of adding it was
to do creation of base rungs, so replaced CreateBaseBlocksFromAtoms()
with CreateBaseRung() in CBase::Read().
Debugging BaseBlock-Atom shift in rbd file.
Removed pWindow->SetRotationCenter(vOrigin) in CRbDoc::InitDoc()
(to maintain constant camera position when doing new doc).
Fixed atom shift bug (was saving m_vMin instead of center for atom pos).
Got Atom rotation working properly.
Added "set base oos [on|off|toggle]" command (outline on selection).
Added CGoDoc* param to SelectionParam struct.
This mode is needed currently because the base outlining, which is
useful when selecting an individual base, looks bad when selecting
many. It should probably be replaced or supplemented by the option
automatically decide to do base outlining depending on whether a single
or multiple bases are selected.
Fix hack in CSelection which used cast to CRbDoc
(probably implement CRbDoc specific selection param).

Added helix generation test function CRbApp::HelixGen(),
command 'helixgen".
This function reads a secondary structure file (base pairing)
and generates a sequence of blocks to represent the bases.

Added command 'set ruler wire [on|off|toggle]"
(needed for selections where large ruler extent obscures selected objects).
Replaced Graphics Options 'iGOWireframeOn/Off/Toggle' with
'iGOWireframe' + pParam (numerous places).
Added CSelection::SetRulerOption().
Turned off calculation of CSpringBond transverse and axial forces by default.
Turned off drawing of CSpringBond polys and eq vertices by default.
Addition of spring bonds between adjacent bases in the 1542 bases
Ecoli16S.coord file still results in a fairly slow rendering time
compared to the quick rendering time w/o spring bonds (bases are shown
as simple CBlocks).

Did profiling compile and run to investigate slow helixgen execution.
Took a long time to process the 1500 lines in Ecoli16s.coord file.
Function times dont add up, but there were 8 million hit counts for the following:
Added module 'experiment.cpp', moved helixgen function there
to isolate it from the main code and make profiling exclusion easier.
Changing pHelix->FindObjectFromName() to pHelix->FindChildObjectFromName(recurse=false)
dropped the hit count down to 1 million and reasonable execution time.
Added CRbOptions::ProcessCmdLine(), ShowUsage()

Added script processing to CRbApp::Idle().
Added CScript, CScriptCmd objects.
Replaced strcpy() with sstrncpy() in CRbCommand statements
which were assuming a maximum command line length (no longer true).
Added CScript::GetNextCommand().
Added script object initialization to CRbOptions::ProcessCmdLine().

Changed CForceObject::CalcStericForce() so it only is doing Block objects
at this time,
Removed intersection volume and using intersection radius instead.
Gave CSpringBond a min extent so CSelection::UpdateAxes() doesn't complain.

Added CPolySet::Select(SelectionParam *pSel) to support secondary selection
Added "Center on Selection/Origin" menu items to View menu.
Changed "sel child" logic to just select children of top level selected object (deselects parent top-level object)
Added command "sel parent" (deselects children of first top-level object).

Added command 'rot a,x,y,z' (rotate selection by angle about vector)
Added command 'rot std' (rotate to std orientation)
Included CPdbObject in IsForceObject() macro.
Converted 'g.pdb', 'a.pdb' files to rbd files and aligned
these bases to a std orientation.

Added handling of "wire" command to CAtom (handles iGOWireframe in SetOption()).
Added handling of "ins sbond" to CAtom by responding to iGOGetSelectedVertexPair in CAtom::SetOption().
Changed CBlock::GetVertex() to return center point if iVertex == -1.
Changed CSpringBond::IsValid() to report valid for vertices >= -1.
Added CAtom::UpdateExtents() to override base class UpdateExtents() when atom has no block polys.
Note: the updating of extents following translation or rotation
is currently inconsistent and perhaps redundant when updating an
object, its children and parent.
The entire scheme should be re-analyzed carefully at some point
to ensure consistent and minimal updating.
Removing references to CForceObject::Draw() as bonds are already
in the child object list and are being called twice.
Sucessfully added a spring bond to atoms in two separate bases
but the spring is not acting correctly (bases move far apart).

Added 'szArgs' param to CGraphicsObject::GetPropertySz(), '-ext' flag.
(report extents in property).
Tried to create util function 'ssnprintf' (to safely terminate formatted string),
but there were problems passing va_args to _snprintf.
Routed CRbApp::MsgBox() text to LogFile (msgout()).

Routed CTextConsole keyboard input to LogFile (msgout()).
Removed CAtom::UpdateExtents() override - it wasn't correct
as extents without block polys must be set directly inside of move, rotate and read
methods. If a center point was used instead of m_vMin and m_vMax,
a CAtom::UpdateExtents() method might make senese.
However, CGraphicsObject::UpdateExtents() was changed to prevent
initialization of extents to zero as this will create incorrect
extents for objects with only non-extent child objects (such as CGoText and CSpringBond).
Added CResidue::GetMemberObject() to implement rasmol-style selection syntax.
Changed CBase naming in CBaseList::CreateBases() to provide compatibility with
rasmol expression syntax.

Added parent force transfer to CBase children (blocks and atoms).
Added saving of complete timestep info in CRbDoc.
Added command 'sho dist' (distance between selected objects).
Measured distances in adjacent A-G bases from tetrahymena pdb file,
Created individual A and G bases in rbd format, created 2 spring bonds,
one between A115.O3* and G116.P, one between A115.C4 and G116.C4,
ran forcefield and the two bases seemed fairly stably held together,
though not at the equilibrium spring bond distances.
(file 2base2bonds.rbd)

Added "sho steric" command (display of steric collisions and forces)
Changed CProperty::OnExitCalcStericForce() to create CGoCurves to
show steric forces and torques.
Fixed "sel child", "sel parent" commands to actually add/remove children to/from selection object
(they were just setting select flag previously).
Added CProperty::OnEnterCalcForces().
Added logging of steric collisions to CProperty::OnExitCalcStericForce(),
this allows me to see that CalcStericForce() is only being called for
base and ribose blocks because the atoms are children of the entire
base and not of the blocks. This may require a redesign of the
base child hierarchy.

Made atoms children of base blocks in CBase::CreateBaseBlocksFromAtoms().
Added CBase::GetRiboseBlock(), GetBaseBlock() as block ordering
in m_rgBlock cannot be assumed to remain constant after file i/o.
These methods currently use the non-ideal means of identifying
the ribose and base blocks by assuming the name of the blocks
begin with "RiboseBlock"/"BaseBlock".
After recreating a and g rbd docs from pdb originals, with
atoms now children of the base blocks, and inserting spring bonds
between the P and O3* and between atoms in the rings, and
running the forcefield, the springs are working but there are
some problems: one of the bases is trying to head south and
there is far too much steric intersection.
Further trouble-shooting will be helped by adding a wire-frame/stick
bonding view of the molecules.

Changed 'View' menu to 'Camera' menu,
Added 'Draw' menu (rendering options).

Added drawing of covalent bonds in CAtom::Draw().

Replacing atom string names with enumerated names:
Replaced CAtom::m_szPdbName with m_iPdbAtomName,
Added PdbAtomNameMap table to CPdbRecord.cpp,
Added PdbAtomBondDef struct,
Added f_rgRiboseBlockBonds table to CBase.cpp,
Added CPdbRecord helper func GetPdbNameId(char *szName);
Changed CResidue::GetAtomFromPdbName(char *szName) to GetAtomFromPdbNameId(PdbAtom iId)
Changed CBase base block defs from arrays of char* to arrays of PdbAtomName.
Added CPdbRecord helper func GetPdbNameSz(PdbAtomName iId).
Loading of pdb files such as "a.pdb" is working again.

Added command "read script <scriptfile>".
Script file processing is working.


Created CRbScript object for more powerful scripting.

Created CString class, made CStatus derive from it.
Added recursion option to CGraphicsObject::GetPropertySz().
(useful for debugging parent and child extents).

Added CRbScript::ScanVariableDeclaration().
Removed CString::m_cbText, doing a strlen() instead for
strcat ops in order to allow full access to the text buffer
(minimal performance hit is worth the resulting safety).
Added CRbScript::IsValidVariableName().

Added CRbsVar class.

Adding CRbScript::ScanFunctionCall().

CRbScript::ScanFunctionCall() is working!

AlignBase.rbs script is working!

Moved status line creation to CRbApp::CreateStatusLines().
Replaced iGOOptionOn/Off/Toggle with option int params,
Added option int param to ObjectOption struct in CRbOption.cpp.
Added 'spacefill on/off" command (synonym for sho atom sphere, compatibility with rasmol)
Added NULL pointer checking for option params in all object SetOption() methods.

Added command "create covalent" (create covalent bonds for selected object(s)).
Adding CBase::CreateCovalentBonds().

Added CResidue::m_pAtomList, CResidue::BuildAtomList().
Added GetElementValence() to element.cpp.
Fixed memory bug in CRbScript::ScanFunctionCall().
CBase::CreateCovalentBonds() is working.

Added command history stack to CTextConsole.
Added CVoidPtrArray::RemoveAndPack() (packs after removal to retain sequential order)
Created CStringList object.
History stack is working.
Fixed file position bug in CScript::GetNextCommand().

Considering adding CGoFile save flags to limit saving of unneeded data
in base class methods (such as saving mass in CForceObject for CAtom objects).
To do this, CAtom and CForceObject file object tag enumerated type declarations were
moved into the class definitions, allowing them to be referenced in other modules.
However, in the interests of time, I am just doing Atom-specific type checks in
in CForceObject and CBlock Write methods for now, to skip saving of mass, size, and color.
Moving the enum types into the class definitions also requires explicit
reference of the type with the scope operator (such as CAtom::iFileTagEnd)
because CBlock methods are used to read and write CAtom objects.
Consequently, the enum types have been moved back into the module files for now.

Created low-res atom sphere consisting of 24 triangles for rendering large numbers of
atoms in spacefill mode. Looks pretty good.
Created CAtom::DrawQuickSphere(), CalcQuickSphereNormals().

Changed 'sho/hid' syntax to 'sho <arg> [on|off]' to allow for toggling of option.
Adding items to Draw, Camera menus. Moved Camera menu under Options menu.
Added 'Read Script' menu item, dialog.

Added selection status line in main window (needed to indicate type of sub-object selected
in cases where a PdbObject, Chain, and Base all show the same extents).
Added override CRbSelection::bool CSelection::Add(CGraphicsObject *pObject...) to
update selection status.
Added CRbSelection::m_pStatus, did research on setting ptrs to NULL inside of destructors.
Selection status line is working.

Created override CChain::UpdateExtents() to Resize block polys
to children if visible.
Did the same thing for CPdbObject.
CChain and CPdbObject block poly frames are now properly
updated when rotating child base objects.

Added "call script" command (allows return to a script after calling another),
Implemented a script stack,
Added classes CScriptList, CScriptStack.
Changing script handling by passing in CScriptCmd as a parameter.
Script calling is working.

Created batch files 'bd1.bat', 'bd3.bat' and sed scripts '' and '' to build
makefile dependency file 'rb.dep' using gcc and the -MM option.
This eliminates the time-consuming 'rebuild all' step every time a
a header file is changed.
Added guanine block atom bond defs.

Added cytosine block atom bond defs.
Removed CPdbObject::Draw() override (no longer using display lists so not needed).
Added Draw menu items 'set atom lowres', 'set atom sphere size'
Added uracil block atom bond defs.

Added CScript::m_pCmdList, AddCmd(CString *pstrCmd) to allow
internal app command sequences such as in CRbDoc::OpenPdbFile(),
to select and center on pdb object after loading.
Changed selection syntax to assume 'sel <num>' is selecting
pdb residue instead of object id, for compatibility with rasmol.
Selection of object by id is now specified by 'sel id <num>'.
Pdb Residue selection syntax supports range and list args (i-j and i,j,k,...).
Adding CRbCommand::SelectResidueObjects().
Experimenting with use of templates for integer list processing.
MSVC compiler requires /GX switch (Enable Exception Handling).

Researching use of C++ Standard Template Library for string and collection operations.
Created 'Tokenize()' function using STL classes for better processing
of cmd lines (required in separate module stlutils.cpp because of
MSVC linker problems with _DEBUG switch and __CrtDebugReport symbol).
Solved unresolved external problem of __CrtDebugReport by using /MTd switch.

When running the new static multithreaded debug version, an old bug
was discovered, where, during construction of child objects of CRbApp,
(the CRbDoc object) a CRbApp method was called (UpdateTRTimestepModeLine()),
which required that the m_pDoc variable had been initialized, but it had
not, since the program had not yet returned from the CRbDoc constructor.
This points out the general problem of preventing object methods from
being called during construction, before initialization is complete.
One interim solution, though it may not be rigorous, is to initialize
all member objects to NULL before doing any initialization of them via
the new operator.
Actually, all member objects should be rigorously initialized before
doing anything else in a constructor, this generally happens through
the SetDefaults() method for most classes, though one has not been
defined for CRbApp.
A utility which can scan the constructor code and detect incomplete
attribute intialization would also be useful.
Created CRbApp::SetDefaults().
Added test in CRbApp::ModeChange() to check for graphics initialization.
The application is working again.

Added std::string version of TrimWhitespace() in stlutils.cpp .
Added integer lists using list<int> templates in CRbCommand::SelectResidueObjects().
(can't use list<T> where T is an arbitrary struct or class type because of compiler
complaints probably relating to lack of an allocator?).
Parsing of residue selection arguments using STL template strings and integer lists
is working!
Changed char* args to all MsgBox() methods to const char*.

Adding CChain::GetResidueFromPdbSequenceNum().

Fixed drawing bug in CAtom::Draw() for covalent bonds where there was a gap at midpoint
between the two atoms. This was caused by the vertex order when calling
glBegin(GL_LINES). Drawing from each atom center to the midpoint should give the same results
results as drawing from atom 1 to center to atom 2, but it doesn't (bug in OpenGL?).
Changed command 'set ruler wire [on|off]' to 'set sel axes wire [on|off]' (selection axes).
Added command 'set sel axes [on|off]'.
Selection of residues by list and range argument is working.

Added 'inv sel' command (invert selection).
Added command 'set sel cursor [on|off]'.

Added string versions of CRbCommand::ParseOnOffToggleArg(), CCommand::MsgBox().
Fixed bug in stlutils::Tokeninze(string) (can't terminate stl strings by setting char to NULL,
must do assignment or substring).
Added Selection Menu (under Options Menu),
'Toggle selection axes', 'Toggle selection axes wireframe' menu items.

Added CChain::CreateInternalCovalentBonds() to create bonds between nucleic
acid residues.

To prevent 'wireframe' arg being applied to CChain and CPdbObject child block polys,
they have been removed from the child list, only referenced in the
internal block poly list CBlock::m_rgPoly.
This was implemented by adding a parameter 'bAddToChildList' to CBlock::CreateBlockPolygons() and
This also requires CChain overrides to do selection coloring of m_rgPoly, but the
general trend towards moving block polys out of the child lists is worthwhile in
in the long run because it reduces the performance hit when recursing through the
child lists for most operations, where the child block polys are largely ignored.
Added visibility check for all SetOption(iGODrawWireframe) cases.
Prior addition of CGraphicsObject::SetOptionIfSelected() is causing problems
when objects try to bypass SetOptionForChildren() in by returning in SetOption() without chaining to base class SetOption()
because SetOptionForChildrenIfSelected() is called in CGraphicsObject::SetOptionIfSelected()
regardless of what is done in the object's SetOption() method.
This raises the question of how options should be set in hierarchical scheme.
Does there need to be a separate set of option codes which only apply to selected objects?
(ie: iGODrawWireframe AND iGODrawWireframeIfSelected?). This seems to be unnecessary duplication and
a potential source of bugs.
An alternative is to make the bSetChildren parameter a pointer or reference which can be modified
inside the object's SetOption() method to bypass the subsequent call to SetOptionForChildIfSelected().
A second alternative would be to implement a separate method as needed, SetOptionIfSelected(), which uses the same option codes.
This second alternative will be used for now for classes which need to override children SetOption behavior.
Note: removing block polys from Base child list obviates this issue somewhat.
The same thing has been done for CPdbObject.
These problems indicate that we need to bite the bullet and remove the block child
polygons from the child list for all block objects include CBlock. This will require
some architectural overhaul in the short term, but it looks like it must be done.
Removed addition of block polys to child list.
Added overrides CBlock Rotate() and Move() to apply to m_rgPoly list.
Added override CBlock::FindObjectFromId() to search m_rgPolys for id when doing mouse selection.
Need to do a SetParent() to CBlock() on m_rgPolys even though they are no longer in the
child list (needed for CRbDoc::GetHierarchySelection()). Will this cause any problems?
Question: should UpdateExtents() be invoked by the caller of an object Move/Rotate method?
If so, and if done after the operation and the parent has updated it's extents, the parent's extents
will be invalid.
So should UpdateExtents() be invoked by the object itself?
It should happen after all child objects have done their move/rotates and updated their
own extents.
Also, if multiple children are being moved, they should not invoke the parent update multiple times.
Also, if an object is calling a base class move/rotate method, the base class should not do an UpdateExtents()
if the derived class will being doing it again on return from the base class method.
Added override CBlock::UpdateExtents() which will still use m_rgPolys for extent calcs
even though they are not in the child list. This actually works well with CChain and CPdbObject
overrides of UpdateExtents(), because they will delete their m_rgPolys before doing the base class
call, thereby eliminating unnecessary traversal of their blocks polys in their CBlock::UpdateExtents().
Should some kind of flag be used, similar to a redraw() flag, so that multiple/redundant
updates are avoided?
Object extents appear to be working again.

Added command "add chain sbonds [backbone]" (creates spring bonds between
nucleic acids residues in a chain).
Added CChain::CreateInternalSpringBonds().
Ran forcefield on ahelix.pdb with spring bonds between
residues along backbone, behaves fairly well.

Added CRbCommand::AddChainObject().
Added command 'add chain sbonds stack' (spring bonds between adj base
rings to represent stacking interactions)

Packed 'backbone', 'stacking' and 'hydrogen' sub options into
CChain::CreateInternalSpringBonds() method.
Ran forcefield again with chain backbone and stacking bonds,
still looking good, but another spring bond on the opposite
end of the ring should make it even better.

Added override CChain::RemovedChild() to update m_pResidueList
when residues are deleted.
ifdefd out BondRx and spring eq vertex attributes and methods for spring
bonds as these are only being used in spring-bond orientation,
which is not currently enabled (simplifies reference handling
on deletion of objects with bonds). (#ifdef SPRING_EQ_VERTEX)
Added child recursion to CForceObject::DeleteBondsToObject() to fix
incomplete removal of bond references to removed objects in CFFVolume::Remove().
Added iGOGlobalRemoveComplete message to allow objects to rebuild
internal references after global removal of objects in the hierarchy
(ex: chains rebuilding their ribbons, extents, etc., after deleting a residue)
Called in CRbCommand::DeleteSelection().
Added CGraphicsObject::FindObject().
Added override CAtom::DeleteBondsToObject() to remove covalent bond
references to removed objects.
Ran ahelix.pdb in forcefield, deleted residue 4 while running,
covalent and spring bonds and references appear to be successfully

To implement object activity through Avicons (Activity Controller objects),
the code in the CRbScript and CRbCommand objects will be leveraged.
Ideally, the Avicon script and command objects should share a base
class and code with the CRbScript and CRbCommand objects, but
due to time constraints, a certain amount of code duplication will
have to be done at this time.
Created CAvScript, CAvCommand, CAvMoveTaget objects.
Added CAvicon::LoadScriptFile().
Added command "set avi script <file>" (object activity controller script).
Added CRbCommand::SetAviconProperty().
Added CRbCommand::SetStatusLine().

Added script processing to CAvicon::Timestep().
Added Rbs Function 'GetCenter()' to CRbScript.
Added Rbs Function 'InitVector()' to CRbScript.
Added Rbs Function 'AddVector()' to CRbScript.
Created avicon script 'mc.rbs' (mRNA Cogger script),
CAvScript and CAvCommand are working.
Added command 'set movetarget pos' to CAvCommand.

Added reloadable target list to CAvicon,

Added 'set reload 1' cmd to CAvCommand.
Added 'set useforce' cmd to CAvCommand
to toggle between using force and imposed velocity
when moving objects with avicons (needed for the
mrna cogger base which would otherwise be expelled
by the target mrna due to its smaller mass).
Added 'unary minus' expression hack in CRbScript::ScanFunctionCall()
to negate value of script var.
Initial mrna cogger script 'mc1.rbs' is working.

Added 'set movetarget relpos' command to CAvCommand to
define move target position at target load time for avicon
(this allows position-independent movement patterns).
Added CAvCommand::SetMoveTarget(string sArg).
Working on relative targeting.

Relative targeting is working except that change in position
of an avicontrolled object by the user doesn't result in an
updated relative movement until the movement cycle completes.
To remedy this, some way of notification is needed to an avicon
following user-caused changes of position. To do this, a SetOption
code will be sent following a CSelection Move() or Rotate().
Added CAvicon::UserMovedObject() to flush and reload target list after
user move.
When doing script to load multiple objects, selection is an issue.
To facilitate this, ungrouped objects must
be selected by default to allowing renaming to a unique name which
can be referenced by subsequent script commands.
Added creation of CChain backbone and stacking spring bonds by default
in CChain::CreateChainFromChildResidues().
After experimenting with top and bottom cog bases interating with
a short oligo, it was found that the cogs were moved significantly
from their intending positions and the relative motion setting didn't
Setting the cog base masses to 100 served to keep them in position.
Their avicon scripts were also rewritten to move to absolute target
A 7-mer oligo was loaded and placed between the cogs. It escaped
at first, but then 2 retaining bases with movement set to off were
placed on either side and the oligo was retained in the channel.
As the 2 cogs went through their movement sequence ('mtc.rbs' and 'mbc.rbs'),
the oligo was successfully forced through.
The script to load the cogs and the oligo was saved as 'cogger.rbs'.

Doing performance analysis.
Added cmd 'set msgbox [on | off]' (enables/disabled msg box).
Created profile script 'profile.rbs'
(loads a 2nt pdb file and runs the forcefield for 100 timesteps).
Added 'run [n]' cmd (run for <n> timesteps).
Added 'exit runlimit' cmd (exit after run limit reached)
Created 'pr.bat' profiling batch file which runs
MSVC profiling tools 'prep', 'profile', and 'plist'.

Created 'renseq.cpp' utility to rename an input file
into a sequentially numbered output file, allowing
the generation of multiple '' profile listing
files as '', '', etc.

Transferred build tools over to laptop.
Wrote perl scripts to do averaging to function times
in the '' files.


The function GetMidpoint() is showing a significant
amount of time relative to its operation (~330 msec, %4)
and is probably partly responsible for the long CAtom::Draw() time,
(~2700 msec and 32%).
The default CGraphicsObject::GetMidpoint() method is calculating
it from m_vMin and m_vMax extents, but for CAtoms, this is an
unnecessary step if we define an additional attribute just containing
the atom center.
The CGraphicsObject attribute, m_v, which has been unused for the most
part (in favor of m_vMin and m_vMax) can be used for this purpose.
In order to improve encapsulation, m_v, m_vMin, m_vMax, and m_vVelocity
have all been made private to CGraphicsObject (will require extensive code change).
Consequently, getting the center of an object will require calling
a data access method such as GetCenter(), which for objects with directional extents
will be obtained through calling GetMidpoint() on m_vMin and m_vMax, but
for CAtoms, can just return m_v.
Made vector.cpp::CopyVector() inline (and selected other vector.cpp functions).
Went through all code with references to newly-private vars m_vMin, m_vMax, m_v,
m_vVelocity and replaced with method wrappers.

Finished fixing about 6 different Extents bugs introduced by the attribute hiding.
Profile script for '2nt.pdb' is working again.

Added 'set con [on|off]' command (to reduce significant hit in
performance from glutbitmapcharacter()).
Doing optimization by inlining high hit-count functions
(especially in vector.cpp).
Created CForceObject::CalcAtomStericForce() to optimize
intersection checks and steric calcs between atoms.
CAtom::GetCenter() and CBlock::GetMaxExtents() have been removed
from the top of the hitcount list now (, but speedup
is not tremendous.

Creating Release version of rb.
Added macros needed for release build to makefile.
Built release version, appeared to run ok.
Did profiling of release version, only appeared to be marginally
faster than debug version (4162 msec vs. 4496 msec).

Minor optimizations in CAtom.cpp, CAxis.cpp.

Optimization: doing direct rotation of atoms and child block polys in
CBase::Rotate() (skipping base class method).
Added vector.cpp::void RotateVectors(Vector rgVector[], int iTotalVectors, double rgdMatrix[16], float fAngle)
(precalculated rotation matrix).
Added CPolygon::MatrixRotate().
Added CBlock::RotateBlockPolys().
Did manual testing of interactions between atoms and blocks
in 2nt.pdb, appears to function ok.
There is a small but significant speedup in profile.rbs (~500msec).
In looking at the forcefield stats for 2nt.pdb, it appears that
the intersection checks and steric collision counts are much
higher than they should be.

Added member selection to CRbCommand::SelectResidueObjects().
Added CResidue::GetMemberObjects().
In debugging the excess steric interactions, it was found that
in CForceObject::CalcForces(), every child object is recursing
the entire hiearchy regardless of parent bounding-box interesection.
This is needed in the case where interactions such as bonds can
can extend beyond the bounding box intersection, but it would be
nice if there were some way of bypassing the other objects in the
hiearchy for each atom when there are no long range interactions
with those objects.
It was also found that atoms within a block were interacting with
each other due to a hack in CForceObject::CalcTargetInteractions()
which bypassed interactions with a target if the target was the
the parent and a base. This worked when atoms were direct children
of the base but failed when they were moved into the child base blocks.
A new hack was added which bypassed interactions with the target if
the target was a base and either grandparent or parent.
This greatly reduces the number of steric calculations.

Added optimization hack in CForceObject::CalcForces() to bypass child interactions
if this and target do not intersect (unless parents are adjacent bases)
added CForceObject.cpp helper func AreAdjacentBases().
This optimization does not currently work because each object
with force children is letting each child recurse the entire hierarchy
Instead, the objects need to recurse the hierarchy to their own level
and then pass their object-level targets on to their force children
for recursion (after doing intersection checks).

Currently, in cogger.rbs, intersections checks are around 19,000, sterics are around 400.
Adding recursion of force target to source object level via
Added CForceObject::GetForceChildList(), m_pForceChildList;
This insures uniform access to child objects which are force children
and elimination of hacks to count and check for force objects in child list.
Removed CFFVolume::m_pFFList, changed references in CFFVolume.cpp to use new m_pForceChildList attribute
from its CForceObject base class.
Ran cogger.rbs again, interactions appeared to be correct, but the number
of intersections and sterics went up! Not down!!!

Debugging increased steric interactions.
Ran 2nt.pdb on older version (, collected the following stats:
for 1st timestep:
Calcs = 45, IntCks = 762, Sterics = 60.
Ran 2nt.pdb on current version:
Calcs = 83, IntCks = 2912, Sterics = 204.
'2nt.pdb' is not the same file on both machines!! Arg!!!!
Copied '2nt.pdb' from ref machine (, ran again:
Calcs = 79, IntCks = 2670, Sterics = 204
Found the problem! After creating m_pForceChildList in CForceObject,
forgot to remove the child from the force child list in CForceObject::Remove(pChild).
Now, the ff stats for ' 2nt.pdb' are:
Calcs = 45, IntCks = 762, Sterics = 60.
In debugging this problem, it was also discovered that steric interactions
are being duplicated between both source and target. This has been
happening ever since force interactions were done below the initial
top-level list. Can we do the 'lesser graphics id' test still, to avoid
the duplication?
Did reference stats for 1st timestep of cogger.rbs:
Calcs = 323, IntCks = 23823, Sterics = 726 (same as
Added HaveIntersection(), AreAdjacentBases() and GetHLevel() to
stats for cogger.rbs are now
Calcs = 2690, IntCks = 9885, Sterics = 378.
IntCks are better, but why are Calcs up?
In printing debug stats, it was found that children are getting
their CalcForce() called multiple times from the parent RecurseTargetForForceChildren().
This would be ok if only steric interactions are calced in the child CalcForces(),
but the bond and friction forces are being over calced.
It seems perhaps that the force calc recursion should be split into
2 parts - one that does steric interactions only using the parent
intersection tests with the targets at its own level, and the other,
a full recursion of the object tree for each object to calculate its
bond and friction forces.

Separated steric force calcs from non-steric calcs in
Renamed 'RecurseTargetForForceChildren()' to DoStericInteractions().
Renamed 'CalcTargetInteractions()' to DoMyStericInteactions().
CalcForces() only does friction and bond forces as well as recurse children.
Top-level force object DoStericInteractions() and CalcForces() are now start in 2 separate for loops
in CFFVolume::CalcForces().
Changes appear to work, except bases need to recurse below the level
of base for targets because base bounding boxes are so big, we don't
get significant parent intersection test savings at the base level.
By moving it to one below the base level, we get some improvement,
but not as much as hoped for.
But moving the source recursion to one below base level is better
(150k intersect checks for trna.pdb vs. 290k for
specific stats for trna.pdb:
Calcs=1840, IntCks=289901, Sterics=5510.
specific stats for trna.pdb:
Calcs=1840, IntCks=148474, Sterics=5510

Changed target recursion so that current object recurses targets to
its level, regardless of what it is.
Needed to add UpdateExtents() to CForceObject::Timestep() after
doing TimestepChildren() (chains and pdb objects were not getting their
extents updated).
Current cogger.rbs stats are:
Calcs=323, IntCks=16590, Sterics=726.
Cogger run looks ok, next step is to remove the steric duplication.

Added reciprocal steric skip, works fine.

Removed CBase block polys (not needed to calc extents)
Changed CBlock::GetMaxExtents() to return just plain extents
if no block polys.
Adding cogger frontblock and backblock avicons for grasping
the mrna during top and bottom cog returns.
Adding avicon start and end msgs (triggers and completion
notifications for avicon move targets).
This allows for conditional object movements where an
avicon-controlled object will not engage a movetarget until
completion of some other object movement.
Added GO option iGOSendAviconMsg.
Added command 'SendAviconMsg <msg>'.
Added CAvicon::SendMessage().
Added avicon commands 'set startmsg <name>', 'set endmsg <name>',
'sendmsg <idname> <msgtext>'.
Added CAvicon::Message().
Added enabling and disabling avicon targets and object movement.
Added scripts for cogger frontblock and backblock,
the cogger script now has synchronized and conditional movement
between top and bottom cogs and front and back blocks.
Ran forcefield with mrna, but the orientation of the cogs and
blocks needs to be adjusted to get proper cogging of the mrna.

Added atom coloring support by adding CResidue::SetColor() to set
m_pAtomList color.
Changed CBlock::SetColor to back to set color on child objects in addition
to color on child polys only (see
Added pdb name to atom GetPropertySz().

Added selection of base.ribose.
Added command 'set sel color [on|off]' (HACK ALERT!!! used global var g_bNoSelectionColoring).
Added member selection to range residue selection (ie: 'sel mrna.1-3.ribose' selects ribose atoms
on residues 1-3 of named pdb object 'mrna'.
Added command 'set cen' (sets rotation center w/o centering camera).
Added CRbCommand::SetRotationCenter().
Trying to develop new version of cogger using 3nt cogs.
Trying to clamp the mrna is like trying to togther a bunch of greased balloons
on a windy day.
Need to add vdw forces.
Added vdw forces with repulsion exponent of 4, attraction exp of 3,
they work great!!
Can now dock 2 3nt frags of rna on either side of the mrna and drag it
to a destination.

Added legends to selection arrrows.
Added CGoText m_pStartText to CRuler.
Because of graphics operations on CGoText, needed to
move CRbDoc construction from CRbApp constructor to
CRbApp::InitializeScene(). Hope this doesn't create any
embarassing bugs!
Axis legends are working.

Added CRbScript command 'GetObjectCenter(szObjName, vRetCenter)'.
Added parsing of string arguments in CRbScript::ScanFunctionCall().
Added member name support to CGraphicsObject::FindObjectFromName().
Needed to rem out 'SetRoot()' in CGraphicsObject::SetParent() (side effects?).
(causes invalid root pointer retrieval).
The only object with a non-NULL m_pRoot variable should be the Root object itself.
Changed definition of GetRoot() (was returning 'this' if m_pRoot is NULL).
Instead, if m_pRoot is NULL, should return m_pParent->GetRoot() if m_pParent, else return this.
Updated CPdbObject::FindResidue() to find residue through chain children
in addition to residue children.
AvCommand parsing of move targets by name is working.
Ran nc.rbs and set cog base 1 movetarget as mrna base 1 initial position,
cog1 approached position and halted (need to reenable object movement if no
subsequent move targets).

Added CAvicon::AddMoveTarget(CGraphicsObject *pObject),
CAvCommand 'add movetarget name <object name>'.
Added CAvMoveTarget::IsObjectAtTarget().
Added SetSize() to CBase at selected places where UpdateExtents() is called,
to set base radius (needed for CAvTarget::m_fTargetIntersectDistance).
Avicon movetargets by name is working. Created mrna.3.rbs avicon script
to approach cog base 3, the molecules successfully docked.

Changed "move" command reference from object min to object center.
Added avicon command 'set intersect <dist>'.
Added avicon command 'set emdelay <time>' (end message delay to allow for good docking).
Cogger is getting there but still needs more work.

Added avicon msg 'd_iAviconMsgLoadScriptFile' to set multiple avicon object
script with a single command using SetOption(iGoSendAviconMsg).
Changed CGraphicsObject::GetAvicon() to just return the pointer
instead of also created a new Avicon if NULL,
Added CGraphicsObject::CreateAvicon().
multi-object avicon script loading is working.

Changed Avicon switching of object movement to switching of object translation.
Changed 'atom lowres' rendering to just render spheres with fewer polys
(bulged cubes just look too crappy).
Sphere lowres rendering looks ok and is fast enough!
Added avicon cmd 'set endtrans <on|off>'
Changed cog1 and cog2 scripts to rel movement.
Experimenting with vdw params.

Added avicon reporting of target engagement.
Still working on cogging.
Need to add multiple start conditions to move targets

Changed move target enable msg to enabling msg list.
enabling list is working
cogging works up to forward movement.

Added side clamp movement,
Added back movement of top and bottom cogs to nc.rbs
Gave demo in Tripp Commons for RNA2000, people liked it!

Adding stick rendering mode.

Fixed some bugs related to 'book.rbd' (in CAvicon.cpp).

Added CAtom::HaveCovalentBond(CAtom *pAtom),
Changed CAtom::GetCovalentBondList() to optionally allocate
new list.
Stick rendering is working, although the triangular faces
are not aligned along base rings.

Adding toolbar.
Removed local 'Vector.cpp', 'Vector.h', created common
wkVector lib (so 3d vector routines can be shared among projects).
Removed local 'glutils.cpp', 'glutils.h', created common
wkGLutils lib.
After changing references in source, include and makefile
and rebuilding, ran 'ahelix.pdb' sucessfully.

Built again after merging mbgl glutils in wkGLutils.lib,
had to include 'gdi32.lib' in rb makefile to get it to link.
Tested on 'ahelix.pdb', it runs.

Added toolbar, it works.

Tried to add Windows GetOpenFileName() common dialog, but
it doesn't work with glut (can't call window repaint during dlg).
Added rotate, transxy, transz, select, center, run, and
stop icons to the toolbar.
They are all working well.

Hooked up wireframe, stick, spacefill, block and ribbon buttons
on toolbar.

Remove construction of block polys for CChain and CPdbObject classes.
Added rendering of selection extents,
turned off rendering of selection axes, color in default mode.

Added Volume submenu to Options menu.
Added selection of base atoms in residue selection (CBase::GetMemberObjects()).
Added drawing condition to CSpringBond to only draw between
atoms if the atom are being drawn.
Removed selection of spring bonds by mouse.

Moving CTextConsole class to wklib.
Changed CTextConsole::GetAndDispatchInput() to PromptForInput().
Removed CTextConsole::m_pCommandHandler.
Retrieving console input in CRbApp::Keyboard() after CTextConsole::Keyboard().
Removed CApp::SetConsoleInputMode(), using internal method: CTextConsole::IsKeyboardInputModeSet().
Added CTextConsole::SetKeyboardInput(), GetKeyboardInput().
The new version of the text console is working.

Cleaning up CTextConsole for move to wklib.
Ran in BoundsChecker, found memory leak which started when CBlock internal polys
were removed from child list (and were not being deleted in the CBlock destructor).
Removed bAddToChildList option from CBlock::CreateBlockPolygons() and ResizeToChildren()
(were not being done at this point anyhow) to guarantee they will not be in the child
list and so safely deleted in the CBlock destructor.
Found another memory leak related to doing delete on void pointers in CVoidPtrArray.
Removed all CVoidPtrArray deletion routines.
This fixed the leak in CString. We now have only two memory leaks:
2304 bytes onexit.c, line 104
36 bytes, gmtime.c, line 71
(not in my code - caused by glut not exiting properly?).

Doing profiling check (pr.bat) - toolbar drawing is adding significantly to profile time.
Added Window submenu to Options menu,
Added 'Toggle Toolbar' item to Window menu.
Added 'Toggle Console' item to Window menu.
Profiling time w/o toolbar drawing is comparable to (2448.622 millisecond).
Finally got start function param working for profile 'prep' (/sf "CRbDoc::Idle").
Changed run limit in 'profile.rbs' from 100 to 1000,
Realtime: 2 min, 10 sec.
Progtime: 5313.942 millisecond
max func: CForceObject::DoMyStericInteractions(): 1072.189 sec (20.6%)
Realtime: 2 min, 9 sec.
Progtime: 5356.094 millisecond
max func: CForceObject::DoMyStericInteractions(): 1097.549 sec (20.9%)

Moved CTextConsole, CStatusLine classes to wklib,
they work.

Added CScrollConsole class (derived from CTextConsole).
Added CKeyboardInput class (to queue special keys such as PGDOWN)
Found glutSpecialFunc, eliminating need for CKeyboardInput for now.
Got display and scrolling of 'help.txt' file working for CScrollConsole
(linedown and pagedown only).

Added CScrollConsole::GetPrevLinePos, but newline translation required
bad hack.
Added CScrollConsole::LineUp(), it appears to work.

Added CScrollConsole::PageUp(), it has a bug (offsets from GetPrevLinePos() are different
than those from GetNextLinePos().

Trying to get proper setting of rotation origin without
camera shift.

Figured out how to adjust camera to give same view when setting
new rotation center (CRbWindow::SetRotationCenter()).
It finally works!!! Yeah!

Fixed StatusLine text update bug (in wkGLgui lib).
Split "toggle wireframe" into "toggle atom wireframe" and
"toggle block wireframe".
Added 'next history line' in CTextConsole in wkGLguil lib.
There is an extents bug when deleting a chain in a pdbfile object
(pdbobject extents not being updated).

Added UpdateExtents() to CGraphicsObject::DeleteObject().
(fixed extents bug).
Added Color menu,
Added "set color cpk", "set color structure", "set user color" items.
Added 'minimize energy' icon to toolbar.

Added saving to pdb file.
Bug: CPdbFile::CreateConectRecords() doesn't work at all because of atom id.
Saving of pdb file w/o conect records is working.

Fixed atom selection bug in CAtom::Draw() for covalent bond portion
belonging to other atom (wasn't loading its graphic id).
There is another bug due to the fact that only one atom is drawing a
covalent bond between it and the other atom. Consequently, if that
atom is hidden, the other atom's portion of the covalent bond is not
Gave demo to Bo Demmeler, he liked it.

Fixed covalent drawing bug, added CAtom::DrawCovalentBonds().

Added command 'draw [wire|stick|spacefill|ballstick|blocks|ribbon]',
Improving CRbDoc and CRbApp::ModeChange() to have info on specific mode
item which is changed (to avoid updating every thing).
This allows for better separation betwen app objects. For example,
when the user clicks the 'Minimize Energy' icon on the toolbar,
the command is routed to the CRbCommand object. It then fires the CRbDoc
method SetZeroVelocity(). Then, CRbDoc, after changing its state,
calls the CRbApp method ModeChange() with the specific mode change id (d_iModeChangeZeroVelocity).
Then CRbApp is the one which actually updates the toolbar state.
This is better than having the toolbar be updated in the CRbCommand method.
Added toggling of toolbar draw buttons,
This allows convenient toggling of multiple draw modes for
atom objects (simultaneous display of different modes such as
wireframe, stick, spacefill, and ribbon). This differs from
the Rasmol/Chime convention which only fires a positive draw
command for a certain mode, which also cancels the drawing of
some other mode (such as 'Ribbon' versus 'Spacefill' mode).

Added CHbond, CHbondList classes.
Adding CBase::CreateHbonds(), CreateHydrogens().

Adding 'add duplicates' flag to CVoidPtrArray so covalent bond
lists can have multiple elements of the same ptr.
BUG ALERT!!! any DeleteAll() method of a pointer list class
derived from CVoidPtrArray must remove dups first.
Also changing initial default grow increment in CVoidPtrArray from 100
to 8, and having it double each subsequent time.
Did quick ahelix smoke test, appears to work ok.

Added 'autorotation' command, autorotate limit and exit on arlimit
to support perf testing of graphics.


Added initialization of resource path from module file name
so toolbar can be loaded when rb.exe is run from a different path.
Added error flag to RbApp to return error codes for batch mode

Strange tar problem: it dropped two bitmap files in rb294.tar
rb295.gz (./debug/res/GoIcon.bmp, ./debug/res/StopIcon.bmp) ???.
Fortunately, I also made a duplicate backup with winzip.
Added report of missing bitmap file in wkGLgui::CGlToolbarItem::Create(),
Added wkutils::wkStatusOut,
Removed functions in rb::utils.cpp which were duplicated in
Finally got the program rebuilt and run on ribomachine1.
Ran all 4 perf scripts in rb/perf.


Working on CBase::CreateHydrogens again. Because of contortions
in trying to determine total bonds to an atom with one-way bond
lists, an RxCovalentBondList is being added to CAtom.
Added CAtom::m_pRxCovalentBondList, AddCovalentBondRx(), RemoveCovalentBondRx(), GetRxCovalentBondCount().
Added AssertFail() back to utils.cpp, renamed wklib::AssertFail to wkAssertFail
so app can print failed asserts to app log file.
Added atexit() in startup() to try to catch glut mem leaks,
did not succeed.
Added CAtom::GetCovalentBondCount(), GetCovalentNBondCount(),
Adding CBase::CreateHydrogens(),
Added 'add hydros' command.


Tried to load the 50S '1ffk.pdb' file, too big for ribosome builder :(
Working on 'add hydros'.
Changed setting of selection status line:
was done through setting of an internal selection status object
in CRbSelection::Add(), propagated through rb doc via CRbDoc::ModeChange(d_iModeChangeStatusLine).
Now, status line is set explicity in CRbApp::GetMouseSelection().
Also in CRbCommand::ParseCommandI() for "inv sel" command,
"inv sel" has a bug when selected residues, it just selects the
top-level pdb object.
Need to add special "invert selection" methods for selected
residues or atoms.
One way to do this is identify a current selection by type or types,
select all other objects of the same type through the root object and
deselect these objects.
Made some notes about atom ownership at the top of 'CBase.cpp'
Selection status line is also being set in CRbCommand::SelectResidueObjects().
Added 'atom count' to end of selection status in
Added graphics option iGOCountAtoms, count being done in CAtom::SetOption().
Atom count appears to be correct for these two selection operations.


Added 'hydrogen list' to CBase::AddHydrogens() so caller could have
selected them after creation, but this caused problems when adding them
to the current selection because they were in the top-level selection list
in addition to being selected indirectly through the selection hierarchy.
So instead, they were added to the selection by deselecting and reselecting
the current selection after adding the hydrogens.
The new hydrogen list was kept however, so that they could be selected
separately if desired.
Added helper function CopyAtomDrawState() to CAtom.cpp.
Adding of hydrogens appears to be working except that double-bonded atoms
in base ring () aren't being recognized as double-bonded.
Changed drawing of atom symbols back to bitmap text.
Added OptionsDrawMenu(), moved some options from draw menu to options draw menu.


Unified setting of draw state via menu, toolbar, command-line.
We have consistent toggling of draw states from menu, toolbar, and command-line.


Added bond count to Atom bond defs in CBase.cpp.
In looking through various pdb files, it appears that the naming scheme
is not consistent. For example, for adenine, the hydrogens on N6 are
sometimes named '1H6', '2H6', and sometimes 'H61', 'H61'. Also,
primes (') are sometimes used instead of '*' to identify ribose atoms.
For this reason, and also to try to improve the load time for large
pdb files, the atom_name - id maps in CPdbRecord.cpp should be converted
to actual stl maps, allowing for fast lookup and mapping of multiple names
to a single pdb id.
Added GetItemCount() helper func to CVoidPtrArray.cpp
Drawing of double-bonds in wireframe mode is working!!


Working on CalcFreeAndNbeBondVectors() in CBase.cpp.


Added helper func RemoveDuplicates() to CVoidPtrArray.cpp.


Working on bond angles,
Added CValenceShell class to compute various kinds of empty bond
Added CValenceShell::AddLinearBondVectors()
Added CValenceShell::AddPlanarBondVectors()


Added helper func CreateVectorAtAngle() to CValenceShell.cpp.
Adding CValenceShell::AddTetrahedralBondVectors()


Finished CValenceShell::AddTetrahedralBondVectors().


Fixed bug in saving pdb files (CPdbFile::Write()): a NULL value
for chain id was truncating the pdb atom records.
Fixed bgcolor bug (wasn't being restored after exiting help screen)
Added 'set textcolor' command
Added 'set bgcolor' and 'set textcolor' menu items to Window Menu.
There is a bug in creating bonds for guanine.


Fixed bond creation bug in CBase::CreateInternalCovalentBonds().
Added CAtom::CreateValenceShell(),
Added 'add vshell' command
Tried to fix intermittent window switching bug (happens when
using GetAsyncKeyState() in CRbApp::idle() to catch shift, ctrl
key presses). Using non-portable Win32 HWND to detect if the
app window is active during the idle function.
It appears to work.
Fixed move mode stack bug by replacing it with AddMoveMode() and
RemoveMoveMode() using an STL list.


Added CreateVectorAtAngle() w/ ortho vector parameter.
Tetrahedral bond angles appear to be correct.


Added radius arg to spacefill cmd.
Fixed 'set sel cursor on' bug
Added cmd 'set sel bbox [on|off]'
Added 'wireframe N' and 'spacefill N' commands.
Made wireframe and stick draw states mutually exclusive.
Finally added 'ball and stick' command on toolbar, menu, and cmd line


Adding selection picking modes: identify, bond angle, distance,
atom and hierarchy selection.
Identify and Distance selection are working.


Added CRbApp::SetMouseSelectMode(), CSelection::Push/PopSelectionDisplayState()
to support atom coloring for atom picking modes such as distance and bond angle.
Added autoerase() flag to status line.
Replaced MAX_PATH macro with stdlib _MAX_PATH to eliminate
redefinition warning between "utils.h" and <windows.h>
Moved definition of TimestepParam struct from "utils.h" to "CGraphicsObject.h"


Added selection icons "select all", "select hierarchy", "select add/subtract"


Adding hier level select: atom, residue, chain.
Changed d_iMouseSelectAtom to d_iMouseSelectHierObject for
CRbApp Mouse Select Mode.
Moved GetHLevel from CForceObject to CGraphicsObject.
Note: make hlevel a builtin value for perf improvement in CForceObject calcs?
Adding CRbDoc::pDoc->GetHierarchyObject(),


Chain-Res-Atom hierarchy selection is working.
Add-to-Selection icon is working
Added 3 additional selection status lines to CRbApp::m_rgStatusLine
to support bond angle and distance reporting.
However, the hard-coded array sizes of these status lines is a hack
and should be improved at some point.
Added bond angle calculations to CRbApp::MouseSelectReport().
It is working well.


Changing 'Edit copy' command from doing CSelection::Copy()
using CGoDoc format to CRbDoc format.
Copying and pasting are working again.
Added command 'ins cbond' (insert covalent bond)
Fixed bug in CRbDoc::Save() where atoms which are not children
of residues (such as those which are manually inserted by the user)
are not being written to the pdb file.
BUGALERT!! quadruple-bonds are not being drawn correctly in
Debugging CValenceShell()::Create() (not adding correct number of
bond vectors for '2c.pdb'


Debugging CValenceShell().
Fixed mouse-move mode bug (wasn't saving select-mode when
queueing an accelerated translate or zoom mode)
This was done by adding a bFlushModeQueue flag to CRbApp::SetMouseMoveMode().
Fixed CValenceShell() orbitals.
Added CValenceShell::AddHydrogens().


Removed AddHydrogens from CBase, added to CAtom::SetOption().
CValenceShell::AddHydrogens() almost working!
(min angle detection not quite right in AddTetrahedralBondVectors())


Added min angle fix in CValenceShell::AddTetrahedralBondVectors(),
Added fix to non-coplanar bond search in CValenceShell::AddPlanarBondVectors(),
Added double-bonded nitrogen condition to the decrement empty bond
rule in CValenceShell::AddEmptyBondVectors(),
Add hydros is working!!!


Added creation of bonds in same plane as double-bond partner in
CValenceShell::AddPlanarBondVectors() so that all hydros and
nbes are in the plane of the base rings.
Addition of 'hydros & nbes' looks good for starting hbonding between
helical bases.


After addition of hydrogen atoms, the 'ahelix.pdb' object
is far more unstable now because of steric collisions between
hydrogens at the base-pair interfaces (there are no compensating
hydrogen bond forces yet).
Compensating hydrogen bond forces will be added, but it may be
necessary to add improved force display to the project.
Currently, the CProperty object supports display of total force,
total torque, bounding box, and steric forces on an object.
The forces are displayed as lines with arrowheads showing direction
and length corresponding to magnitude.
For large forces, it can be difficult to assess the magnitude, as it
can extend for extreme lengths. A volumetric display of the force
vector may be better, and also allow for user selection and investigation
of the force vector properties.
Added CGraphicsObject::GetMemberObjects().
Debugging steric force property (not working correctly for atoms)


Adding amino-acid internal covalent bonding.
Added helper function GetAtomNeighbors() to CAtom.cpp.


Added CResidueList::CreateResidues() to create unknown residues
Moved CreateInternalCovalentBonds() from CAminoAcid to CResidue.
Added Win32 Openfile common dlg back (ignoring screen repaint problem for now)
Fixed extents update bug in CSelection for when CGraphicsObject::SetExtents()
returns false (such as with only text or bond objects in extents)
Successfully loaded all amino acid pdb files from ''


Creating CGlSlider class,
Created CRbApp ortho control methods for drawing and mouse
The slider is working.


Added drawing of charge to atoms
Adding aademo to experiemental.cpp


Added amino and carboxyl find functions to aa demo.
Added status line enable hack to CRbApp (so slider ph update
can bypass status autoerase).


Adding sounds to aademo


Demo is working on Inga.


Changed struct TimestepParam to class CTimestepContext
(resulting in numerous code changes).
Recompiled, ahelix.pdb force test works.


Fixed 'inv selection' command by making it work on atom-level
objects only.
Changed 'set color' command to 'color' command, added pre-defined
color keywords.
Fixed bug in CProperty where steric force vectors were not
being intialized properly.
There is also an inconsistency between CGraphicsObject::GetPos()
and CGraphicsObject::GetCenter() being used in similar situations.


Added fix to "wireframe on/off/toggle" command (wasn't turning spacefill off)
Investigated the potential inconsistency between CGraphicsObject::GetPos()
and GetCenter(). At this time, there does not appear to be an
inconsistency because the only object using CGraphicsObject::GetPos()
is a CAtom object, and it's GetCenter() method (which is virtual)
is defined to call GetPos().
However, there is a bug in CProperty in displaying steric force vectors:
The coordinates of the vector are calculated and saved in
CProperty::OnExitCalcStericForce(), which is called in
CForceObject::CalcStericForce() and CalcAtomStericForce(). However,
the position of the atom object at that time is then changed during
CForceObject::Timestep() before it is actually displayed in the Draw()
This may not necessarily be considered a bug however, if we want to
see the location of the applied force (which was the position in the
previous timestep) which caused the atom to move to its new position
We may just need to add a dashed line or something to indicate the
Fixed the direction of the steric force display vector.
Experimenting with a base pair within ahelix.pdb where only
the 2 bases can move and the rest of the helix is locked.
This may provide a stable enough platform to investigate the
h-bonding without resorting to extreme debug force vector support.
Added hydros to the bases while the simulation was running,
worked fine, except for the need to add the force-transfer-
-to-parent property to the newly added hydros as they are
drifting on their own.


Added rasmol-style cpk coloring.
Added hydros are still moving on their own.


Fixed floating hydro bug (CResidue atom list wasn't being
updated with these new hydros and so they weren't being
rotated in the CBase::Rotate() method.
Added iGOResidueRebuildAtomList option to SetOption(),
This brings up again the issue of how to deal with
separate "mirror" lists of some graphics object such as
a residue, where these lists mirror a subset of the objects
in their child list for performance reasons.
In the case of bonds, the RemoveChild() method is overriden
to update some of these mirrored references, but sometimes
the update may want to be deferred for a block of remove
or add operations so that some like BuildAtomListFromChildren()
isn't called multiple times when each hydrogen is added.
Need to add local-axes orientation for selection axes.


Changed CVoidPtrArray initial grow inc from 8 to 1


Changing CRbCommand::DoCommand() and CRbApp::DrawMenu() to feed
all drwa commands through CRbCommand::ParseCommand() and
All draw commands appear to work as expected from menu,
toolbar, and console.


Adding support for 'write script' cmd.


Added DefinedColor submenu


Added writing and reading of camera state to script files.
Added cmd 'set camera matrix m00, m01, ...' cmd
Rewrote the entire CRbCommand::SetProperty() method using
string arg processing (huge method!!).


Changed 'set camera matrix' to 'set_view_matrix',
saving of view in script file is working.
Added 'set sel add' command (add to selection mode)


Added CBase::CreateHbonds(),
Added command 'add hbonds'.
Creation of hbond donors is working.


Added movement and rotation of hbond electron vectors
to CBase::Move(). CBase::Rotate().
Creation of hbond acceptors is working.


Analyzing force-object recursion prior to implementing
Hydrogen bond calcs.
Current stats for 'ahelix.pdb' (1st timestep):
Calcs=389, IntCks=19723, Sterics=5187
Calcs = total # of calls to CForceObject::CalcForces()
IntCks = total intersection checks done
Sterics = total # of calls to CForceObject::DoStericInteractions()
There are
338 total atoms,
32 blocks
16 bases
2 chains
1 pdb object
389 objects
Created CTimestepViewer class.
added 'add tv' command (timestep viewer)
Created CTsvItem class (timestep viewer item)
Timestep View items are being displayed in a hierarchy
in front of the timestep viewer poly, but we are having
some major depth buffer problems


Switched to ortho view for Timestep View, changed near and far
to 0.001 and 1 respectively, now the polygons are properly overlaid.


Added CRbApp::m_pTimestepViewer,
Added CTimestepViewer mouse motions routines,
timestep viewer zoom and translate are working.


Added Projection matrix stack-size checking,
Eliminated OpenGL stack overflow error when doing
picking in ortho mode.
However, selection of tsv items is NOT working.


Added cmd 'write tv'
Fixed command-line processing to report error for unknown args,
Fixed double-entry of shutdown() bug for when glut main loop
is never entered.
Adding CTimestepViewer::WriteFile().


Added helper function DoItemOption() to CTimestepViewer.cpp
Added helper function GetBaseGraphicsObjectType() to CGraphicsObject.cpp
We have initial output of timestep info.


Added output of timestep to ts viewer
Added class CTsStat.
Consolidated CTimestepContext get and set Stat methods into
RecordStat() and GetStat().


We are finally getting timestep output by object type.


We have graphical output of timestep stat methods in CTimestepViewer.


Added enabling of timestep sequence recording.
Added tsviewer status lines
Added CRbApp::SpecialKey() func to handle function key input.
Addded tsviewer record, run, and step controls
The Timestep Viewer is now working in a usefull manner.
There may be a problem with the tree interactions involving
the 3 non-block child atoms of a base (P, O1P, O2P).


Added new version of CForceObject::DoStericInteractions()
which recurses the source object to the base level, then
recurses the target object to the base level.
Also makes some specific assumptions about the object hierarchy
for optimization purposes.
Ran ahelix.pdb and the CForceObject method counts appear to
be lower overall than with the previous version
(tv001.dat, tv002.dat).
In running the perf tests for ff-large.rbs, the perf time
is comparable to previous perf runs with the old DSI() method.


Adding CForceObject::DoHbondInteraction().
Ran run average of ff-large perf script 20 times,
avg time 19 last runs = 16.844 sec.
Optimization: moved Reciprocal object check from
CForceObject::CalcAtomStericForce() to before the
Atom-Atom intersection check in CForceObject::DoMyStericInteractions()
Ran run average of ff-large perf script 20 times,
avg time of 19 last runs = 16.121 sec.
Changed CGraphicsObject::HaveIntersection() to inline version,
another 19 runs give avg of 16.250 sec. (???)
Added CTimestepContext::m_fHbondFactor.


Finished CForceObject::DoHbondInteraction(),
debugging hbonding.
Added CAtom::IsDefaultColorSet(), m_bCpkColorSet.
Added CHbond::UpdatePrimaryTarget() (to display current
active hbond if any).
Moved CalcForces() loop before DoStericInteractions() loop
in CFFVolume::CalcForces().
Added display of active hbonds
Fixed bug in helper function CValenceShell.IsColinear().
Hbonds are making and breaking!
Changed hbond threshold distance to 4.0 A.
Need to adjust the active bond display threshold.


Set display threshold for active bond to average value
of initial crystal structure (~0.2).
Fixed some torque and vector bugs in CForceObject:DoHbondInteraction().
Adding harmonic-decay force function CalcHbondForce().
For now, after fixing the bugs, hbonding is fairly stable
though still far from ideal.
There is a bug in the timestep viewer after closing the current doc.


Changed LogFile() and msgout() functions to feed through
wkStatusOut() so that all messages and ASSERT's are logged
Added #ifdef FREE_ATOM_FORCEFIELD to re-allow single atoms
to work with the new forcefield assumptions about the object
hierarchy in CForceObject.cpp


Adding sound.
Added CTimestepContext::InputSoundData().
Added class CTsSoundData.
Added CTimestepContext::m_pSoundDataMap
Added CTimestepContext::InitTimestep().
We have recognition of atom-atom collision events
in CTimestepContext::InputSoundData().


Created CRbSound class, hooked into framework.
A sound is now playing on atom-atom collision!


Need to extend the intersection boundary for atom-atom
steric force to beyond the default vdw radius.
However, this will impact performance to some degree.
Added helper function HaveStericIntersection(CAtom *pAtom, CAtom *pAtom2)
with hardcoded threshold of 4A for steric intersection.
Ran ahelix.pdb with sound and 100 sound buffers, there is
noticeble delays, but hopefully due to memory thrash from
sound data allocation in CTimestepContext::InputSoundData().
Need to add a force threshold for sound.
Also need to recycle sound data in the CTimestepContext
sound maps instead of deleting every cycle.


Added 'print mem' command.


Experimenting with sound thresholds and 0.01 sec wave files
and setting frequency proportional to steric force in
Added deletion of CTsSoundData in CTimestepContext::InitTimestep().
Getting pops, click, and weird unearthly sounds from


Fixed bug in CResidueList::CreateResidues() (also in CBase.cpp, CAminoAcid.cpp)
caused by skipping empty atom chain id
Adding timing code.
Adding CPerfMon class.


Performance timing is working.


Adding explicit control over sound buffer playing and
stopping in CTimestepContext::InputSoundData().
Fixing pdb record bug again! When reading an pdb atom record
without a residue sequence number, CPdbRecord::GetResidueSequence()
needs to return -1 for a blank value in the pdb record.
Did fix in CPdbRecord::Create().
We have good sound with a single atom-atom collision, but
not when doing 2nt.pdb


Added command 'print sound' to print current sound status
Added CRbSound::GetInfo().
Added stopping of all sounds on doc close.
Added CRbApp::OnDocClose().
Added 'set spacefill on' to atoms with no covalent bonds
in CPdbObject::ReadPdbFile() so atoms with no bonds will
be visible on first load.
Fixed bug in CRbDoc::OpenPdbFile() where the root object's
extents were not being updated after add the CPdbObject
as child.
Fixed offset of pasted objects to each new pasted selection
appears below the previous one.


Added 'Set Selection Color/Extents/Axes' icons to toolbar
the buttons are working.
Added 'Selection Axes Define Off/X/Y/Z' icons to toolbar.
Added 'Identify/Distance/Angle' icons to toolbar.
Removed CRbCommand::ToggleToolbarItems(), replaced it with
CRbApp::DisplayToolbarItem() (much cleaner logic).
Toolbar menu now switches between Identify/Distance/Angle
sequence and Chain/Residue/Atom sequence.


Adding CRbApp::MouseSelectDefineAxes().


Added CSelection::SetAxisDir().
Found bug relating to assumption that cross product
resultant vector is normalized (BUG ALERT!! check
all code using cross product!)
Normalized the vector with no apparent affect (glRotated
may be normalizing it regardless).
However, there appears to be a surprising amount of error
when adding a rotation to a rotation matrix in
CSelection::SetAxisDir() via glRotated() when defining
a new selection axis direction.
Is this error also present in other areas, such as for
molecular force calculations?


Added command 'rot org <ox,oy,oz,d,x,y,z>' (rotate selection
about origin).
Need to have high-precision atom coordinate file to debug
rotation errors.
Created class CHiResPdbFile, derived from CPdbFile.
Changed iMaxPdbRecordLen with max length of 1024 to
d_iMaxPdbRecordLen with length of 256.
Removed internal copy of pdb record text in CPdbRecord
to reduce memory usage.
Added CPdbRecord::CreateFromHiResRecord().


Added CRbCommand::ParseSoundCommand().
Added CRbSound::EnableSound().
added command 'sound [on|off]'
added -pdh option to save command (save to hi-res pdb format)
Added CHiResPdbFile::Read().


Added CHiResPdbfile::Write(). Output to 16 decimal-place
precision is working for pdh files.


Created rbmain.lib, moved various object modules there to
allow other apps to link to rb objects and libs.
Removed CRbDoc *pDoc member from SelectionParam struct
to remove CRbDoc dependency in CSelection (only used for
access to currently obselete pDoc->IsOutlineOnSelectionEnabled()
in CBase::Select()).
Added CInterpreterScript class.
Changing portions of CRbScript to CInterpreterScript to remove CRbApp
dependency from CAvScript.


While implementing matrix rotation code in the investigative
project 'GlRotate' app, it is realized that the probable
source of error due to rotations is the fact that the
center of an object such as a base is currently being
calculated as the average of its extents instead of doing
a center-of-mass calculation!
Added CResidue::CalcCenterOfMass().
Added CSelection::GetCenter(), CalcCenter(), which calculates
center using center of mass for all selected atoms.
The centerpoint is being recalculated inside of UpdateAxes(),
so maintenance of a correct center point assumes that
UpdateAxes() is always called whenever the selection changes.
Added selection center info to 'sho prop' command.
Selection centering now appears to be correct. A selection
of 2 bases in 2nt.pdb can now be rotated about an angle
without the centerpoint changing.


Added CForceObject::m_vCenterOfMass.
Added CBlock::CalcCenterOfMass().
Added CForceObject::GetCenter() which overrides
CGraphicsObject::GetCenter() to return the force object's
center of mass as object center.
Moved CSelection center of mass calculations to CRbSelection.
Added calculation of center of mass using both atoms
and force objects in selection.


Completed exhaustive listing of all places where UpdateExents()
is called (summarized at top of CForceObject.cpp).
Added CForceObject::UpdateExtents(), changed all references
in CBlock.cpp from CGraphicsObject::UpdateExtents() to
Created debug output in the UpdateExtents() method for the 5 classes
which define it.
Added 'CGraphicsObject *pParent' param to many constructors
in the CGo hierarchy to facilitate initialization tracking.


Coordinating UpdateExtents() output with analysis tool 'UeTree'.
Analysis with UeTree reveals potential bug arising from duplicate
graphics id when ResetGraphicsIdCounter() is called in CRbApp::OnDocClose()
because there are ruler and child graphics objects still in existence
with graphics ids, so that resetting graphics counter to one will
will result in new objects having the same id.
However, this may not be a true problem as the rulers and their child
objects are not part of the graphics object hierarchy. Also, they
should actually be destroyed when the doc is closed.


Removed 'ResetGraphicsIdCounter()' call.


Spent some time documenting CForceObject::DoStericInteractions()
in conjunction with this month's status report.
Changed CGraphicsObject::dbout() to Print(), using std::ostream.
Added command "print objectTrees".
Made CGraphicsObject::Print() virtual to allow override and reporting
of child objects not in child list (such as CBlock's m_rgPoly list)
Object tree output to files 'MainGoTree.out' and 'SupportGoTree.out'
are working.


Added global function IsLogging(), UpdateExtents() logging option.
Fixed CForceObject::CalcCenterOfMass() (wasn't setting mass or cm)
Made CForceObject::GetMyCenterOfMass() virtual, added CAtom override
for it which just return atom position.
Forcefield simulation for 2nt.pdb and ahelix.pdb are now appearing
back to normal.


Added rotation about existing defined axis 0 for second axis
definition in CSelection::CalcRotationMatrix().
User definition of two selection axes is now working.


Added CRbApp::SetSelectionDisplayState() to keep toolbar icons
in sync with actual selection display state. It is working.
Changed CRbDoc::MoveSelection() to call new CSelection movement functions
Added CSelection::TranslateSelection(), RotateSelection.
Translation and Rotation along user-defined axes are working.


Fixed CHBond drawing so it is only drawn if its parent atom is
Added initialization checks to CRbSound, made sound disabled
by default.
Added enabling to CPerfMon object, made it disabled by default
in CRbApp.
Ran perf scripts, timings roughly comparable to prior runs.
Note: we are getting an error loading the wav file, it needs
to be loaded from the \res subdirectory.
Also getting miscellaneous errors loading various pdb files,
(mostly unknown atom names and bond defs), this should
be fixed to remove all errors from the perf scripts.


Fixed sound loading from res directory, added sound icon
to the toolbar.
Added CTimestepContext::IsRecordingEnabled() around CTimestepContext
recording methods to reduce function call overhead in
forcefield functions in CForceObject.
Replaced CTsSoundData with CTsForceData in forcefield data recording.
In the process of combing sound and property force data recording
via CTsForceData objects (sound and property not currently working).


Added CTimestepContext::AddForceData(), CProperty::AddForceData(),
Added CTimestepContext::IsRecordingForceData(), CProperty::IsRecordingForceData().


Added "record fdata" command, CRbCommand::ParseRecordCommand()
for enabling/disabling of force data recording.
Replaced CTsSoundData with CTsForceData in CTimestep::InputSoundData(),
added m_iUserId1 to CTsForceData to hold sound buffer id.
Sound is working again.


Changed "record fdata" command to "ff record" command,
Changed CRbCommand::ParseRecordCommand() to ParseForceFieldCommand().
After beginning to add force data info to the CProperty class,
there is a problem due to the fact that for any two interacting objects,
only the object with the lower gid will actually calculate the force data.
However, the force data dispatch has been modified to check for a
request from the target object's property as well as the global timestep
recording and the source object's property.
Replaced CProperty flags with an stl set<> of enumerated types.
Currently, there is a problem in determining when to clear the
recorded force data in a CProperty object. Previously, it was
done in CForceObject::CalcForces() with a call to
CProperty::OnEnterCalcForces(). But for CSpringBond force calculation
this will not work because an object can receive force from a spring
bond calc before entering its own CalcForces().
It may be possible to dispense with the detection of the start of
the timestep in the CProperty object via OnEnterCalcForces().
All incremental forces added to an object and monitored by its
CProperty must be input via CProperty::AddForceData(). This always
happens before the object's Timestep() method. At the start of each
object Timestep(), the current list of force data can be transferred
to a previous list, and force data for the next timestep will go
into the current list.


Created CForceDisplay class (inheriting from CGraphicsObject).
There is still a problem with the CProperty object receiving
end-of-force-calc notification via an object's timestep
because CAtom objects are not timestepped at all (being locked
to their parent base).
Adding global 'Begin timestep message' (Note: timestepping
in this application actually refers to the movement phase
of a timestep which follows the force-calculation phase).
Added CFFVolume::SetOption() to notify object in force child list.
CForceDisplay vectors are working.


Need to distinguish between residue selection and atom selection
for multiple selection.
One nice UI way to do this is to select an object on first click,
then on a subsequent click, select its child objects instead,
and on a another click, their children, etc.
Added mouse hierarchical selection down (single object),
Added hsd single and hsd all toolbar icons, menu items.


Adding "hsd all" selection to CRbApp::GetMouseSelection().
Adding new token parsing to CRbCommand::SelectObject().
Added [on|off] to 'sel id <num>' command.
Improved 'sel children' command to select all children
of current top-level selected objects or, if no children
to retain the top level object. This allows quick
selection down the object hierarchy with a few mouse clicks.
This is useful when it is desired to select all the atoms
of an object such as a base or ribose block, prior to
add force display.


Added CRbSelection::GetSelectionStatus() to show selection
status of top-level objects.
'sel children' command is working.
Created Forcefield menu.
Steric and spring bond display are working.
Fixed keyboard movement of selection (x and y dirs were switched).


Adding 'two-stage' sub-step command (calc forces, movement)
Added CRbCommand::ParseRunCommand().
Sub-step command is working.
Need to change property force display to update after
end of CalcForces() instead of beginning of Timestep()
so that new forces can be displayed before movement when


Changed notification from iGONotifyBeginTimestepMovement to
Added toolbar icons for steric, spring, hbond and total force display,
Added toolbar icons for enable/disable trans, rotation.
Removed Force and Torque clearing in CForceObject::Timestep(),
moved it to beginning of CFFVolume::CalcForces() via a global
Removed check of 'IsTimestepEnabled()' at start of CForceObject::CalcForces()
(disabling object movement was prevent force calculation).
Ran test of 2nt.pdb, steric, spring bond, trans and rot icons
are working.
Ran test on ahelix.pdb, added display of steric and spring forces
for all atoms (after creating hydros and hbonds). It ran, but was slow.


Fixed CRbSelection::Copy to use CRbDoc so clipboard has pdb file
instead of GoDoc.
Replaced CSelection::SetShowProperty() with SetOption() equivalents
so that children have their show property set if selected (instead
of having to be selected directly).
Disabled 'Select Hier Down All' toolbar item (no longer needed
for force display).
Did demo for Steve Lodmell at the U of M.


Fixed extents bug for Base blocks in CBase::CreateBaseBlocksFromAtoms().
Debugging forces for 'ahelix.pdb': there is a large steric
force between the phosphorus and 3' oxy along the backbone.
This is due to the default vdw radius of a phosphorus atom,
(4.70A, oxy radius = 3.37A). The initial distance in the pdb
structure is 1.6A.
Fixed toolbar states on opening new doc (added CRbApp::OnInitDoc()).


Added 'off' arg to 'sel children' command.
Fixed discrepancy in CBlock:GetMaxExtents():
A parent base had small extents than its child blocks when
displaying its bounding box because the base didn't have block
polys and was consequently returning regular extents, while
the child blocks were returning MaxExtents (based on length of
block diagonal).
Performance Alert!!! The bounding box size for force object intersection
testing is now quite large for base block and base objects.
(this may be good for the thresholding problem, but bad for
Added display of total force to CProperty.
Modified CForceDisplay to display 'summation items' such
as TotalForce and TotalTorque to show at center of mass
while other items show at initial origin of force (src object).
TotalForce display appears to be working correctly now.


Fixed negative len in ForceDisplay vector.
Fixing vanderwaals radii - they've been wrong for a while!!
Using values from PCModel obtained from 'Molecular Modeling on the PC'
Schlect, 1998.
Found bag bug in CSpringBond::CalcForce(): wasn't using the
normalize vector between object 1 and 2!!!
Experimenting with large spring bond forces, small timesteps
(ks=100,000, timestep=0.001) to maintain
proper covalent bonding along the backbone, with limited


Added display of hbond forces. They are working.
Added cmd 'set hbond' for hbond force factor.
Fixing hbond force directional factor.
Added CRbApp::DoForceDisplayObjectSelection() to
get detailed info from force display arrows.
Added CProperty::FindObjectFromId().
Fixed bug in CForceObject::DoHBondInteraction()
(cached atom1 pos for src hbond was hidden by local var)
Hbond directionality is looking good now.
Ran 4nt.pdb again with sterics, spring and hbonds.
Force displays all appear to be working. Now,
the major problem is the bogus hydroxyls on the phosphate


Fixed oxygens on backbone (made O1P double-bonded to the P,
added -1 charge to O2P).
Now, need to add eq distance to hbonding,
fix dotted display of primary hbond target so it only
shows for force above a certain threshold.


Added Elst-Harmonic Hbond function CalcHbondForce(),
it appears to work.


Made SpringBond function harmonic (it wasn't before! Just linear!)
Ran 2nt.pdb with spring constant of 10,000 with 3 additional
spring bonds along the backbone, appeared to work well
(timestep len = 0.001)
Added inactive display threshold for hbonds (0.2), changed
active force display threshold to 10.
Added priority to CRbSound::GetFreeSoundBuffer() so that
the top 100 forces will always be able to play.
Fixed 'sound print' command.
Added min/max freq to sound print info.
Sounds are still weird.
Fixed bug in 'set atm lfr', 'set atm rfr' commands.


Sound priority isn't going to work because of yanking
id while some prev sound data object still assumes that
it has it.
Also tried adding spring and hbond data to sound generation,
but this will require adding force id to sound data map
and there isn't time to do that.
Restored sound back to prior working condition with
steric input only.
Ran 4nt.pdb in a box, worked ok.


Changed GetResourcePath() refs to use 'makePath()' function
(part of wkutils.lib), added GetModulePath() to give
path for help file.
Wrote '' perl script to output html version
of this project history.


Working on display of bond-angles, springs to maintain
bond angles.
Moved res directory from 'debug' to base dir.
Changed default field-of-view from 90 to 60 in CRbWindow.
It seems to help (view of adjacent atoms is more comfortable
close up)
So, the bond-angles and springs to maintain them which need
to be added are:
1. Between O3* and O1P, O2P, and O5* of the base on the 3' end
2. Between P and C3* of the base on the 5' end
Added method CBase::CreateBondAngleSprings()
Added command: 'add bas'
Creation of bond-angle springs is working.


Adding names and other pdb data to created hydros so that
they can be properly reloaded after saving to pdb file.
(in CValenceShell::AddHydrogens()).
Added helper func GetAncestorResidue() in CPdbFile.cpp
Added some additional pdb atom name ids in CPdbRecord.h
Saving and reloading of added hydros is now working
for ahelix.pdb
PERFORMANCE ALERT!! Doing a 'ff sho <forceProperty>'
on a selected Base results in CPropertyObject creation
for all child objects. Note: for steric forces, this
is necessary, but for things such as hbonds, CProperty
objects are only needed for selected atoms. However,
considering that display properties are a kind of debug
feature, this may be acceptable.


Added cmd 'set hbond dist'
PERFORMANCE ALERT!! Previously, static data was precalculated
for the hbond force by assuming a constant distance.
Now that we let the user specify it, we suffer a performance
hit until we get the forces nailed down.
In debugging hbonding stability, part of the problem appears
to be that when there is an equilibrium bond between
a donor and acceptor along the face of a base-pairing edge,
there are also strong attractions from adjacent donors and
acceptors which destabilize the bond. (See pic 'AdjHb.jpg)
A possible fix is to remove 'hbonding' availability for
a bond that is currently near equilibrium-bonding already.
How much this departs from physical reality is not known
by me. One rationalization is that the electron clouds
are oriented and captured by an existing hbond donor hydrogen
and thus shielded somewhat from forming other bonds?
Since one of the immediate goals of this program is to get
it to form stable hbonds, by almost any means possible at
this point, the 'hbond-shielding' idea should be tried.
Redefined hbond force-function using quadratic and linear components
Created helper class CHbondForce to calculate the hbonding
potential for a given distance in order to implement the
CHOP scheme.
Initial testing with helper class:
Fractional Potential scaling of the force is completely
crowbarring the competitor hbonds even without CHOP allocation!
Also, the desired hbonds which remain still don't give
good lock, partially because of their reduction by frac-potential,
but also it seems that orientation is not being helped as
much as it could be if force were applied between the hydrogen
and acceptor atom (or better yet, the nbe of acceptor electron)
instead of just between donor and acceptor atoms
(see hbond-no-orient.jpg)


Added display of total torque.
Changed toolbar selection to combine
(identify-distance-angle) with (select-chain-residue-atom-down).
Further analysis of the hbonding problem reveals that it
isn't just a matter of applying force between hydro and
nbe, the problem is that at equilibrium distance, but
non-equilibrium orientation, zero force is being
generated. This allows steric forces to prevent restoration
of the hbond (see hbond-not-enough-torque.jpg).
Need to modify CalcHbondForce() to generate force when
at eq distance but not at eq orientation.


Another idea: apply force between donor and acceptor atoms
AS WELL AS between hydrogen and nbe pair.
Yet another idea (if previous one still doesn't give enough
Hbonding stability): modify the vdw force so that two
hbonded atoms squish their vdw radii in at hbond center
and bulge out in a region surrounding it (to give a
flatter contact surface). However, this may be difficult
to implement efficiently.
Added CalcForce() to CHBondForce. It is now being used
in place of the old function in CForceObject. Ran
hbonding sims on a single bp and on ahelix.pdb, still not
Performance note: when displaying force arrows for ahelix.pdb,
all types except Steric can be displayed with good performance.
However, for steric, presumably because of the large number
of atoms, the performance drops considerably. It would be nice
to add a threshold for displaying force arrows, or better yet,
have a separate tool for selecting all forces above a certain
threshold from the entire monitored set and then have that
tool do the steric force display request.
(in other words, don't build thresholding into CForceDisplay
or CProperty).
Another idea on the stability: reduce hydrogen vdw wrt hbond
Added multi-center capability to CHBondForce.


Added detailed description to CForceObject::DoHbondInteraction()
prior to adding second center to hbond calculation.
Changed CHBond primary target value to fractional potential from
magnitude of force.
Display of active hbonds based upon potential instead of force
is very nice!


Added pot and force calcs for hydro and nbe pairs in
Added vOrigin vector to CTsForceData, to allow display
of forces applied other than at atom centers.
Fixed origin, force bugs for Hydro and Electron interaction
in CForceObject::DoHbondInteraction(),
Hbonds for 2ntbp-hb.pdb are stable!!! yahoo!!


Before beginning work on WriteFFParam() and ReadFFParam(),
here are some thoughts for implementation of sub-base object
rotation (such as base rings and even individual hydroxyls):
Currently, torque is calculated in various places using the
following strategy: within the function where the force
has been calculated between 2 interaction objects, the
torque is subsequently calculated using the force vector,
vForce, and the moment arm, vr. The moment arm is simply
the vector from the force contact point to the center of mass.
This additional moment are calculation was the original
reason why the the torque calculation code remained within
the function. However, it is now realized that it should be
very straightforward to hand-off Torque calculation up the
force object hierarchy to the actual Force-parent recipient,
in the same way as is currently done for force and torque
application, via Add/SubtractForceVector(),
This could be done through a new method, GenTorque():
pObject->GenTorque( vForce, vOrigin);
This call can recurse up the force object hierarchy until
reaching an object whose m_bTransferForceToParent flag
is false. Then, inside of this function the moment arm
and resulting torque can be calculated and applied.
In addition to localizing the error-prone torque calculation
code, there is the advantage that torques on multiple
objects in the hierarchy can now be done. For example,
we can modify the 'transfer-force-to-parent' flag for
a force object where it will still hand off forces to
the parent, but apply torque to itself as well.
Let us consider a base block, such as the pyrimidine ring
of Cytosine. This block should be free to rotate around the
axis defined by the C1* - N1 bond. When applying a force
on this object, we can compute the torque applied at the
center of mass if the block, and then project the component
of this torque onto the C1* - N1 axis. Then, the block
could recursively call the parent CBase object to apply
torque around its own center of mass.
To assess the changes required, a list of current torque
calculation follows:
1 CForceObject::CalcForces() (friction)
4 CForceObject::DoHbondInteraction()
2 CForceObject::CalcStericForce()
2 CForceObject::CalcAtomStericForce()
2 CSpringBond::CalcForce()
Before implement this new method, it is time to have the
capability to output not only positions, but velocities,
forces and torques each time step to serve as a reference
run that can be used to validate the force-field engine
and identify the introduction of new bugs.
Bug fix: script: cleared command history when doing
'new' command (to allow for proper script creation).
Found CTimestepViewer bug: double delete of it was done
because it was part of the CRbDoc object hierarchy and
was also being deleted by CRbApp separately because of
its own CRbApp::m_pTimestepViewer reference!!
adding command 'tv draw [on|off]'
Added CRbCommand::ParseTvCommand().
MSVC is having some serious crash problems. It looks
like the Linux Exodus may restart (been reading lots of ESR)
'tv [on|off]' command appears to be working.
'tv write' command is working.


CTimestepViewer has too much graphics overhead. We just need
a textual output of timestep data.
Creating CTimestepReporter.
Added some documentation to CTimestepViewer.
Adding documentation to CTimestepContext in order to
best determine data recording and reporting via CTimestepReporter.


Added 'tr record [on|off] command'.
Adding CForceObject::PrintForceData() (in lieu of a derived
Print() method because of gcc merge-method limitations)
Changing some file-scope enums such as GoFieldType to class
member enum per reccommendations in Lakos '96.
Timestep Reporter is working.


Tried to open pdb file 1zif.pdb, nothing happened, no error
or anything. Just got 'Error: no current model' when
trying to select something.
Added some error messages to CPdbFile::Read(), CRbDoc::Open().
Fixed the bug (different count between atoms in file and atoms
Changed CountTotalAtomsInFile() to CountTotalAtomsInModel().
in CPdbFile.
1zif.pdb loads fine now.
Played around with it, trying to hb. Not happening.
Added centerPos, mass, myCenterOfMass, centerOfMass to
timestep recorder output.


Added data export helper clsses CGoDataExport, CFoDataExport.
(to help project tool tsda)

Working on adding multiple types to data export in


Changed data export name from CForceObject::PrintForceData()
to ExportData().
Added CAtom::ExportData().
Added VdwRepulsiveExp and VdwAttractExp to CTimestepContext ff params.
Added CSpringBond::ExportData().
Export of timestep data is working and can be parsed by
tsda tool.


Working on huge steric collision between O3* and P of adjacent
bases. For example, between C4.O3* and G5.P in 4nt.pdb,
they are 1.59 angstroms apart, and the steric force between
them is 148.6
The predefined vdw radii are: 1.74 for O, 2.05 for P
Then, their eqDist is 3.79
The scaled distance is then 1.59 / 3.79 = 0.4195
The repulsive force is 1 / (0.4195)^6 = 183.422
The attractive force is 1/ (0.4195)^4 = 32.283
this should give a net force of roughly 151.139
(it is closer to 148.6 when done in Calculator with more
We should be able to define a specific vdw interaction
parameter between these two atoms so as to reduce this
large steric force. This will help to produce more
stably-bonded conformations.
One possibility is to add an additional data element
to CAtom for user-defined vdw interactions with specified
targets. Another might be to do do the lookup in
in CForceObject::CalcAtomStericForce().
Added hack to CForceObject::CalcAtomStericForce().
Added CTimestepContext::m_dO3PEqDist.
We have a stable a-form-helix!!!


Added some fixes to CValenceShell for Phosphorus atoms
Then decided to bypass adding hydros to Phosphorus
entirely in CAtom::SetOption().
Fixed bug in CBase::CreateInternalCovalentBonds() where
excess bonds were being added because max bond count
wasn't being check during addition of double bond def.
Adding 'target base' command
Prior to working on a class to generate CAvicon scripts
for base targeting, we note that there is a significant
problem with scripting as currently implemented. The
problem is that objects are referenced by GraphicsId()
instead of name. GraphicsId's are currently used because
they are guaranteed to be unique and provide for fast
lookup in the object tree. However, objects saved and
reloaded from disk will get a different graphics id
and so their reference in a script will break.
A solution would be to reference objects by name only,
and prompt the user when duplicate names occur.
Since names as currently implemented are widely duplicated
(many objects have a short simple name such as C2, G5, etc)
we could provide an interim solution which could hopefully
be implemented quickly where we create an internal name
which is unique. This internal name could be generated
from the short name and the initial graphics id, and
in addition, a timestamp.
Started to implement the internal name idea and then scrapped
it. Would not solve the scripting problem.
A much simpler option is to just generate a command to
select by name in command parsing and have the actual
selection by id be done indirectly.
For example, currently, when an object is selected by
mouse, it generates a text command such as 'sel id 294',
which selects the object by graphics id. Instead,
if we generate a text command such as 'sel u.A.U12'
This selects residue U12 in chain A of pdb object 'u.pdb'
Added CGraphicsObject::GetFullName().
Deprecated CGraphicsObject::FindObjectFromName(), FindChildObjectsFromName(),
Replaced with CGraphicsObject::GetObjectsFromName().
(used in CRbCommand::SelectObject()).
Recursive method GetObjectsFromName() is working.
Changed CPdbObject, CChain, BaseBlock default names
so that they no longer use the graphics object id in them.
Insertion and reference of pdb file objects in scripts
is now working!!


Creating CBaseNav to handle base-targeting through CAvicon
Added helper functions GetOnOffToggleOption() and AssignArgs()
to CRbCommand to reduce some redundant code.
Documented current CAvicon support and created
specifications for base-pair targeting in in CBaseNav.cpp
After considering CAvicon infrastructure, for now we will
try a more specific (and hopefully faster) approach:
deriving CBasePairCon from CAvicon.
Caught some destructors which were still not virtual:
Adding method CBasePairCon::TargetBase().


Added CBasePairCon::Timestep().
Added module function GetLookVector() to CBasePairCon.cpp
Added warning message to 'rot std' command if no selected base
Added CSelection::SelectionChanged() method to tell CSelection
to update its selection indicators when the selection contents
have been changed in some manner outside of CSelection
(which happens in the 'rot std' command).
Actually, the true cause was a missing UpdateExtents() in
CBase::SetOption( iGORotateToStdOrientation ).
Created script to load 4 single bases and put them in std
orientation (4bref.rbs)
Made them bounce around in a 25cuA volume for a while.
Sound still works. Need to add rotation of base rings soon.


Adding rotation to CBasePairCon::Timestep().
Fixed some bugs in hierarchy select, toolbar icon init.
Selecting objects pasted from the clipboard is broken because
of the dot char in '~clipboard.tmp.pdb' filename. This
conflicts with the dot naming scheme for child objects.
Rather than rename the clipboard file, we need to deal with
it as users will have dots in their own pdb files.
Added code in CPdbObject::ReadPdbFile() to replace '.' with
Fixed bug in CBase::SetOption( iGORotateToStdOrientation )
where hbonds were not being rotated.


Adding CForceDisplay capability for forces generated in
Added command 'ff show bpConTorque'
Display of Base-Pair Controller torque is working.
Orientation of source base to bonding orientation with
target base is working.


*rb426.gz Adding force to CBasePairCon::Timestep().
Added bp con force to CTsForceData, display.
Getting major intermittent crashes, built with /W4
flag set, analyzing warnings with perl script,
file 'nmake-out-build426-001.txt'
Fixed bug in bp con torque display vector
Added summary of code changes needed for addition of new
force type (added in CTsData.cpp)
There is a bug for CBase when calling GetPos(). The
CGraphicsObject::GetPos() method is called and just returns
m_v which is (0, 0, 0).
Adding CForceObject::GetPos() method which returns
Force targeting is partially working in CBasePairCon::Timestep(),
the move vector is correct, but it is slamming into the other
base (need deceleration).


Changed base block definitions of G and C so their ring normals
align with A and U (they were opposite)
Possible bug fixed in CSelection::SetAxisDir() (deletion of
pointer which was still being used). The code in this method
is very messy and needs to be fixed.
Found a configuration where 2 bases remain stuck at a tilted
angle when hbonding (TiltHbond.pdb).
While analyzing what was happening, I deleted the other 2 bases
initially loaded from the 4bref.rbs script and found a
problem where the parent chain and pdb object of the deleted
base no longer contain any force objects and an assertion
failure occurs when updating extents in CForceObject::Timestep.
A fix should be done where the expected behaviour upon deleting
the sole base object is to auto-delete its chain and pdb object
parents as well.
Added UpgradeDeletionIfEmptyAncestors() call to CRbCommand::DeleteSelection()
Added CGraphicsObject::GetChildCount()
Added creation of new chain for non-consecutive residue num in
We can now delete the 2 non-hbonding bases from TiltHbond.pdb
while the forcefield is running and not get any ASSERTS.
Still getting crash in CSelection.cpp at CAxisDef::GetDefinedVector()
because of bogus atom pointer. Added destructor to CAxisDef (was
default destructor deleting pointers in member vector?)
Also noticed that in CSelection::SetAxisDir(), the vector
vector<CAtom*> vpAxisDefinitionAtomList is being passed by value.
Is it doing anything besides constructing a new parameter vector
containing the CAtom* pointers?
Maybe we should pass by reference?
Found possible bug in hbonding: hydro-electron interaction is
repulsing on long hbond (should be attracting)
Found the problem! the G residue that was being tested had
pre-generated hydrogens at a distance of 1.0 A from the
donor atom! The eq dist for this doesn't work!
Need to add a distance check for pre-gen hydros.


Have selection bug selecting residue C4 in ahelix.pdb -
all C4 atoms are being selected as well.
There is a problem in display of total torque on a base:
With BpCon forces applied, a net torque is displayed but
the base does not rotate. Outputting of the total torque
using the TimestepReporter shows that the total torque
is zero.
Analyzing timestep sequence for record and display events.
Removed CProperty::m_pPrevForceDataList (no longer used).
The problem is the following: currently, all object
forces get transferred to force display objects at the
end of CFFVolume::CalcForces(). But BpCon force data
isn't created until the CFFVolume::Timestep() phase because
the CBasePairCon input occurs during the timestep phase.
Presumably, we should move the CAvicon/CBasePairCon call
from CForceObject::Timestep() to CForceObject::CalcForces().
Or add an additional avicon method that is called in
CalcForces() and only does force input. Avicon-generated
movement (via velocity input) could still be done in
the Timestep() phase.
Added CAvicon::CalcForces(), move CBasePairCon forces to
CProperty::m_pPrevForceDataList was being used to hold
the pointers to the allocated CTsForceData objects.
For dubious reasons of efficiency and desire to avoid
memory-thrashing, CForceDisplay objects just received
pointers to these objects. However, this can lead to
potential bugs and crashes if these objects are deleted
when the CForceDisplay objects still have references to
them. The synchronization was done by CProperty, but
this is a dangerous practice. Consequently, CForceDisplay
has been changed to create its own interna CTsForceData
object from the parameter object on construction.
Force display is working again. However, for things to
properly add up, force and torque vectors should also be
displayed for atmospheric friction.
Adding data output to CTimestepContext::AddForceData().
Added CTsForceData::ExportData()
Output of CTsForceData to Timestep Reporter file is working.


Added output to Timestep Reporter file from CProperty objects.
Needed to add doctype to CGoDoc because of need to access
CRbDoc from CGraphicsObject m_pDoc pointer, in
CProperty::OnEndAllCalcForces() (don't want to enable rtti
at this time).
Transferring CRbApp::Keyboard() move key handling to
CRbCommand so the actions can be saved for scripting.
"move dir <dir>" command is working.
Output of CTsForceData from CProperty is working.
Added command "move mode [rot | trans]"
Added command "move rate <N>"


Added parent id to force object data export.


Added frictional force and torque reporting
Added command sub-option 'ff show frictionForce'
Friction force output is working.


Added friction torque output.
tsda analysis shows a large discrepancy between
recorded torque at end of timestep and sum of all
reported torques.
Created a debug routine to record data in
After comparing the output from that debug routine with
the tsda output, the discrepancy is due to the different
times at which the total force and the tsda force data
are recorded.
The total force and torque for a CForceObject are output
to the tsData file at the beginning of the timestep
via the call CForceObject::SetOption(iGONotifyBeginCalcForces).
The individual forces are saved in the CProperty object
as they are generated and are then output at the end of
the timestep via CForceObject::SetOption(iGONotifyEndOfCalcForces)
and m_pProperty->OnEndAllCalcForces().
Finally, the 'totalForce' and 'totalTorque' CTsForceData
objects were not being saved along with the other CTsForceData
to the tsData file. These are the ones that need to be
used when comparing accumulated forces to the total. They
should also be equal to the the force and torque values
of a CForceObject in a tsData file for the next timestep.
Cleaned-up CProperty::OnEndAllCalcForces() to save total force
and torque in force-data list.
Analysis of torque from script 'dbAllForces.rbs' now
gives matching calculated and recorded total forces
and torques for base G8
( tsData saved as 'tsData-000-dbAllForces-001.txt' )


Added CBase::DrawRingPlate(), command 'draw base plate'.
Rendering of base ring plates are working.


Found bug where CSelection(), in moving selected objects,
is using CGraphicsObject::Move() and
CGraphicsObject::MoveChildren(), and as a result, the
extents of the selected objects parent is not being
properly updated.
For most objects, when the MoveChildren() method is done,
the parent of these children is the object doing the move,
and so it can update its own extent. But CSelection has
been acting as a 'pseudo-parent' for the selected objects
that it holds, causing the problem mentioned above.
This should probably be fixed by moving the selected objects
from the child list of a CSelection object to an
an explicit 'selected-object' list. However, we must consider
what may break in the course of doing this.
Made CGraphicsObject::m_pChildList private
BUG ALERT!!! Big change: replaced CSelection child list
with m_pSelectedList for selected objects.
(why wasn't this done a long time ago?!)
Added CSelection::UpdateExtents()
Actually, this whole selection-move-update bug was the
result of a fortuitous mistake where the reference from
CRbDoc->GetSelection() had been declared as a
CGraphicsObject and so the CSelection override of
CGraphicsObject::Move() was not being called (this was
happening in CRbCommand::ParseMoveCommand() and other
places in CRbCommand.cpp ).
Catching this bug would have been all that would have been
needed to fix the extents bug, but in making this more
comprehensive change of removed selected objects from the
CSelection child list and creating a dedicated Selected list
is a much better way to go in the long run as ownership of
child objects should be kept clearly distinct from the
collection of selected objects.
The extents bug found in 4bref.rbs has been fixed.
Selection appears to be working properly. Ran ahelix.rbs
and ran the forcefield, hbonding is working and the
helix is stable. Whatever bugs may remain due to CSelection
change should not affect the forcefield, but should be
mostly ui-related.


Added CSelection::SetColor().
Shortened length of base rung so it works better with
drawing of base plate.
Added check for max bonding distance in CBase::CreateInternalCovalentBonds()
( residue PSU55 in trna.pdb had impossible bond between C1* and N1 )
The distance check is working.
Ran dbAllForces.rbs again to investigate action of bpConTorque
on the terminal base of a 8 base chain and the ability of
the torque to reorient the base into base-pairing orientation
while it remains attached to the rest of the chain. It
appears that the bpConTorque is able to orient the base,
although it happens very slowly.


Added m_dBpConForceFactor, m_dBpConTorqueFactor to
Added commands 'set bpConForce', 'set bpConTorque'
Increasing force and torque helps in situations where
progess towards a partner gets impeded.
Modified CGraphicsObject::GetObjectsFromName() to only
do recursive search on composite name so child objects
can now only be selected by full name (was getting
multiple object selection before, even with full-name spec
when doing full recursive search on simple name).
Targeted and docked a few disparate bases in separated
strands of ahelix. Still a rather dodgy process, though
when the bases get in proximity, and a little 'wobbling'
is done, they do tend to snap into hbonded configuration
rather nicely. This wobbling may need to be added to the
bpcon repetoire.


Replaced 'Base block' icon with 'Base plate' icon on toolbar.
(this toolbar change requires multiple messy changes all over
the place - toolbar integration needs to be cleaned up )
Changed other toolbar icon toggle indicators to the method
first used by the force display icons - the background
color is used to indicate the current state and the arrow
indicates the new state if clicked. This is a nice
way to communicate that kind of toggling functionality.
Added drawing of hbonds when base ring plate is drawn,
regardless of atom draw state.
Fixed selection toggling (broke after adding new selection by
Loaded trna.pdb, added hydros and hbonds. It looks very
with only base plate and backbone rendering - the hbonding
and base orientation can be see very clearly and the
visual display is not too distracting when bases are colored
Ran the forcefield for 2000 timesteps and although it ran
very slowly (about 2 timesteps per second), the trna
structure remained stable!!


Added Draw() method to CBasePairCon to display target
Adding command 'target selpair'


The program runs noticeably more slowly on ribomachine1
than it does on beryllium. Improved
CRbApp::UpdateFrameRateStats() to average over 20 timesteps,
running ahelix.pdb (1rxb.pdb) in hbonding sim gives
a framerate of around 7 frames/sec on ribomachine 1.
Update rb and wklib makefiles to build release versions.
Built release versions.
We are getting a framerate of around 12, but also some
weird behaviour - centering is not working!


So far, on ribomachine1, the bug has been tracked down
to the inline function SetMyCenterOfMass() in
CForceObject.h. If not inline, the bug goes away
(uninitialized member data somewhere?)
Rebooted machine, got same behaviour.


Rebuilding on beryllium. Changed c runtime lib to
single-threaded version, debugging with BoundsChecker.
Fixed some memory leaks, but still get a bunch related
to cstartup, glut, nvopengl.
Got the exact same rotation bug on Beryllium in release version.
Wrote member-data initialization check utility '',
it found some uninitialized member data in CRbSelection!!
Did release build after adding missing init code, same bug!


More work with Iscan to catch uninitialized member data.
Found uninit data in CRbApp:
(in other words, nothing significant)
Added SetDefaults() to many many classes to reduce
uninit reporting (mostly false, because it was being
done in the Constructor). However, still need to add
check that SetDefaults() is being called by all constructors.


Looking at assembly listings of CResidue::CalcCenterOfMass()
to debug com problem.
With optimizations turned off, doesn't happen.
Isolation shows that turning /Oy off (Frame-Pointer Omission)
fixes the problem
Rebuilt program and wklib with /Oy- switch, problem appears
to be solved.
Release version runs ahelix.rbs ff sim at a framerate of
around 17 fps.
Working on 'target selpair' command.
Made CGraphicsObject::m_pAvicon private.
'target selpair' command is working.


Fixed help.txt file handling by using a stringstream
in CScrollConsole so now the help file can be opened
by another process.
Added 'SetMass()' to CResidue::CalcCenterOfMass() so
that bases now reflect the aggregate masses of their
child atoms (was just being set to '1' before). Consequently,
we can up the default timestep to 0.2 and still get
Added command 'sho spring' (show/hide spring bonds)
Added override method CAtom::DrawChildren()
'sho spring' command is working.
There is a naming/selection problem when inserting
another copy of a pdb object from file.
Fixed selection bug in CRbCommand (still had some
pSelection->GetChildList() references).


Adding object-frame definition of selection axes for
selected residue.
Added CRbCommand::DoPostSelectionWork().
Added CBase::GetRingFrameDefAtoms()
Rotation along base ring frame is now working, however,
during ahelix sim, it doesnt allow for good user-guided
base-pairing. Attempts to rotate appear to be resisted,
and further rotation quickly disrupts the structure.
The problem may be solved by defining rotation along
covalent bond axes instead.
(or perhaps, implement or translate this 'higher-level'
user-defined rotation direction through component rotations
around covalent bond axes ).


Added command 'set massfactor <n>'
Adjustment of massfactor to 0.1 improves 'spriteliness'
of bases in ahelix.rbs sim.
Added command 'set TsPerIdle <n>' (timesteps per idle tick)
It works. We can run around 5 ts per idle with acceptable
speed, but still a little jerky. It doesn't appear to
give too much benefit.
It's becoming increasingly apparent that we need to allow
movement for the 4 additional bonds along the backbone
before we can observe useful behavior.


Added class CRotGroup.
todo: replace Add/SubtractTorqueVector() methods with a
single AddTorque() method for CForceObject.


Changing SubtractTorqueVector() refs to AddTorqueVector().
Before beginning change from stv to atv, timestep data
analysis was done on ahelix.pdb and some discrepancies
were noted between the total and recorded forces and torques
for timestep one. Analysis was then done on 2nt.pdb and
similar discrepancies were found.
Changed precision of Timestep Report to 15 digits.
From timestep 1 of 2nt.pdb with hydros and hbonds:
-0.012078903534369 -5.305300084945742 -9.367816230467877 Calculated Total Force
Base C1 -0.012076309374054 -5.303840705382930 -9.365222735427350 Recorded Total Force
Base C1 0.000002594160315 0.001459379562812 0.002593495040527 Delta Total Force
Comparison of dbforce.txt output from rb with tsda output,
sorted by magnitude of x component reveals a force missing
from tsda.
It's the friction force! dumbkopf! Reanalysis with
friction force and torque recording gives agreement between
calc and recorded force/torque, timestep 1 for 2nt.pdb as follows:
-0.012076309374051 -5.303840705382918 -9.365222735427341 Calculated Total Force
156 Base C1 -0.012076309374054 -5.303840705382930 -9.365222735427350 Recorded Total Force
156 Base C1 -0.000000000000003 -0.000000000000012 -0.000000000000009 Delta Total Force
-36.432443704563553 -17.976220596041177 14.097666446985981 Calculated Total Torque
156 Base C1 -36.432443704563603 -17.976220596041099 14.097666446985899 Recorded Total Torque
156 Base C1 -0.000000000000050 0.000000000000078 -0.000000000000082 Delta Total Torque
tsData save to reference file 'tsData-2ntRef-001.txt'
Ran ahelix.pdb, timestep 1 'tsData-ahelixRef-001.txt' results:
-10.925164600925282 13.472145127772132 -5.264596881001500 Calculated Total Force
563 Base G8 -10.925164600925299 13.472145127772199 -5.264596881001500 Recorded Total Force
563 Base G8 -0.000000000000018 0.000000000000068 0.000000000000000 Delta Total Force
-68.445551024762622 15.998737856769081 22.201485849100774 Calculated Total Torque
563 Base G8 -68.445551024762906 15.998737856769001 22.201485849101399 Recorded Total Torque
563 Base G8 -0.000000000000284 -0.000000000000080 0.000000000000625 Delta Total Torque
We have agreement to the 12th decimal place for the max discrepancy.


Resuming removal of SubtractForce/TorqueVector().
Replaced all SubtractTorqueVectors() with ATV's, checked ahelixRef, no diffs.
Replaced all SubtractForceVectors() with AFV's, checked ahelixRef, no diffs.
Renamed AddForceVector() to AddForce()
Renamed AddTorqueVector() to AddTorque()
ahelixRef test still checks out.
Made some notes in CRotGroup.cpp about the 'lost' torque
scheme - it looks like it may work.


Changed name of CRotGroup to CRotBody.
Added class CRotSegment.
Added AddTorque(), ReceiveTorque(), DoCounterRotation(),
AddLinkAtoms() to CRotSegment.
There are some issues in CRotSegment::DoCounterRotation()
when doing rotation of atoms. Unfortunately, there
are currently quite a few dependencies such as acceptor
bonds, block polys, base rungs, extents.
We may need to go to more 'calculation on the fly' for
things such as these (as is currently done for base plates),
It may be a litte slower, but cleaner in the sense that
we only have to update atoms and not worry about updating
other stuff all over the place every time we move atoms.


Came up with efficient scheme to draw base rung:
just translate and rescale Ringblock to draw both backbone
and rung blocks!


Added method CBlock::DrawBlockPolys().
Added method CBlock::GetNormals().
Changed name of CBlock::GetBlockSize() to GetSize().
The scheme above does not work with the current way in which
blocks are drawn. The scaling scheme would work if the
block vertices defined edges aligned with the world frame
x, y, and z axes, and subsequent block orientation is
done doing glRotate. However, currently, the vertices
are defined in the world frame and no rotation is done
during drawing. The actual world-frame coordinates are
rotated as the block changes its orientation.
Thus, when the scaling is attempted on world frame
vertices, the block is no longer aligned with the
world frame and the glScale() does not work as desired.
Added method CBlock::GetVertices()
Added method CBlock::GetScaledVertices()
Added static method CBlock::DrawBlock()
It looks like this approach will actually work.
Currently, rung block is drawn with correct dimensions
and orientation. Just need to add movement to proper


Eliminated CBase::m_pBaseRung.
Base rung drawing is working
Added CChain::GetNextResidue().
Eliminated CBase::m_pNextBaseInRibbon, added drawing
of ribbon line using dynamic lookup of next base in chain.
Ribbon line drawing is working.


Moved electron vector from CHbond to its component CAtom.
Added following methods/data to CAtom:
Rotate( double[] rgdMatrix )
This removes explicit electron vector manipulation to
some degree in CBase::Rotate() and
However, a check is still needed for atoms which may
have electron vectors and a call to CAtom::RotateElectronVectors()
still needs to be done because for (dubious?) efficiency
reasons we are still directly manipulating atom positions
during base rotation instead of calling the CAtom:Rotate() method.
This could be changed at some point, however the main benefit
of the new way is that it allows the CRotSegment to do the
same thing when rotating atoms.
Actually, the original reason for doing explicit rotation of
atoms in the CBase methods was to avoid redundant calculation
of the rotation matrix. However, we can define a new CAtom
method which receives the precalculated rotation matrix
as a parameter.
This can now be used to fully encapsulate electron vector
rotations within CAtom methods.
The only loss of performance is the function-call overhead,
done for every atom.
Ran ahelix.pdb after changes to atom movement, but with
ElectronVector stuff ifdefd out, atom translation and rotation
appear to work ok.
Added PrintData() methods to CAtom, CBlock, CForceObject, CGraphicsObject
to assess memory usage.
Added PrintData() to a reference CAtom object in PrintClassSizes()
(called by CRbApp::PrintObjectTrees() ), there is a huge amount
of storage being used by a CAtom object:
Object Sizes
sizeof( CGraphicsObject ) = 192
sizeof( CPolygon ) = 264
sizeof( CForceObject ) = 328
sizeof( CSpringBond ) = 240
sizeof( CBlock ) = 408
sizeof( CAtom ) = 456
sizeof( CBase ) = 480
sizeof( CChain ) = 424
sizeof( CPdbObject ) = 408
Total size of CGraphicsObject data = 175
Total size of CForceObject data = 126
Total size of CBlock data = 68
Total size of CAtom data = 44


CGraphicsObject has 33 virtual methods. This should only result
in an additional 4 bytes for a vtable. Maybe it has to do with
even boundaries for class data?
Also got really weird bug printing out CForceObject::m_dRadius
and CBlock::m_dRadius: printing out the address of the var
completed failed.
After doing work-around and adding bytes for CGraphicsObject
data we have 175 bytes used for data, another 5 bytes within
the data section accountable to partial use of 4 byte segments
by bool vars (1 byte for each bool var) and an additional
4 bytes on either side of this data region giving a total
of 188 bytes. If we add another 4 bytes for a vtable, we
reach the 192 bytes given for sizeof( CGraphicsObject ).
Implemented CAtom electron vector methods.
Ran ahelix.pdb sim, hbonding looks ok.


Ran ahelixRef.rbs, did tsda analysis, output is identical to
Working on CRotSegment::DoCounterRotation().
In deciding how to do the rotation, we could introduce a new
class, CRotBody, in between CForceObject and CResidue, with
its own Timestep() method. CRotBody just consists of a list
of CRotSegment objects. During its Timestep(), it calls
CRotSegment::DoCounterRotation(), before or after calling the
base class Timestep() method.
The other option is to hook a reference to a CRotBody
object explicitly into CBase, and do the work in the
CBase::Timestep() method. This is perhaps less clean, but
for now may be the way to go because it avoids mucking with
the class hierarchy, and also lets us deal with the block
poly rotations which need to be done in concert with any
atoms rotations done by CRotSegments.
Added CBase::Timestep().
Added CRotSegment::CalcRotation()
Checking for needed normalization of vRot when doing rotations:
methods such as CAtom::Rotate() call wkGLutil function
RotateVector() which ultimately calls glRotate(), which doesn't
appear to require a normalized vector.
( performance question: should this be replaced by a dedicated
function? )
Other methods, such as CBase::Rotate(), use the wkGLutil
function GetRotatedMatrix() directly, which also calls glRotate(),
so it would appear that normalization of vRot is not needed.
Finished initial coding of CRotSegment.cpp,
Added CBase::m_pRotBody, CForceObject::m_pRotSegment,
recompiles ok.


Added CBase::CreateRotBody().
We finally have some segment rotations, though they are
pretty crazy!
Adding CRotBody::ClearTorques().


Added CRotBody::ClearTorques(). Ran a test on 2nt.pdb,
not getting expected rotation (magnitude is very small).


Created rb2.cpp, moved it to rbmain.lib to allow external
program pdbtrans to use CPdbFile class (the linkage dependencies
for rb classes is really messed up!)


Did some work on the glRotate project to compare glRotate()
accuracy to new wkUtil GetRotatedMatrix2() function, there
is a significant difference, looks like glRotate() only
maintains float-level accuracy when doing glRotated().
Changed wkLib calls to GetRotatedMatrix() to new
On loading ahelix.pdb, this shows a bug when drawing base
rungs and plates.
Fixed bug in wkGlUtil (switched row-order to column-order),
GetRotatedMatrix2() is working now.
Ran ahelixRef.rbs test, found minor differences as expected
between tsData-ahelixRef-002.txt and tsData-ahelixRef-003.txt
but deltas for ref003 did not appear to decrease, just change.
??? Why didn't increased accuracy of rotation for
GetRotatedMatrix2() produce a smaller delta for ref003?
In any event, alignment of bond between P and O1P to x axis
using tool pdbtrans worked, saved test file 'segTest.pdb',
which can now be used to debug segment rotations.


Added command 'set sel axes local [on|off]',
Added CSelection::EnableLocalAxes() to allow switching
back to world-frame when adjusting position of a base.
After aligning the base so that the P-O5* bond is
coincident with the x axis, tried to apply a force
to one of the atoms in the base so as to produce a
torque precisely parallel to the P-O5* bond, but eventually
came to realize that such a torque cannot be produced unless
the vr vector from atom to center-of-mass is orthogonal to
the desired bond vector.
One solution is to set one of the atoms mass to near zero,
recalc base center-of-mass, then move the atom so that its
x and y coordinates are equal to those of center-of-mass.
Then, its vr will be in the neg z direction and a force
applied in the neg y direction should produce a torque in
the desired direction.
Added command 'sho valence [on|off]'
Added CSelection update when changing object mass.
In the interminably ugly 'UpdateExtents()' issue
(which has never been properly thought out or determined)
it is realized that when changing the extents of an
object such as a CAtom, during a call to its Move() method,
for example, the call to the parent object's UpdateExtents()
method will only update the extents of the immediate parent
in the hierarchy.
There is no recursive call to parents higher up the hierarchy
and it seems that there should be. Is the solution to make
UpdateExtents() automatically call the parent UpdateExtents()?
Redundant calls would definitely be a problem when every atom
atom in a base called the same parent multiple times (this
is why bUpdateParentExtents is a parameter in the Move() method).
Note: CChain::UpdateExtents() calls its parents UpdateExtents().
Perhaps something akin to a 'repaint' flag could be used, where
multiple child windows post a 'repaint' to their parent window.
Bug: Residue center-of-mass is not being called when hydros
are added.
Is there a design pattern relating to this hierarchical updating
problem? (Certainly, the Java awt and swing hiearchies have to
deal with analogous bounds updating for containers and components)
BUG ALERT!! Big change: adding 'bUpdateParentExtents' parameter
to UpdateExtents() method. By default, it will be set to 'false'
Passed on bUpdateParentExtents flag in
CGraphicsObject::Move() and CGraphicsObject::Rotate().
Added call to parents UpdateExtents() at bottom of
Passed on bUpdateParentExtents flag in
CAtom::Move() and CGraphicsObject::Rotate().
Ran ahelixRef.rbs again after these changes, no diffs between
tsda-ahelixRef-003.txt and 004.txt (after commenting out
CreateRotationBody() in CBase::Create() of course! )
Finally got an aligned hydro to generate a torque parallel
to P-O5* bond axis, now just need to set m_pRotSegment for
newly added hydros (this may explain the drifting hydros
observed in the ahelixRef.rbs run where CreateRotationBody()
was still being done!)
We have a bug in the CTextConsole msg box when reading
segTest.rbs script.
04/22/ 2001 WK rb462.gz Debugging CTextConsole bug.
Found the problem: results from improper assumptions of
function of sstrncat(). I had assumed that it uses the
n parameter as the max size of dst string (as in some other
versions of sstrncat(). However, it just passes n along
to strncat().
Changed sstrncat() in wkutils to clamp n to remaining
space in dst string (how many problems has this bug been
causing up till now?). The bug is fixed.
Added CForceObject::GetPropertySz(),
Added CResidue::GetPropertySz().
The way to update residue c-o-m after adding hydros is
is in CResidue::BuildAtomListFromChildren() (called
via CResidue::SetOption(iGOResidueRebuildAtomList).
However, that is not the place in which we can update the
m_pRotSegment pointer for newly added atoms, this needs
to be done in CValenceShell::AddHydrogens() at point
of hydro creation.
Added CRotSegment::AddAtom().
Added CGraphicsObject helper func IsZeroExtentObject().
Finally tracking down AxisDef bug in CSelection:
AxisDefs weren't being delected on DocClose()!!!
Added call to CSelection::Initialize() in CRbDoc::Close()
Actually, CSelection::Initialize() was being called
in CRbDoc::InitDoc(), but AxisDefs weren't being cleared
in CSelection::Initialize().
segTest.rbs script is finally working.


Added command 'print' to print info about current selection
Revamped Print() methods and renamed ExportData() methods
to Print() methods, tried to make them more consistent
in calling base class methods, added 'end' blocks.
Added 2 more DataExport classes (CSelection, CBlock).
This will break the tsda tool though.


Added bRecurse flag to Print() methods.
tsda is working again. Saved new file to
Analysis with new tsda version give identical results to
old analysis (analysis saved as tsda-ahelixRef-004.txt).
Updated 2ntRef.rbs, generated tsData-2ntRef-002.txt


Added CBase::Print().
Fixed some problems in CRotSegment, changed saved
forward and rear lost torque vectors to magnitudes.
In segTest.rbs, the rotateable linkage between
P and O5* actually appears to work when torque is applied -
the P segment remains in the same direction when
the base rotates in response to an applied torque, as
However, when the base is rotating due to acquired
angular velocity, no counter-rotation is done in this
case and the P segment rotates in sync with the base.
Also getting a strange translation of the base c-o-m
downward over time. Note: this translation does not
occur when rotation body creation is disabled, so it
may be due to the missing rotation of the P segment
during velocity rotation.
It seems that we may need to a 'local' angular velocity
for the rotation group, in addition to a 'local' torque?
Must consider the angular velocity of the 'driving'
segment as well as external torque.
Another idea: apply an 'internal' torque using the
current angular velocity of the entire rotation body.
This torque, in addition to the external torques,
should be propagated through the segments.


Instead of actually calculating an 'internal' torque,
we can just project the current angular velocity along
the link axis.
Problem: calculating counter-rotations requires use
of link vectors. Need to separated counter-rot calcs
from actual rotations during CRotBody::Timestep(),
otherwise, one segment's vector will have changed
during its rotation prior to another segment's calc
Added CRotSegment::CalcCounterRotation().
While debugging CRotBody rotation, found wicked old bug
in CForceObject::Timestep(): angular velocity was being
calculated from unclamped rotation angle!!! Not clamped
rotation angle!!
Added the fix and ran ahelix.rbs w/o rotation segs, looks
good! Base-pairing seemed strong and possibly more stable
than previously.
Changed clamping of max rotation in CForceObject::Timestep()
so that the 2 parts ( v0t and 0.5at^2 ) are clamped
individually to half the max (done so that CRotSegments
can do equitable clamping of their 2 parts )
No, that doesn't work. The rotations would have to be done
separately and they are not commutative.
We'll just have to ignore the inequity when clamping occurs
(shouldn't be too much of a problem as clamping shouldn't normally
Added dHalfTimestepSquaredDivMass param to pSegment::CalcEltCounterRotation()
calc, segTest.rbs now works as expected!!!!
Did demos in Montreal, reactions generally favorable.


Fixed bug where rotation was being done on a zero-vector in
CForceObject::Timestep(). (how old was this bug?).
Did some limited testing of 2 bases interacting where the one
bond between P and O5* can rotate.
Added command 'set rotbody [on | off ]'.
Added command 'ins bassfil <fname>'.
Created CBass class
Created CBaseBlockCreator class.
(temporarily non-compilable)


CBassBlockCreator is now in a compilable state.


Released source code to Mel, John Kohler.


Finished GetBlockParams(), CreateBlockVertices() in


Moved CreateBlockVertices() to CBass, added Draw() code,
Inserted 1ffk.pdb file, it loaded very quickly!
Added CBass::UpdateExtents().
Ribosome Builder can finally load the Ribosome!!!!


Added drawing of base rungs to CBass, not quite there yet.


Changed clipping planes to (1, 1000), def volsize to 500
(glenn noticed major artifacts on 1ffk blocks, they look
much better now)


Fixed slow residue range selection (residues were being
added 1 at a time to CSelection, which is slow).
Added property info to CPdbObject.
Added creation of covalent bonds between amino acid residues.
Working with DNAPol.pdb (1BPD), we are getting creation of
2 chains when there only appears to be one.
Fixed bug: added increment of default chain id in
Adding block definitions for amino acids.


Added command 'draw block wire [on|off]'.
AminoAcid backbone block creation is working.


Earlier, CPdbObject and CChain were short-circuiting
iGODrawWireframe option so they wouldn't toggle their
own wireframe state as well as that of child blocks.
That change required that child residues be directly
selected in order to toggle their wireframe state.
This is a pain.
Currently, since CPdbObject and CChain blocks are not
visible, we can remove this short circuit. However,
If they become visible in the future, may need to a
a 'residue-level' or lower iGODrawWire option.
Fixed offset problem for CBass base blocks.
Sucessfully loaded 1fka.pdb (30S structure) after
handling missing base atoms in file.
Added 'draw block', 'draw backbone' buttons to toolbar.
Added command 'draw backbone [on|off]'
Changed name of 'ribbon' cmd to 'base rung'.
Added command 'backbone [on|off|N]'
Added CResidue::DrawBackboneSegment().
Backbone drawing is working.
Improved base colors, the 50S looks nice in block mode.


Added translation and rotation of CBass objects.


Added command 'set errbox [on|off]'
Created demo1.rbs w/ 30S, 50S, and trna.
Showed demo to Russ Piazza at Piper Jaffrey (investors
in Tripos).


Created CBassFile, CBassChain, CBassResidue classes from CBass
preparatory to supporting protein loading from bass files.
New bassfile loading is working.


Adding multi-chain capability to bassfile loading


Added reverse toggling to select-state toolbar icons.
Added chain ids to CBassChain objects.
Made CBassChain objects children of a CPdbObject after
being loaded by CBassFile.
Hiearchical selection is working. However, we are getting
getting 52 chain objects from 1fka.pdb, much more than
we should.


Adding command 'sho seq'
Added CRbCommand::GetSelection() wrapper function.
Made CBassChain derive from CChain.
'sho seq' command is working, for both CBassChain and CChain
Multiple chains in '1fka.pdb' is due to chains being split
because of non-consecutive residue numbers.


Adding selection to CBassChain residues.
Added 'szExtraInfo' param to SelectionParam, renamed
other fields to make meanings more clear.
Abstracted OpenGL picking code from CRbApp::GetMouseSelection()
into GetNearestHitRecord(), TraverseHitRecords().
After recompile and brief test of hierarchical selection
of trna.pdb, original selection capability appears unbroken.
For selection of CBassChain residues, the selection specification
has been modified to allow specification of 'internal' info
by appending a bracket-delimited block of residue numbers.
Ex: 'sel trna.A[0 1]' instead of 'sel trna.A.G1,trna.A.C2'
CBassChain hierarchical selection is working except for
add/remove selection of residues (need to query current residue
selection state to get proper new selection state of residue).


Adding CGraphicsObject::IsInternallySelected( string sSelectionSpec ).
for internal-selection types of objects such as CBassChain.
Still not quite there: needed to modify CSelection::Remove()
to skip actual removal of object if doing internal selection.
Add/Remove selection appears to finally be working for
CBassChain residues.
Adding backbone-drawing to CBassChain.
Backbone drawing is working, but slow (probably because of
calls to glxRotateCurrentMatrix() in drawing the cylinder).


Fixed DrawBackboneSegment() to do explicit shifting of
vertices instead of doing glxRotateCurrentMatrix(), now
backbone rendering appears as fast as block rendering.
Added vUserColor to BassResidue struct. User-coloring
of BassResidues is working.
Adding centering on selected residues of CBassChains.
Added virtual method 'GetSelectedExtents()' function to CGraphicsObject
to get selected extents of CBassChain-type of objects in CSelection.
Centering on selected CBassChain residues is working.


Added property info for CBassChain selections.
Trying to reduce size of CRbCommand.cpp. It's now up to
191 kb. Added helper module CRbCommandUtil.cpp.
This cut CRbCommand.cpp down by about 20k. Cutting more
would entail significant rework.
After long-recode, ran program and tested loading and selection
of 1ffk.pdb, command changes appear to work ok.


Intermediate stage in adding CGraphicsObject::GetObjectsObjectsAndIssFromName().


Debugging internal selection. Note: one good reason to use
pointers instead of references: it makes explicit the
pass-by-reference intention, which is useful in situations
were we are expecting to have data returned from a function
call thorough a param. If passed by reference, the data in the param
container will always be accessible to the caller. If passed by value,
however, the contents will be lost on return. This can easily occur
if the param is 'accidentally' declared to be passed by
value instead of passed by reference. When passing pointers,
this accident cannot happen. This disadvantage is compensated, however,
by guarantee that the reference is always initialized, while the
pointer may not be.
Added detailed explanation of new selection scheme in header of
Residue selection by name, as well as range selection by index
is finally working for both traditional residues and CBassFile


Added CBassChain to IsForceObject() macro to avoid 0 mass ASSERTs.
Have bug in new selection scheme: by assuming that a numeric
value in a name spec implies residue range selection, we got an
error on a chain with a chain id of '0' (zero) in 1ffk.pdb.
Bug is fixed for now by only applying the range-selection spec
to Chain-level objects.


Compiled in MSVC 6.0, only had to fix a couple of minor map<>
declarations in CProperty.cpp, CForceDisplay.cpp.
Fixed some bugs in help.


In comparing performance with VC50 and VC60, running
ahelix.rbs script on release version, we get a framerate of
15.4 for VC60 on the Sony VAIO PIII-700MHz (Intel 82815 Graphics).
However, after installing VC60 on the Sony, compilation using
VC50 is now failing.
Added auto-repositioning of toolbar on window resize.
Added backbone radius resizing to CBassChain.
Added 'color vol <r,g,b>' command.
Added rendering of volume floor and directional indicators.
Adding command 'rot byRefObjects targetObj refObj1 refObj2 x y z'
(used to align pdb objects such as 1ffk to a std orientation).
Created script 'ins1ffk.rbs'.
In trying to manipulate 'internal' objects such as BassResidues,
it often is at odds with the traditional, convenient mechanisms
available with a direct reference to a CGraphicsObject. One
means of emulating this convenient access would be to create
a 'CIndirectObject' class which derives from CGraphicsObject
and consists of a CGraphicsObject reference to the containing
object in conjunction with a 'indirect reference string' to
access the internal object.


Created class 'CIndirectObject'. However, the problem with
creation of 'indirect' objects which serve to 'relay' methods
is the destruction of such intermediate objects. They
should not become part of the root object hierarchy, as they
are for temporary utility purposes.
Perhaps we need something like the 'Release()' method of
an interface.
Alternatively, we could use local CIndirectObjects which
can be initialized with the appropriate CGraphicsObject
relay object and then used as needed until they go out of
This alternative has been done.
'ins1ffk.rbs' script is working.


Created scripts 'ins1fka.rbs', 'ins1tra.rbs', 'demo3.rbs'
Re-enabled functionality of blocks with spring bonds.
Ran test with 2 blocks and a spring bond - there is
an unknown (frictional?) force which is acting with all
apparent friction turned off.
Ran ahelix.rbs test, did not appear to be affected by
changes from block re-enabling.
Hooked up 'ins file', 'ins bassfile' to insert menu,
fixed up other insert menu items.
Added CRbDoc::OpenBassPdbFile().
Big pdb files are now automatically opened as bassfiles.


Added transformation frame to CBassChain.
It's not working (can't apply transforms aligned with world
frame to local frame).


Recompiled without errors after wklib const additions.
Added HETATM loading from pdb file (to handle file 1e9w.pdb -
thiostrepton - for Bill).
File 1e9w.pdb now loads ok.
Bug: phosphate backbone bonds are created in wrong direction
when loading file 1mms.pdb
It is assumed that for 2 consecutively
numbered base residues, the lower number is 5' to the
the higher number. This is the case in 1mms.pdb.
For example, residue A1067 is 5' to residue G1068.
So, the O3* of A1067 should be bonded to the P of G1068.
And yet, instead, it is bonded to the P of U1066. Note:
this only happens for Chain D. In the isochain C, the bonding order
is correct.
Currently, in CChain::CreateNucleicCovalentBonds(), the assumption
is that the next residue in the m_pResidueList is higher in sequence
number. Somehow, this sequence has been reversed.
While the source of this reversal should be investigated, the immediate
fix is to simple retrieve the next residue using pRes->GetSequenceNum() + 1.
Also, a distance check has been added to prevent the bogus long bonds
which ocurred.
The bug has been fixed.


Fixed Residue naming for file '1e9w.pdb'


Fixing Element parsing in CPdbRecord.cpp to handle Mg.
Removed addition of reciprocal bonds in CONECT records
in CPdbFile::Read().
Cleaned up residue selection by number in CRbCommand::SelectResidueObjects().
Removed member arg option from res num selection.
Added lots of const qualifiers to CRbCommand and CRbCommandUtil.
Numeric-Arg-Only Residue selection is working for standard pdb objects
(CBassFile NAO selection not yet implemented,
though sel by '<pdb>.<chain>.<N>-<M>' is, except for status update).


Changed bool flags to bitset flags in CAtom.
Added writing of CONECT records for HETATMS in CPdbFile::Write().
Added const qualifiers to CVoidPtrArray, CGraphicsObjectList, CAtomList methods.
Replaced some C-style casts with static and reinterpret casts.
All the casting for these classes is really nasty and needs to be
cleaned up.
Ran ahelix.rbs test script, behaviour appeared normal.
Opened trna.pdb, copied and pasted residues 36-39,
HETATM covalent bonds appear to be correctly created from
clipboard pdb file.
We are getting some ASSERTs for zero bond counts though.


Adding camera-frame rotation and translation.
It doesn't work when cam is rotated such that +wy is -cx,
+wz is -cy (w = world frame, c = cam frame). In this
orientation, rotation input about cx produces actual rotation
about cy.
Keyboard mapping of rotation inputs:
The rationale behind these keyboard mappings is as follows:
They create the same rotations as would be produced by
the fingers of the hand pushing on the viewed object, where
the hand/numeric keypad plane is aligned with the x-z plane for
UP/DOWN and IN/OUT inputs. Then we have:
'UP' = '8' pushes down on -z axis to produce ccw rot looking down x axis from - to +
'DN' = '2' pushes down on +z axis to produce cw rot looking down x axis from - to +
'PD' = '3' pushes down on +x axis to produce cw rot looking down z axis from + to -
'EN' = '1' pushes down on -x axis to produce ccw rot looking down z axis from + to -
For the LEFT/RIGHT input, we imagine the hand/numeric keypad plane is aligned with the
x/y plane. Then we have:
'LE' = '4' pushes down on -x axis to produce ccw rot looking down y axis from - to +
'RI' = '6' pushes down on +x axis to produce cw rot looking down y axis from - to +
Ref: when cam and world frames are aligned, currently, the
non-null pParamFrame gives equivalent rotations for the
inputs above. However, when the wy axis is rotated forward into the cz position,
then the RIGHT rotation input causes ccw rotation looking down the cy axis from - to +
when it should produce rotation in the opposite direction.


After brief analysis of camera-frame rotation in glcalc app,
it is apparent that the problem has something do with mixture of
rotation matrices and rotation vectors (a vector about which the
rotation occurs).
Currently, most if not all Rotate() methods in the GraphicsObject hierarchy
use a rotation vector as a parameter. This eventually results in calls
to wkGLutil functions such as RotateVectors(), where the actual rotation
matrix is finally created.
There has been some optimization of this, as in CBase::Rotate(), which
precalcs the rotated matrix and then calls an CAtom method which takes
the rotation matrix as a parameter.
The CSelection method RotateSelection() takes an axis param to do
create a vAxis vector, defined as the x,y, or z axis, either in the world frame
or a user-defined frame. Then, the selection was rotated about this
vAxis vector.
The param camera matrix was being used to rotate this vAxis vector.
Instead, the rotation matrix corresponding to this vAxis vector should
be obtained, and multiplied by the param camera matrix to produce the
final rotation matrix applied to the selection.
When the wy axis was rotated forward into the cz position, this produced
a rotation matrix consisting of a 90 rotation about the x axis.
Then, the RIGHT rotation input will result in a vAxis vector = (0, 1, 0 )
Then, multiplying this vAxis vector by the input rotation matrix moves it
to (0, 0, 1 ) which is wz, which is currently aligned with -cy, which explains
the observed behaviour.
To do rotation about the screen frame axes, we can instead create
a rotation matrix corresponding to the vAxis vector, m3multiply the camera
matrix into this, and the resulting matrix should have the correct rotation.
The question is, if we want to keep the existing Rotate() interface, we then
need to translate this resultant rotation matrix into an equivalent vector
which is passed as a parameter in the existing interface, or instead
define a second Rotate() method with a matrix parameter for all selected objects.
Another anomaly: currently, the 'rot d x y z' command is rotating objects
according the the left-hand rule, whereas the OpenGL convention is according
to the right-hand rule. That is, in OpenGL, rot '10 1 0 0' should produce a
rotation of a standing person facing the viewer along the z axis, then their
head will be more inclined toward the viewer. The right-hand rule also means
that if the rotation vector <x,y,z> is pointing toward the viewer, the
rotation about that vector will be counter-clockwise.
The anomaly occurs because RotateVector() in wkGLutils calls MultiplyVectorAndMatrix()
instead of MultiplyVectorAndMatrixOpenGLStyle(). Ideally, there should be
be a single, consistent rotation direction, but there is not currently time to
implement the necessary changes.
Added CSelection::RotateSelection( iAxis, dAngle, rgdFrame )
Added CSelection::Rotate( vOrigin, rgdMatrix )
Added CGraphicsObject::Rotate( vOrigin, rgdMatrix )
Added CGraphicsObject::RotateChildren( vOrigin, rgdMatrix )
Renamed CForceObject::GetMaxExtents() to GetMaxPossibleExtents().
Adding const qualifiers to
Note: after trying to declare certain member functions const
which were returning the this pointer, and researching the
true meaning of the const qualifier for a member function,
the const qualifier has been left off of these member functions,
since the pointers returned are used as non-const in many places.
Finally got the program working after large recode.
Ran ahelix.rbs, the program is busted.
The source of the bug has been quickly discovered:
The CBase Move() method didn't have the const qualifier added,
so its override didn't occur during CForceObject::Timestep().
We need a utility to flag for likely Derived-class methods which
might have been overlooked during the refactor.


Finished vscan utility, going through unmatch repeat methods.
Note: the absence of a default arg (at least of the same type) does not
change the signature of an overridden method with respect to a base
virtual method.
Example: the following CPolygon method correctly overrides the
virtual CGraphicsObject method:
void CPolygon::Move( const Vector DUMARG, bool DUMARG)
void CGraphicsObject::Move( const Vector DUMARG, bool DUMARG= false)
CPolygon::MatrixRotate() to Rotate() - rgdMatrix
CBase::Move(), CBase::Rotate().
CBase::Rotate() - rgdMatrix
Recompiled, ran ahelix.rbs, it's working again!


Rotate selection no longer working with screen frame matrix.
Getting weird VC crashes.
Note: VC 5.0 compiler at /W4 doesn't warn about doing
delete var instead of delete var[] when allocated as
var = new type[] (C4155);
Note: this warning only given when using /Za switch!
for CAtom.cpp Line 2112:
m_rgElectronVector = new Vector* [d_iMaxElectronVectors];
Deletion occurs at CAtom.cpp Line 2151:
delete m_rgElectronVector;
We can't use the /Za switch because we get 100 errors
in the STL headers (max compiler error count).
Writing a small test program without header files
failed to give any errors deleting a pointer to an array
at /W4 with and without the /Za switch. Perhaps, under the
MSVC implementation, this isn't an error (though, it does appear
in the MSVC tips!).
Wrote batch file and perl script to compile files at /W4 and
filter warnings (ccw.bat,
Made all remaining protected data in CGraphicsObject private.
Removed methods Move(x,y,z)
Added CAtom::UpdateExtents().
Added CBlock::Rotate() - rgdMatrix.
Added CForceObject::Rotate() - rgdMatrix.
Added non-GL matrix multiply to wkGLutils lib.
Selection rotation is still messed-up (even with
identity camera frame!)


Using CPolygon vertices to debug extents problem (happens
with translation as well as rotation).
Made CPolygon an internally-selectable object, direct vertex
selection by mouse is working.
Added CBlock::SetOptionForBlockPolys()
Changed all CBlock protected data to private.
Resurrected rbd file format with 'save -rbd' option.
Fixing up CGoDoc, CRbDoc file i/o.
(Intermediate state - non-compilable)


Program is compiling.
Minimal Rb doc format is working.
Revamped CBlock::Write( CGoFile *pFile ).
Added saving of block polys as <InternalObjects>


Finally tracked down the block move problem:
the CBlock center-of-mass was not being updated
upon movement.
The problem is the following:
when inserting a single block, and moving it to (1,0,0),
the selection extents are not being updated properly
(they remain at (0.5, 0.5, 0.5)
The source of the problem is this:
In CBlock::UpdateExtents(), it first calls CForceObject::UpdateExtents().
This results in to call CGraphicsObject::UpdateExtents().
Since the block has no children, this method does nothing.
Then, in CForceObject::UpdateExtents(), the center of mass is calculated
from the current extents, resulting in a cm of (0.5, 0.5, 0.5)
CForceObject::UpdateExtents() returns false, and CBlock::UpdateExtents()
goes on to correctly update the new extents from its internal block polys,
giving an extent center of (1,0,0). But the center-of-mass, which is
used for the selection extents, remains at (0.5,0.5,0.5)
The problem results from the fact that CForceObject::CalcCenterOfMass()
assumes correctly updated extents. But CBlock::UpdateExtents() called
the base class before updating extents from its internal poly objects.
This would suggest that an object always update extents from its internal
objects before calling the base class UpdateExtents(), which updates from
child objects if any.
However, currently, the CGraphicsObject::UpdateExtents() method assumes that
it is the first time that extents are being updated and will set the min
extent to the first child object (first non-zero extent child object).
So it would seem that if we implement a policy of updating extents from
internal objects first, before child objects, we must add an 'bUpdatedAtLeastOnce'
flag to the CGraphicsObject::UpdateExtents() method?
Another option is to not call CForceObject::UpdateExtents()
and just handle it's work in CBlock::UpdateExtents().
What's the right way to do it?


One good way is as follows:
Part of the problem is that currently, the center-of-mass
calc is piggy-backing on UpdateExtents(). We need to separate
these into separate functions. The reason it was piggy-backed
was because of the necessity for placing calls to UpdateExtents()
in every function which changed position (Rotate(), Move()).
If we defined a new method, CGraphicsObject::PositionChanged(),
then inside of this method, we can call UpdateExtents().
Then for force objects, we can override PositionChanged() and
then, when a CBlock is moved, CForceObject::PositionChanged()
is called, and inside there, the CBlock::UpdateExtents()
is called, which first calculates extents from child objects
by calling the base class CGraphicsObject::UpdateExtents(),
and then adding extent updates for internal polys.
Then, the second method in CForceObject::PositionChanged()
is called, CForceObject::UpdateCenterOfMass(). For a block with
no child objects, the geometric extents will be used, and at
this point, they will have been correctly calculated.
The other issue in this new scheme is parent notification. We
Need to generalize bUpdateParentExtents to a general bNotifyParent
flag passed to PositionChanged().
This flag will then be passed to UpdateExtents() and
UpdateCenterOfMass() to produce a call to the respective parent
methods if the flag is set.
Added CGraphicsObject::PositionChanged().
Added CGraphicsObject::ChildCountChanged().
To flag extent updates on adding/deleting children, it seems
that we should have 2 separate Add/Remove() method groups.
One group is public, and will call the 'ChildCountChanged()'
method. The other is private, only called internally, and
so the 'ChildCountChanged()' notification is not needed there.
This should help to deal with the problem of redundant updates
during multiple object addition/removal:
CGraphicsObject::PublicAddChild( childList )
for all children:
PrivateAddChild( child )
ChildCountChanged(); // update extents, c-o-m, etc.
Created private methods AddChildI(), RemoveChildI()
Replacing UpdateExtents() references with either
ChildCountChanged() or
Rewriting CBase, CAminoAcid, and CResidue creation
in CXXList::CreateXX() methods.
Created class CResidueFactory.
Elimination of removal of atoms from input list should
provide some performance improvement for large atom lists
in CPdbObject::ReadPdbFile().
Made temp backup because of lightning.


Added CVoidPtrArray::FastCopy()
Getting rid of CBaseList, CAminoAcidList, replaced with
CResidueList (they were only used for Base and AA creation).
Adding virtual methods
CResidue::Create( ResidueInfo, CAtomList )
CBase::Create( ResidueInfo, CAtomList )
CAminoAcid::Create( ResidueInfo, CAtomList )
By passing in the AtomList in the Create() method,
we also avoid the large inefficiency which was incurred
during the later CreateBaseBlocksFromAtoms() method,
were child atoms had to be removed from the CBase and
transferred to the child blocks.
All this inefficiency resulted from adding the atoms
to the CBase inside of the CBaseList::CreateBases()
method, prior to calling the CBase::Create() method.
They should have been added at Create() time.
Now, they can just be added directly to the child blocks
of the CBase, without having to remove them from the
child list of the CBase.
temporarily non-compilable.


Added CBaseUtil.cpp module for CBase support functions and data.
Renamed privated method CGraphicsObject::DeleteChildren() to
DestructorDeleteChildren(), added protected method DeleteChildren().
Investigating the Propagator pattern for doing extents and
center-of-mass notifications.
Renamed CResidue::BuildAtomListFromChildren() to UpdateAtomListFromChildren().
Created CChangeManager class, adding initial specification.
Made CResidue::Create() into a template method.
Got rid of bUpdateParentExtents flag in UpdateExtents,
Rename bUpdateParentExtents flag to bNotifyDependents in movement
Added CGraphicsObject::ChildPositionChanged().
There is a problem with calling CGraphicsObject::ChildPositionChanged()
from CPolygon::PositionChanged(): a class can only call a protected
member function of an object of the exact same type ( I didn't know this ).
So, we cannot make this call as long as CGraphicsObject::ChildPositionChanged()
is protected. Is there another way to do this without making this method
temporary backup - temporarily not compilable.


Finally compiles again. Loaded 2nt.pdb. Residue factory appears
to be working, but there are problems (extents not updated correctly).


Created class CDebug for global debugging utils.
Commented out all 'using namespace std' directives at the
top of all source files which still had them (there were a lot).
Added command 'debug rbdfile [on|off]'
Got rid of a few defines in CRbDoc, kicked off more refactoring.
Debug output to rbdfile is working.


Working with tool 'xcheck' (object extents checker)
Got rid of bogus extents in CSpringBond (this object should have
zero extents.


We have center-of-mass problems.
The source has been found: PositionChanged() was added to
CGraphicsObject::ChildCountChanged(). Selection center is now correct for
2nt.pdb, but there is no movement on simulation.
Found the problem: the SetParentForceTransfer() flag was not being done.
This was done in CBaseList, it is now being done in CResidue on successful
Ran ahelix.rbs, the forcefield is working again.
Back to debugging selection rotation.
Found it: 1 wrong number in wkGLutils MultiplyMatrix().
Rotation now stays around object center, but cam frame stuff still not right.


Debugging cam rotation.
Working on project documentation.
Overrode CSelection::CalcAxisRotationMatrix() in CRbSelection,
After wkGLutils Make3x3Matrix() and TransposeMatrix(),
we finally have correct rotation of objects in the camera


Extents is broken on CBassChain objects.
Added web documentation of object hierarchy.
Added web documentation of object extents updating strategy.
Rewrote CBassResidueCreator, reading of bass files is working,
the extents of CBassChain objects is working.


Documenting object property methods.
Fixed creation of blocks in CBassResidueCreator().
Fixing error in reading 1fka.pdb (failing to record backbone
vertex for unknown residue types ).
1fka.pdb loads without errors now.
We really need a scrollable text box for object info.


Split off chem objects in gobj lib into gchemobj.lib.
Replaced CString with std::string in GetPropertySz methods,
renamed to GetProperty().
Split ForceObject info from CProperty into CFoProperty,
Renamed CProperty to CGoProperty (lots of resulting changes).
temporarily non-compilable - must leave for pizza


Added bitset for flags to CGraphicsObject.
Replaced global 'IsSelectionColoringEnabled()' with flag
in CGraphicsObject.
Got rid of CGoDoc pointer, fileid vars in CGraphicsObject.
Added classes CObjectFactory, CRbObjectFactory to remove
derived class code in CGraphicsObject::CreateObjectFromTag().
A string object gives sizeof() = 16, 4 times the size of
a pointer, but given the advantages, replaced
const char *m_szName in CGraphicsObject with std::string
After large recode, program compiles and runs ahelix.rbs
but selection coloring needs to be fixed.


Splitting out derived class functionality from CAvicon.
into derived class CForceAvicon.
Renamed CInterpreterScript to CRbScript.
Replaced CString, CStringList, CStatus with std::string
in gobj.lib.
Down to 9 unresolved externals linking gobj.lib in
rbq app (was over 100).


Got rid of global CDebug coupling to CGraphicsObject,
replaced with methods to set/get internal debug flag.
Removing rb-app specific references to CIndirectObject,
clarifying definition of CIndirectObject,
documenting object selection.
Changed name of CSelection::Initialize() to Reset().
Initialize() should be used for one-time initialization,
Reset() means resetting of an object to a known, initial
state and can be called multiple times.
Moving util functions to wklib.
Added class CRbIndirectObject.
rbq project compiled and linked without errors!


Recompiling with new makefile, new wklib organization.
Split libs off into makefiles:
Found new bug where a string sStatus var was passed
as a reference, and called code was doing sStatusRet += sResult,
causing a crash because the reference was null.
Assigning a string with a single space fixed it, but this
is new behavior.
(A string which is not intialized is left as null?)
bool func( std::string &sStatus )
sStatus += "not implemented\n";
return false;
string sStatus;
bool bRet = func( sStatus );


After more debugging, this is not the problem. The problem
is we are doing a sStatus += szText where szText is NULL.
After searching on usenet, we find others have been bitten
by the same bug. There appears to be no easy fix,
doing a 'string s = 0' is verboten.
Hopefully, this is not too prevalent in the current code,
given the willy-nilly replacement of char* with string
over the last year.
About a dozen if( szVar != NULL ) checks were put before
string assignment statements with the common names
sMsg, sError, sStatus, sStatusRet.
After a reboot and a full recompile, the 'ahelix.rbs'
script runs, but now, significantly more slowly than
before. Is this due to the /MD switch?
Added command-line macro to define Runtime Lib to
rb, wklib makefiles, rebuilt all with /MLd flag.
After the rebuild, ran script again, still slow.
note: the size of the rb debug exe is 3,207,216 bytes.
Built the release version of rb and wklibs with /MD flag,
ran script and it runs quite fast, perhaps faster than
before. Does this mean that in debug build VC60 is
simply slower than VC50?
note: size of rb release exe is 688,128 bytes.


Minor .mak changes.


Documented rb libraries in html.
Added hack to skip ASSERT for no bonds to HOH HETATMs in
We need to fix selection coloring. We no longer can use
a 'global' flag which CGraphics can check at draw time.
So the way it should work is, when an object is added
to the selection, it's 'd_iGoFlag_IsSelectionColoringEnabled'
flag should be set at that time by the CRbSelection object
if the app global coloring flag is set.
Next, whenever the global coloring flag is changed by the user,
the appropriate state should be set in all objects in the
selected tree.
Got rid of global selection coloring data and functions.
Added setting of selection color from 'set sel color'.
We are getting tons of asserts loading trna.pdb.


Investigated the 'pui' graphics widgets from the PLIB project,
there is no good message box there.
Added classes 'COrthoControl' and 'CMsgBox'.
Added class 'CGraphicsContext', and *pcg parameter to
the Draw() method of all CGraphicsObject classes.


Got rid of utils.cpp, added
Got initial background for CMsgBox, but it will
take too much time to do correctly.
Created CConsole, CMsWinConsole.
Display of external status window is working.
Temporarily removed bottom icons of toolbar
to make room for status window.
Affected code sections tagged with 'TOOLBAR_CHOP:'
Status and error messages are being successfully routed
through external status window.


Changed current 'print' cmd to 'dbprint' (debug print)
Added CGoCollection class (from pcg project)
Added commands 'print', 'print *', 'print <objName>'
Added TreeOp() methods (to replace SetOption())
Renamed CGraphicsObject::Move() to Translate().
Added operator= to CVoidPtrArray.
CGraphicsObject::Print() method is working.


Added rennaming of empty chain name for chains loaded
from pdbfile with no chain id.
Got rid of all those dumb parent pointers in constructors of
CGraphicsObject-derived classes.
Changed meaning of CIndirectObject from a wrapper to
an interface (see usage in CRbDoc::PrintObjectInfo()).
Finally came up with a decent implementation for INS
(internal-name-spec) object retrieval,
refactored CGraphicsObject::GetObjectsFromName() to
cleanly handle both INS and non-INS objects.
Selection of CBassChain residues is working.
Added printing of sequence info to CPdbObject, CBassChain.


Added CRbDoc::MakeUniqueName() to avoid duplicate-named objects
in doc.
Fixed user-coloring in CBassChain.
Created test sub-project swtest (SWIFT++ testing).
Added option '-poly' for save command (save to .poly file format)
in CRbDoc.
After annoying failure at defining a std::vector<Vector3f>
(const allocator problem in template code),
the saving of poly data from CBassChain objects is working.
Successfully loaded exported .poly file from 'a.pdb' bassfile into
swt SWIFT test program.


Changed CVolume parent class from CForceObject to CGraphicsObject.
Ran ahelix test again, works after hacking around CResidue types
(todo: implement support for general residue objects in ff).
Ready to add SWIFT interface.


Added classes
Movement of CBassChains in forcefield is working.
Adding CBassChain::CreateCollisionUnits().


Added CBassChain::FillPolyData().
Addition of SWIFT objects is working!
Insertion of 1ffk.pdb and creation of its
swift objects took a long time, but it worked!


Added C-O-M calc to CBassChain.
Added repositioning of input box for
reduced graphics window.
Finished added support for SWIFT queries.
They don't work. Infinite loop occurs with
trna - trna test. Very imprecise intersection
occurs with 2 a.pdb blocks.
Downloaded VCollide, added classes


Got the VCollide engine to work. For tRNA-sized
objects, it works great. For the big kahuna 50S,
it's slower than death.
Got SWIFT working by removing all the <iostream.h> stuff
and transposing the rotation matrix. It works great
with tRNAs but also dies a slow death loading the kahuna.
Also, it can sequentially load 30 tRNAs (2250 residues)
but then the query takes at least a minute or 3.
The only hope at this point is to try registering just a
subset (surface patch) of the subunits and test
docking with the tRNA.
Adding command 'ff coleng add' (add selection to collision engine)
Release version testing:
With 4 trnas loading, running in realtime gives a rate of
about 1 timestep / sec (SWIFT engine).
On the other hand, VCollide release runs ~5 ts/sec with 30 trnas!!!!
Added addition of seleted residues in CBassChain
(TODO: exposed internals of CCollision engine derived classes,
fix this)
Addition of CBassChain colunits is working.
Finally getting collisions between 1ffk.pdb and trna.pdb!


Added command 'ss [radius] [on|off]' sphere select.
Adding Sphere selection to CRbSelection. Almost working.


Sphere selection is working.
Added command 'group <name> create' (group definition)
Added method CSelection::GetCurrentSelectionSpec().
'group <name> select' is working.
Added CBassChain::CollisionEvent().
Added dispatch of collisions to CVCollideEngine::CalcCollisions().
Added coloring of colliding CBassChain residues. It's working
for 2 trnas but not for trna and 1ffk.


Added selection of CPdbObject chain children by chain num.
(by Adding CGraphicsObject::GetChildObjectsFromSequenceRangeSpec())
Added optimization hack in CRbApp::GetMouseSelection() for slow
CBassChain::IsInternallySelected(), replaced stringstream with
sprintf in CBassChain::GetResidueIndexFromName().
Fixed collide bug (using iRes instead of iResNum in


Adding serialization of CBassChain object from RbDoc file.
Serialization is working.


Added documentation of collision engine code.
Added removal of collision units on CCollisionObject destruction
Removal of collision units on CBassChain deletion is working.


Fixed bugs in removal of collision units.
Tested multiple creations and deletions of tRNA objects
from doc and collision engine.
Added command 'ff coleng remove'
Did profiling run to investigate slow addition of
large residue counts to VCollide engine. Profile data shows
that 50%+ time occurs in VCollide PairData::AddPair()


Added BassAtom struct to CBassChain.
Added module CBassChainUtil.cpp
Added LilAtom struct in CBassResidueCreator.


Final version prior to split-out of src and include
files into src and include subdirs.


New version builds and runs.
Added structs CmdDef and ArgDef,
Creating new command definitions in CRbCommand.


Added class CCmdParser.
Added class CRbCmdParser.
Added class CCmdLine.


Added class CArgFormat.
New command-line processing is working.


Added 'set select axis frame <view|world|local>' command


Split out CCmdLine from CCmdParser.h into CCmdLine.cpp.
Added indirect flag '*' to ArgDef processing.
Got rid of CRbCmdParser, genericized back to CCmdParser
by internalizing the CRbCommand pointer to member func type,
Dispatch is now internalized, CCmdParser calls
CCommand::DispatchCmd( int iCmdId, CCmdLine &cmd ).


Added 'sym insert rot' command.
Cleaned up CRuler, CGoText.
Added CSymElement, CSymInvert, CSymSigma, CSymNaughty.
Changed hierarchy selection in CRbApp::GetMouseSelection()
so that it doesn't require enum Hierarchy level.
Added 'GetClassName()', GetClassNameI()' methods to all
classes in CGraphicsObject hierarchy.
Renamed all remaining 'SetDefaults()' methods to 'InitializeData()'
Select of CSymRot elements is working.


Added sigma planes to sym tool.


Added help support to CCmdParser.
Found Uninitialized Variable bug in CGraphicsObject::DeleteObject().
Added WARN_LEVEL macro to makefiles, recompiled with warn level 4,
fixed 9 remaining C4701 warnings, (ignored 3 from <istream>).
Added 3-point defn for Sym sigma element.


Added Naughty operator to CSymmetryPlugin.
Filling in all missing elements in CPdbRecord.cpp


Finished new Periodic Table data.
Ran ahelix.rbs, appears to work.
Built release version, found bugs.
Fixed stack-overflow bug in CFoProperty.
Fixed bug in CFFVolume() ( InitializeData() wasn't being called
in constructor.
Added scan for missing InitializeData() calls to vscan tool.
No other relevant missing init was found.
After fixing CFFVolume init, release build now is going into
CFFVolume::Timestep(), but is getting an Access Violation.
(running ahelix.rbs).
2nt.pdb works though.


Finally tracked down release version bug in
timestepping ahelix.pdb:
A CBlock object was being passed into CForceObject::DoHbondInteraction()
when only CBase objects should get in there.
Added short-circuit returns in CForceObject::DoStericInteractions().
Added dynamic_cast() check.
Fixed wkAssert function to be routed through app logfile
(was only going to the window before).
An object of CResidue type was being passed. Fixed with dynamic_cast
Running of ahelix.rbs in release mode is finally working again!
Getting a framerate of around 13 fps.


Renamed CCommand, CRbCommand to CCmdProcessor, CRbCmdProcessor.
Cleaned up old CCommand cmd-stack, CStatus stuff.
Added 'volume' command.
Documented Command Processing.
Adding atom data to CBassChain


Wrote perl script '' to generate dependencies
using gcc under cygwin,
Added resulting .inc files to makefiles.


Documenting Object Center-Of-Mass calculation.
Adding c-o-m calculation for selected objects.


Moved several module functions into CPdbRecord as
as static methods,
added CPdbRecord::GetElementFromAtomId(),
residue c-o-m calcs in CBassChain are working.


Redefine atom bond def structure to CBaseUtil::BondPartner
(from int*) to make it more typesafe.
Moved module functions from CBase into static methods
of CBaseUtil.
Added CBassChainUtil::CreateCovalentBonds().


Added processing stats to CBassFile.
For 1ffk.pdb:
no bond creation:
66885 line(s) read, 29 chain(s), 6484 residue(s), 64268 atom(s), 0 bond(s) created from file '1ffk.pdb'
file processing time = 4.01 sec ( 16026.9 atoms/sec )
with bond creation:
66885 line(s) read, 29 chain(s), 6484 residue(s), 64268 atom(s), 76552 bond(s), created from file '1ffk.pdb'
file processing time = 12.58 sec ( 5108.74 atoms/sec )
Note: creation of covalent bonds causes the file to take 3 times longer.
Did profile run to find bottlenecks (,,
bottlenecks appear to be in map lookup in CPdbRecord::GetElementFromAtomId()
and use of vector<pair> structure to determine bond counts.
Replaced map in CPdbRecord::GetElementFromAtomId() with switch block, got
speed down to 8 seconds.
Replaced functions using vector<pair> with dynamic local integer array, got the time
down to 5.7 seconds!!
Did one more profile, bottlenecks all appear connected to remaining
vector<pair> ops (why are they so slow?). Will try to replace them with
Replaced vector<pair> with vector<int>, it's still the bottleneck.
Replaced vector<int> with fixed-size int* array, time is
back down to 4.3 secs!! C code rules for speed!!


Added wireframe rendering of backbone between non-contiguous CBassChain residues.
Moved global functions from CAtom.cpp into static class CAtomUtil.
Added CBassChainUtil::DrawBonds()
Added CAtomUtil::DrawCovalentBond().
We can render wireframe bonds for all RNA chain of 1ffk.pdb
with decent performance now!!


Moved 'ff' command into new cmd parser.
Created 'extra-command-info' file


Adding html helpfile generation to CRbCommandUtil.
Created helper class CCmdsHtmlDoc.
Integration of internal command usage with external
info files is working.


Updated documentation of libraries.
Integrated html command reference docs into
master html doc.


Added extended documentation of ff command to html.


Added project skeleton to master html homepage.
Added unit testing skeleton.
Added 'window' command group
Added auto-repositioning of status window
Added 'file' command group
Added 'script' command group


Added 'edit' command group


Changed object GetProperty() methods to consistently
report a summary of the object properties.
Added CGraphicsObject::GetChildrenProperty().
Made 'bassfile' the default open format,
Added [-osf] flag (old-style format) to 'file open' cmd.
Fixed residue selection bug for CBassFile.


Added drawing of inter-residue covalent bonds in CBassChain.


Fixed hierarchical selection bug.
Changed clipboard file format to RbDoc (so bassfiles are supported).
Fixed broken extents calc for CBassChain.


Fixed selected extents, com calcs for CBassChain
(weren't adding transform)
bounding box is still wrong though.


Added stick, spacefill rendering to CBassChain.


Added nearest-neighbor covalent bond creation to CBassChain residues.
Fixed selected atom count for CBassFile atoms.


Moved 'coleng' to separate command group
Added 'ff coleng print' command.


Added CPolyModel class to rgGraphics lib.
Added 'ins' command group to new command processing
Added 'print' command group to new command processing
Added 'ins atom' menu item
Converted SysUtils module functions to CSystemUtils static methods.
Added CSystemUtils::GetStringFromDlg()
Added 'ins polyModel' command,
loading of test poly model 'tree.spm' is working.


Added CGrTransform to CPolyModel. Rotation and translation are working.


Added AddData(), AddModel() methods to CPolyModel.
Loading of models generated by polytool app are working.


Added saving of selected subset of residues of CBassChain
Copy and paste of basschain selected res is working.
Added 'dev' command group.
Added 'dev writepm atombb <filename>'
Added class 'CPmCube' to graphics lib
Fixed reading of CBassChain sel res subset from .rbd file
(file open rbdoc)
Fixed 'ins file' bug when inserting rbdoc.
Fixed CSelection::Add( CGraphicsObjectList, ...)
bug in which iss list was out of sync with gobj list
in various calls.


Added wrapper class CQhull for qhull routines.
Quick-hulling of eftu.pdb is working!!


Added new cmd-group 'draw'
Did major reorg of CRbCmdProcessor draw code.
Added hull wireframe drawing for CBassChain.
There are errors in the hull around the trna residues
(triangles in interior of hull)


Created CHetPolyModel class to debug qhull errors.
Dumbkopf!!! There is no error in qhull, only in
your verdamnter CPolyModel draw wireframe code!!!
Qhulled 1ffk and trna look good together.


Added qhull facet stats.
For 1ffk chain 0, the avg number of facets per hull is 82.
Added poly count stats.
With 1ffk chain 0 rendered with solid hull, and the rest
as backbone, we are getting polycounts approaching 500k
Added qhull Wn param, when set to 0.5, and excluding base
base-block atoms from the hull, it drops the avg facet
count per hull down to around 40.
Added creation of 2nd hull around base block atoms
It's working.
Changed addition of blocks to addition of polymodels
to collision engine in CBassChain::AddCollisionUnitsToEngine().
Collided 2 trnas, it works. Gets slow in full collision
with about 500 collision pairs.


For 1ffk, we are getting an avg facet count of about 36 (Wn = 0.5).
Added rainbow coloring option, cmd 'color rainbow'.
Added hulls to CBassChain extent calcs,
Fixing broken extent calcs.
We have a problem: calculating aabb extents from original
extents and object's transform matrix doesn't work.
One alternative is to do a min/max update on all vertices
after each transform, which seems wasteful and time-consuming.
Another option is to just abandon updated extents and just rely
on the collision engine, though this seems capitulationist.
Another option is to use a 'loose' aabb, calculated from transforming
all 8 verts of the original aabb
For now, we will choose option 3.
Added class CGraphicsUtils to utils lib.
Added CGraphicsUtils::GetTransformedExtents().
Option 4: transform extents of residue hulls and then
iterate their min/max verts to get the chain extents
( but only at the point when residue hulls are using their own
transforms, at this point they do not ).
The loose aabb is working for CBassChain.
Created class CBrHull.
Added separate coloring of the 2 res hulls,
multiplexed hull index with res id in collision unit src id.
Single hull-hull collision detection is working.


Fixed bug in CCollisionEngine (not all units being removed,
CBassChain model ids were out of sync with res ids),
Added reporting of timing info to CVCollideEngine.
Timing info for total overlap of 2 trnas:
294 collision unit(s) in collision engine
1167 current collision(s)
--- Timing Info
Time (secs) Rate (colpairs/sec) Event
0.796885 1464.452587 EngineCollide
0.000206 5660329.512195 EngineReport1
0.000099 11800347.966102 EngineReport2
0.029327 39793.125857 CollisionDispatch


Added geometry code from CPolyModel to CBrHull, replaced
CPolyModel references in CBassChain with CBrHull refs.
CBrHull creation is working.
Finally started work on CBrHull::CalcCollisionForces().


Finished coding CBrHull::CalcCollisionForces(),
debugging interactions between 2 trnas.


Added display steric force data to CBrHull::CalcCollisionForces(),
found bug. 2 tRNA steric interactions appear to be working.
There is a bounding box bug for trna.A.U68
Added 'QJn' option to qhull to produce simplicial output, n = 1e-3.
(this fixed the bug).
Now we can load and quickhull trna and eftu without errors.
Ran sim on trna and eftu,
got NAN in CForceObject::m_AngVelocity, added _isnan() checks
to CForceObject::Timestep(), CalcForces().
Added bool return type to all Timestep() methods, changed
name to TimestepMove().
Fixed bug in CForceObject::TimestepMove() for setting
angular velocity (was dividing by 0 )


Debugging tRNA-eftu interactions, unstable.
Debugging with 2nts show that the CBassChain center-of-mass is
wrong, bbvertex point is being used.
Moved force object commands out of ff cmd group into
new fo cmd group (force object cmds).
Added cmd group 'fo show'
Added display of forceobject properties 'velocity', 'angvelocity'
Moved 'set velocity', 'set mass' to fo cmd group.
Added CRbCommandUtil::ReportMass().
Found bug where CBassChain mass is changed, but parent
CPdbObject still reports its old mass.
We could add CForceObject::MassChanged(), but instead
we will just call CForceObject::PositionChanged() on SetMass().
This problem must be reclassified as 'By Design'. We cannot
directly set the mass of a CPdbObject because its mass is
determined by its children. Consequently, the iGOSetMass
option is now bypassed in CPdbObject::SetOption().


Added 'pos' cmd group (position command)
Fixed bug in CBrHull::CalcCollisionForces() (torque on obj1 was wrong)
cet2nt.rbs interactions appear stable now.


Added 'tog' option to command-processing
Added reporting of fo 'enMove', 'enTrans', 'enRot' state
Considering adding bitflags to CBassChain::BrAtom,
created perf test to compare stl <bitset> to old-style integer bit ops.
Results, debug build:
time_secs rate_ops description
2.754306139895 3.6e+006 bitset test(), 1e+007 op(s)
1.195161668818 8.4e+006 integer bit test, 1e+007 op(s)
Results, release build:
time_secs rate_ops description
3.908339898423 2.6e+007 bitset test(), 1e+008 op(s)
5.057294792068 2.0e+007 integer bit test, 1e+008 op(s)
!!! <bitset> is actually faster in the Release build!!!
Before adding bitset to BrAtom, did load timing for 1ffk.pdb:
Debug build:
Release build (2nd load):
66885 line(s) read, 29 chain(s), 6484 residue(s), 64268 atom(s), 77936 bond(s) created from file '1ffk.pdb'
file processing time = 2.8 sec ( 22952.9 atoms/sec )


Added bitset flags, load time remains at 2.8 sec
Added CTimestepContext param to CollisionEngine call tree
Added steric potential energy calc to CBrHull::CalcCollisionForces()
Renamed CTimestepContext::RecordStat() to RecordIStat() (interaction statistic
as opposed to others like 'energy' statistic, etc. TODO: rename CTsStat
class to CTsIStat.
Added recording of min atom intersect distance to CTimestepContext.
Added tri-state coloring of hulls (hull collision, atom bbox intersection,
and atom collision, tested with eftu-trna, works well. In addition,
global backbone rendering combined with wireframe hull and spacefill atoms
for contacting hulls looks great!
Added CBassChain residue flag 'd_iBrf_DrawSawhoc'


Added command 'draw sawhoc'
Added display of static energy under 'sho stats ff'
Energy calcs for eftu-trna are working.


Gave brief demo of eftu-trna to Steve Lodmell.
Fixed bugs in sphere-select.
Added cmd group 'set sel sphere'
It's working.
TODO: add 'set sel sphere size',
change CBassChain::GetResiduesInSphere() to use residue
extents instead of just backbone vertex.


Created Elm plugin (energy landscape mapper).


Added display of mapped orientations. For tRNA, there are
over 7000 orientations with an orientation separation param
of 2 angstroms (using the low-res mapping at the poles).
Adding sphere-selection for residue hulls.
Renamed CGraphicsUtils class to CGeomUtils.
Doing 1fka alignment:
Added cmd group 'orient',
Added cmd 'orient sel <obj1> <obj2> <axis>'
Added cmd 'orient find'
Orient is working, but residue-level precision
isn't quite good enough (for trna), need atom-level precision.
For 1fka:
x axis: 1fka.A.A751 1fka.A.A427 (dists=1.50364,2.05254)
y axis: 1fka.A.C24 1fka.A.G194 (dists=1.11858,1.67597)
z axis: 1fka.B.UNK550 1fka.E.GLY85 (dists=1.31737,1.52621)
It works! (if we reverse names for x and y)


Working with 1fka and if2.
if2 is 2 chains, need to add inter-chain spring bond.
Renamed CForceObject::GetVertex() to GetSpringBondVertex().
Added CBassChain::GetSpringBondVertex() override method to support
spring bonds for CBassChain objects.
Looks like we need to add atom selection to CBassChain at this point.
This will be a lot of work. For now, we can dock the 2
chains of if2 separately.
Did test docking of if2 chain a with 1fka, got steric energy of -63.
Added cmd group 'ff steric',
Added cmd 'ff steric repulseExp [N]'
Added cmd 'ff steric attractExp [N]'


After a visit to Sequence La-La Land, we have the aligned
sequences for 1fka.A and 1gix.A:
1fka.A.427 -> 1gix.A.A431


Created sequence map tools 'genSmap', 'smap'.
1fka.A.A751 -> 1gix.A.A767
1fka.A.G194 -> 1gix.G199
1fka.A.C24 -> 1gix.C23
Alignment of 1gix is now working.


Manually aligned 1fka and 1gix.
There is a bug in CBrHull extents,
its UpdateExtents() is not being called everytime
that the parent CBassChain can change its extents.
A good fix would involve elimination of storage CBrHull
extents in member data vars m_vMinExtent and m_vMaxExtent
and instead calculate it on the fly inside of
CBrHull::GetExtents() using the transform and m_vLocalMinExtent
and m_vLocalMaxExtent. This shouldn't incur a runtime
overhead at this time as the only places currently calling
CBrHull::GetExtents() are CBrHull::IntersectSphere() and
CBassChain::GetResidueExtents(), which currently are only called
in ui-command events.
Note: it is also called indirectly from CBrHull::Rotate(), which
will happen when independently-moving hulls are implemented.
(unless cached hull atom c-o-m bypasses it).


Fixed 'printing-of-selected-residues' bug in CBassChain.
Added reading of 'HETATM' records to CBassFile.
Added CBase::BaseType iNonStandard to support wyebutosine.
Added handling of 'TER' record in pdb file to terminate
current CBassChain (needed for eftu.pdb, after residue 405)
Fixed bugs in trna and eftu loading,
Did quick docking of 1gix.B with 1fka.A


Created plgDock (docking classes and ops)


Created cmd 'dock rms'.
Created class CSeqUtils.
Created class CSequenceMap.
Tried to add interface to clustalw code for seq alignment,
it's too messy.
Downloaded a simple alignment code using needleman-wunsch algorithm.


Working with thiostrepton pdb again.
Added flag for non-standard residue name to BassResidue, storage of
non-standard residue names in separate table in CBassChain.
Display of non-standard residue names is working for thiosmod.pdb
We need to process CONECT records for CBassChain atoms, and so, we
must add PdbAtomNum to BassAtom struct (4 more bytes per atom!).
Adding CONECT support to CBassChain.
Added iPdbAtomNum to CBassChain::BrAtom struct.
Changed BrAtom.iPdbAtomId to iPdbAtomType,
Chainged CPdbRecord::GetElementFromAtomId() to CPdbRecord::GetElementFromAtomType()
(PdbAtomId is a MAJOR misnomer!!)


Got rid of BlockDef stuff in CBassResidueCreator (hull replacement is working fine).
Added parsing of atom serial.
Loading of 1tran and 1fka is working.


Added resizing of graphics window on console window resize,
it's working.
CONECT bonds for CBassChain are working.
Wrote script to load 70S in standard view (load70.rbs)
Added command 'sel ext <D> <U>' (extend selection along chain)
Aligned the 2 50S subunits.


Created final alignment doc 'fullalign.rbd'


if2 not quite bonded correctly, need to add atom bonding table.
Changed Element.cpp to class CElement.
Replaced GetMaxBondLength( el ) with GetMaxBondLength( elI, elJ ).
if2 is now bonding more correctly.


Added writing/reading of CBassChain allres backbone and color to rbd file.
Added writing/reading of camera view to CRbDoc file.
Added selection box.


Did namespace changes for wkGLutils functions.
Selection box is almost working.


Added 'space-selection' enabling flag to CBassChain residues.
Changed CBassChain residue extent calcs from bbvert to atom extents
because non-hull extents were too small. Now they're too big.
Added 'tight-bbox' extents and 'loose' extents methods to CBassChain
and CBrHull.
Selection box is working!


Added auto-creation of hulls on adding residues to collision engine.
Added progress status for adding collision units to engine.
Fixed bug in CBassChain residue copy and paste.
Did BLAST search and alignment of stephano's if2,
added missing leucine between the chains.
Checked out the protein motions database (morph server), it's very cool.


Created class CChainSeg.
Found bug in collision engine: on removing an object from the
engine, the indexing in the CCollisionEngine collision unit list
becomes incorrect.
Documented collision engine operation and data at top of
Changed CCollisionEngine m_pEngineCuList to <list>.
EiCu map bug is fixed.
Created pdb object 'if2new', which removes the final 4 residues
of the first chain because of steric collision with second chain.
There is a bug with selection box (position not tracking selection center).
The bug was fixed.
Did some limited md work on if2new and 1ffk.0.


Added cmd 'dock anchor', CAnchorCon.
Anchor controller is working.


Introducing chain segments.


Made CGraphicsObject::GetExtents() virtual,
CBassChain now computes them on demand only.


Moved residue transform methods from CBassChain to CChainSeg (many changes).
CBassChain loading, extents, and hulls appear to be working.
However, there are forcefield/collision engine problems.
Moved sbrs into single bsc file.


The forcefield problem has been found: the CBassChain
was still doing force calcs and timestep movement instead
of the new CChainSeg components.
The fix brings up a new problem: the normal fix is to
make the CChainSeg components force-object children of the
CBassChain and to set the approprate flags (timestep children=true,
transfer-force-to-parent=false). However, since we want the
chain segments to be very dynamic (create lots of them for a local
simulation, then destroy and free memory for a different local sim),
the overhead of having them be added and removed from the traditional
CGraphicsObject/CForceObject hierarchies is probably quite large.
Instead, it may be easier for CBassChain to override the CForceObject
CalcForces() and TimestepMovement() methods to hand-off processing to
the CChainSeg components there. Since the introduction of the collision
engine, the hierarchical object interaction code in CForceObject::CalcForces()
is essentially obsolete.
Added overrides CBassChain::CalcForces() and CBassChain::TimestepMove().
We now have a moving CCSegChain (in eftu.rbs). However, due to invalid mass,
it is unstable.
Added CBassChain::SetSegmentMass().
Now, we need the capability for selection of individual segments of
a CBassChain. In using a hierarchical specification, there may be
conflicts with residue selection. One possible help is that we can
obtain a direct CForceObject reference to a chain segment.
Introducing naming convention '$1', '$2' as CChainSeg names.
Moved CForceObject::SetMass() from protected to public.
Added reporting of chain segment masses to 'fo mass' report.


Added command 'fo com' (center-of-mass report)
CForceObject is too heavy with member data, but there is no time
to fix it now, so CChainSeg must be moved to derive from a
new, 'light-weight' force object class.
Created class CFrcObj.
Unlike CForceObject, it is very abstract.


Testing eftu dynamics with new CFrcObject code, still not quite right.
Creating test file tstForce001.pdb
Fixed bug in CBassResidueCreator where final residue preceding
TER record wasn't being added.
Fo Enables for CChainSeg objects is working.
Ran sim on tstForce001, the 3 residue chain is showing numerical instability
in unbalanced rotation.


After several bug fixes, dynamics of test file work as expected.
That simple test file is extremely helpful in rapid identification of bugs.
Ran eftu.rbs test again, it's now stable.


Added command 'dev segchain'.


Chain segmentation is working, but we also need intersegment hull
activation in the collision engine.


Added spring bonds to CBrHull
Added spring bond creation in CChainSeg::CreateSpringBondToNextSegment()
Spring bonds are working!


Fixing rendering of backbone, inter-residue covalent bonds and pdb conect bonds.
(old code assumed common transform between residues).
Added methods:
Rendering for moving chain segments is fixed.


CBassChain::GetSegmentFromResIdx() introduces a major
performance hit for chains with a segment for every
residue because currently, it iterates all segments
to calculate the residue's owner segment. This impacts
methods such as IsIntraSegment( res1, res2 ).
Added iSegNum to BassResidue struct.
This improves the framerate hit.


Added cmd 'dev stericReport'
It's working.


The steric report shows (among other things) that we need to
handle the closer contact between backbone-bonded atoms
by using a value different from the standard vdw eq distance.
Fixed a bug in center-of-mass calcs for residues.
Added CForceObject::GetSelectedMass().
Fixed bug in extents calc.


Bug in intersegment bond drawing.
Moved 'ParseColor' cmd processing code into new cmd processing.
Added cmd 'color rbseg' (color rainbow segments)
Added description to new cmd defs.
color cmds are working.


Fixed bug in intersegment graphics,
added methods CBassChain::DrawNearSegLink(), CBassChain::DrawFarSegLink().
Added range and list selection by name in CBassChain,
added method GetResidueIndicesFromNameSpec().
Wrote script to highlight the 4 domains in if2.pdb, it works.
Concatenated separate portions of original if2.pdb file into if2-003.pdb


Wrote script load_70gi.rbs
The old rbd files are not loading correctly.
Added status and warning output to CBassResidueCreator,
moved ASSERTs to warnings so that they don't interrupt the status loading dots.
Fixed bug in 'pos sel' command where extents were being used instead of c-o-m
Added 'exclude file' option to 'orient find' cmd (to allow comparable alignment
between 1giy.A and 1ffk.0).
After all that work, trying to align 1ffk using aligned residues of 1giy doesn't work.
Did manual alignment of 1ffk.
There is a bug in the draw code drawing backbone segments in 1ffk (release version only!)
Fixed bug in CONECT record parsing in CBassResidueCreator.
Fixed bug in backbone draw code (also showed up in debug version, was in CBassChain::DrawSolidRes()).
We still don't have a good orientation scheme.


Added seg transform to CONECT bond draw code in CBassChain::DrawPdbConectBonds().
It works.
Added filtering to residue removal from engine (only those in engine are now in param list)
Added util method CBassChain::FilterResidueList().
Added cmd group 'run', moved run code to it.
Run cmd group is working.
TODO: cleanup pop-up menu, cleanup help.txt file, add 3rd-party lib section to html doc.


Created plug-in 'plgBrot' (backbone rotation).


Created classes CAtm, CPdbAtom
Created classes CBrotObj, CBrotSegment.


Created class CExtent.
Created class CAtmUtil.
Created class CGrBrot.


Created CAtmUtil::CreateCovalentBonds().
Created class CTxAtomGroup.
Created lib rbGrChem.lib, class CGrAtmUtil.
Added method CGrAtmUtils::DrawSpacefillAtoms().
It works.


Added method CGrAtmUtils::DrawCovalentBonds().
Renamed CGrBrot to CGrBrotRes, CBrotObj to CBrotRes.
Added classes CBrotChain, CGrBrotChain.
Added class CExtentObj to rbUtil.lib.
Created brilliant new concept! Added 'uninitialized' flag
to CExtent class.


Adding inter-segment bond drawing.
Added class CTxAtom.


Added ' bVisibleOnly' flag to CBassChain::GetResiduesInBox()
(for cmd 'set sel box')
added cmd 'set sel box visonly [on|off|tog]'
It works.
Todo: add 'invert selection' operating on CBassChain residues.


Added cmd 'pos matrix [m1 ... m16]'
It works. We can now load 1ffk in alignment with 1giy (script 'load_1ffk.rbs').
Added saving of Pdb ATOM records for CBassChain atoms.
It's working except for problem with pdb atom type (occaisionally unknown).
We may need to explicity save Atom name from original pdb record (5 byte overhead
for every atom).
Design question: most of the uses of BrAtom::PdbAtomType are to retrieve
the Element type of the atom. Should we just store Element explicity as well?
(more overhead, faster execution time).
Oh, the evils of data exposure!!! Versus the benefits of indexing tricks
using arrays of structs.
Also, when exporting if2.pdb and 1ffk.pdb into a combined output pdb file,
we have the problem of duplicate chain id 'A'.
Need to add query to rename duplicate chain id.
Added cmd 'dev setChainId [c]'
It's working.
There's a WEIRD bug in the release version when doing
PdbFileParam fp = { &out, &iNextAtomSerial, &bRet };
pRootObject->SetOption( iGOWriteAtomsToPdbFile, (void*) &fp, true );
and then,
PdbFileParam *pfp= reinterpret_cast<PdbFileParam*>( pParam );
PdbFileParam &fp = *pfp;
*fp.pbRet &= WriteAtomsToPdbFile( *fp.pOut, *fp.piNextAtomSerial );
It looks like mixing pointers and references isn't working!!??
Actually, on further testing, it turns out that the statement
*fp.pbRet &= WriteAtomsToPdbFile( *fp.pOut, *fp.piNextAtomSerial );
is the culprit. And it has nothing to do with & references, as
(*pfp->pbRet) &= bLRet;
gives the same problem. It would appear that the &= is the cause.
The problem was fixed by using an if/else instead.
Generated first pic for the marzi paper.


For easier Molscript preprocessing, it would be nice to add comments
to the exported pdb file documenting the chains.


Rasmol is showing invalid atom type for rb exported pdb file because
we are writing atom names starting in column 13, according to the PDB spec,
but it appears that only names beginning with a digit start there.
This is fixed.
Added chain remarks to exported pdb files.
It's working.


Added default user-descrip to CBassChain.


Added 'TranslateSelected()', 'RotateSelected()' methods to CGraphicsObject hierarchy
to allow transform of a subset of chainsegs in a CBassChain.
Added CBassChain segment selection to selection command
( 'sel if2.A.$1-$3' ), it works.
Created seg_if2.rbs script, segmented if2 in mm3 model,
moved individual segments around trying to satisfy link and steric
constraints, exported model to 'mm3.pdb'.
There is a problem which recurred in creating the mm3.rbs script.
An additional pdb object was added (1fka.pdb) and the manual chain
chain renaming was left out, resulting in duplicate chain ids in
the exported mm3.pdb file.
Also, the file results in 6 digit atom serials, and PDB spec 2.1
only appears to specify a 5 digit serial (though the next column
appears unused?). Searching on the web shows a reference to an
XPLOR extension to 6 digits. We should adopt likewise.
Added reporting of CBassChain segment transforms to cmd 'pos matrix'
to allow recording and script reproduction of repositioned chain segments.
It works.


We need to add error-reporting to indirect selection.
Added error reporting to object selection when doing ins selection (internal-name-selection)
Fixed name selection bug.
Looking at 2fmt.pdb, there are a couple of bugs in loading.
Fixed bug in CBassChain::GetResidueIndexFromName() (wasn't checking for non-standard residue name)
The other bug was a little more problematic. The non-standard residue
formyl-methionine had a first atom as N and was assumed to be an amino acid
residue, consequently, a covalent bond was created between it and the previous
residue, which was incorrect.
The fix involved checking allowed bond distances during
inter-residue bond creation in CBassChain::CreateChainCovalentBonds().
TODO: add bond count check as well.
BUGALERT: for such a residue, CChainSeg::CreateSpringBondToNextSegment() will still fail.
There is a ASSERT in copying and pasting chain D from 2fmt.pdb.
Removed CBassChain CGrTransform data, its all handle by component segments now.
Question: are CBassChain c-o-m and extent updates still needed now that segments
calculate them only on demand? (ie: is PositionChanged() strategy still needed?).
The ASSERT is fixed.


Added auto-renaming of CBassChain name when loading chains with duplicate chain ids in the same file.
It works.


Working on docking if2 with 70S, we finally have a decent dock for marzi results.


Reorganized chem, chemobj libs (all CForceObject dependencies now in chemobj).
Abstracted CTimestepData into CTimestepContext, created derived class CRbTimestepContext.
About to create abstract chem class CBnd (for bonds)


CTimestepContext changes are finally done.
We have removed all rbMain dependencies from chemobj lib
with the exception of CBasePairCon.cpp.
Currently, this is still stuck between the two because it
needs to be referenced by both CBase in chemobj lib and
it also references CRbTimestepContext, which holds specific
params for base-pairing control.
Debug version builds and runs.
Working on 'brot create'


Transfer to ribomachine3.


Put a lot of work into the CDescribe class in rbUtil.lib to allow
for better self-documentation and meta-data in the framework, but
it's incompatible with the current 'sel <objSpec>' command and
CSelection/CGraphicsObject interaction because there is no explicit
storage of the INS (internal name spec) during selection.
This INS is needed for traversing the CDescribe component hierarchy.


Added command 'dev xgr <outfile>' (export ribbon graphics)
Added CBassChainUtil::ExportRibbonGraphics()
Added class CVrmlUtil.


Added CVrmlUtil::OutputVrmlNurbRibbon().


Only the problem now is that vrml2pov has all kinds of
problems! Arrgh!
Added direct export to PovRay, it works.


Added ribbon coloring, rung fix to ribbon graphics export.


Added class CColengQuery to support collision engine reporting, but
no time to implement it at this time.


Added cmd 'ff coleng deactivateAll' (deactivates all current collision pairs in
Found bug in collision engine when removing \proj\um\stefano\8.pdb tRNA from
engine. Caused by out-of-order C2* atom in pdb file (follows ring atoms).
Also results in much larger ring hull.
Fixed by adding CBassResidueCreator.cpp: ResortAtoms() function.
It works.
Moved wklib CopyVector methods into wkVector namespace, lots of housekeeping changes.
Still getting some spurious errors on add/remove units from collision engine
(uninitialized vars?)


Fixed coleng bug - using res count instead of res index num in SetResidueFlag() call.
The accidental use of a count index for a residue index is a potential source
for many bugs in CBassChain and related classes. Replacement of indexed accessed
by pointer to CBassChain::BassResidue was done where possible.
Finally fixed release version sawhoc bug!! Uninitialized variable!!!


Rebuilt db and rel versions with warn level 4, compiler is not warning
uninit params passed by reference such as:
int i;
func( &i ); // no warning generated for this statement
Fixed drawhull bug in sawhoc mode in CBassChain::DrawWireRes().


Added VCollide::ReportEx() to VCollide library to report disabled pair count,
Added reporting of total active/inactive collision pairs to CCollisionEngine.
Moved selection code into new command system.
Added caller id prompt to input commands.
Added command 'sel srss' (selected-residue-sphere-selection)
It works.
Still can't dock if2 on 30S (S12 gets in the way)
04/06/2002/ WK Adding cmd 'rot selResDown/Up'
(rotate residues downstream from selected residue)
It works.


Added re-segmentation (involving application of transforms
to atom verts and hull verts, allowing for segment merges)
prior to residue rotation.
Added command 'key map <key> [commandString]' to allow
convenient and rapid residue rotation.


Added key-mapping methods to CRbApp.
It works (but for keypad+, only ALT is working, CONTROL input not received from glut!!)
Added -noecho option to key mappings.
We can now rotate one chain segment relative to another while the
forcefield is running to observe changing steric energy.
We need something better than 'draw sawhoc' mode to show steric
clashes ('draw topcol <N>' ?) (-sawhoc, -saoc, rainbow coloring in order of energy? )


Added command 'draw topsterics <E> [on|off|tog]' (draw atoms with steric energy greater than <E>)
energy in spacefill mode, color according to segment and energy).
(should we do 'top 10 atoms in chain greater than threshold <M>?
this would obviate need for global comparisons).
Adding recording of steric interaction data, created classes
Needed to remove const qualifier from CRbTimestepContext::InputData()
to handle transfer of CTsBassChainAtomData pointers in
CRbTimestepContext::InputStericInteractionData(), is there a better
way to do this that can preserve the const character of ts input data?


Moved 'ff record' into 'record' subcommand group.
Added command 'ff record sid'
There is a bug selecting objects whose name contains a '-' char
(ex: 'stef8-s12', name parsed as a range spec).
Top Steric Colliding Atom Highlighting is working.


Finally doing 30S docking on the marzi project, but
for reconforming, we absolutely need additional
backbone rotation capability (currently, 'rot selResDown'
only rotates the inter-residue link).


Created, a tool to scan the makefiles and
generate html documentation describing all classes.
Also integrated with Doxygen html docs.
It's working.


Added library 'rbFastPdb.lib', abstract class CPdbObj,
implementation class CFastPdbObj.
Called from srs test app, release version reading 1ffk.pdb
with no bond creation gives rate of 23896.3 atoms/sec (2.69 sec load time)
Surprisingly, this is comparable to (CBassFile, CBassResidueCreator, CBassChain)
time above (01/16/2002). Is this because of a performance hit in
CFastPdbObj due to use of std::vector<> instead of array realloc?


Incorportated generic, fastpdb test projects into rb inc,src and mak project sub-trees.
Created rb\src\test dir, renamed orig test dir to 'protoTest'.
Created rb\mk\test\generic\mk\rbTest.lib.
Created abstract class CTestCase.
Created test driver project rb\src\test\fastpdb to test fastpdb library,
Created test case 'CBasicReadTest'.
It works.


Renamed tst subdir 'generic' to 'tstFrameWk', added 'tst' prefix
to 'fastpdb' tst project, added calling of test programs to their makefiles,
inserted 'tstFrameWk' and 'tstFastPdb' projects into rb project workspace.


Added CPdbRecord::GetElementFromAtomName().
Added inner class CAtm::AtmListIterator.
Added CLargeReadTest() to tstFastPdb app, reads 1ffk.pdb file.
Added CFastPdbObj::GetAtomIterator().
Added checking for invalid element in CFastPdbObj testing.
It works.
Added EmptyPdbFile test case, found bug.
Added logging option for unit testing.
Split out runtime wrappers from CSystemUtils/CMsWinUtils to CRuntimeUtils/CMsRuntimeUtils in util lib.
Added intra-res covalent bond creation to CFastPdbObj.


About to create CTorAtom class (torsion atom, Zhang atomgroup local frames
representation for rotations).


Renamed CTorAtom to CTorNode.
Renamed CTorBuilder to CTorGraph.


Finished CTorGraph::CombineNodes().
Created unit test project tstTorNode.
Found first bug in CTorNode::IsAncestor().
Unit tests work.
Finished class CSimpleNodeTest in TorNode unit test.


Added operator<< to CTorNode.
Created class CUnitTestDriver in test framewk lib.


Created class CUnitTestDriver_Cla (command-line-app variant),
Moved code from CUnitTest_CTorNode to base test driver classes.


Moved CUnitTest_CFastPdbObj into new test driver framework.
Completed CTorGraph::CreateGraph() by splitting it into
2 parts: single-atom node creation, then cycle removal.


Added operator<< for CTorGraph.
Added inner class CTorGraph::GraphIterator.
Added test driver CUnitTest_CTorGraph,
Added test case CSimpleGraphTest.
It works.
Rebuilt all for rb debug just before Santa Fe trip,
it runs.


Created RingGraph test case for CTorGraph.


Fixed CTorGraph::CombineNodes(), it now works for
simple ring graph.


Created plugin plgTor (use of fast pdb, tor classes, new graphics classes).
Added command 'tor open', added class CTorObj,
Loading of fastpdb file, torsion graph creation.
It's working.


Created CGrTorGraph (graphical tor graph).
Moved some global methods in CGraphicsObject.cpp to class static methods.
Added CGrAtmUtils::DrawHalfCovalentBond().
Rendering of TorGraph is working.


Replaced manual class naming code with typeid(), type_info.
Getting rid of the old selection level stuff in SelectionParam.


Added selection of nodes in CGrTorGraph.
Added command 'tor rot'.


Renamed CTorNode inner class AtomPos to independent class CTorAtom.
(wraps param atom, adds updated pos vector).
Fixed bug in testFastPdb CBasicReadTest (24 bonds in a.pdb instead of 48).
Added CTorGraph::UpdatePositions(), replaced CTorNode::OutputPos() with
CTorNode::UpdatePos(), which uses CTorAtom.
Finally got torsion node rotation implemented, but it's not rotating
a.pdb molecule correctly ( atoms are twisting weirdly).


Added unit test case CRotateGraphTest to torsion lib testing.
CRotateGraphTest passes (rotation of 2nd node in graph with 3 nodes).


Tested rotation on a glycine residue (no rings), same problem.
Added friend operator<< to CAtm,
added abstract method CAtm::TextOut(),
CTorAtom::TextOut(), CPdbAtom::TextOut(), CFpoAtom::TextOut().
Looks like rotation problem may be due to wrong rotation center.
Looking at text output, root node origin is 0, child node origins are
same as atom pos.
Solution? : make root origin same as root atom pos, child origins
relative to parent atom pos?


Found bug: in CGrTorGraph::DrawNode(), GetBondPartners( pAtom ) is
returning a ref to unmoved atom instead of wrapping CTorAtom.
Fix: created list of CTorAtom bonds in CGrTorGraph,
added method CTorGraph::FindTorAtom( pUnmovedAtom ),
added method CTorNode::GetTorAtom( pUnmovedAtom ).
Atom bonding is now drawn correctly, but rotation is still not right
(vector about which rotation occurs appears incorrect).


(rb log, rb.cpp)
Built on Beryllium, fixed child delete bug in CTorPlugin.
Created plgTor unit test case CRotate2Node_GraphTest.
This test confirms that nodes continue to be rotated about their
original rot vectors and origin points subsequent to an initial
rotation which places them in a different location.
The node rotation must be redefined so that the node rotates
about its new origin and rot vector, relative to its parent node.
No no no! Just had to swap multiply order to 'CGrTransform3f txFrame = m_localFrame * parentFrame;'
in CTorNode::UpdatePos() and it totally works!! Yahoo!!!


(rb log, rb.cpp)
Added command 'tor rot rand <deg>', it's working.
Made IsSelectionColoringEnabled() a static class method in CGraphicsObject
(was previously a flag in each graphics obj).
Fixed bug in CForceObject::GetSelectedCenterOfMass() where CTorObj
extents were not being obtained because of explicit call to CGraphicsObject::GetCenter(),
replaced with call to GetExtents() and GetMidpoint.
Updated code following movement of wkVector functions GetMidpoint*() into wkVector namespace.
Did random torsion on an adenine nucleotide for about 800K timesteps.


(rb log, rb.cpp)
Found bug loading 3nt.pdb in fast pdb class - problem with inter-residue bonds.
Created InterResReadTest test case for FastPdb lib.
Added friend operator<< for CBnd.
Fixed 1st bond bug in CFastPdbObj (off-by-one err),
Found 2nd bond bug: inter-res bond creation not implemented.


(rb log, rb.cpp)
Added CFastPdbObj::CreateInterResCovalentBonds().
It works. InterResReadTest works, 'tor' loading of 3nt.pdb
and random rotation works.


(rb log, rb.cpp)
Created abstract class CEncon, (energy calculation of a configuration of atoms)
derived class CNsaEncon (n-squared atom energy calc).
Finished initial code for CNsaEncon.
Added tstEncon module.


(rb log, rb.cpp)
Added CNaRes_NsaEnconTest test case to calc energy for an adenine residue.
Energy is too high - +1800.
Added detailed pair energy reporting to CNsaEncon.
CBnd::BondList not being copied properly.
Did full rebuild.
Actually, bond ptrs were being deleted. Caller with
a bond list param must maintain valid bond ptrs until
call return for CBnd::BondList data.
New calculated energy for a.pdb is 37.4.
CNsaEncon tests are passing.
Vdw radii between a small subset of atoms in a.pdb
remain to contribute to the high intra-residue steric energy.
We need to integrate energy calcs into the existing framework.
Adding html documentation to Fo command.
Added command 'fo energy'.
Loaded 2 nucleotides in forcefield, there is a bug where they
leave the forcefield volume instead of rebounding.
Found the problem: this is because we never implemented volume
bounce in CFrcObj::TimestepMove().
This was because we couldn't get a reference to the FFVolume from
CFrcObj. Investigation of CForceObject code shows that the only place
the reference to the FFVolume is needed is in this bounce code.
This information can be obtained instead from the timestep context param.


(rb log, rb.cpp)
Removed m_pFFVolume from CForceObject, added to CRbTimestepContext.
But this doesn't work because CFFVolume is a container of CForceObject
in addition to defining a ff volume boundary.
To fix this, we separate the boundary definition into a component class
Housecleaned lots of changes due to moving AddVector*, SubtractVector* into
wkVector namespace in wklib.
Added override method CBassChain::SetVelocity() to set velocity of
component chain segs.
We can bounce 2 nucleotides in a box correctly again.
sawhoc draw mode still not right though for hull solid polys.
Added chain seg velocity reporting to CRbCommandUtil::ReportVelocity().
After running forcefield for interaction between the 2 nucleotides, it is
apparent that the 'velocity' dynamics isn't going to give good interactions
using a constant timestep because any velocity and timestep combo which gives
visible movement (to the user) also results in such a large discrete timestep
that excess vdw repulsion will almost always occur to separate the approaching nucleotides
because of too close of an approach.
Perhaps a auto-variable timestep could be introduced which allows for a long-term
scale for approaching objects which then automatically slows down as needed during
close approach. However, for large models with many interacting pieces, this
would likely result in the forcefield remaining almost always in the 'small ts' mode.
Another option would be to scale the force params between individual pairs of interacting atoms.
Implementing command 'fo energy'.
Added CRbCommandUtil::CalcEnergy().
Added abstract class CMol (source of a set of CAtm objects and CBnd objects).
Changed CBnd::BondList to CBnd::BondPtrList,
Added CBnd::BondList to hold full bond data.


(rb log, rb.cpp)
Converted CNsaEncon() param from BondPtrList to BondList.
Adding CBassChain CMol overrides GetAtoms(), GetBonds(),
Created class CBasicAtom (most data-lightweight implementation to satisfy
abstract methods of CAtm).


(rb log, rb.cpp)
Added intra-seg inter-res bond creation to CBassChain::BuildMolData().
Added test case CMultiNaRes_NsaEncon to Encon testing.
Energy calculation for 2nt.pdb is -40.6769.


(rb log, rb.cpp)
Created CCmdLineApp class in FrameWork lib to support creation
of command-line tool 'enconReport'.
Tried to do 'fo encon' on trna.pdb, it's too slow for 1652 x 1652 atoms (2,729,104 pairs),
using CNsaEncon (n-squared atom energy config).
We need a more geometry-aware encon class.


(rb log, rb.cpp)
Debugging bond iterator bug in CFastPdbObj when reading
Created command-line tool 'fpt' (fast pdb tool).
Added multi-statement input to CCmdLineApp.
Adding Doxygen-style brief description to rb project header files
(up to CSeqUtils.h).


(rb log, rb.cpp)
Added text output of CFastPdb components:
CFastPdbObj::GetChainInfo( int iChain )
CFastPdbObj::GetResidueInfo( int iChain, int iRes )


(rb log, rb.cpp)
Fixed bug in CFastPdbObj in setting CFpoChain residue parent idx.
Beware of 'useful' default params, the 'bHetAtom = false' one
in CFpoAtom constructor caused a bug in CFastPdbObj::ProcessAtomRecord()
because the needed param was forgotten to be put there.
Found cause of bug in BondIterator in CFastPdbObj:
failed to iterate past residues with 0 bonds in
It's fixed.


(rb log, rb.cpp)


(rb log, rb.cpp)
Adding timing to enconReport tool.
Added util classes CTimeReporter, CTrEvent to rbUtil lib.
Time reporting is working.
Added progress indicator to CNsaEncon.
Tested 'minus-bond' strategy, in CNsaEncon.
it's MUCH faster, but it gives a different energy!
A quick look at CAtmUtil::CreateCovalentBonds() shows that
it may be creating multiple bonds between 2 atoms.


(rb log, rb.cpp)
Small difference in energy calc for a.pdb between default
and 'minus-bond' strategies in CNsaCalc may be due to
round-off error (37.4105 vs. 37.4107).
Added multi-bond reporting to chemtool fpt.
No multi-bonds found in 1tra.pdb, but energy is radically
different between the 2 strategies: (-22804.8, -22553.2),
this is not within the bounds of rounding error.
However, there are ~1.5M additions, and we may have
addition and subtraction of large numbers, so perhaps
this IS due to rounding error.
For a total difference of ~251, this works out to an average
error of 0.00016 per addition op.
Changed CEnergy scalar type to double.
That was it. Running 1tra.pdb through enconReport gives -22831
for both default and 'minus-bond' strategies now.
A second look at CAtmUtil::CreateCovalentBonds() shows that
each atom pair is only visited once, ruling out multi-bond creation.


(rb log, rb.cpp)


(rbq log, history.txt)
Created from old rbq project.


(rbq log, history.txt)
Added frameWk library.


(rbq log, history.txt)
Added status window, command processing.


(rbq log, history.txt)


(rbq log, history.txt)
Translate, zoom and rotate are working on the axis in
the graphics window!


(rb log, rb.cpp)
Moved html command help creation code from CRbCommandUtil to


(rbq log, history.txt)
Created about dialog.
Created CRbqHelp class.
Generation of html help for command ref is working.
Created CRbqDoc class.
Created CRbqMol class (abstract class, unit of data for CRbqDoc).
Created CRbqPdbMol class (concrete class, unit of data for CRbqDoc).


(rbq log, history.txt)
Added CMouseMode (for state info rotate/trans/zoom).
Added toolbar mouse nav buttons (rotate/trans/zoom),
they are working.


(rbq log, history.txt)
Added recursive menu creation to CRbqMenu.


(rb log, rb.cpp)
Created CGrPdbObj class (graphical display of pdb object) in grchem.lib.
Added GetAtom() method to CFastPdbObj, this is exposing data but seems
fairly necessary for practical implementation of CGrPdbObj drawing.
Added indexed bond drawing methods to CGrAtmUtils.
CGrPdbObj drawing is working in rbq project!
Loaded 1ffk.pdb and it is usable in debug mode, but seems
slower than CBassChain drawing in rb.
Need to add framerate for quantitative measurements.
One possible solution may be to inline certain CFastPdbObj methods???
Probably not, CBassChain::Draw() appears to make far more calls.
Do some timing using CTimeReporter.
Fixed framerate reporting (was linked to timestep, now linked to
graphics window draw).
Created class CFrameRate in rbUtil.lib
Added redraw for every idle cycle to get accurate framerate report.
It works, but we are getting major mouse flicker.
Comparison between CBassChain and CGrPdb for 1ffk.pdb, debug:
3.0 fps vs. 2.3 fps.
Release ver: 5.8 fps vs. 6.1 fps!!


(rbq log, history.txt)
Created CRbqDocListener class,
Added 'file new', 'file close', graphics bgcolor.


(rbq log, history.txt)
CGrPdbObj drawing is working.
Rotation of 1ffk seems shakier than in rb app.


(rb log, rb.cpp)
Created class CGLGraphicUtil in rbUtil.lib
Finally got it working after (re?) discovering that
lighting must be disabled for proper display of text color
using glutBitmapCharacter!!!
Created class CGoOrthoText in rbGraphics.lib.


(rbq log, history.txt)
Added CRbqOrthoText (manages ortho text info in graphics window).
It's working.
However, doc-independent graphics text info is defined
with doc-dependent info, should we define 2 separate
CRbqOrthoText managers? (CRbqDocOrthoText, CRbqAppOrthoText)?
Stuff like 'runstate' in doc, 'framerate' in app.


(rb log, rb.cpp)
Minor changes (adding SetDefaultName() to CGoOrthoText, CAxis, CAxisGroup),
Added child reporting in CGraphicsObject::DrawChildren().


(rbq log, history.txt)
Added CFrameRate counter to CRbqGraphicsWindow.
Qt updateGL() doesn't work like glut PostRedisplay(),
it causes an immediate draw every time.
We should be able to dispense with the whole 'Redraw()'
logic by just drawing a frame every tick in the main
event loop.
Removing CViewDrawer interface.
This works for a good framerate, but it gives the same
mouse-flicker problem as in rb.
Perhaps the solution is to implement our own 'redraw'
flag which is checked in the timerEvent method.
This has been done.
Strange bug: for some reason, the ortho text is not being
drawn in the first frame. Spent a couple of hours trying to
track down the cause, but didn't find it. Subsequent frame
draws work fine.
For now, doing work-around of issuing a 2nd redraw during
graphics window init. It works.
Added framecount ortho text.
Moved CGoOrthoText drawing outside of scene-graph, this
is currently the only exception for graphics object drawing
outside of the scene graph, though it could be argued that
ortho text is a separate category. It's necessary in order
to display poly count for its own frame, because that ortho
text must be set and drawn after the rest of the scene graph
has been drawn. Also, it's possibly better from the standpoint
that all ortho text could be drawn within a single ortho projection call,
instead of each one setting it, as is done now (performance diff should
be insignificant though, for such a small number of ops).
It works.
Added 'BoolOption' dispatch code to CRbqCmdProcessor to reduce
duplicate code for processing simple get/set commands.
It works.
Created CInputCmdDlg in qt ui editor.


(rbq log, history.txt)
Created CInputCmdDlg_Imp with cmd history.
It works.
Working on rotation center.
Fixed up help commands, hooked up html help.


(rb log, rb.cpp)
Added 'empty arg' to CCmdParser, 'variable string args' to CArgFormat.
Backup sync with grm012.gz, rbq007.gz.


(rbq log, history.txt)
Rotation center is working.
Positioned dlg at bottom of graphics window.
Added separator, checked, enabled params to CRbqMenu
backup sync with rb619.gz, grm012.gz.
Doing reconsideration of a CRbqOption class, and what
functions it would perform, as distinct from immediate
dispatch to the relevant component. Such an option class
could be a container for options which meet 2 criteria:
1. Getting/Setting the option does not require any immediate action.
2. Option involves more than one component.
The alternative is to always define some principal component
to be the 'owner' of the option.
An additional consideration is that the CRbqOption would be
a component of the main app (or main win) object, and could
have close coupling for updating option indicators in the menu,
toolbar, etc.
Another consideration is linkage to the CRbqDocument class for
saving and restoring options.
Another consideration is to maintain a strong boundary between
the gui update code and the gui-independent code.
For now, CRbqOption serve as a temp repository until the option is moved
to a more appropriate class.
There is also the question of what name to give for it:
'Option', 'Prefs', 'Settings', 'Config'. Option seems the most general,
because it can represent both App-centric settings and prefs as well as
Document-related config data.
Is 'Config' more general? No, because 'Config' connotes a set of component
options, whereas 'Option' can imply both the component settings and the set
of components.
Created class CRbqOption.


(rbq log, history.txt)
Created class CRbqSelection.
Adding 'view setCenter' command, we're still having problems
rotating stuff in the ole' jello bucket.
You've got a view matrix.
You've got a view, it looks down the -z axis from the orgin.
You do a 'rot 90 0 1 0' on the view matrix, this rotates the view
clockwise, looking down from the +y axis to the origin,
this view now looks down the +x axis from the origin, ie.,
it follows the left-hand-rule. This is because we rotated the world
90 degrees counter-clockwise, following the right-hand-rule.
You've go an object, it looks down the +z axis from the origin.
If you transform the object with the same matrix that the view has,
the object looks down the +x axis from the origin.
Again, the object has been rotated ccw 90 degrees, according to the
right-hand rule.
So we have some arbitrary point, transformed according to the view
matrix. We want to move the center of the view to this point.
Or, to think about it backwards, we want to move the world so that
is in the center of the view.
Now, starting with the view center and world center the same, we
translate the world so that some initial world point T, say (0, 0, 10),
coincides with the view center. From the view's frame, the world origin
is at (0,0,-10).
Then we then produce a rotation of the 'world', say (45, 0, 1, 0), with
rotation origin at world point (0,0,0).
Well, we have now rotated the world.
With the current code, at this point the view origin is in world coords
is reported as (-7.07, 0, 7.07). It looks to be correct as well, looking
at the representation of the world axes from the viewpoint.
Now, what if we wished for the view center to coincide once again with
the world origin. We cannot do a 'trans 7.07, 0, -7.07), because translation
occurs in the view frame, which is not parallel with the world frame.
From the view frame, we need to do a 'trans 0 0 -10' to make the origins coincident.
If we look at the tx component of the view matrix, we see that this is the value.
Indeed, however much we rotate the world, the tx component will contain the
translation vector needed to return the view center to it.
But what if we instead want to set the view center to some point other than the
origin? What translation vector is required?
One possibility is to temporarily rotate 'the world' so that its orientation
is aligned with the view frame, translate along the world vector, then rotate back.
This would require an inverse rotation with the rotation origin at the view center,
not the world center.
This works!!!


(rbq log, history.txt)
Backup on beryllium along with grm013.gz,


(rbq log, history.txt)
Added 'file open' dlg, it works.
Adding extents to CRbqSelection.
Added file mru list handling to CRbOption, CRbqMenu, CRbqCommand.
It works.


(rb log, rb.cpp)
Minor changes on beryllium to adjust for grmatrix changes.
Backup sync with rbq008.gz, grm013.gz.


(rbq log, history.txt)
Added centering of view on inserted pdb object.
Adding mouse select mode logic.
Prior to that, renaming current CMouseMode to CMouseMoveMode.
This creates 2 separate objects for mouse mode, but they are
distinct and have their own intricate behaviour, so better not
to mix them in a single class.


(rbq log, history.txt)
Added select menu and toolbar.
Added 'sel' command to cmd processor.
Created class CRbqObjSpec.
Created class CRbqObjCount.
Created class CRbqSelParam.
Renamed CRbqObjSpec to CRbqIndexRange.
Renamed CRbqObjCount to CRbqIndexPos.


(rb log, rb.cpp)
Fixes for move of MultiplyVector*AndMatrix* into wkVector namespace in wklib.
Fixes for move of RecordMin/MaxVector* into wkVector namespace in wklib.
Created utility header files 'OpenGLdecl.h', 'WindowsUndefs.h' to
deal with MS Windows defines.


(rb log, rb.cpp)
Created class CGrResidue in grchem lib.


(rb log, rb.cpp)
Backup sync with rbq009, wklib075.


(rbq log, history.txt)
Drawing with CGrResidue works.
Backup sync with rb621, wklib075.


(rbq log, history.txt)
Adding rbq ini file.
Saving and reading from ini file works.


(rb log, rb.cpp)
Added inter-res covalent bond drawing to CGrPdbObj in grchem lib.
Added class CRbqDrawStateParam to grchem lib.
Added CGrPdbObj::SetDrawState().


(rbq log, history.txt)
Added draw menu, toolbar.
Hooked up world, rot axes, ff volume display.
Added 'draw' cmd to CRbqCmdProcessor.
Added lighting.
Covalent and spacefill drawing are working.


(rb log, rb.cpp)
Covalent and spacefill drawing are working in CGrPdbObj.


(rb log, rb.cpp)
Adding backbone drawing to CGrPdbObj.
TODO: changed existing CPdbAtom class name to something like
'CPdbAtomCr' (concrete implementation), make it derive from
abstract interface CPdbAtm class.
Created abstract class CPdbAtm.
Made CFpoAtom derive from CPdbAtm.
Added class CGrResUtil to grchem lib, moved backbone draw code
from CResidue in chemobj lib to CGrResUtil.
Added method CFastPdbObj::GetResidueBackboneAtomIdx().
Fixes for move of MultiplyVector*, CrossProduct*, VectorMagnitude* into wkVector namespace in wklib.
Backbone drawing is almost working.


(rbq log, history.txt)
Backbone drawing is almost working.


(rb log, rb.cpp)
Added interface CProgress to rbUtil lib.
Added progress output to CFastPdbObj.
Did full release rebuild, get 4.8fps for 1ffk.pdb with covalent wireframe.
It's slower than test on 6/25/2002. ????
rb exe size is 1,458,176 bytes.


(rbq log, history.txt)
Added class CRbqProgress.
Progress dialog is working for 'file open'.
Did full release build, got 5.3 fps for 1ffk.pdb in covalent wireframe.
rbq.exe size is 561,152 bytes.


(rbq log, history.txt)
Backup sync with rb623, wklib076.


(rb log, rb.cpp)
Backup sync with wklib076, rbq011.


(rbq log, history.txt)
Mystery frame-rate drop is solved, it's back up to 6.1 fps today
because the laptop is plugged in. Last night, it was on battery,
and therefore must have been turning the clock rate down.
With CFpoAtom with element member var, framerate is now up to 8.1 fps.
However, inter-res bonds were not working.
After fixing inter-res bonds, framerate is 7.3 fps.
Residue backbone, covalent and spacefill are working.
Created class CSelectionController in framewk lib.
Mouse selection is working.
Except for small bug in CCmdLine in index range parsing.


(rb log, rb.cpp)
Lower frame rate was due to running on battery.
Added member var for element to CFpoAtom.
Added CFastPdbObj::IsNucleicResidue(), misc name renames.
Member element in CFpoAtom increases framerate by 2 fps for 1ffk,
it is now default.
Pushed CGraphicsContext class down to GoGraphicsContext (needs ortho text support),
Redefined minimal CGraphicsContext interface in rbUtil lib.


(rb log, rb.cpp)
Added low-sphere-res setting to CGrAtmUtils,
IsResidueSelected() to CGrPdbObj.
Backup sync with rbq012.


(rbq log, history.txt)
Added level selection.
Added CRbqCmdProcessor::GetIndexPosFromLevelSelect().
There is a problem with implementing default range
when just given the 'first pos' arg, because 2 different
intentions, 'no arg given' and 'final pos', are both
specified with the token '-1'.
The solution is is to not mess with with the index pos or
range classes, instead, default ranges should be detected
during parsing by noting missing args.
As for level selection, the method just needs to return
a range instead of a position.
Renamed to CRbqCmdProcessor::GetIndexSpecFromLevelSelect().


(rbq log, history.txt)
Added cmd 'draw ballstick'.
Added CRbqPdbMol::GetSelectedExtent(),
'mouse setRotCenter sel' cmd is working.
Backup sync with rb624.


(rbq log, history.txt)
'level down' selection is finally working.
Adding 'vol' cmds.
Added FloatOption processing to CRbqCmdProcessor.
Added VectorOption processing to CRbqCmdProcessor.
Added 'move selection' icon.
Renamed CSelectionController to CSelectObjectController,
Added class CTransformObjectController.
Added base class CTransformController,
CViewController and CTransformObjectController derive from it.
Actually, we need only a single 'CMouseTransformController'
with a dynamically-switchable target frame.
However, the only problem with that is that view and object
transform are inverses of each other.
Instead of deriving from CTransformController,
CViewController and CTransformObjectController could
have the CTransformController as a component.
Yes, this last option seems the best.
Created class CTxcListener.
Renamed CSelectObjectController back to CSelectionController.
Renamed CViewController to CViewMover.
Renamed CTransformObjectController to CObjectMover.
CViewMover and CObjectMover do not have CTransformController
as a component, they are just both listeners to a single
single CTransformController which is a component of the
View control still works.
Added cmd 'trans', object trans with mouse in view frame is working.
Added cmd 'rot', object rot with mouse in view frame is not quite working,
it wanders from the selection center.


(rb log, rb.cpp)
Added residue selection counting to CGrPdbObj.


(rbq log, history.txt)
Backup with rb626.gz


(rbq log, history.txt)
Changed rotation to always occur about view center, problem solved.
Toggling between view navigation and object movement with
Ctrl, Shift and Space keys works well in conjunction with
'r' hotkey which is need to reset rotation center to center of
selection just before rotating selection after it has undergone
Added 'edit insFile' command.
It works.
We still have an extents problem in a doc with 1tra and 1fka.
Added down hotkeys 's' and 'c' (enable selection, enable selection coloring).
Renamed CRbqSelection to CGrSelection.
Added CRbqDoc::ShowSelectedExtents().
Extent drawing is working.
It reveals the extent problem above, one corner of original
molecule extent remains constant during translation and rotation of the object.
Is it some hidden, unmoved atom?
It's in the 33rd residue of the 2nd chain of 1tra.pdb
Created ui widget CPdbTreeWid.
Created class CPdbTreeWid_Imp.


(rb log, rb.cpp)
Backup with rbq014.gz.


(rbq log, history.txt)
Added Window menu.
While trying to implement combined rotation in CTransformController::MouseEvent(),
we ran into a weird bug where -x vector was not producing rotation opposite
to that of +x vector. In tracking it down, found major bug in
CGrMatrix3f code : optimized rotation matrix init for x, y and z vectors
is in opposite sense to matrix init for arbitrary vector!!
Fixed it and then combined x and y mouse moves into single vector,
view and object moving are working.
Added CRbqOrthoText single-shot item display,
got rid of 'NoCurrentSelection()' msg via Qt messagebox (was screwing up
'space-bar' mode and generally annoying. Now message is displayed in
graphics window. It works great.
Integrated view and object movement are working very well now,
except for auto-rot-centering after object translation.


(rb log, rb.cpp)
Backup with rbq015.gz


(rbq log, history.txt)
Starting pdbtree stuff.
Added CPdbTreeWid_Imp::PdbSelectionChanged().
Added CPdbTreeWid_Imp::AddItemsToView().
Added CRbqDoc::GetPdbInfo().
The Pdb tree is working.
However, in order to be able to rebuild the tree
(after a show() or pdb deletion), we need to access
the original 'select-all' range info instead of just
inferring it from a selection spec, because during rebuild
a selection spec is not used, just current sel state.
Therefore, the 'select chain' as oppposed to 'select all residues in chain'
intent must be saved somewhere.
It could be saved in the CGrPdbObj, but this would seem to violate
the principal of simplicity and encapsulation (ie, if more complex functionality
is needed, don't modify your building blocks, instead, provide extensions to
handle it).
On the other hand, the simplicty of the CGrPdbObj has already been violated
in providing the 'IsChainSelected()' function which requires knowledge of
'all residues in chain are selected' and attendant code.
It is state info which is queried, so perhaps it should be stored there.
'Selected' state info was added to CGrPdbObj pdb and chains.
Hierarchy selection is working.


(rb log, rb.cpp)
Added misc pdb info methods to CFastPdbObj.
Added explicit 'selected' state to pdb and chains in CGrPdbObj.


(rbq log, history.txt)
Backup sync with rb628.


(rbq log, history.txt)
Added CRbCmdProcessor::PartialSelection(),
Added CRbqDoc::HavePartialSelection().
Added 'flash select' methods to CRbqGraphicsWindow.
It works, but need to use timer instead of frame count in order to
get constant flash time.
Moved flash code into component class 'CSelectionFlasher'.
It works.
Need to distinguish between doc selection changes due to
transformation vs. deletion notifications (1st needed by CGrSelection,
2nd needed by CPdbTree).
One way to do this is to do a deselect before deletion.
This has been done.
Fixed bug in deletion.
Deletion is working.
Selection extent bug is still there, shows up just after
transforming selected pdb after inserting a 2nd pdb.
Extent bug is fixed!!!


(rb log, rb.cpp)
Backup sync with rbq016.


(rb log, rb.cpp)
Fixed uninitialized var bug in CGrPdbObj.
Fixed bug in CExtent::UpdateMyMinMax() (skipped update
if param extent was uninitialized).


(rb log, rb.cpp)
Added 'SetDefaultColor()' to CGrResidue, fixed color bugs.


(rb log, rb.cpp)
Backup sync with rbq017.


(rbq log, history.txt)
Backup sync with rb629.


(rbq log, history.txt)
Added 'Color Names' menu, dynamic menu item def generation to CRbqMenu.
Added CPdbTreeWid_Imp::RebuildFromCurrentSelection().
CRbqDoc::GetPdbInfo() is slow for large atom record counts,
Added progress meters in 2 places:
It works.


(rbq log, history.txt)
Added selcenter cache to CRbDoc, rotation about selection center.
Added 'color' cmds.
Color cmds are working.


(rb log, rb.cpp)
Numerous data-access changes to CFastPdbObj and CGrPdbObj
for speed optimization purposes.


(rb log, rb.cpp)
Backup sync with rbq018.gz, wklib077.


(rbq log, history.txt)
Backup sync with rb630.gz, wklib077.


(rbq log, history.txt)
Tried to inline some stuff in CFastPdbObj to speed it up.
Tree build time is long but acceptable in release mode for selecting
all residues in 1fka.
Added 'rebuild tree' on show only if selection has changed.
Added rebuild for toggle select. It almost works, just need
to change IsChainSelected() logic slightly in CGrPdbObj so that
it returns true if chain selected flag is set AND all residues in
chain are selected.
It works.
Optimized CRbqDoc::GetPdbInfo():
records add in param list instead of returned,
replaced string methods with sprintf in Atom info.
It's significantly faster.


(rbq log, history.txt)
Adding selection from pdb tree.
It's just about there.


(rbq log, history.txt)
Transfer backup to ribo3.
Added all pdbs to pdb view.
Added sel cmd output to CPdbTreeWid_Imp.
It works!!


(rb log, rb.cpp)
Adding class CGrResDrawState to support file i/o of CGrPdbObj.
It works.


(rbq log, history.txt)
Started on file saving.
Finally added dependency file generation
File saving to rbd format is working.
Added saving of graphical state.
Residue draw state save and read works!!!


(rb log, rb.cpp)
Fixed bug in CGrPdbObj::DrawResidueBackbone().
Unit test in tstFastPdb is failing: CMultiNaRes_NsaEnconTest.
It appears that an inter-residue covalent bond is not being


(rbq log, history.txt)
Backup with rb631.gz


(rbq log, history.txt)
Just thought of a nice mechanism to extend doc
data while keeping it compatible:
a 'client-info' section which allows external
clients to submit a named chunk of data during file write.
The doc writes all such submissions out during file-write
and later reads them into a member-list where the data
can then be processed by clients, and the doc
doesn't have to know anything about the nature of the clients.
Any amount of data can in principle be associated with
the doc as the submitted data could just be a filename
which points to a separate file processed by the client.
Examples of external information to be stored include
the graphics window view, and descriptions of pdb molecules.
<MainWin_ViewMatrix> entry was added to <ClientData> section,
saving and restoring of view works, doc doesn't need to know about it.
In creating a decent steric energy calculation scheme,
we want to efficiently determine all atoms with 4x vdw radii distance
for a given atom of a residue.
To do this, we can create a convex hull around each residue using 4x radius bbox
around each atom, then do VCollide intersection testing of the convex
hulls, then exhaustively check each atom-atom distance for each
pair of intersecting hulls.
Also, the encon stuff should not touch any of the current
CRbqDoc and CRbqPdbMol code - it works and should remain fairly constant now.
This kind of functionality, as well as behavior definition and mol description,
should be implemented through a 'plugin-like' interface.
There is a bug in the pdb tree - in add-to-sel mode, get
multiple entries in chain view of the same chain.
Need to check if its there before adding?
TODO: add name and user-description tags to rbd file.


(rb log, rb.cpp)
Backup sync with rbq020.gz


(rb log, rb.cpp)
Ran enconReport on 2nt, we need to have html documentation
which gives a detailed description of steric energy calculation
on test molecules.
Updating html documentation.
Keeping track of all the files in all projects, libraries
and docs is getting to be a hassle. We need a flexible and
simple 'master project file list' which documents all files
need in a collection of projects and libraries and also allows
for automated directory and file comparison between project
file sets in 2 different locations.
This tool should use text files for storage of the information
in a format which allows interaction with a graphical tool,
either web or Qt-based, which shows a tree-based view of all
Created Ozone, a project management tool.


(rb log, rb.cpp)
Found the bug, it's in CBnd::IsBondInList(), no reciprocal check, duh.
It's fixed.


(rbq log, history.txt)


(rb log, rb.cpp)
Documented Steric Energy Potential formula.
Documented tstEncon unit test calculations,
Redefined steric energy potential calculations in


(rb log, rb.cpp)
Backup motivated by new ozone project management tool.


(rbq log, history.txt)
Redefined display of selection in Pdb Tree so that sel level view and
ancestor views show all sibling unselected and the immediate descendant
view of the selected level shows children unselected.
Selection is now working well.
Added hotkey trapping for keydowns in Pdb Tree widget.
Added selection in pdb tree via keyboard.
It's working great!!!


(rb log, rb.cpp)


(rb log, rb.cpp)


(rbq log, history.txt)
Added resource path fix.
Added mol name, 'edit name' command.
Hooked up menu item 'whatthis' to status bar.
Added 'set bgcolor' cmd.
Added 'about' app icon.


(rb log, rb.cpp)
Fixed bug in CCmdParser::DoCommandHelp().
Created rbEncon lib, moved econ classes over to the lib.
Added commenting option to CFastPdbObj, CTimeReporter.
We need to be able to analyze encon results at the atomic
level, graphically, but CGrPdbObj only provides access down
to the residue level. Rather than create a second gr pdb class
with atomic resolution, we should be able to get convenient
atom-level graphical i/o via the CGrTorGraph and related classes.
Created rbTorsion lib, moved torsion classes over to the lib.
But of course, we need to separate graphics from chemistry, so
we could either create rbGrTor lib or put CGrTorGraph into rbGrChem.
The latter has been done.


(rbq log, history.txt)


(rbq log, history.txt)
Added class CRbqApp.
Added override of QMainWindow::close() to do file save query,
Added CRbqCmdProcessor::CancelOnSaveCurrentFile().
Added saving of offset view rot center.
It would be nice to add things like Energy calculation and viewing
via true plugins which are loaded as dlls and dynamically add to
menus and such, but we don't have time to code that generality into
framework at this time.
Created 'Energy' submenu underneath Forcefield menu.
Created class 'CEnergyViewer'.
Created class 'CAtomDataReceiver' (to avoid redundant copying).


(rb log, rb.cpp)
Created interface CAtomDataReceiver in chem lib.
Added CGrPdbObj::GetSelectedAtomData().
About to change CTorGraph::Create() CBnd::BondPtrList &bonds to
CBnd::BondList, but first we need to document TorNode unit testing
Began documentation of current TorNode unit test results.
Should we assign a numerical id to every test case UNIT_ASSERT() ?
We could use token pasting to automatically identify and log the assert conditions.
Added detailed logging of assertion info in test cases, works great.


(rb log, rb.cpp)
All 5 test cases in torsion unit testing have been exhaustively documented.
Changing from bnd ptr list to bond list in tor classes.
Unit tests work after change, no problem.
CGrTorGraph works (tested in rbq), but for tRNA-sized graphs, drawing
is major slow.
CGrTorGraph::GetBondPartners() is likely the bottleneck, as the entire list
of bonds in the graph is being searched for bond partners for each atom during
We could try creating an explicit list of bond partners for all CGrTorNode atoms.
Another option is to try searching for bond partners only in the node's group atom list and the
in the group atom lists of the node's parent and children.


(rb log, rb.cpp)
Added list of CTorAtom bond partners and index list to CGrTorGraph,
drawing of full tor graph for tRNA is fast now!


(rbq log, history.txt)
Backup sync with rb635.gz


(rbq log, history.txt)
Rendering of CGrTorGraph in energy viewer is working, but slow.


(rb log, rb.cpp)
Added progress to CNsaEncon.
Added support for cancelling during progress to
CNsaEncon and CFastPdbObj.


(rb log, rb.cpp)


(rbq log, history.txt)
Added Internal Energy Setup Dlg,
Added energy calc to CEnergyViewer.
Adding CEnergyInteractionWid widget.


(rbq log, history.txt)
Built on Beryllium.
There is some squirly rotation happening when doing
a drag-select with the mouse, looks like mouse downs/ups
getting split between the selection controller and the transform controller.
Uh, there is no handling of QWidget::mouseReleaseEvent(), duh.
Added that, but still have the problem.
Further debugging shows that on fast mouse clicks, the
mousePress() event is receive AFTER the mouseRelease() event,
but ONLY during a selection event.
Further debugging shows that the mouseReleaseEvent() is ocurring
asynchronously in the middle of the mousePressEvent() processing.


(rbq log, history.txt)
Backup w/ rb636.gz


(rb log, rb.cpp)
There is a bug in CNsaEncon::Energy() in reporting interaction
details - invalid atom index atom the end. Adding more unit testing
to tstEncon project.
Updating Encon test case html documentation prior to adding new steps in test cases.
Updated Encon test cases.
Added min/max recording to CNsaEncon.
That bug in CNsaEncon didn't go away, just wasn't trying the right residues.
Energy calc between residues 3 and 4 of 1tra.pdb does it
on atom pair 1016:
1015 59.655 21 22
1016 19.2584 0 -1
1017 35.4625 23 24
Error is in CNsaEncon::CalcEnergyI_AllMinusBonds().
Found the problem:
it was in CGrPdbObj::GetSelectedAtomData().
The problem was that all bonds for a selected residue were being added to
the atom data receiver, including bonds to atoms in non-selected residues.
Since we are currently specifying inter-residues bonds for a fastpdb residue as
only bonds to the previous residue in the chain, we have simple fix whereby
bonds are not added to the receiver if the previous residue is not selected.
This works.
Also making a change in CNsaEncon::CalcEnergyI_AllMinusBonds() to always report the
lower index atom first (allows for removal of dups later).
It works.


(rbq log, history.txt)
Added queueing of mouseReleaseEvent() messages in
CGraphicsWindow::mousePressEvent(), now she is rock solid!


(rbq log, history.txt)
Energy interaction widget almost working, added atom name and
serial access methods to CRbqDoc, CRbqPdbMol using CAtm ptr.
There is a bug in CNsaEncon::Energy() in reporting interaction
details - invalid atom index atom the end. Adding more unit testing
to tstEncon project.
After further testing in rb, the problem went away.
Energy Interaction widget is working.


(rb log, rb.cpp)
Backup with rbq026.gz.


(rbq log, history.txt)
After a few bug fixes, did successful energy interaction between
3rd and 4th residue of 1tra.pdb
Backup with rb637.gz.


(rbq log, history.txt)
Gave demo to the lab, there is a bug in the energy viewer:
if pdb mol is transformed, the energy viewer highlights
the atoms without applying the transform.
Moved energy viewer to a separate library 'eview.lib'
Created project lib rbqUtil.lib.
Created interface CMolDoc.
It works.


(rb log, rb.cpp)
To deal with the issue of geminal atom (1-3) interactions,
we need something different from CNsaEncon. Determining 1-3
bonding in the n^2 atom loop is too expensive. A possible solution
is to used the implicit bonding information in residue-level atom sets.
Created CNsrEncon (N-squared residue energy conformation calculation).
It's working except still need to add final boundary calc.


(rbq log, history.txt)
To deal with the issue of geminal atom (1-3) interactions,
we need something different from CNsaEncon. Determining 1-3
bonding in the n^2 atom loop is too expensive. A possible solution
is to used the implicit bonding information in residue-level atom sets.
In addition, the new class will provide the opportunity to apply the
pdb transforms to the encon atom sets.
Creating CNsrEncon (N-squared residue energy conformation calculation)
in rb encon lib.
Sliced CEnergyViewer into derived class CNsaEnergyViewer.
Added CNsrEnergyViewer, it works.


(rb log, rb.cpp)
Still shaking out bugs in CNsrEncon and related energy viewer.
TODO: check distance on 0 energy value (serial 79, serial 89), 1tra res 3.4
the graphics appear to show intersecting spheres rather than just touching.


(rb log, rb.cpp)
Backup with rbq027.gz, evw002.gz.


(rbq log, history.txt)
Still working on CNsrEncon and viewer.


(rbq log, history.txt)
Backup with evw002.gz, rb638.gz.


(rb log, rb.cpp)
Added CNsrEncon::InterResCovalentOrGeminal(), HaveIntraResCovalentBond().
Finished CNsrEncon::CalcEnergy().
It appears to work (need detailed checking and unit-testing).


(rbq log, history.txt)
Moved selection mode commands into submenu.
Added limited fix for pdb tree display when doing toggle selection:
just erases all but top-level pdb view.
We now have coherency between graphics window and pdb tree widget when
doing toggle-select.
Added summary and detailed selection reports.


(rb log, rb.cpp)
Added CGrPdbObj::GetSelectedResiduesInChain().


(rb log, rb.cpp)
Added CFastPdbObj::SetChainId()


(rb log, rb.cpp)
Backup with rbq028.gz


(rbq log, history.txt)
Added residue sequence number to name in pdb tree residue view.
Added reporting of selected range by name.
Added selection by idx1
Added selection by name.
Added setting of printable chain ids in CRbqPdbMol.
Selection by name is working.
Adding lua scripting, it works!!!


(rbq log, history.txt)
Backup with rb639.gz


(rbq log, history.txt)
Added rbq-lua interface class CRbqLua.
Created rbq doxygen documentation.
Created rbq html documentation.
Created script menu.
Added rbqLua lib sub-project.
Added class CRbqLua to interface between rbq and lua.
Dynamic creation of Script menu items using 'ScriptDefs.ini' and
'CreateScriptMenu.lua' is working!!
Fixed dynamic menu item def addition to include menudef data
and recursive ptrs to its menu items.
Found annoying bug where ids of submenus were not being set in
Dynamic script menu creation and deletion is finally working properly.
Added CRbqPdbMol::GetResidueCenter(), GetResidueExtent(), GetResidueAtoms().
lua script 'ReportDistance.lua' is working!!!!


(rbq log, history.txt)


(rbq log, history.txt)
Implemented PdbTree support for toggle selection at the residue level.
It works.
Redefining hotkeys for more convenient usage.
Instead of having CTransformController and CSelectionController as
separate keyboard listeners, it would be better to have a single
app-wide keyboard listener which set the various modes in response to
key events.
Created class CRbqKeyboard (receives key input from all main window child widgets).
Create class CSignalReceiver;
Redefined and added more accelerators.
Added color toolbar.
Started adding 'Model' scripts to Script menu.
Added 'SetLocalEnv' script.
Added menu separators.
Spent a long time fixing bugs in menu creation/deletion,
Fixed annoying bug in lua safe_getglobal.


(rbq log, history.txt)
Creating Model scripts.
Created PositionSelection.lua
Moved CRbqUtil methods into RbqUtil namespace, got rid of CRbqUtil.
Created CRbqAxis, CRbqAxisGroup.
Added command to set world axis size.
Adding command 'edit insRuler'.
Adding CRbqRuler class.
Created script InsertRulerBetweenPdbs.lua.
(trying to get method for standard alignment of subunits in volume).
Might need a more dynamic ruler (endpoints retrieved from objects instead of absolute?)
But first, create script 'RotateVectorBetweenCentersToDestVector' ?


(rb log, rb.cpp)
Added display of backbones if no covalent bonds in CGrPdbObj.


(rb log, rb.cpp)
Replaced CGraphicsContext with CWkGraphicContext.
Moved CGoOrthoText and CGLGraphicUtil into external lib grBase.
Moved rbChem into external lib chemBase
Ripping the guts out of rb:
rbEncon -> wkEncon
rbFastPdb -> wkFastPdb
rbGrChem -> wkGrChem
rbTorsion -> wkTorsion
The move is done, rb compiles and runs.


(rbq log, history.txt)
Added arrowheads to CRbqRuler.
Replace rb CGraphicsObject base class with abstract interface CWkGraphicObject.
Major housekeeping in shifting libs out of rb project.
We're down to CmdProcessor in rbFramewk and CFrameRate in rbutil.
rbq builds and runs, but rough initial assessment of debug build is that
it is slower.


(rb log, rb.cpp)
Backup with rbq030.gz
Moved CCmdProcessor et al into wkParse lib.
Get rid of szString version of CmdProcessor::InputCommand().


(rbq log, history.txt)


(rbq log, history.txt)
Moved cmd processing code out of rb into wkParse, rbq is
now completely independent of rb code.
Created BuildWkLibs.mak, built release versions of wklibs,
build rbq release, it runs ok.
But there is a bug in drawing backbone in trna in 1gix.


(rbq log, history.txt)
Added 'mouse moveRate' command.
Added annotations container to scene graph.
Add class CDistanceMonitor?
or, add class CScriptObject? Added to graphics window,
it contains a chunk of lua code. When drawn, the
lua 'draw()' function can be called.
Added class CRbqScriptObject.
Added cmd group 'edit set',
Added cmd 'edit set rulerPoints'.
Added dynamic generation of scripting code: script object draw() function.
Script 'InsertRulerBetweenPdbs.lua', using dynamic ruler positioning
via CRbqScriptObject draw() code, is working!


(rb log, rb.cpp)
Moved unit testing projects, testframewk out of project.


(rb log, rb.cpp)
Compiled on Beryllium, runs ok.


(rbq log, history.txt)


(rbq log, history.txt)
Added script obj directory delete on obj delete,
Added 'NoCurrentDoc()' check to edit cmds.
Added CRbqPdbMol::CalcCenterOfMass(), GetSelectedMomentAndMass().
Selection center is now determined by center of mass.
It works.


(rbq log, history.txt)
Built and ran on Beryllium.
Copied all project files to selway\proj\wkDist\001.
Unfortunately, it's running more slowly now.
Got script 'alignCenterWithZ.lua' working,
we know have a automatic standard alignment of 1gix/1giy at the origin.


(rbq log, history.txt)
Added display of pdb molecule title and chain description info in pdb view.
Creating 'AlignSelectedResidues.lua'
Added CRbqLua::rbq_GetBackboneAtomPos().
Added CRbqDoc::GetBackboneAtomIdx(), GetAtomPos().
Added CRbqDoc::TranslatePdb().
Align translation is working!!!


(rbq log, history.txt)
Alignment rotation is working.


(rbq log, history.txt)
Added toggling of volume floor.
Added script 'DimSelection.lua',
Added CRbqDoc::SetResidueDrawState(), IsNucleicResidue().
Adding script 'SelectHelix.lua'.


(rbq log, history.txt)
Finished creating helix table for ecoli 23S.


(rbq log, history.txt)
Added '_SeqUtil.lua', functions findHelix() and getMappedBase().
Script 'SelectHelix.lua' is working! (for 1ffk.0).


(rbq log, history.txt)
Added range selection to pdb tree.
It's working.
Created Ecoli.23S-1giy.A sequence map.
Added RbqUtil::ShowWaitCursor().
Fixed safe_getglobal(), module loading vars in lua utils (moved all to Startup.lua).
'SelectHelix.lua' is working for 1giy.A.


(rbq log, history.txt)


(rbq log, history.txt)
Generalized 'SeqMap_Ecoli_Hmari.lua' script to
_SeqUtil.lua reportMappedBases(), translateMappedBases(),
Added 'SeqMap_23S_Ecoli_Hmari.lua', 'SeqMap_23S_Ecoli_Ttherm.lua',
Added _VectorUtil.lua getProjectedVector().
Finished 'AlignSelectedResidues.lua' (alignment of next backbone links),
it works!!
Sort of, it doesn't always align properly, no time to figure out just yet.
Debugging alignment problem.
Added command 'rot selAbsCen' (rotate around param center about param world-frame vector)
Added command 'edit delAnnotations'
Found 2 bugs in alignment problem:
1: moving nextbb pos wasn't being updated after 1st rotation!!
2: opposite order in projected vectors in second calcRotVector() call.
NOW residue alignment is finally working!!!
Added script to load Stefano's if2.
Added CRbqDoc::SetPdbTransformMatrix().


(rbq log, history.txt)
Added D. Radiodurans (1kpj) seqmap and load scripts.
Working on backbone bug in tRNAs in 1giy (modified residues have atoms in different order).
The bug is in wkFastPdb CFastPdbObj::IsNucleicResidue(), it is assuming the P comes first or second.
One fix is to add a bool flag to CFpoRes at creation time and check all atoms then for P or CA.
This one-byte increase in memory hopefully will be faster than the lookup at draw time.
Perf benchmark: with 1giy and 1gix loaded in backbone draw, frame rate = 6.7 fps (release build, ribo3).
Perf benchmark: 1st load time for 1gix: 0.72 sec ( 12373.6 atoms/sec )
After change in wkFastPdb:
Frame rate is the same, it works.


(rbq log, history.txt)


(rbq log, history.txt)
Added CInputDlg ui widget to res, CInputDlg_Imp widget to framewk lib,
so we can position the input dialog at same pos as the cmd input dialog
(Qt QInputDialog provides no positioning methods).
It works (and definitely worth it).
Fixed a bug in _SeqUtil.lua selectHelix().
Ready for integrating torsion code.


(rbq log, history.txt)


(rbq log, history.txt)
Built and ran on Beryllium.
Added script 'CreateTorsionGraphs.lua'.
Started on torsion graph creation.
Creation and drawing of torsion graphs is working.
Added CProgress support to torsion and grtorsion creation.


(rbq log, history.txt)
We need to integrate graphical selection of torsion graph objects
with as little impact on the existing framework as possible.
The torsion graph is a component of the CRbqPdbMol object, so
during drawing, the hierarchical hit id will contain the parent pdb mol index.
We can use the same CRbqIndexRange param for selection as is used to
specify <pdb,chain,res> for the 'unmoved' pdb objects. We just need
to intercept the selection prior to validation and selection of this
standard range. An indicator of an extended range spec is if the
chain index is greater than the final chain index of a pdb and the pdb
has torsion graph objects.
Added CRbqDoc::IsExtraPdbComponent(), SelectExtraPdbComponent() at top of


(rbq log, history.txt)
Changed CRbqDoc::HaveSelection() implementation from checking residue count
to querying CRbqPdbMol objects.
Renamed CRbqPdbMol::IsSelected() to IsPdbModelSelected().
Added CRbqPdbMol::GetSelectedTorsionGraphMomentAndMass().
Centering on selected torsion nodes is working.


(rbq log, history.txt)
Added torsion graphs to selection summary report.
Added torsion graphs to extent calculation.
It works.
Fixed bug where settings weren't being saved on exit:


(rbq log, history.txt)


(rbq log, history.txt)
Tried to move validation of sub-pdb portion of selection index into
CRbqPdbObj from CRbqDoc, eliminating the need for the hook method above
but it didn't work well.
Instead, just added torsion graph select/deselect to 'all-pdb' select op
CRbqPdbMol::Select( iSelectOp ).
It works.
Added range-selection to CRbqPdbObj::SelectExtraComponent().
It works.
We are ready to torque!!!


(rbq log, history.txt)
Node rotation almost working! Just have to pass input fRot value in from tx
Added fRotateX, fRotateY params to CTransformController::Rotate()
because this is needed for torsion graph rotation.
Removed them again, found a simpler solution: calculated cross-product
between screen x axis and rot vector.


(rbq log, history.txt)
That didn't work for certain orientations,
Had to add methods CRbqGraphicsWin::GetRawTransformX() and GetRawTransformY().
Rotation of torsion node by mouse is now working well.
(except for the first node).
Fixed first node rotation bug in wkTorsion lib.
Added script 'load_1jgo.lua'
Adding script 'RandomlyRotateSelectedGraph.lua'
Documented script objects in doc\\html\\scriptObjects.html', prior
to adding needed 'time user' script objects.
Need to add 'CRbqTimeUser', time user list in CRbqMainWindow,
called from CRbqMainWindow::timerEvent().


(rbq log, history.txt)


(rbq log, history.txt)
Added interface CWkTimeUser in framewk lib.
Added interface CWkTimeGiver also, so objects can manage their
own addition and removal from the time user list.
Random rotation of torsion graphs is working.
Next step: concurrent energy calculation of graph.


(rbq log, history.txt)
Added command 'view lookDir'.


(rbq log, history.txt)
Added deletion of torsion graphs.
Added 'Delete All Annotations' menu item to edit menu.
Added command 'file exportPovray', exporting of selected chains to povray.


(rbq log, history.txt)
Found bug in CGrTransform3f in grMatrix lib,
Fixing COffsetView.
Created class CSimpleView.
Created new class COffsetView derived from CSimpleView.


(rbq log, history.txt)
Fixing bugs in consequent of changes in grmatrix lib.


(rbq log, history.txt)
View and object rotation are finally working again!
New commands 'view lookDir' and 'view upDir' are also working.
Things flipped out again, but after more fixes,
view and object transformation are working properly again.


(rbq log, history.txt)
Built on ribo3, it works.
Built release version on Beryllium, it works.


(rbq log, history.txt)
Small additions to povray header output.


(rbq log, history.txt)


(rbq log, history.txt)
Implementing pdb file save,
Added CRbqDoc::ExportToPdbFile().


(rbq log, history.txt)
Added show/hide for toolbars.
There is some conflict with the Qt popup menu which does the same thing.


(rbq log, history.txt)


(rbq log, history.txt)
Fixed bug in CSimpleView::Point_ViewToWorld().


(rbq log, history.txt)
Added saving and restoring of graphics win bgcolor.
It works - awesome client data scheme has automatic backwards compatibility!!
Added some needed doxygen comments.


(rbq log, history.txt)
Need to try better docking of IF2.
Adding script 'GetChainsInRangeOfChain.lua'.
Adding CRbqLua::rbq_GetSelectedChainIndex(),
Renamed CRbqLua::rbq_GetSelectedResidue() to rbq_GetSelectedResidueIndex().
The old 'how to indicate full subrange in a CRbqIndexPos' issue comes up again
in updating CRbqDoc::GetNameFromIndex() to handle chain names in addition to
residue names.
One new idea to handle it is to add a separate variable which records the
number of explicitly initialized levels (as opposed to earlier attempts
which considered assigning special values such as '-2' to sublevels.
Added 'CRbqIndexPos::GetTotalInitLevels()'.


(rbq log, history.txt)
Script GetChainsInRangeOfChain.lua is working.
(but need better progress, speed).


(rbq log, history.txt)
Added lua interface to CRbqProgress.
It works.
Fixed sizing bug in CInputDlg_Imp.
Added cmd-line args to lua scripts.


(rbq log, history.txt)
Adding script 'SelectHelixFromRes.lua'.


(rbq log, history.txt)
Found a bug in the ecoli->radiod and ecoli->tthermus smaps
while trying to select helix 41.
Fixed bug.
'SelectHelixFromRes.lua' script is working.


(rbq log, history.txt)
Mapping for helix endpoints is too slow, created script
It works. SelectHelix.lua is fast now.
Adding 'CRbqLua.cpp: rbq_AddScriptObjectData()'
Adding script 'ChainRunner.lua' (does sequential highlighting
of residues).


(rbq log, history.txt)
Added setting and getting of global data around execution
of function scripts in CRbqScriptObject.
It works.
Added CRbqLua.cpp : rbq_GetResidueIndex().
'ChainRunner.lua' script is working.
Changed top-level command name 'lua' to 'script'.
Added commands 'script listObjs', 'script listVars', 'script var'
Added 'script so' sub-command.
Added 'script so gte' (global tick enable).


(rbq log, history.txt)


(rbq log, history.txt)
Adding script 'GetHelicesInRangeOfChain.lua'.


(rbq log, history.txt)
Script 'GetHelicesInRangeOfChain.lua' is finally working.


(rbq log, history.txt)
Adding mol data transfer interface method CMolDoc::GetDataInRanges()
(for eview class CTgaEnergyAnalyzer).


(rbq log, history.txt)
Implementing mol doc transfer methods in CRbqDoc and CRbqPdbMol.


(rbq log, history.txt)
Inter-group energy analysis is working!


(rbq log, history.txt)
Backup with evw005.gz


(rbq log, history.txt)
Added pair reporting options to CTgaEnergySetupDlg_Imp.


(rbq log, history.txt)
Fixed bug in CRbqProgress (needed to delete the dialog to prevent
it from showing in delayed processing after call to Hide()).
Calculated interaction between 1kpj.0 helix 40 and IF2 in Brandi model 003,
CTgaEnergyViewer works.


(rbq log, history.txt)
Backup with evw006.gz


(rbq log, history.txt)
Added description documentation for all functions in
lua files
Fixed bug in 'SelectHelixFromRes.lua'.
Modifying CRbqDoc::GetIndexFromName() so that a residue sequence
number can be entered without prefixed symbol.


(rbq log, history.txt)
Wrote script 'Srd-display.lua'
It works, but need to have autoration around loop center added.
Another camera bug: when rotating view about view upDir, the
upDir should remain constant but it doesn't.
Note: this is not a bug, 'view rot' expects local frame vector.
might need to add 'view absRot' command.


(rbq log, history.txt)
Srd-display script works except for annoying bug in which the view
drifts farther away.
Moving the tick script to a separate file which is used as a template
was a good idea though (Srd-display.tick.lua).


(rbq log, history.txt)
Created class CRbqForceObject.
Created class CRbqForceContainer.


(rbq log, history.txt)
Created 'forceobject' command group,
created command 'ff fo create' (create force object from current selection).


(rbq log, history.txt)
Added ff run and zerovel items to menus and toolbar.
FF interactions don't appear correct between 2 residues
of 2 tRNAs, may need to add force display capability.


(rbq log, history.txt)
Forcefield and force objects are working!!


(rbq log, history.txt)


(rbq log, history.txt)


(rb log, rb.cpp)
Fixed transform bug in CBassChain (resulted from changes in CGrTransform3f).
Fixed graphics export bugs CBassChainUtil::ExportRibbonGraphics() (resulted from changes in CExportGraphics in wkGrChem lib ).


(rbq log, history.txt)
Added export of residue hull graphics to povray (cmd: 'dev expSurfPov' ).


(rbq log, history.txt)
Added cmd 'dev expSmoothSurfPov'.


(rbq log, history.txt)


(rbq log, history.txt)
Added loading of CWkMesh objects.
(command: 'dev insMesh <meshFile>').
Changed pdb file export to allow for partially selected pdb object.
It works.


(rbq log, history.txt)


(rbq log, history.txt)
Added loading of CWkWireMesh objects.
(command: 'dev insWireMesh <meshFile>'),
for use in developing the l-surf project.


(rbq log, history.txt)
Added loading of CWkWireSegPair objects.
(command: 'dev insWireSegPair <segFile>'),
for use in developing the l-surf project,
Renamed wire mesh to wire loop.
Added some error checking and status to CRbqLua.cpp:rbq_TranslateSelection().


(rbq log, history.txt)
Added 'ann' command group (annotation commands).


(rbq log, history.txt)
in rbqUtil lib, derived from wkGraphic objects (needed to add names to base class objects
so they can be handled by annotation commands).
Added lua i/o function 'rbq_ShowAnnotation()'.
Made CRbqScriptObject a keyboard listener.
There is a problem resulting from the earlier change where
CRbqKeyboard replaced the framework class 'CKeyboard'.
This was done to provide a level of abstraction and allow
for dynamic definition of mappings from keys to app events
via the CSignalReceiver interface.
The problem is that the CRbqKeyboad class expects predefined
signal targets.
A solution would be to have the CRbqKeyboard class inherit
from the CKeyboard interface and just do parallel dispatching
via both the CSignalReceiver and the CKeyboardListener interfaces.
Did some better documention of CRbqScriptObject.
Added CKeyboardListener implementation to CRbqScriptObject.
Created test keyboard-user script 'viewSlabs.lua' and associated
keyDown template script 'lsv.keyDown.lua'.
Script object keyboard-handling is working.


(rbq log, history.txt)


(rbq log, history.txt)
Added param [name] for creating annotations.
Added code to delete an annotation.
There is a really annoying sliding bug when rotating the view.


(rbq log, history.txt)
Added loading of CWkGrPointSet files.


(rbq log, history.txt)
Added CRbqDoc::DeleteMol().
Added command to insert bitmap text
'ann insBmText <text>'.
Added documentation to lua modules
Marching Cubes case viewer script 'viewCases.lua' almost done.
Create '_AnnUtil.lua' (annotation utils)?


(rbq log, history.txt)
Created AnnUtil.lua.
Added rbq_ExistAnnotation() in CRbqLua.cpp.
Minor ui problem: we need to create an 'echo status' flag which is
distinct from the 'echo command' flag in processing commands.
Added flag to CRbqCmdProcessor, replaced its internal use of 'StdOut()' to
conditional 'StatusOut()'.


(rbq log, history.txt)
Added command to load CWkSmoothMesh ('ann insSmoothMesh').
Added class CRbqSmoothMesh.
It works.
Created interface class CRbqTxAnnotation (transformable annotation object),
Made CRbqWireSegPair, CRbqWireLoop inherit this interface,
Added command 'ann trans <annName> <x y z>'.


(rbq log, history.txt)


(rbq log, history.txt)
Created class CRbqSmoothColorMesh.
It works.


(rbq log, history.txt)
Created lua script to export atom colors: 'exportAtomColors.lua'
Finally redirected lua _ALERT function to rbq_ErrOut().
Added selection of helices for non-standard pdb chains in


(rbq log, history.txt)


(rbq log, history.txt)
Built and ran release version on beryllium.
Added status to helix selection scripts.
Added 'command status enable' stack to CRbqLua,
'cmdStatusOff()', 'cmdStatusRestore()' functions
to _ScriptUtil.lua.
Added 'Features' submenu to script menu.
Added 'HiThiostrepton.lua'.
It works for 1giy.A and 1kpj.0, but not 1ffk.0 (because it's not there!)


(rbq log, history.txt)


(rbq log, history.txt)
Added command 'draw surf [on|off|tog]' to support
addition of surface display to CGrPdbObj.
Surface meshing from CGrPdbSurfFactory through CGrPdbObj works!!!
We need to add hooks to rbq progress and status though.


(rbq log, history.txt)
This has been done by doing an explicit call for surface creation, if needed,
from the command processor to the doc prior to setting the draw state.
Added command 'dev setSurfVdwExpand', default vdw expand value of 1.8 which seems
to work best.
Surface mesh status and progress work well.


(rbq log, history.txt)
Added 'draw surf on/off' menu items and toolbar icons.


(rbq log, history.txt)


(rbq log, history.txt)
Changed command 'dev expSurfPov' to use CPovRayExportGraphics_PovSurf instead of CPovRayExportGraphics_ResidueMesh.
Povray export works for surface graphic!
TODO: add 'no_shadow', 'double_illuminate' to output.


(rbq log, history.txt)
Added specification of reference pdb in 'AlignSelectedResidues.lua' script.
Created class 'CRmsCalc'.


(rbq log, history.txt)
During implementation of CRmsCalc, and its retrieval of data through the
CRbqMol interface, we are replacing the CRbqIndexPos parameter for specification of pdb data
with a more generic IntegerList parameter.
Finished the code for CRmsCalc, but now we are faced with the question of
how and where to store this persistent object. Deriving from CRbqScriptObject
is one possibility.
From a design standpoint, we note that the reason this object is persistent is
for performance reasons. It is possible to do an rms calc through existing
calls to the Document interface, but mapfile processing and pair distance calculation
would have to be done anew each time.
In addition, we must anticipate future related 'intermediate, persistent'
entities as will be needed for real-time interaction of objects which represent
the ribosomal translation cycle.
The current script object provides graphic output, idle processing and keyboard
event processing, and doesn't know anything about the CMolDoc interface.
Another consideration is the process of creation and use of the rms calculation.
It should definitely be created through a script interface. The current interface
provides get and set methods on user-defineable script object data, but this
object would also need a general command interface, where the user could
query for the current rms value, for example:
'so cmd calcRms1 calcrms' -> "RMS for pdbI.chainI and pdbJ.ChainJ = NNN.NNN"
(so cmd <soName> <command args...>)
Perhaps this is something along the lines of the 'CCmdProcessor' interface used
by animation objects in the plo project (and the same 'CCmdProcessor' interface
used in this object).
So perhaps the derived type can be CRbqCpScriptObject (for 'command-processing'
script object).
Or maybe this interface should just be added to the CRbqScriptObject class?
It doesn't strictly have to be, as we could do a dynamic_cast on a CRbqScriptObject ptr
to a CRbqCpScriptObject ptr, or to just a CCmdProcessor, in processing the 'so cmd'.
Created class CRmsCalcScriptObject, derived from CRbqScriptObject and implementing
the CCmdProcessor interface.
Added command 'so cmd <scObjName> [args...]'.
Added command 'ann insRmsCalc <sPdbChainI> <sPdbChainJ>'.
Almost done coding rms calc.


(rbq log, history.txt)
Added code to skip validation beyond total init levels in pos in CRbqDoc::ValidateIndexPos_Status().
Fixing bugs caused by changes in CRbqIndexPos,
added design rule where m_iTotalInitLevels is only set in constructors
or set by user.
RmsCalc is finally working!!
Brief trials give 1giy.A.C2443 and 1ffk.0.U2478 alignment an RMS value of 12.9


(rbq log, history.txt)
In trying to add optional command-line arg to lua scripts, had a bit of trouble,
ended up with using rawset( globals(), "g_sCmdLine", sCmdLine ) in runScript(),
it's kludgy but works.


(rbq log, history.txt)


(rbq log, history.txt)


(rbq log, history.txt)
Added CRbqMainWindow::DoExternalScript().


Adding interface to allow execution of scripts as specified by external applications. The idea is to have a web browser running in parallel with the rbq app. The browser can display a page of descriptions of some scenario or process, broken down into a sequence of steps. Each step is linked to a lua script which is to be executed when the link for that step is clicked in the browser.

One way to implement this is to create a subdirectory which can receive files and which is scanned every tick by the rbq app. When a file is found, it is opened and read. A single line can contain the full path of a script file. After a file has been read, it is deleted. If a new file is read while a script is currently executed, the current execution is halted and execution of the new script begins.


Created the cgi script yesterday and it is working. A 1 second delay needed to be added when scanning the script request subdir, as doing it every idle tick caused problems. Script loading is now working. Successfully called script 'loadTrna.lua' from html page in exp\browserTest.


Adding saving of window geometry and state (to help working with browser). After dealing with annoying bug where the Pdb tree widget was interfering with sizing problems, it seems to be working.

Still getting crashes and weird behaviour though. Moved some CRbqMainWindow constructor code to a new method called 'PostConstructInit()'. Finally got proper main window sizing to work by moving showPdbTree() code to beginning of init main window state, along with doing a show(), updateGeometry() and qApp>sendPostedEvents() between this component show and subsequent sizing of main window.


(rbq log, history.txt)
Added CRbqLua.cpp : rbq_OpenPdbFile().


(rbq log, history.txt)


(rbq log, history.txt)
Added creation of input subdir on startup if needed.
Made command processor progress meter line up better in app main window.
(removed resizing of progress meter widget, didn't seem to help).
Prog meter repositioning is working.


Before resuming working on exp\pap_Bashan2003, did a little timeout to fix the position of the progress meter, it was in the middle and cutoff, which was annoying. Added code to position it relative to lower right corner of the status window. It worked, but after some tiresome coding and debugging.

Also want to add a simple residue-residue intersection method to the wkEncon lib, where the atom bounding boxes are determined by a user-defined parameter. In revisiting the wklibs, this highlighted the need for better htnl documentation of the wklibs. Created a master index 'wklibs.html' in \proj\doc\html.


(rbq log, history.txt)
Added _ChemUtil.lua
Added _ChemUtil function 'getResIntersect()'.
Added CRbqLua.cpp : rbq_GetResidueIntersect().
Added CRbqDoc::GetResidueIntersect().
Residue intersect methods and script are working.
Next: create atom-intersect methods
(list of intersections between atoms in 2 intersecting residues).
Creating sequence map for 1njm.0.


(rbq log, history.txt)
Got 'too many open files' error after running rbq and web browser for awhile,
rewrote the ext script scan delay using another QTimer.
This appears to work.
About to creating script 'showHelixAxis.lua' (shows graphical rep of a helix axis).
But, going back to residue-residue energy calcs instead.
Changed CRbqPdbMol::GetResidueName() to GetResidueAbbr().
Added CRbqPdbMol::GetResidueSeqName().


(rbq log, history.txt)
Added export of selected residues to pdb file (before, could only export
a fully-selected chain).
It works.
Adding sphere and cylinder selection.
Added 'sel sphere' cmds.
Created class CGeomSelector (manages sphere, cylinder and box selection).


(rbq log, history.txt)
I would like to link graphics window view rotation center updating
with automatic setting of selection sphere center. There are 2 ways to
do this. One way would be to add a 'Graphics Window Listener' interface,
which would receive a notification of changes rotation center, and update
the sel sphere center. The other way would be to have all calls to
CRbqGraphicsWindow::SetRotationCenter() go through a single method in
CRbqMainWindow, which could do the update there. Currently, there are
about 5 calls to the method, divided between CRbqCmddProcessor and CRbqMainWindow.
It would be nice if friend access could be specified to a class method indiviudally,
but at this time, I think the 2nd option will be used, and will rely on an
implicit understanding to call CRbqMainWindow::SetViewRotationCenter() instead
of the public call to CRbqGraphicsWindow::SetRotationCenter().
Added CRbqMainWindow::SetGraphicRotationCenter().
Sphere selection is working.

(rbq log, history.txt)

(rbq log, history.txt)
Built and ran on ribomachine 3.
In working on exp/pap_Bashan2003, the view 'walking' problem is back,
saved doc as exp/pap_Bashan2003/walk.rbd, still happens after app restart
and doc reload.
Perhaps a quick fix is to change the transform in CSimpleView from CGrTransform3f
to CGrTransform3d, but this might open a can of worms.
Created a typedef of RbqTransform for CGrTransform3f and then did search and replace
in the code (only 38 places) and then made a new discovery in my C++ knowledge that
it is illegal to do a 'typedef TYPE' after a previous 'class TYPE' class name declaration.
The short term fix is to just replace the class forward declaration with an include.
Since I already used transforms as member data in a lot of the base classes, I presume
that the CGrTransform.h file is already being including at compile time, and hopefully
will not incur a hit on compile time performance.
Successfully replaced CGrTransform3f with CGrTransform3d, but the view still walks.
Subjectively, it appears not to walk quite as quickly, but it still is not right.
On second pass, it seems the walking is just as bad.
Skipping that, and moving on with trying to do torsion node rotation to discover
2-fold axis in 1njm.0, and the goddamn torsion nodes are walking too.


(rbq log, history.txt)
Debugging walking problem. Created more defined conditions
under which this occurs. Set rot center at <0,0,0> and observed
no walking. Set rot center at <0,0,100> and observed large movement of
viewpoint away from rot center in the +z direction with a slight up and down
rotation about the x axis.
One problem: the CGrTransform3f was still using a float version of Rotate().
Fixed it so that the double version is being called. The walking is decreased,
but still there.
As an interim fix, we can try moving the model to the world origin. Later,
I can work on improving the rotation errors.
Added command 'trans selAbs' (translate selection by world-frame coords).


(rbq log, history.txt)
Adding documentation to the rbq-lua interface commands in CRbqLua.cpp.
Got the 'too many open files' error again today after leaving rbq running
for a while. An important clue to the problem is that this ocurred without
any files being input or scanned in the 'input' subdirectory. This points
to the 'findfirst()' call in wkFileUtils::GetFilenames().
Aha. Looking at the documentation for _findfirst(), I see that there is a
_findclose(). Added fix to wklib.


(rbq log, history.txt)
Finished documenting rbq lua interface functions.
Creating html documentation for them.
Wrote script 'tools/doctools/'. It works.


(rbq log, history.txt)


(rbq log, history.txt)
Working on perl script to generate a 2nd html document
for the lua modules.
Finished script 'tools/doctools/'. It works.
Added multiple groups to
Creating model exploration doc exp/mod_1gix_1giy.
There appears to be a bug in the 'view rot d <vx vy vz> <cx cy cz>' command.
When given the view up vector to rotate about, it appears to rotate about
the look vector instead.


(rbq log, history.txt)
No, this isn't a bug. The rot vector is in view frame, not world frame.
Updated documentation for the command.


(rbq log, history.txt)
Added rbq_GetObjectCenter(), rbq_GetObjectExtent().
Multiple animated rotation sequences in exp/mod_1gix_1giy/lod_1gix.lua are working.


Had a somewhat successful demo of rbq for my talk at the ribolab journal club, where I used it to discuss Bashan2003, a paper on symmetry discovered in the PTC of the 50S. Now, I'm finally free to pursue work on rbq without any other jobs hanging over me.

Spent the last 2 days supplementing documentation of the rbq_lua cpp interface functions and the lua system library functions, as well as writing a couple of perl scripts to automatically generate html documents from them. It worked beautifully.

Working on exp/mod_1gix_1giy, an exploration of the low-res 70S structure. With the browser-input scanning bug (too many open files) solved, I'm now considering how to implement scripts with lots of animation sequences in them, to show rotating views of various components of a model.

This raises the question of how to implement a sequence of animations in lua code. Animation code typically needs to run discontinuously, being called every idle tick. But currently, the lua code executes non-premeptively. The simplest, most obvious way (to me) to implement animations with the current system is to define a set of functions, one per animation sequence, and have an animation driver call each function in turn. It can keep calling a function until the function returns true, indicating that its sequence is complete. Then the next function in the list can be called.

Got the animation sequences working. They look good.


(rbq log, history.txt)
Added lua lib function centerObjectInView() (in ViewUtil.lua)
An inconsistency has become apparent in using the function rbq_GetObjectCenter().
For pdb objects, the center of mass is returned. But for residues, the
center of the bounding box is returned.
To eliminate this discrepancy, the CRbqPdbMol and corresponding CRbqDoc functions
should be renamed 'GetXXXMassCenter()' and 'GetXXXBoxCenter()'
where XXX = Pdb, Chain and Residue.
Note: CRbqPdbMol is clearly misnamed. It should be rename CRbqPdbModel at some point.


(rbq log, history.txt)
Changed CRbqPdbMol, CRbqDoc and CRbqLua XXXCenter() functions to XXXBoxCenter() and XXXMassCenter().


Started the riboLit database.


Redid layout of article entry form for riboLit db, entered more articles. 26 articles entered so far.


(rbq log, history.txt)
Added rbq_GetViewXXX functions (XXX = LookDir, UpDir, Center, RotCenter).


(rbq log, history.txt)


Created doxygen docs for wklib library.

Created an example for CTorGraph usage in /proj/wkTest/wkTorsion called 'ex_CTorGraph.cpp', added it as an example to the doxygen comments in CTorGraph.cpp.


(rbq log, history.txt)
Added setting of draw state for torsion graphs. It works.
Added CRbqPdbMol.cpp : CreateTorGraphBondInfo().


Got the changes in the torsion graph code done yesterday so that we have great stability now because the rotation is simply accumulated in an scalar angle variable instead of in a matrix, which quickly accumulates errors after multiple rotations.

Now the question is how to proceed next. One thing which definitely needs to start happening is doing energy calculations on a subset of interest in an rbq document. Also, this interaction energy between atoms somehow needs to be translated into movements, both of translation and rotation around the torsion nodes. It's almost as if we need some new kind of object which represents a 'dynamic' molecular fragment which can accumulate force and velocity and exert force on other dynamic fragments. Such an object reflects previous functionality in earlier versions of the program: segments, hulls, force objects, etc. It should be kept simple and elegant, and interface well with the existing program structure without requiring modifications to it.

Perhaps, before trying to further define such a dynamic object, we should further develop and work with the components, such as steric energy calculation, hydrogen bonds and electrostatics. We can create script objects to calculate and display these things, and the combination can then occur incrementally into a dynamic molecular fragment.

Ok, the first thing is to implement drawing command for torsion graphs. This has been done.

Next, we will do energy calculations between atoms within a torsion graph. Adding doxy comments to eview lib. We have a problem. Currently, only CNsrEncon handles geminal interactions in its steric calculations and the torsion graph data structure doesn't fit the CNsrEncon stratgey for determining geminal interactions. We will likely have to create another encon class for torsion graphs.


After thinking and thinking last night about how to handle the problem of determining geminal atoms for torsion graphs, I came up with a wonderful solution. I call it the 'iterative token exclusion' (ITE) strategy. It works by creating an array of the complete set of atoms to be iterated, and a parallel array of equal size which will hold the ptr token. For each atom, we will compute the interactions with all remaining atoms in the array, but we want to exclude its bonded neighbors and their bonded neighbors (which are its 'geminal' atoms). So at the beginning of each cycle, before computing the interactions, we place the ptr of the current atom in the token array at the positions of its bonded neighbors and their bonded neighbors. Then we can simply iterate all subsequent atoms in the array and skip interactions where the subsequent atom has a token ptr which is equal to the current atom.

Creating class CIteEncon in wkEnconLib. The only other issue is to pass in bond information along with the list of torsion atoms. The bond information can be stored in a single integer array for uniform and efficient lookup using the following format: (O0, O1, O2, ..., On, T0, I0_0, I0_1, I0_2, ..., I0_m, T1, I1_0, ...) O0 = offset to bond info for atom 0 (holds location of T0), T0 = total bonds for atom 0, I0_0 = index to first bond partner of atom 0, etc.). Created CRbqPdbMol.cpp : CreateTorGraphBondInfo().

Finished coding CIteEncon. It's beyond cleaner than CNsrEncon.

Creating bond info in CRbqPdbMol.cpp : CreateTorGraphBondInfo() is too slow for large torsion graphs. Added map for faster lookup, speed is acceptable now. Created a torsion graph for a whole tRNA and it works.


(rbq log, history.txt)


(rbq log, history.txt)
Added CRbqLua.cpp : rbq_CalcInternalEnergyOfTorsionGraph().


I've been looking at the eview library and considering whether to add a new energy analyzer and viewer for the CIteEncon class, along the lines of the CTgaEnergyAnalyzer and CTgaEnergyViewer. However, the interfaces are rather complicated and confusing. It may be easier for now just to write a simple script in the lua interface instead. Ideally, all that I'd like to do is to have a selected torsion graph and just compute the current energy for it. Creating 'CalcIntraGroupEnergy.lua'.

There is a bug in creating pdb surface for a colored tRNA, Assertion failed: CGrPdbSurfFactory.cpp:2129. It happens when coloring the main chain in the tRNA, but the waters in chain b have not been colored.

Finished code to calculate torsion graph energy, calculated the energy for the first 3 residues of 1tra. Got a value of 47.861, which is quite different from the value of -49.479 calculated using CNsrEncon. Now we need to add detailed reporting.

So the logical way to do this is to create an energy analyzer class to work with CIteEncon after all. After thinking about what needs to be done, and how it currently works with CTgaEnergyAnalyzer, a little documentation and UML diagrams may help. We should create an additional interface, CEnergyAnalyzerClient, as well.


Starting creating 16S helix definition file 'seq/E.coli.16SHelices.hlx'. Created genetic code reference table 'doc/html/geneticCode.html'. Finished 16S helix number file.


(rbq log, history.txt)
Fixed bug where we were forgetting to delete torsion graph bond info
when torsion graph was deleted in DeleteSelectedTorsionGraphs().


Added detail reporting to CIteEncon. Found the bug in the token exclusion algoritm (top level ptr was being lost in the recursion). The bug has been fixed, CIteEncon now gives same energy as CNsrEncon.

Fixed a bug related to deleting torsion graph (wasn't deleting the associated bond info). Now that the torsion graph energy calculation appears to be working well, the next step is to calculate and apply forces to get the torsion graphs to move. In looking back at previous code, CRbqForceObject was implemented to provide force calc and movement for selected fragments of a pdb. It wasn't quite working when work had to be diverted to creating surface graphics. It seems now that it should be redesigned slightly to apply to torsion graphs instead of pdb fragments. Also, energy calculations involving pdb fragments should be clearly referred to as energy calcs for static objects as opposed to energy calcs for dynamic objects such as torsion graphs (and subsequent enhancements). Also, CNsrFcon in the wkEncon library should be made obsolete and replaced with CIteFcon.


(rbq log, history.txt)
Rewired CRbqForceObject to use torsion graphs.
Removing drawing of torsion graphs from parent pdb frame.
We have force object movement. It's completely messed up,
but the objects are moving.
Created class CRbqForceDisplay.
Created command group 'ff fo show'.


Finished rewiring of CRbqForceObject to do calculations using torsion graphs. Now we finally having moving objects in the forcefield again, but they're not moving correctly. The next step is to add force info display for debugging purposes. Looking at how the old rb code did it, it seems too complicated. Force objects had CFoProperty components for displaying graphical force information using a force display list which created, drew and destroyed a bunch of individual items each timestep. It seems like it could be simpler. For some reason, the design was influenced by the sound event code, which tried to generate sounds for forces and interactions.

In rbq, the natural thing to do is to create a class which will be treated as an annotation and make queries to CRbqForceObject for displaying things like total force, velocity, etc. However, for interactions between 2 objects (or their component atoms) this will not work, because such information is not stored in CRbqForceObject. Instead, if it is desired to display such detailed interactions, the information can be generated in a detail report file and extracted later by an interested object. This seems better than trying to hook into the functions where the interactions are calculated, as was done in the rb project.

Created class CRbqForceDisplay.


(rbq log, history.txt)
Force display is working.
Added single-stepping of forcefield (command 'ff step [N]').


Display of total force on force objects is working. Wrote script exp\test\testForce.lua to load 2 a.pdb objects and create force objects from them. Debugging forcefield interactions. Added single stepping to the forcefield.

After adding display and reporting of force object properties, the bug has been isolated to the rotation being done around the center-of-mass of the torsion graph atoms. The rotation center does not appear to correspond with where the torsion graph root transform center is located.


(rbq log, history.txt)
Added rbq_RotateTorsionGraph(), fixed bugs in rotating torsion graphs.
Forcefield interactions between 2 a.pdb objects is now working!


(rbq log, history.txt)


Changed the implementation of rotation and translation in CGrTorGraph so that instead of calling the Rotate() or Translate() method, we create a separate transform with the param rotation or translation and then multiply it by the existing transform, as is done CRbqPdbMol. Now rotation of torsion objects work if created from a pdb object which doesn't have any additional transformation done to it. But if the source pdb object has been translated, the rotation of the subsequent torsion graph is still not quite right. Ok, the reason is now clear. The torsion graph is still using the pdb atoms as reference atoms, so that when the pdb moves, the reference atoms of the torsion graph have mode. It now appears that what we need is a torsion graph with reference atoms which are completely independent from the pdb object used to create it. But, translation of the pdb only alters its own frame, not the original pdb positions of the atoms.

Aha - found bug in calculating selection center in CRbqPdbMol, was still adding pdb transform to it. Yes, that fixed it. Running 'exp/test/testForce.lua', the 2 nts are finally doing a dance!!

Now, we must rotation of torsion nodes. Adding torque calc to torsion nodes in CRbqForceObject.


(rbq log, history.txt)
Added class CRbqTorsionGraph, migrated torsion data
from CRbqPdbMol to component CRbqTorsionGraph.
It works.


Been thinking about and working on calculating torques on torsion nodes and of course it is a more difficult problem than originally envisioned. At this point, I am calculating the application of the total force on each atom to each torsion node in the graph, producing an incremental amount of torque on that node due to each atom. The current problem is that I must determine the location of the atom in terms of which side of the torsion node it is located in the graph, in order to apply the torque to the forward or back torque at the node. Forward and back refer to rotation of the atoms below and above the node in the graph hierarchy. The problem is how to efficiently determine an atom's relation to each node. We could obtain the atom's owner node and iterate up its hierarchy to see if the current node is an ancestor. But this seems computationally expensive, especially for terminal nodes at the long end of a chain. And yet, no other obvious optimization presents itself.

At some point, we will need to have residue information for atoms in the torsion graph, so perhaps now is the time to add that, and use that information to determine atom polarity wrt an arbitrary node.

TODO: create a torsion graph manager class as a component in CRbqPdbMol, the current code is getting very messy. Created class CRbqTorsionGraph, moved torsion data from CRbqPdbMol to component CRbqTorsionGraph. It is working.


(rbq log, history.txt)
Finished creating all the support code needed just to
make the simple determination in CRbqForceObject::IsDescendAtom()
needed by CRbqForceObject::CalcNodeTorque() to determine an atom's
contribution to either forward or back torque at the node.
First run of force objects with node torque. The nodes are rotating,
but torques do not appear correct as collisions do not always produced
expected node rotations.
Adding command 'ff fo show nodeTorque <N>'.


A problem exists in defining an origin and direction of a node using member data which store an initial point and vector. Since the intention is to define the node origin in terms of the root atom and its covalent bond to its parent atom, the node origin and direction should be calculated from these atom positions. The stored initial values will become invalid as soon as node rotations occur. Eliminated m_vOrigin and m_vRot from CTorNode, replaced with calculation from node atom and parent node atom. Actually, this really screwed things up. Then, I thought perhaps it is because the unmoved atom positions must be used instead, but using them still gave errors. Perhaps somehow because of node consolidation? It's strange. I restored to the saved position and dir and then it was working again.

Renamed original data values to 'Unmoved' origin and dir, added member functions to return transformed origin and dir.

Found the problem with the node dir: in consolidation, the parent node is NOT necessarily the node to which a child node was originally covalently bonded. We should be able to add 'm_pBondAtom' data and get rid of the origin and dir data.


(rbq log, history.txt)
Added translation of selected torsion graph.
Added commands 'ff fo report atomForces', 'ff fo report nodeTorques'.
Added command group 'ff fo enable'.


Added m_pRefAtom data to CTorNode, removed m_vOrigin and m_vRot. It works as expected. Debugging force interactions in exp/test/testForce.lua, the observed torque on a node is drawn as expected but is too big. Found the bug: wasn't zeroing atom forces at start of timestep.

After adding zeroing, it looks like the node torque stuff is working, at least the node forward rotation. Now we also need to add the node back rotation. This is turning out to be a hassle, looks like we will have a major performance hit as we need to do update atom positions twice for each node back rotation.

Implemented back node rotation, it seems to work. However, after running force interactions between 2 nts for a while, with movement enabled for just a single node on one of the nts, it started to drift, indicating significant accumulation of error in a transform matrix.

Investigating quaternions. Another option is to do periodic normalization of the rotation matrix.


(rbq log, history.txt)
Added command group 'pos', 'pos sel transform [m0 - m16]'.
(getting and setting transform of current selection).
Getting and setting of pdb and torsion graph transforms is working.
Added commands 'ff fo enable nodeFwdTorque', '... nodeRevTorque'.
Added command 'ff fo show atomForce'.
Added command 'ff fo show logScale'.


Read a 9 page debate on the merits of quaternions vs. angle-axis vector methods (between diana gruber and some dude named jason). For now, I will try matrix renormalization, but may well use quaternions at some point. The main issue is the the back-rotation of nodes. I'm worried about the performance hit of having to do atom position updates after every rotation. The reason for the update being that the rotation vector of a node will be invalid if the node atoms have been significantly moved by the rotation of a previous node. But the alternate consideration is that even if the node atoms are in the correct, new position, if they have moved significantly, the calculated node torque may no longer apply anyhow, because the atoms are in a new configuration. So one possibility is to simple rotate a single node every timestep, perhaps using a probability based upon the relative magnitude of its torque. But this could slow things down as well. In fact, in thinking about it late last night, I became rather pessimistic that the whole node rotation strategy is even going to work in a situation such as a highly wrapped tRNA. I suspect that the only way to see interesting phenomenae such as a base flipping out from a helix can only be done using extremely stiff spring forces to represent the covalent bonds. But I could be wrong. At present, will pursue the current strategy. The matrix renormalization needs to be fixed in any event.

After adding rotation matrix normalization, the drift problem seems to be solved. Now, in observing single node rotation in 2 nt interaction, the node is slowly rotating in multiple revolutions instead of hitting a minimum.

Ran testForce.lua for 300k timesteps, still get some drift, but much much less (no visible movement). No wait, perhaps it was just rotation of the base node?

Added enabling of bak and fwd node rotation individually. This allows the spinning base problem in testForce.lua to be clearly visible. I suppose the next natural yado is display of total force on the atoms.

Added atom force code. From arrows, it is clear that atom forces should produce a negative torque at the node at a certain point in the base ring rotation, but it isn't happening. The huge lengths of the forward and back torques at the node make it difficult to see what is happening, adding 'logScale' option to the ff fo show command.

Added the option, and now it is clear that both the forward and back torques at the node are equal large values, indicating that the source of the bug is that atoms upstream of the node are being used to calculate the forward torque in addition to the back torque (most likely bug in 'IsDescendAtom()').

Ran for over a million ts with a single not fwd rot enabled, started to get wobble. Even in the virtual world bearings wear out!!

Found the bug related to IsDescendAtom(). It reveals the peril of using integer indices instead of types (I swapped iNode and iAtom params in the function call). Using integer indexes brings benefits of efficiency (using large parallel arrays of data for many interacting objects) and universal applicability in function calls across multiple class group boundaries (don't need to include internal class typedefs), but we lose the benefit of type safety.

It's working. Enabling all node rotation causes the 2 nts to pack together. However, if we try to rotate a few nodes manually, things get messed up (within the torsion graph of the nt whose node has been rotated). Then, trying a second time, this didn't happen. I could rotate many different nodes and the behaviour still looked good. But another strange thing, as I rotated parts into the other nt, it caused it to move away, as normally expected, except that I had whole-force-body rotation and translation disabled. Strange. Still, things are looking very promising.

Disabling node back rotation eliminates the strange whole body translation and rotation. Perhaps it results from back rotation about the root node? Also, this is occurring after I removed all the intermediate UpdateAtomPositions() in the CRbqForceObject::RotateTorsionNodes() function.

In reflection, it appears obvious that both forward and back rotation from the root node should be disabled because it does not have a valid node axis. This has been done. After running again, it may just be that the apparent translation and rotation of the whole body is really just resulting from the total forward and back rotations of the nodes. In any event, watching the interactions of the 2 nts with all of their beautiful articulations in play is a delight.

Did backups, copied to damnimp. Next: add whole body force and torque calcs. Ok, this has been done, but now we get continual rotation once the 2 nts close with each other. This is to be expected as we are exerting the torques twice, once on the nodes and once on the whole body. Perhaps we should just leave out the whole-body torque? Ok, this appears to work. Next: do intra-force calculations.

Created intra-force calculations, ran it on 2nt.pdb for a bit, with certain node rotations, I induced a persistent whole-body velocity, causing the thing to drift, but with friction added, it shouldn't be too much of a problem. The next thing was to load ahelix.pdb, a 16 nt model composed of 2 8nt strands paired in an A-form helix. Created torsion graphs and force objects for these 2 chains and ran it. The good news is that the performance is fairly acceptable for this larger model. The bad news is that at certain points very jerky interactions are produced, most likely due to a small rotation at a base node which produces a very large movement of nts further down the chain.


(rbq log, history.txt)
Fixed CRbqForceObject::CalcNodeTorque(), interactions between the
2 nts in exp/test/testForce.lua is totally awesome!


(rbq log, history.txt)


(rbq log, history.txt)
Added force enable icons to the forcefield toolbar.


(rbq log, history.txt)
Adding spring bonds to CRbqForceObject.
Created class CRbqDynamicSegment.


Thinking this morning about the torsion rotation problem as it applies to longer stretches of RNA and how it just doesn't seem like it will work because of the movement amplification problem. The torsion graphs work very very well on single nts. The old rb approach of connecting nts worked really well in modeling larger objects such as helices, at speeds approaching realtime, in terms of holding them together with hydrogen bonds. The problem with the old approach was that the individual nt chunks were frozen. So perhaps combining these 2 approaches may give the long sought-after solution? Create a torsion graph for each nt, giving a nice small recursion size, and then connect the torsion graphs with a strong spring bond between the nt's? I don't know if it will work, but at this point I just need to get something that will let me model individual fragments of the small and large subunits, in a way that can produce some indication of potential movements and conformational change. Then hopefully I can stitch together the fragment movements into a coherent picture of ribosomal mechansims.

For nucleic acids, if we split the nts between the P and the 5'O, we can create a spring bond between these 2 atoms, and in addition, because of the nice tetrahedral configuration of the phosphorus, we also have the 3 other oxygens which can serve as anchors. If we create spring bonds to each of these atoms as well, this may provide a good flexible link between torsion graph objects. Duh, we can do the same thing, only between the P and the 3'O, so that the graph exactly corresponds with a pdb residue object.

In between considering the design changes needed to add spring bonds to CRbqForceObject, I've been reading the transorientation hypothesis paper (Simonson, 2002). I believe this will be THE paper which kicks off my attempt to simulate the translation cycle. The anti-codon flip will be a perfect test of the hoped-for flexibility resulting from the new spring bond - nt torsion graph combination.

Since each torsion graph now represents just a single residue, we need to create CRbqTorsionSegment to manage a set of consecutive residues. Really, though, the torsion graph is just an implementation, what we should really specify is something like 'CRbqDynamicSeg' (dynamic chain segment)

Rehacking torsion graphs into CRbqDynamicSeg objects, and rewiring connections between the force objects, dynamic residues and nodes. This involves reworking the interface between the command processor, the main win force container and the document, in accessing selected segments, residues and nodes.


(rbq log, history.txt)
Massive housekeeping recode transferring refs to torsion graphs over
to new dynamic segments.
Program compiles but has not been tested.
Also, various portions not currently implemented in CRbqDynamicSegment.


(rbq log, history.txt)


Major code housekeeping changes in replacing references to torsion graphs and node to the new CRbqDynamicSegment and dynamic segment residues. Got most changes done, it compiles again.


(rbq log, history.txt)
Finished implementing functions in CRbqDynamicSegment.
Added 'node' selection level to mouse selection.
Got rid of CRbqIndexPos::GetIndexList() (was getting confused with CRbqIndexPos::GetList()).
Selection of nodes is working.


(rbq log, history.txt)


(rbq log, history.txt)
Doing paco-based design, adding inter-res init code for CRbqForceObject.


(rbq log, history.txt)
Added class CBsjForce (ball-and-socket joint force object).
Added drawing of inter-residue bonds to CRbqDynamicSegment.


Code has been added to handle the inter-residue bonds for the new dynamic segments. There are still some issues left on how to handle drawing of these bonds. Also, the main question is how to implement the force between the 2 atoms of a pair of bonded residues. Spring bonds definitely will not cut it. I've been thinking of creating 2 shadow atoms at the locations of each atom's bond partner, but which belong the same force object as the link atom of a residue. Then, steric forces could be applied at the shadow center and the atom center in order to produce forces and torques on the residue which tend to move it into a position where the original bond length and bond angle are maintained.

One requirement for implementing a shadow atom is that it will need the local transform frame of the link atom. This seems to require adding extra data to the current torsion graph library, something I'm reluctant to do, but don't see any other convenient way of retrieving a node's local frame by an external client.

Also, gave a brief demo of the program to my cousin Bob yesterday, but it was pretty lame. I definitely need to write up some demos which just use the existing rigid body capabilities at the very least.

Well, I added m_pMonitorFrame to CGrTorNode member data. I hate to add unnecessary data, but it's only 4 bytes for a ptr value, and the memory and computation overhead are minimal. Next, we need to create a component class for CRbqForceObject to calculate the forces needed to maintain the inter-residue bond. Created class CBsjForce. In reflection, this approach appears to be pretty much the last thing I was working on in molecule theatre for covalent bonding using electron point charges. In that project as well, I tried to maintain a covalent bond by using 2 points on each atom as handles to exert force and torque to maintain the covalent bond angle. The problem in mol theatre was that the electstatic force dropped off with distance, so that if the fixed electrons moved too far away from the orbital attractor points, the bond became broken. The key improvement here may be to define something like an inverse steric repulsion force, where the attractive force increases the farther away the point gets. Of course, this is essentially the same as a spring bond, except that it uses an exponential instead of a linear force term. The 'extended region' for applying this force can be thought of as resulting from the extended region that an orbital electron occupies in space. The other difference is that the force will also result in a torque which is applied to the whole body of the force object. In mol theatre, I didn't think about how a torque could be applied to the atom and it's other orbitals. Perhaps applying that idea could make mol theatre workable.

The idea of adding the monitor frame variable appears like it will work very well with CBsjForce because the unmoved atom of force obj j, when transformed by the concatenated torsion frame of obj i, will be at the shadow atom position needed for the force calculations!

Added drawing of inter-residue bonds to CRbqDynamicSegment.

Debugging inter-res bond force calculation, with graphical display, it's coming along well.

No, not really. Lots of force debugging is still needed. Arg.


(rbq log, history.txt)
Added code to delete force display objects when force objects deleted.


(rbq log, history.txt)
Backup prior to cycle sim work.


Started work on the simulation of the translation cycle. First step was to read the 'Programming in Lua' book. Now I know how to do object-oriented programming in Lua. Cool. Created class CPdbModel30S. It works.


(rbq log, history.txt)
Added caption param to rbq_GetInputString().


Finishing creating helix definition data for 16S. Also created html documentation of seq tools in doc/html/SeqTools.html. We need to change the format of the helix data files to split helix num field into helix index field and helix num field, which can be non-numeric (i.e.: helix 35a in E. coli 23S helices). This will break scripts. The lua code is starting to get complex enough to require unit tests. Where will the time be found??!?


Wrote script seq/, found 3 errors in E.coli.16S.hlx. Found 5 errors in E.coli.23S.hlx. Updating _SeqUtil.lua.

Got an idea for working with large torsion graphs again in case the spring-bonded residue force objects don't work out. The idea is that with every rotation at a node, and the resulting large displacement which can occur for extended chains, we can compensate by doing counter-rotations from the next 3 or so nodes downstream to bring the downstream portion back to its original position, or at least to approach it. The trick is determining what counter-rotations to do, absent a solution to the inverse kinematics problem. Since the solution only needs to be approximate, and the rotations fairly small, the following simple algorithm might work: calculate the resulting position of the downstream portion for a small fixed rotation, + and -, for each of the 3 downstream (or simply adjacent?) nodes. Pick the one which moves the downstream portion nearest to its original location, and then repeat until the original position is reached within some delta, or a maximum iteration limit is hit. If the original position cannot be reached, we could simply undo that particular initial node rotation and try a different one.


(rbq log, history.txt)
Large rewrites in _SeqUtil.lua and seq-related scripts.


(rbq log, history.txt)


Fixing lua sequence code. A lot of the rework involves replace helix index params with sHelixNum params. This is one illustration of the value of using iterator-type code instead of for loops. A lot of the new code replaces for loops which iterate using index with 'getNextHelix( sCurHelix )' type of stuff. This is especially useful for collections where the sequential set of items may change in some way, invalidating a simple index request. Of course, it is also more compatible for data structures where the items are not stored in a simple array as well.

Another problem is emerging: because the current code is using file names as handles to helix and sequence map data, there are compatibility issues concerning whether the base path is tacked onto the file name. This has been fixed by having all functions accept just the simple file name and tacking on the base path internally.

Utility script GenHelixFileForChain.lua is finally working. Generated helix file for 1ffk.0. But it sure does run slowly. At some point in the future, the code should be modified to load the sequence map and helix data into memory instead of reading from file. But for this one-time-utility, speed doesn't matter.

Note to self: use the floor() function when using the mod() operator in Lua.

Script 'SeqHelixSelect.lua' is working!


(rbq log, history.txt)
Added command 'pos sel cen [x y z]'.
Created class util\CRbqArrow.
Added flag to prevent re-entrancy in CRbqLua::RunScript().


Finishing up sequence work to enable selection of 16S helices. Created 'CreateHelixArrows.lua'. Created class CRbqArrow.

The helix arrow script was mostly working, but then ran into a tricky bug where the lua getglobal() returned corrupt data for the draw.lua script for the helix arrow script object when another script was being run. This was because for the first time, we were having re-entrant CRbqLua::RunScript(). Added a flag to prevent re-entrancy from occurring, but now the draw script fails for the script object. It seems like the script object must check for run deferral if another script is running.

Added CRbqLua::IsScriptRunning() and check in CRbqScriptObject::RunScriptFile(). It works!


(rbq log, history.txt)
Discovered the joys of Edgar Toernig's pack() function in lua, added to ScriptUtil.lua
Working on 'HelixArrowAlign.lua'.
Initial helix align is working.


(rbq log, history.txt)


Working on 'HelixArrowAlign.lua', a script to align 2 pdb models using helix arrows. It's a lot of work. Got the initial helix alignment working.


(rbq log, history.txt)
Added command 'pos sel resetTransform' (reset transform of selection).
Added interface func rbq_GetScriptObjectVar().


Getting closer on 'HelixArrowAlign.lua'. Almost have calculation of rotation angle for second helix align.

Secondary helix alignment is now working. Now we need to add rbq_lua func to access script object vars from lua scripts, which requires a detour through the rbq code to get to the CRbqScriptObject memory. This indirect access is currently required because of the single Lua context currently being used for all lua code. Eliminating the need to switch contexts may be giving benefits of more stable scripting code, but we pay for it a little bit with this indirect access. However, it can all be hidden behind library functions so who cares at this point? Added function rbq_GetScriptObjectVar().

multi-helix rms calc is working in HelixArrowAlign.lua. Now we just need to add exhaustive secondary align (to see if it's better than the angle-midpointDist estimation).


(rbq log, history.txt)
'FindBestHelixAlign.lua' script works.
In aligning 1fka.A to 1gix.A, got best RMS of 4.737 using helices (21, 44).
In aligning 1ffk.0 to 1gix.A, got best RMS of 12.487 using helices (65, 67).


(rbq log, history.txt)


Debugging large RMS values in Haa.lua. Added _GeomUtil.lua function 'alignPdbFromHelix()' which abstracts code from Haa.lua to do a single 2-helix alignment.

Finally got helix alignment completely working once I realized that I had to calculate the vRot for the second helix alignment using the crossproduct of the 2 projected vectors instead of using the first helix aligned axis, because the cross product gives you the correct direction for rotation.

Finally got comprehensive helix alignment script done. Trying to predict the best secondary helix alignment didn't really work, so the script just tries all of them for each first aligned helix. In aligning 1fka.A to 1gix.A, got best RMS of 4.737 using helices (21, 44). In aligning 1ffk.0 to 1gix.A, got best RMS of 12.487 using helices (65, 67).


Spent some time trying to get a handle on how the object-oriented lua design is going to be implemented. The colon operator provides a mechanism for inheritance, along with the settag method for dispatch. But after experimenting a bit, I preferred to avoid using inheritence and focus exclusively on composition. This requires explicit passing of an 'obj' param in many of the function calls, and explicit reference of class names, but that doesn't seem too much trouble, and looks like it will be more straightforward and predictable than 'behind-the-scenes' tag method calls. Also don't need to worry about multiple inheritence issues. Still, the existing work done is too prelminary to know how well it will work or what other problems may crop up. So far, created 3 classes: sub30, CPdbModel30s_1fka and CPdbModel. The cycleSim page currently has a script to load the 1fka model and rotate and position it into a standard orientation and position which is best aligned to 1gix manually centered at the origin.

Now we need to consider how to add animation and timeUser code to the scripts.

Added cycleSimTick() and associated script object. It works. We have an animated movement of 1fka to center stage!

Wasted 2 hours because of 2 small bugs, 1 in _VectorUtil.lua, the other was an ref of one class in another class function in exp\cycleSim. arg!! Need unit tests and syntax checking for lua!


(rbq log, history.txt)
Interp dock of mRNA with sub30 is working.


(rbq log, history.txt)
Added a bunch of param checking code to _VectorUtil.lua
while debugging the cycle sim scripts.


(rbq log, history.txt)
Hooking animation enable to forcefield run.


Aside from the problems last night, I changed the positioning and orientation code to used a single composite variable called tLoc, which holds a pt and 2 directions. Also changed the CPdbModel functions to curLoc() and stdLoc(), and added interpToLocation(). This works well in moving a pdb model from an arbitrary position and orientation to a defined one, in a smooth animated way.

But now, I am trying to add IF2 and fMet-tRNA to the simulation and there is the new requirement to position one model at a specific position and orientation relative to another model.

After reading and thinking, it seems the best way to achieve alignment of one object in 3D relative to another, using features of the objects to get an origin and 2 directions for each object, is to define a local coordinate frame for the 1st object from the 2 directions. Then, we take the point and 2 direction vectors of the 2nd object, when it is in alignment with the 1st object, and convert them to the local frame of the 1st object from the world frame (using the transpose of the matrix formed by the basis vectors of the local frame). Then, subsequently, during interpolation, these location values can be converted back into the world frame, where they can be used to align the 2nd object to the 1st object.

However, after thinking a bit more about the general requirements during simulation, it may be more important in the short term to simply drive association between 2 objects (such as IF2 and tRNA-fMet) by using spring bonds between residues which are known to be associated. This seems a little more realistic (if less precise) and more generally useful than simply interpolating to absolute frozen crystal alignments.

Adding enabling of animations (timeUser script objects) to the 'forceField Run' control. Adding this was good. Now we can single step the animation of the mRNA approaching the 30 and see where collisions need to be modelled and forces applied.

Could efficient collision detection be done by calculating residue intersection for each timestep and then re-running it with steric interactions enabled for intersected residues?


(rbq log, history.txt)


Added tRNA-fMet component to cycleSim. We now have 3 pieces docking in the simulation.

Starting on IF2. For now, just added simple position interpolate to get a residue on IF2 to coincide with a res on tRNA-fMet.

Added sequential and simultaneous move sequencers. They work.


(rbq log, history.txt)
Added 'ann insSphere' command.


(rbq log, history.txt)
Added rbq_GetAtomPos().


Finally got world-to-local frame functions working in Lua. These are used to calculate docking points for one molecule relative to another. For some reason, it took me a long time to get it right, not sure why. All you need to do to calculate world-to-local frame is to calculate a local coordinate frame consisting of a origin point and 3 orthogonal unit vectors. This is easily done from the existing code which calculates an origin and 2 direction vectors from residue backbone atoms. Then, once you have this local frame, you can easily convert a point from the world frame to the local frame by first subtracting the local frame origin and then multiply the point by the local frame matrix (which simply consists of the 3 unit vectors). Then, to convert back to world frame from the local frame, all you do is to first multiply the point by the inverse of the local frame matrix and then add back the local frame origin. Simple. But making a couple of bugs in the test, combined with a little confusion about this process, which always seems to give me a hard time, caused much delay and annoyance.

Great. Got the docking code done, only to find minimal homology between marzi's c2 domain if2 and 1g7t.pdb.


(rbq log, history.txt)
Added command group 'draw surf'.
Transparent surface rendering is working.


Adding transparency to drawing of surface meshes. Before doing so, added setting of wireframe, which is a cheap transparent option.

Transparent rendering is working, and looks fairly decent after changing glBlendFunc dest factor from GL_ONE to GL_ONE_MINUS_SRC_ALPHA. Still, it seems as if it could be improved. The problem is that multiple layers of surface add together to give a brighter image than seems desired.

Now that we have transparency for surfaces meshes, I have to fix the 'inside-out-little-blob' artifacts which appear in the interior of the mesh. This occurs when there are small regions in the interior of the pdb model which are outside of the isosurface, but are completly surrounded by regions inside of the isosurface. I'm not sure if there is a simple way to solve this however.

An algorithm is formulating in my head. It really needs to be solved because the 50S is a mess when meshed, regardless of the resolution, rendering transparency pointless for it. The algorithm might work by considering an initial partial isosurface cube which touches outside space. This cube is tagged as 'visible'. Then, we iterate all neighbors of this cube and tag all adjacent neigbors which are partial isosurface as 'visible' also. Then, we visit each visible neighbor, and iterate all of its neighbors, tagging all partial ones as visible, until no new neighbors are found. This should leave the internal cubes as untagged islands, which we can consider as non-visible. This algorithm won't work for discontinuous visible chunks, but if we also modify the input to use chains instead of pdb models, that should not be a problem.

Another issue, perhaps, may just be an implementation issue, is that if recursion is used, it may blow out the stack for large models, but perhaps there is a non-recursive implementation (layer-based?). On reflection, it seems that recursion will be needed, but we don't need to do function recursion. Instead, we just use a stack of nodes.

As I consider this change, another idea comes up. The idea of transparency is probably most useful only for sections of the molecule. Since the smooth color mesh code already provides for coloring the mesh from residue color, an easy way to implement selective transparency is to define a specific color which would be considered as transparent, and do the alpha/glBlend calls for that color. This could be done by adding a function to CWkSmoothColorMesh such as SetDrawIfTransparentColor( vTransColor, vDrawWithAlternateColor ). The only limitation of such a scheme is that all transparent triangles would have to be drawn with the same alternate color (unless, perhaps we used a table of multiple 'transColor', 'drawColor' pairs). In practice, however, that may not be an issue.

Just spent a couple of hours trying to find a very annoying bug where using the color of a mesh triangle to draw as transparent wasn't working properly. Now I believe I've found the source of the bug in the encoding of the floating point rgb color into an 24 bit value in CGrResidue. Arrg. No, that's not it. It's the color averaging that is done in CGrPdbSurfFactory::CreateSurfaceMesh(). For Huff's sake. Removed averaging, it wasn't needed anyway. Problem solved.

Finally have a solid meshed 50S with a single helix shown as transparent. It looks cool.


(rbq log, history.txt)


(rbq log, history.txt)
Moving spacefill hotkeys to surface (spacefill too dangerous anyhow).


Added default coloring to graphical residues in CGrPdbObj.

Debugging the ASSERT in CGrPdbSurfFactory::CreateSurfaceMesh() where the offset in the atom color info array doesn't match the pdb object atom array, I wonder how it could have ever worked, because TER records can be assigned their own ATOM serial. Instead, I just should have added the ATOM ptr to the atom color info.

Backed all new changes to damnimp.

Made a nice big transparent window in the 50S using the selection sphere. It would look great except for all the blob junk inside. I'd like to implement that visible tagging algorithm for the surface mesh, although I should really get back to work on the cycle simulation. Also, really need to add a 'drive around' option where the view rotation center tracks the current view. Well, shoot, the next thing to add in the sim is the 50S, and if I don't have a decent looking surface shell, it's gonna look like crap. Starting on the blob removal code in CGrPdbSurfFactor.

Came up with a fairly simple non-function-call-based recursive algorithm.


Implemented the algorithm without too much trouble, but the results were fairly disappointing. The island-removal is easily the slowest part of the meshing. For 1kpj, in debug mode at 4 A resolution with 1.8 vdw expansion, the removal part seemed to take at least 2 minutes. Also impossible to properly estimate the progress. In the end, it didn't really work as well as hoped, because lots of blobs were still in the interior. I believe this is because the gridpoints of the blobs are still within one neigbor distance to the surface. Out of about 220,000 cells, approximately 2300 were removed. At this point, my best bet may be to just manually tag blobs for removal.

Adding IF2 from 1hr0 pdb to sim. Created helix and smap files for 1hr0. Best align between 1fka.A and 1hr0.A is helix (21, 38) (5.324 RMS). Aligned the pdbs and saved align position of IF1.


Looking at IF2 - 50S docking papers. There is a bug in drawing transparent surfaces where the backbone of anohther molecule is not being hidden (because depth test is enabled). Can it be fixed by drawing surfaces in a separate loop?

While investigating that bug, found another in creating surface for tRnaf.pdb. Found the cause of the 2nd bug, for some reason, the code skips HETATOM atoms when calculating pdb extents. Why? Looked at the original msurf code, didn't see any notes on it. Removed HETATOM skip, that problem is fixed, but there is another surface mesh bug where the transparency isn't right when viewed from a particular angle (something to do with depth disabling I think). It's only really noticeable when the transparency is down around .1.

After thinking, reading and experimenting, the transparency viewing problem seems to be due to the back-to-front draw ordering because the depth buffer is made read-only. This appears to be a fairly difficult problem to solve if drawing back to front is the only solution. It is true that the surface as a whole is created with a well-defined orientation, so a partial solution to the problem could be to detect the angle of the surface model direction with respect to the current viewing direction and flip the drawing order if the model arrow is pointing away from the viewing direction. This should produce correct drawing for most orientations, but not all, because in an extended model, when the model direction is nearly perpendicular to the viewing direction, some triangles will be seen as pointing away before others. Still, this hack should be tried as it will improve the appearance over the current situation, where the model is drawn correctly in only about one half of the possible orientations.


(rbq log, history.txt)
Added UpdatePdbView() when showing pdb tree widget.
Adding 'Fly' move to navigation.
Made CRbqGraphicsWindow provide 'COffsetViewI' interface instead
of exposing COffsetView component to CViewMover.
Added mouse rotate z command.


Adding zorder-flip to CWkSmoothColorMesh. Added it. As predicted, there are a few leaks at certain orientations, but in general it works fairly well! Also, thanks to the foresight of adding a DrawContext param, I was able to set the current view direction in the param and handle z-order flip for both view and object transformations.

Now I really want to implement 'flying' navigation, internal surface rendering and clean up the inside of the 50. First step: create a nice 'flying' navigation icon for the toolbar. Found a dragonfly.

Some object-oriented design notes in implementing the 'fly' code: There is a CViewMover object which operates on a CView object to translate and rotate it in response to input from a CTransformController object. In the Translate() method of the CViewMover object, I needed to update the rotation center of the view object. Initially, I just did a dynamic cast to the COffsetView object which it really was, and then updated the rotation center by doing a call to the methods of COffsetView. But the problem was that the graphical axes which represented the rotation center were not being updated when the rotation center was changed. This was because I had exposed the COffsetView directly to the CViewMover object, whereas in other areas of the application, calls to SetRotationCenter() went through the CGraphicsWindow object, which owns the COffsetView as a component, and updated the graphical axes along with it. So I realized that I shouldn't have exposed the COffsetView to the CViewMover, but instead, require the view mover to make calls through the CGraphicsWindow instead. Initially, I considered making the CRbqGraphicsWindow inherit from COffsetView, but this would have required writing a zillion wrapper methods for CView and COffsetView methods. Instead, I created a 'COffsetViewI' interface object, which just provides the COffsetView methods needed by CViewMover, and had CRbqGraphicsWindow implement this COffsetViewI interface.

Implemented fly code, it works. Mein Gott, how did I live without fly mode for so long??!!? Next, we HAVE to implement z-axis rotation. Hardest part is creating the new icons. Done.


(rbq log, history.txt)
Finishing rotate z code. It works.


(rbq log, history.txt)


(rbq log, history.txt)
Moved development 'ann insXXX' commands to 'dev insXXX'.
Moved 'edit insRuler' to 'ann insRuler'.
Adding command 'ann insLine'.
Added class CRbqLine to rbq util lib.


Finished implementing rotate z code. It didn't take long and works beautifully!

Working on cycleSim addition of IF3, also adding to the ribolit database and references to papers and models in the cycleSim html pages.

While reading the ribo papers, I often refer to pdb models in rbq. It would be nice to have labels for things, such as proteins and helices. This always produces the question of where to put the label in a 3D model where it is likely to be visible. After thinking a bit, I considered a scheme where a line is drawn from the center of mass of the entire pdb model to the center of mass of the chain or helix to be labelled, and then continue this line for a little distance (say, for half the longest bbox extent of the pdb), and at this endpoint we can put the label. This might be a nice automated algorithm for label placement, I must write a script to try it out!

Adding command 'ann insLine'.

Here's another cool idea: just as MSVC has 'tip-o-the-day', I should add 'ribo-paper-o-the-day' to rbq. Features: 'don't show again', 'next/prev tips', 'show again on exit'.


(rbq log, history.txt)
'GetChainDescrip()' methods to doc chain.
Added support for chain labelling script 'CreateChainLabels.lua'.
It works.


Creating 'CreateChainLabels.lua' script. Fixing bug in CFastPdb::FindBackboneAtomInResidue() where I had previously assumed that residues must be either nucleic or protein, with bb res name of ' P ' or ' CA ' but this is invalid because you can have single metal atoms as residues. Fixed.

Chain labelling script is working and I even added a script to randomly color the chains so that we now have some very pretty models with labels. But yet another refinement that would make it better would be if we could create surface meshes for individual chains instead of the entire pdb, so that the main RNA chain could be made translucent and the individual proteins could be seen clearly. This, combined with blob elimination should make for some execellent displays of the ribosome.


(rbq log, history.txt)
Added multi-chain surface mesh creation.


(rbq log, history.txt)


Considering how to implement multi-chain surface meshing. It looks like the simplest way, at least from the standpoint of CPdbSurfFactory, is to create a separate mesh for each chain, and have CGrPdbObj render a list of surface meshes. This should just require passing an additional atom list into the factory which is the chain subset of atoms (and potentially, any other subset).

Amazingly, when I created the original msurf project, I used a reference to a CFastPdbObj object, but it turns out that it is not even needed, once I changed the atom coloring code. All we need is an atom list to do the meshing, enabling the new changes to be easy.

Well, I successfully implemented the multi-chain surf mesh creation, and it works well for solid rendering, but of course, it messes up the whole z-order rendering scheme when one of the chains is transparent. Damn. However, there is a fix. Just render the transparent chains after the solid one. Almost to graphic nirvana. Now just need to skip the metal chain. Done. With a particular random coloring, in white bg, and labels added, it does look nice. Also, now that we render chain surface meshes individually, we can implement chain selection by surface mesh picking.

Trying to quickly add chain mesh selection. Did it! Now of course, that we can select chain by mesh, we want to set chain mesh color, transparency, etc. It may take a little time to define the proper ui, as we would like to have the option of one color for the mesh, and another for the backbone? Also, currently, each group of visible chains are created concurrently, but ideally, we should just create a mesh per chain, individually. It looks as if we need to make the mesh a fully-qualified chain attribute in CGrPdbObj. But, must backup now.

Posted a nice screenshot of 1kpj on my blog.

Entered some additional articles in the ribolit database and created some more category lists of ribo papers in exp\cycleSim.


(rbq log, history.txt)
Added graphic selection state to surface meshes for individual pdb chains.
Added surface menu and toolbar.
Working with bgcolor of white, so changed default
ortho text color to be always visible against current bgcolor.


Created 'Surface' submenu and toolbar, 'createPdbSurf', 'createChainSurf', 'MoreTrans' and 'LessTrans' items.

Back to work on cycleSim. Improved bgcolor, vol color and ortho text color. Noticed for the first time that there is still a z-order problem with transparent rendering. The backbone of the mRNA model is always being drawn in front of a transparent surface for the 30S. It looks like we will have to do a global '2nd-pass' rendering for transparent objects, not just in CGrPdbObj. Obvious in retrospect. Also, in closeups, the z-order flip edge region looks really bad. Woah, here's an idea: create 2 surface meshes at right angles to each other, and always render the one whose model vector is most parallel to the view vector. Or actually, it would it take 3 models. Expensive, but it should work if needed. Man, that is a slick idea, I better publically prior-art it so some lamo doesn't try to patent it.

On further thought, we only have to do a single mesh creation. All that needs to be done is to create 2 additional triangle index arrays which are sorted according to location along the x and y axes. I'm sure someone must have used this strategy already, it would seem to be a common solution to rendering transparent 3D meshes.


About to start implementation of the tri-axes mesh sort, but first, I must mention some thoughts I had this morning while reading the Gualerzi 1990 review of initiation. It may be fruitful to model some of the mismatches that may occur during initiation. If we place the mRNA and non-cognate tRNAs in the canonical locations and try to observe the differences in the resulting interactions, as compared to the cognate components, this may provide useful information.


(rbq log, history.txt)
Clean rendering of transparent surface meshes is now working after
adding triangle sorting for all three axes.


Finished implementation of CWkSmoothColorMesh using sorted triangles to fix transparent rendering flaws, it works beautifully!


(rbq log, history.txt)
Added 2nd-pass rendering for transparent objects to CGraphicsWindow.
It works.


(rbq log, history.txt)


(rbq log, history.txt)
Adding annotation command 'rbq_DrawBox()', class CRbqBox.
(for drawing camera positions).


Adding CWkGraphicObject::DrawTransparent(), 2nd-pass rendering for transparent objects. 2nd-pass rendering is working. mRNA now shows properly against a transparent mesh of the 30S. After backing up, back to work on the cycle sim.

Started adding a camera to the sim. Initial camera code is working, but now the question is what rbq lua lib module to put the camera functions in? _ViewUtil.lua or create a new _CamUtil.lua? Since _ViewUtil.lua is an interface to the view functions in rbq, which knows nothing about cameras, better to create a standalone camera module. Working on _CamUtil.lua.


(rbq log, history.txt)
Renamed rbq lua module 'DrawUtil.lua' to 'ChemDrawUtil.lua'.


Added graphic state ops to rbq lua libs so I don't have to keep passing 16 float homogenous matrices in all the drawing calls.

Have a working drawing of a camera in the graphics window, but the depth testing seems a little off on it. Did a little net research and OpenGL reporting, turns out the default depth bits size is only 16 bits and there is no obvious way to increase it! Funny that I never really noticed this before.

Wasted a lot of time trying everything I could think of to get 32 bit depth buffer in QGLWidget, including creating a class derived from QGLContext, whose method choosePixelFormat() was successfully called using an appropriate PIXELFORMATDESCRIPTOR, but the resulting graphics context didn't have any lighting and reported a bogus pixel depth. Arrg.


Adding camera transform ops. The code is basically a redo of the C++ CGrTransform3f into lua, although I was hoping to simplify it. However, it seems necessary to do all transform concatenations using 4x4 homogeneous matrices, and then always have to do an extractTranslation() call to get the translation back into the tFrame.ptOrg data vector. For some reason, I thought that it should be easier to do transform concatenations if the rotation matrix and translation vector were kept separated, but this doesn't appear to be so (or I just have no idea how to do it). Camera transforms are working.

Created exp/cycleSim/modelAlignments.html to document all the details of the models in the initiation phase.

Created init phase scene director, which controls object and camera movement. Created 2 cameras, they are almost working but something is not translating correctly from the camera frame to the homogeneous matrix used to draw the camera. It's amazing how much trouble these camera/frame operations give me, but I think I almost have it. The lua tFrame data structure defines a coordinate frame through a an origin point, ptOrg, and a 3x3 rotation matrix where the rows define the x, y and z directions of the coordinate frame. I created a camera which has been translated to (0, 0, 450) and then rotated 180 degrees. After the translate and rotate operations, a print of the camera frame gives the expected origin and matrix, or the negation of the origin, depending on how various operations are defined.

The whole trick to this stuff is figuring out whether to use a matrix or its transpose, which order of matrices to use in multiplication, whether to use row-major or column major order, and so on. I will make a few notes here to help in figuring out how to fix the thing. First, I note that in OpenGL, when a model matrix is translated to a certain location, and an object is drawn there, such as (x, y, z), this is reflected in the modelview matrix at m[12], m[13], and m[14] without any change of sign. When a glMultMatrix() is done, the order of multiplication is mn = mc * mp, where mc is the current modelview matrix and mp is the param matrix.

Fixed some annoying bugs in the translateFrame() and camfront setup code, but still faced with the fundamental problem that the homogenous matrix gives the negation of the frame origin. Now here is something which just occurred to me. I think of the frame as an object which can be transformed, relative to the world. But when doing things like glTranslatef( pt.x, pt.y, pt.z ), where we 'move' to a point in the world, which becomes the 'origin' for the object at that point, we have also, in a sense, translated the frame of the world to (-pt.x, -pt.y, -pt.z). So, perhaps, when I do the extractTranslation() function, I should negate the values? This is not what is done in CGrTransform3f in the grMatrix lib, but perhaps that is because that library also does a bunch of multiple negations?

No, I don't think negating in extractTranslation() will work, because it will give negative values even when no rotation exists. Perhaps the problem is that the 'translation' as extracted from a homogenous matrix just doesn't have a good correlation with the ptOrg of a coordinate frame? Should we just use the [m12], [m13], [m14] values from the homogenous transform matrix instead? If so, what is the purpose of the vTrans component in CGrTransform3f? It is there so that it can be recombined with the 3x3 rotation matrix. So, we must have it in the tFrame data struct. We just can't think of that as the frame origin. Perhaps this is the source of my continual confusion when developing the CGrTransform3f class. That I somehow felt that the translation component should be made to look like the world-frame point which described the origin of the transform frame. But it isn't. It's purpose is to hold the 3 float values which are used to build the translation component matrix, which can then be multiplied by the rotation component matrix to produce the transform matrix.

Used hmatrix translate values for ptOrg in setting camera view. But things are still not right. For cam30, we have done a translation of {-50, 0, 0} followed by a 90 rotation about the y axis. This puts the cam in the correct location, and pointing the right way, but the frame direction vectors are wrong. Perhaps this is because I converted the frame row vectors to homogeneous matrix column vectors? That is something different from CGrTransform3f. The transpose vectors are the correct ones. Doing another flip. This is done in 3 functions in _VectorUtil.lua: extractRotation(), getHMatrixFromFrame() and getFrameFromHMatrix().

Ok, that fixed it. Both cameras are working now!! Cameras and objects are moving from direct_initPhase.


(rbq log, history.txt)
Adding mass and box center cacheing to CRbqPdbMol because we can't
have calculation of 50,000 atoms every time a camera increments
toward a molecule.


One week to demo. Added circleCam. Adding interpolation methods for cameras. Adding mass and extent cacheing to CRbqPdbMol so it doesn't have to be recaculated for every tiny camera interp movement.

One thing about work yesterday concerning the reimplementation of object frames in lua, one remaining difference from CGrTransform3f is that CRbqPdbMol does updating of its CGrTransform3f by doing a matrix multiplication opposite that of OpenGL and the lua functions. That is, for a translation, it does m_transform = translateTransform * m_transform. This may be a backwards artifact which should perhaps be fixed at some point, as the current fix may involve always specifying a calculated rotation center, whereas the OpenGL and Lua way automatically cause rotation about the center of the current object frame. The consequence of always calcuating a transfrom involving a center offset may be the greater accumulation of errors, as was seen in some of the long torsion simulations.

Fixing a bug in _GeomUtil.lua calcRotVector(). It rotated the wrong way for some reason and ended up with a zero vRot vector when the angles were 180 degrees out-of-phase. Actually, it's because the rotateFrame() code follows the left-hand rule for rotations and CRbqPdbMol (using CGrTransform3f) follows the right-hand rule for rotations. Switching sign in rotateFrame code so that it's rhr too. Ok, circleCam move 1 is working.

This camera code is a lot of work, but it's great stuff because not only will it make the rbq demo look cool, but I think it will come in useful for future applications involving games, alife, ai and robotics.

That discrepancy between ptOrg and vTrans is going to be a problem in using the tFrame data structure. Should we have both?

Fixed pt_LocalToWorld( tFrame, ptL ) and pt_WorldToLocal( tFrame, ptW ) using getOrigin( tFrame ). db_circ.lua shows valid conversions. I am going to bite the bullet and just replace tFrame.ptOrg with tFrame.vTrans in all lua code.


(rbq log, history.txt)
cycleSim demo camera work is coming along well.


(rbq log, history.txt)


Working away on the camera code. Still trying to get circleCam functions working. It's a lot of work because it involves shaking out bugs and limitations in the lua lib vector and geometry functions. Stuff like handling vector angle calculations for angles 180 degrees out-of-phase and such. crossProduct() gives a zero vector for such situations, so the current calcRotVector() code fails. The fix isn't a big deal, just need to return a 180 deg rotation about an arbitrary perpendicular vector, but there have been lots of little things like that which I have been continually adding in the last couple of days. It's a pain. But you only have to do it once, right? At least, in any given library!.

Added rotation about center point for lua frames. circleCam is working!!


(rbq log, history.txt)
Added CRbqLua.cpp : rbq_DrawOrthoText(), rbq_DrawOrthoPoly().


Added ortho text and background drawing to rbq for info captions in cycleSim.

Added billboard object to cycleSim, showing pdb info during circling. It works.


Moved cycleSim startup and support code into functions of object cycleSim. Moved billboard descripts into pdb models.

With the 50S loaded, things are starting to get a little slow. Wonder if there is the time and benefit for doing vertex arrays on the surface meshes?


Trying to move along with the sim, but constantly dealing with re-org issues in lua coding. Adding 'setup_xxx()' functions for all direct_initPhase move functions so that I can set the simulation to an arbitrary point in time so I don't have to constantly keep running the damn thing all the way through to debug. In doing so, I started reorganizing and filling out some of the location code in CPdbModel, and realized how incredibly inefficient the current curLoc() code was, because it was doing a lookup of atom positions from residue names instead of residue indices, so we need to do a residue index lookup just once at object init time. No big deal, just a time-distracting hassle.

Now, adding setting of simulation to specific sequence points.

In doing this, things get complicated. Also, to maintain the capability to interpolate objects to their docked positions, indepedently of the current state of the director script, we need to add a separate tick function to the cycleSim script object. Ack. Either that, or we could temporarily disable the direct_initPhase() tick func. Actually, perhaps a combination of both is needed, whereby we push the current tick func onto a stack and run a new one, which can auto-pop when all of its component functions have been removed. Yes, this is the way to do it.

Did it. It works


Trying to finish up the 'goto sequence point' code in the cycleSim. One additional issue has come up in setting pdb objects to a std location (position,orientation) where the location origin point is different from the object center, which is defined using center-of-mass. Modified CPdbModel methods which receive a tLoc parameter to use the ptOrg point instead of center of mass.

Fixed bug involving cached center-of-mass in CRbqPdbMol::Rotate() where I foolishly assumed rotation would always be around object center-of-mass.

Finally finished step-by-step setting of sequence points up to tRNA-fMet walkon. Started work on IF3.

Finished dock of IF3 and ternary dock of IF3, mRNA and tRNA-fMet. Also, all checkpoints finished. Whew!


(rbq log, history.txt)
Added bug fix to c-o-m flag in CRbqPdbMol::Rotate().


Starting on docking of if2 in cycleSim. Taking a little time out to try to record the Blue Danube track off my legally purchased 2001 DVD so I can play it for a demo via mp3. Before trying it out, got a nice dock of if2 on 30S using Stefano's constraints!

Finished if2, starting on sub50. Finished sub50 up to dock 1.

Did a successful sound capture on blue danube from 2001 DVD, added rbq_SpawnProcess() then had to add rbq_WinExec() so I could set the damn show state of the window. Now we can run it automagically from the demo. It works! Starting at walkOnIf1() is almost perfect for the timing, we just need a final rotate around the 70.

Added circle70(). Added infoboard.


(rbq log, history.txt)
Gave a demo for the ribo lab, went well.


Gave a demo to the ribolab on 2003-06-24. It went well. Now I have a little time to reorganize things and prepare the project for open source distribution.

Created the proj/rbo top-level directory, moved all app and library code into it. Started reading books on CVS and GNU autoconf/automake tools.

src tree, build tree, install tree. Yes.


Finished reading the AutoTools book to get suggestions on how to setup recursive makefiles and build paths, but didn't really get any specific advice from it, other than the important insight from yesterday. Through trial and error, I created my own recursive project makefiles which build all intermediate and output files in a bld subdir from the top-level dir. In addition, each subdirectory makefile can be run independently, which I have found to be important for modularity, and also from annoying experience with recursive makefiles from other people's projects.

Currently, I am still building on WIN32 platform only, but I cleaned up some of the cruft from my existing makefiles and renamed most of them to ''. It is also gratifying that they all now build without creating any junk in the src tree, an important step prior to moving to CVS.

Almost have the project makefiles done. Note to self: the macro 'LIB=' which is hanging around some of my old makefiles is a major pain in the butt (should be 'LIBTOOL=lib' and when empty, it wacks the default lib search path and messes up the link step).

It builds and runs!!


Making the initial steps for working on the rbo project using CVS. Yesterday, got the LAN connection working for the GNU/linux OS on beryllium and figured out how to set up cvs with pserver access. I will briefly document the steps I had to do for future reference. The GNU/linux version was Mandrake 8.1. First I had to install xinetd and enable the cvs pserver to be run by it. Then I added a cvs group to the /etc/group file with my username in it. Then I had to specifiy the location of the cvs repos dir in the cvs.conf file. Then I had to create the cvs repos dir by doing 'cvs -d /usr/local/cvsrepos' init. Then I had to change the permissions for this dir by doing 'chgrp -R cvs .' and 'chmod ug+rwx . CVSROOT'. (Most of this is straight from the 'Open Source Dev with CVS' book). Then I had to create a passwd file in the CVSROOT dir of the repos dir and add my username and encrypted passwd (using the perl crypt script from the book). Then, on my WinMe machine, I had to download a newer client cvs that supported remote access. Then I was able to successfully login to the server on beryllium.

Downloaded Mozilla Firebird, it rocks.


Working with cvs and rbo on ribomachine3 and beryllium. Discovered why .exe files weren't being reported as not in the tree (default cvsignore list).

Moving all pdb models listed in the script/model menu into a pdb dir in the exp subdir. Testing loading of all models. There is a bug centering on '1giy' after loading it.

Broke down and readded dsp and dsw files to mak dir so we can do ide debugging.

The bug above is not a bug, the script was setting the transform matrix after insertion.


My cvs login from ribomachine3 isn't working today for some strange reason. Rebooted ribomachine3 and tried again and it work (after trying a whole bunch of other config stuff on beryllium). Note: also added SystemAuth=no to cvs/cvs.conf file.

Fixed model loading from script menu.


In the last couple of days, got Drew Kearn's FPsocket library and added an simple Http server class to it, in preparation for adding one to the rbq app, so that it can get commands from an html browser without needing a separate web server installed.

Added FPSocket lib to the src tree. Created the htsrv application. Create class CRbqHtSrv.


Finished htsrv app. The cycle sim demo is now working from the rbo project.


Back to work on dynamic segments. Because of the current design, where the force container holds references to force objects which are owned by dynamic segments (a component of a pdb mol which the force container knows nothing about), we must implement code to delete all force objects and dynamic segments if any deletion of a dynamic segment or force object occurs (to avoid orphan references). This has been done.

Fixed another bug in creating inter-residue bond between adjacent residues in a dynamic segment. Now we must also change the design somehow so that the first residue of a dynamic segment is bonded to an anchor which represents the non-dynamic portion of the pdb model.

Now we have another failure in CTorsionBodyIteFcon in wkEncon lib.

Also found some corrupted bmp files in the res directory. This is strange, as I had thought that I had deleted and readded them as binary.

One nice solution for the anchor problem: just create an extra residue force object at the beginning and mark it as unmoveable.


Added 'ff fo segment' command group. FF calc for force objects is causing problems. Added some not-a-number checks. Ok, that found the bug right away. Doing force calc for bsj force without returning on dist = 0. Duh. Also been reading on slashdot about floating point error. Might be helpful to skip calcs with very small distance vectors.

Ok, bug fixed. Did forcefield on 2 residues, one anchored. Second residue is floating around a lot due to some unstable forces, only remains partially properly bonded to first res. Need to add bond-angle and bond distance error calcs.


Added fo enable commands to menu. Debugging using 2nt.pdb. Adding file report for force objects. Added doxygen build to master makefile.


Still debugging force objects. One problem seems to be the way torque is currently calculated. The total force which is accumulated on each atom is applied to all possible rotation nodes to produce torque at each node. Also, whole-body torque from each atom is skipped because when combined with the node torques, it produced strange results. But I believe strange results are being produced in any event. It just is not right to produce multiple torques (and consequently, multiple rotations) from a single force. And to neglect whole-body torque (for forces which don't act on nodes) is also not right.

But the scheme of propagating torque down the nodes, as envision in a previous attempt, is also problematic. Consider the case of a force acting on a rotateable node which is at right angles to the next node, and the force is perpendicular to both, and thus capable of producing torque at both nodes. Since the force is perfectly perpendicular to the first node, all of its effect should act at this node, producing rotation around it and no rotation around the next node. But consider a second force acting on the other side of the first node, in the same direction as the first. The combined forces would produce 0 torque at the first node and full torque at the second. So it seems that we must consider the combined effect of multiple forces at each node before we can know how much torque will be transmitted down the chain. But I'm not sure how to do that.

Time is limited for much exploration at this state in the project, but one possibility is to see how ODE does it (presuming that it has a proper joint to represent rotation around covalent bonds). I just got it compiled in GNU/linux. Perhaps it will also help with maintaining a proper bond length and angle between adjacent residues through spring bonds. My current implementation doesn't do a good job of that either. One idea that I had was to give more processing time to the spring bond movement at the expense of other forces. The forcefield does appear to work better when the zero-vel mode is turned on, however. Tried increasing the spring force constant by a factor of 100 and running in zero-vel mode on 4 mobile nts in 1tra, but it just can't maintain proper inter-residue bonding. We may have to ditch the one-torsion-graph-per-residue approach. But that will get us back to the long-distance instability of large torsion graph node rotation though.

Wrote a perl script to convert downloaded archived ode mailing list files into html (using mhonarc).

Reading ode docs. Predefined joints don't include a good covalent bond joint, but there is a doc on defining new joints. Lots of stuff to learn.


Wasted a lot of time yesterday trying to work with KDevel on GNU/linux. Explored some ODE stuff. But then got an email from Steve that Walt is coming back and expects to see what I've been doing for the last three years with ribosome builder. Presentation is next Tuesday morning, so my slack time to explore ODE goes out the window. Back to trying to make my current forcefield work.

Added reporting of violated spring bond constraint. Added resetting of force objects. Currently running at timestep length of 0.05, with spring bond force constant of 1e5 and things are working ok on the 5nt test in 1tra (dbfo.lua). We don't quite get the nice real-time movement of the nts with this timestep, but I can see them gently float around. Perhaps with a multiple timstep per tick rate, the movement will be visible. Also need to add some external driving forces and torques. This is where lua should shine.

Ran for 64K timesteps, still stable. Just realized that this was the debug version, release version should be faster. Also, an easy way to apply external forces is appyling node torques.

Built and ran in release mode, something is not right with the node torques. Got a violation of the inter-residue bond constraint around 30K ts, after perturbing a base ring (should have rotated back into place right away, but it didn't - that's the problem with the node torques).

One curious thing in the CBsjForce code, the forces calculated between the link atoms are applied to the force object as a whole, (along with torques) and not applied to individual atoms, as is done for steric forces. Don't know if this is a problem or not. One consequence is that the inter-residue force will not be able to affect node rotation, but given that it has been made humongous, perhaps this is a good thing.

Adding reprorting of inter-residue bond forces. There is a discrepancy between reported and displayed inter-res bond force for force from next residue.


Discrepancy wasn't really there, I had logscale enabled for one residue and not the other.

Also, on the node torques apparently not being applied, that also was not really the case. Instead, it was the extremely small timestep which was masking node rotation, in comparison to the larger movements caused by the huge spring bond force.

Debugging node stuff. One thing that could help speed up rotation of base ring node is to change the code to use the mass of the upstream or downstream portion that is actually being rotated. Currently, the mass of the entire residue is used, which is wrong.

Implemented node mass, but since it only reduced the ring node mass by a factor of around 3, didn't see a dramatic increase in node rotation. But the node rotations appear to be correct in direction and rate.

Simulated a larger number of bases at in the anti-codon stem loop. The backbone remained within the bond distance constraints, although there was significant departure from the initial conformation. But of course, we aren't even doing electrostatics, hbonds and hydrophobic effect, so this is to be expected. Is there time to add hydrogen bonds before next Tuesday?


Adding hydrogen bond creation for force objects. Coming along, but a lot of work. One thing I just found in debugging is a potentially very nasty bug that could bite me in lots of places. There is a place in my code where I took a const ref to a vector item, then later on, pushed another item onto the vector, and of course, the ref to the prior item became invalid because of reallocation. I never really thought about this before (one place where using values instead of references is definitely better). Anyhow, I must find some way of scanning for this elsewhere in the code, because I take const refs to vector items all the freakin time.


Added CHbondDonor and CHbondAccept classes. Added drawing of hbond vectors. We need more torsion node monitor frames, so changing the code in CTorNode to allocate an internal monitor.

Done. The hbond donor and acceptor vectors are moving with the torsion atoms, and the spring bonds are still maintaining the constraints, even with the additional steric forces from the hydrogen atoms. Now we just have to do the hbond force calculation!

Arg. Bug in the endpoint check found, which means that the constraints were being violated all the time. Not too big of a deal, we can ease the constraints a bit and also drop the timestep.

Looking over my previous hbond force calc code, it's dreadfully complicated. For now, I'll try a much simpler approach, alongs the lines of the spring bond code, which works well. We can simply define 2 shadow positions which represent the target positions of the opposite hbond atom, and use a coloumbic force to attract them. Ah, but, that won't quite work. The columb force approaches infinity at the eq dist. We want zero force at the eq dist.

Ok, no need to riw, I'm just gonna use CHbondForce from the rb project. Did a quit plot of the force function from CHbondForce, looks great.

Added hbond force calculation. The directional factor doesn't seem strong enough and the eq distance seems a little of as well. Added drawing of hbond potentials. Ran a sim of hbonds on ahelix.pdb. In debug mode, it's slow, but not impossibly so. In release mode, not bad.

Next: implementing (atom, shadow-pos) force pairs for hbonds.


Added the (atom, shadow-pos) code for hbonds. It didn't work at first, but then I adjusted the harmonic width term for the hbond force, as well as the eq distance, and started getting stable bonding on 2 test nts from ahelix.pdb. One thing though, in order to get the hb atom nodes to rotate to the optimal orientation, the code needs to apply torque to the node somehow. The current code bypasses that by applying force and torque to the force object directly. If we apply the hbonding forces through AddAtomForce() for the atom, and directly to the force object for the shadow pos, will this introduce a bad asymmetry? I will try it though.

Well, one problem is that steric clashes are interfering with proper hbond atom alignment. Should we exclude just the steric interactions involving the hbonds? Or can we just through out all hydrogens in steric calcs? That would be the quick fix for now. Though, to what degree is steric attraction a factor in initiating hbond formation? We could just clamp the net steric force to zero on the repulsion side for hydros. And then there is the question of the atom-atom repulsions for the main atoms in the hbond. With the nt pair that I'm looking though, the overlap there is fairly minimal and perhaps could be overpowered by a strong hbond force.

Added hydro atom exclusion to CTorsionBodyTgaFcon, CTorsionBodyTgaxFcon and CTorsionBodyIteFcon. Ok, that worked. The graphics also showed me that I need to be applying forces to the hydro atoms as well as the main atom in the hbond. Duh.

Ok, applying forces to hydrogen atoms instead. New problem. Because of the wider harmonic region now, the force from the twin hydro on a nitrogen now has a greater restoring force than the hydro which is closer to the shadow position.

Ok, this is why I was multiplying the force by the potential in the rb code. I should have added a comment in there about that. Need the alignment factor too. Ok, the nodes are rotating to lock!! Another rbq first! Yeah!

Yeah, but when all nodes and node dirs are enabled, it gets messed up again. Arg. Well, we can always just enable selected nodes for forward rotation perhaps.

Also, with node rotation turned off, and looking at the bonding happening when we already have optimal node alignment, I'm reminded of a thought I had when observing the same activity in rb, mainly that a lot of wobble is happening because of the steric spheres rolling against each other at the hbonding face. As a consequence, the bases just don't really 'lock' like one might expect. It's almost as if we should reduce the steric radius between hbonding atoms. However, that would complicate the existing steric calculations.

Found a bug in the potential calculation code. Maybe fixing that will help. Yeah. Finally have high-potential bonding for all 3 hbonds between the 2 nts.

With tsLen of .1 and zerovel, we get good locks between the 2 nts. But of course, that ts rate won't work with intra-res spring bonds.

The relative offerings of zerovel and non-zero vel indicate that we should consider adding frictional damping back in as an option.

Fixed hydro-add bug for nucleice inter-residue atoms.

Changing force object creation to create for all selected residues. Looked like it would be easy, but turned into a big annoying recode. Great.

Well, the record seems to work ok, thank god. Running out of time though. Did another run through of the initiation demo, everything still works fine. Starting creating some force objects on the demo pdbs and right away found a bug in electron positions not being updated with the pdb transform.


Gave a demo of the program to Walt Hilll at the ribolab yesterday, he liked it. Fortunately, the forcefield demo of helix 45 of 1fka.A went well. Afterward, walking in town, I was thinking how to improve things, especially the inter-residue spring bonding and the node rotations. For the node rotations, I finally realized that the main thing was that node rotations should not change the center of mass of the residue, so that what I could do in the TimestepMove() is to do node rotations first and then do a corrective translation to maintain the existing center-of-mass, followed by whole-body rotation and translation, which can legitimately alter the center-of-mass.

On the huge and problematic spring bond forces applied between residues to maintain the proper bond distance and angle, I thought of an alternate idea which seems very nice, if it doesn't produce undesired effects. If we consider the inter-residue bonds as a necessary constraint which simply must be maintained, then we can just fixup the bonds after doing timestep movement of the individual residues. An easy way to do this is by sequential connection to a single starting residue, which could be chosen at random, or perhaps better, by choosing the residue which has the greatest displacement from its previous position. This should be a quick and effective way of always having the correct inter-residue bonding. I will try implementing this idea immediately.

Added CBsjForce::ConnectObjects(). Added inter-residue bond fixup to CForceContainer::TimestepMove(), but then I realized that the fixup needs to be done for each dynamic segment, not just for the entire set of force objects. It seems that we need a force container that has to know about dynamic segments. So time to derive a force container from existing one. Created class CRbqDsForceContainer.

Ok, that has been done and now the 2 chains in ahelix.pdb are maintaining proper covalent bond alignment. Now, of course, the problem is that total movement is quite constrained so that we can get unacceptable steric clashes between bases. Followed, of course, by violent separation. Ah well, it was a nice idea at the time. Perhaps there is yet another fix which can fix it. It's pretty much the same problem as was observed with the full-chain torsion graph.

Did some googling and found some good ideas on doing a local move (adjusting downstream torsions to restore to prev conformation). This is something I had considered earlier, and forgot about.

Another idea: choose each residue in chain as the starting residue, and connect the adjacent residues, and compare the resulting set of conformations and use that as input to reduce excessive change.

Went back to previous scheme of applying strong inter-residue spring forces. Prior to implementing the c-o-m correction for node torques, I looked at the activity of a single residue, and it didn't undergo any net translation or rotation as the nodes came to equilibrium. The flexibility of the nodes looked really good, except that they happen on such a longer timescale than the inter-res spring bonds. I'm going to try using a different inertia for node rotations, relative to whole-body movement. It's a total hack, but then so is the forcefield in general. I predict that it will cause excess instability in the inter-res bond.


At .001 relative inertia, and dropping the ts down to .01, the spring bond remains reasonably stable. ahelix.pdb falls apart however. Perhaps tweaking of the hbond/steric values would help. Also, we might need to add base stacking, and definitely electrostatic forces in.

The dynamic activity is fun to watch now. Also, I can see one problem that I must fix right away. The lack of charge on the O2P allows creation of a hydrogen there, and causes inappropriate behaviour by producing hbonding interaction.

Adding a node velocity might be another alternative to tweaking the relative inertia.

Added a distance threshold for the steric interaction (25A), it speeds things up a lot!

Redesigned access to setting forcefield timestep context params. The current scheme was incredibly unwieldy because I was trying to stick to principles of good encapsulation by hiding access to the timestep context, which is a component of the force container object. As a result, I had a 4 level cascade of wrapper methods for every single Get/Set function pair: ( CRbqCmdProcessor, CRbqMainWindow, CRbqForceContainer, CRbqTimestepContext )!! This seems to be one area where strict encapsulation is an unworkable idea, so I provide the timestep context pointer directly to the command processor, thus eliminating 3 layers of wrapper functions.

Added progress handling to force object creation.

Added charge addition for O2P. Next, we need to do something about the steric clash at the base edges for hydrogen bonding.


After redesigning interface to CRbqTimestepContext yesterday, it is much easier to add parameters and flags. After adding enable flags for steric, hbond and inter-res forces, I can see immediately that there are problems with the hbonding which are completely independent of the steric interactions. Now adding display of hbond forces.

After adding display, the forces seem too large at the eq point. Adding reporting of hbond forces as well.

Had an idea after observing yet again the nice lock which occurs in hbonding with zerovel turned on. Both zero-vel and velocity modes offer benefits. Zero-vel locks in expected conformations, and velocity is help for exploring and discovering new conformations. Perhaps the amount of velocity could be tied to the potential energy, so that when a residue force object approaches a local minimum, the decreasing potential energy is coupled to an increasing frictional value, therefore approaching the zero-vel condition. This could lock residues for stable configurations, and allow them to move around when unstable.

Added hbond reporting. Large forces were because couldn't get to zero dist.


Consolidated forcefield constants from code into single locations in classes. Added more ff params. Added drawing of force arrows in wireframe mode so that I could see them in relation to shadow positions. After watching 2nt for a bit, it seems clear that I should be creating the acceptor shadow at the electron location instead of at the acceptor atom, so that a torque can be generated for alignment. This bypasses node torques, but that is ok as nbe electrons are typically on an atom which cannot rotate.


One more observation in hbonding: because of the current way the shadow points are used to define the potential of the hbond bond, there is an asymmetry which can occur when one base is closely aligned with the shadow point of the other, but the other base is far away from the shadow point of the first, because the first base is tilted either up or down. As a result, one base can experience a large force while the other does not.


Worked on hbtest.cpp tool to investigate hbond force, added COption class to handle command-line option processing.


More analysis of hbonding. By multiplying the hbond force with the potential (as mentioned above, to lock out influences of nearby bond partners), we have changed the desired nature of the force from a restoring force which decreases linearly as the eq distance decreases, to a different function.

Did a plot of the product function, looks ok. What I'd really like to see is a plot of the actual forces as 2 force objects approach each other. Added enabling of individual hbdonors and hb accepts. Writing a script to line up one force object accept vector on the donor vector of another.


Writing hbstepper.lua. Note: somewhere, need to document the problems which can occur if a script object script returns a value, and how that can screw up the lua stack and the getting and setting of global vars in the script object.

hbstepper is working.


Generalizing access of force object properties from lua.

C++ note: when creating maps, use an array of std::pair<KeyType const,ValType> f_rgMapData[] = { make_pair( K0, V0 ), ..., };

Note the 'const' required after 'KeyType'. Also, after getting VC compiler warning C4503 because of the function ptr with StringList param, I learned how to use a wrapper class as the map value instead. Also, to fix error C2536 (explicit initializer for arrays), add string( ) wrapper around char[] keys.

Finally got the map working. Well, it's true that C++ maps are a hell of a lot more of a pain than Perl hashes.

Finally got a plot of hbond force between 2 bases with a single enabled, aligned hydrogen bond. The force plot is pretty much as expected. Now, debugging hydrogen bonding in ahelix.pdb, don't get stable bond formation with just hydrogen bond forces and steric forces turned on. This may be due to the tilt problem mentioned above, and also just the general instability of the integrator. We can try adding friction to help the problem...

Now I'm thinking perhaps a linear plot of the potential vs. time for each base pair trying to bond in these conditions, as well as 'zero-vel' set, might help me to better analyze the problem.

And this will allow us to do a series of such plots while varying various parameters, to try to identify the optimal parameters. We can efficiently grab maxPotential from the hbond acceptors, but need a way to identify their owner force objects in the output data (only have a ptr to an hbond donor).


Adding output of hbond ptr and name info to '' file. Adding more force object and segment functions. Came up wit a good scheme to select segments and force objects by name: use same name as static models, just add a '$' after the chain id. Then, the command processor can translate the name into the dynamic segment index instead of the chain index.

Added reporting of selected dynamic segments. Added selection of dynamic segments by name.


Adding drawing of hydrogen bond donor and acceptor indices (so we can build a table of base-pair potentials to monitor).


Wrote perl script to read hbond ptr file (written in xml format). This allows creation of a table which maps hbond acceptors and donor ptrs to index. This revealed that some of the base-pair hb acceptor and donor indices had been incorrectly defined for ahelix.pdb.

Wrote a script to display force object atom names (similar to script yesterday to display hb acceptor and donor indices).

DrawAtomNames.lua script is working. Navigating to a view of each base pair manually is tiresome. Wrote a script to align view for each base pair, lookAtBasePair.lua. It works.


Finally have got a plot of base-pair potentials in exp\dev\dbhbonds.

Added options to rbq_SpawnProcess() so that the perl scripts in exp\dev\dbhbonds can be run from the web browser. It works.


Added startup of htsrv in Startup.lua script. But then the spawned process prevented termination after exiting the rbq app. Calling raise( SIGNINT) in the crt didn't work. Fortunately, the Win32 TerminateProcess() worked to kill it, hopefully not interfering with any dll cleanup.

Cleaned up lua script path separators in startup script.

Cleaning up exp dir prior to adding to cvs. Added exp directory to cvs.

Working on exp\dev\dbhbonds. Doing a 1000 timestep run of ahelix.pdb. Realized the option I added the other day, disabling of reporting ff stop ('ff enableReportWhenStopped') is completely unnecessary. Instead of doing a periodic ff step, the outputHbPot.tick.lua script should just do an 'ff run off' at end of timestep limit. Duh.

In the last few days, finally started using 'foffi', 'foffo' and 'foffa' functions in my perl and lua code instead of hardcoding 'failed opening file for input/output/append' everywhere. One reason is because I like the sound of the functions and therefore they make good mnemonics.

We need to handle htsrv process id when resetting the lua state.


Created 'in' and 'out' subdirectories, created simulation specification files so that we can automatically do multiple simulations, with varying parameters. Of course, I just realize that this means we must add some file and directory methods to the rbq lua libraries. Sigh. No big deal, it's done.

Created 'jobDispatch' script object, which will manage execution of a worker script object to process simulation requests. In doing so, found a cute bug where the jobDispatch script object creates the worker script object during its tick() function, and in causing the worker script object to be inserted into the timeUser list, screws up the iterator in the main window timerEvent() function.

After reviewing 'Effective STL', I must remember that iterators of vector containers may always become invalid after any insertion or deletion (because of possible reallocation).

Fixed that problem easily enough by using a pending insertion list, but then spent another hour chasing down an annoying bug. Lua Tip #23.5: don't create a global var with the same name as a function name, because lua treats them as the same object. I should have realized this from my object-oriented lua code in cycleSim, but I forgot. I had named a global var "init", as a flag to detect initialization of my worker object. Then I defined a function named init() as well. Consequently, the init flag was always true. One reason this happened is that I violated my usual hungarian naming habit for script object vars such as "init" instead of "bInit", because they are treated as strings by the CRbqScriptObject which saves and restores them for the lua context. But perhaps in the future, I should stick to hungarian notation for script object vars. It certainly would be more self-documenting.

Fixed that, and then ran into ANOTHER weird lua bug where a chunk containing a function and a global table were loaded in a dofile() in jobDispatch.lua, but then disappeared when trying to be referenced by outputHbPot.tick.lua. No idea why. As a really unsatisfying hack, referencing the function in jobDispatch.tick.lua kept it around so that outputHbPot.tick.lua could see it. Why??

Researching this on the Internet. Not mentioned in the list of known bugs. Is it because of garbage collection?

No, it's all a stupid mistake. The dofile() was failing, because of a bad path, and I just wasn't checking it! Arrg.

After fixing that, and adding SetScriptObjectVar(), got a horrible crash when running the jobDispatch.lua script where the entire program just aborted. Added an app logfile output to track what the hell is happening.

After looking at the logfile, it is happening where we have access to an undefined global var inside the lua code for ouputHbPot.tick.lua, causing an error and failure in executing that script object. There is a message, presumably from the lua code: 'error: unable to recover; exiting'. Currently, in CRbqScriptObject::RunScriptFile(), after the CRbqLua::RunScript() has failed, we still try to get script global data. Bypassing that if error.

Looking at the job dispatch code, I see that we did an addScriptObjectVar() on an empty string. This is probably the reason for the abort. Yes, I believe the problem is that we are not consistently checking for NULL strings in lua_tostring(). Assing them to a std::string will cause trouble.

One other potential source of trouble: the jobDispatch object was doing a getScriptObjectVar() call to the worker object after the worker became invalid. We should check for an invalid worker state and return nil on object var get/sets. This has been done.

Yes, adding empty strings will cause problems the current scheme of script object vars. For now, we will just reject empty strings. Later perhaps, we can come up with a solution.

Finally got job dispatch and execution working. Man.


Finished reading of job input files in dbhbonds. Started on perl recursive report script. Note to self: must use the spaceship operator (<=>) when doing numeric comparisons in sort subroutines.

Recursive report generation is working. todo: job settings, dual-scale plots, total potential in reports.

Done. We now have nice looking reports with a master index.


Improved report generation, Added ff common settings file 'model.ffcommon' to exp\dev\dbhbonds. Running simulations for 1000 timesteps now.

Analyzing the 8 1k ts simulations. Todo: add steric attract and repulse exp params to the forcefield timestep context.

Also, because of oscillations, reporting the final total potential is misleading. A better measure would be to integrate the total potential over some interval.

However, the first thing to do is to add some friction and rerun.

No, doing averaging of total pot in final half interval (needed to do average instead of integration because timestep length varies between sims, but we don't really care about that, just how well the potential is converging). Done.

Some other features of hbonding of pairs which can be investigated: most-variable, most-improved.

Oh, I must document my idea that I had last night about displaying steric potentials. The idea is to display the positive and negative potential between all atom pairs as a 3D plot with the atoms along both the x and y axis and the atom-pair potentials plotted on the z axis. The question is how to order the atoms on the x and y axes. An arbitrary ordering could be done, but a more potetially interesting idea is to let the x and y axes represent a location on one of the 3 spatial x and y axes. This would allow for the mapping of the complex 3D steric interaction interface into 3 separate x, y and z plots. The next question is how to deal with the fact that multiple atoms will share a common point on the given spatial axis. One way to deal with this is to combine the steric potentials for all atom pairs within a given spatial interval, such as 1 A. I'm not sure how well this idea would work out, but it would be interesting to try. It might allow for the visual identification of various molecular configuration motifs, for example.


Added linear and rotational friction.

The problem with the model.ffcommon settings file that I created yesterday is that it will prevent reprodution of previous simulations as it changes over time. For purposes of reproducibility, it is necessary to have all forcefield parameters in each job input file.

Created script to automatically generate sets of job input files from previous sets, with certain parameters modified (after taking 'The Art of Unix Programming' adminition to heart of avoid hand hacking and writing programs to write programs).

Doing another 8 sim set run with default values of linear and rotation friction added.

Success. As I cranked up the friction in successive simulations sets, started to see real good convergence in certain simulations. Parameters of hbond force 5, timestep 0.05 and friction (10,100) give the best results so far. It's interesting also that the smaller 0.01 timestep gives worse results.

With one more magnitude increment, we get the best so far: timestep 0.0, hbondScaleForce 10 and friction (100, 1000) we get very rapid convergenece and stability.

It's time to move on to fixing the node rotations. Implementing the c-o-m fix discussed above. The c-o-m correction has been implemented. Now we must add some means of reporting the actual amounts of node rotation which are occurring and correlate them with the potential.

Adding output of node torques via lua. Done. We have huge torques, even at the eq hbond potential. We need a good way to understand the source of these large node torques. We start by analyzing steric forces.


Writing a perl script to analyze atoms forces and node torques. Finally learning more pattern matching and also wrote some more general code for reading data from xml-like format into memory data structures (ReadXmlElement() function in


Completed node torque analysis perl script. It verifies the C++ code. The large node torques are due to atom forces in the range of 1e3 by moment arms in the range of 1e1, giving torques in the range of 1e4. The large hbond forces are caused by atoms near the eq point. Since these should average to zero over the long term, however, we should expect the node torques to average to zero as well.

The next step should be to record the actual node rotations during the hbond simulation. The net rotations should also be close to zero.

Added output of node rotations to outputHbPot.tick.lua script. Creating file to create node timestep records from data. With a node inertia factor of 100, max rotation over 1000 ts is around 5 degrees, but looks like it is always increasing, which is not probably not right.


Got a plot of the node rotations. None of them ever decrease, which is suspicious. I'm so tired of the artifacts introduced by this whole scheme of node torques and rotations. Instead of constantly inventing yet another hack to try to make it work, or understand why it doesn't, I'm considering just applying bsj forces between all nodes, in the same way that it connects 2 residues. When I look at all the data and processing currently used for the node scheme, perhaps it won't even take too much of a performance hit. The problem is the additional time lost in doing another core redesign, but at this point, I don't think I have much choice.

Been thinking about it, and it could work. Adding 'void *m_pUserData' to CTorNode, adding class CRbqNodeBsjForceObject, renaming existing CRbqForceObject class to 'CRbqNodeRotForceObject', with the emphasis on the 'Rot'.




Finished implementation. Testing. It wiggles. We have some bugs. One apparent problem: we need flip the order of multiplication when doing translations and rotations of the node transforms (just like with the pdb transforms). Added the flip.

Needed to drop ff maxMove down to .01 to stop the wiggles. Perturbed an hbond several times and it reformed. This might be a first (note: linFriction and rotFriction set to 1, hbondScaleForce = 100).

For better convergence, hbondScale was set to 10000. Things are still not satisfactory.

In setting maxMove to 1, because things are completely stuck, I notice that the hydros move really far, even on a base isolated from other bases. This tells me that intra-residue steric forces are probably causing trouble. No, that's not it because hydros are excluded from that. It's large velocity buildup resulting from slight perturbations of the spring bond. I think it may be that my maxMove param has been masking some serious errors in the timestep movement. Or, perhaps, it's a problem with the friction calc. That can introduce instability as well. Yes, the friction was definitely a problem when doing a large maxMove.

spring const 1e5, no friction, maxmove .1, tslen .005, hbondScale 100: we have fairly good stability and movement and spontaneous formation of hbonds. But the conformation is a tangled mess. Perhaps adding base-stacking?

settings: timestepLength 0.005 maxMove 0.1 maxRot 5 zeroVel 0 maxIrSpringDist 10 maxStericDist 25 maxHbondDist 4 nodeInertiaFactor 0.01 hbondScaleForce 100 stericForceEnabled 1 hbondForceEnabled 1 interResForceEnabled 1 linFriction 0 rotFriction 0 springBondForceConst 100000

Here's an idea: run the forcefield with these params, and add a script to apply random torques around random bonds, to facilitate exploration of conformations.


Added rotation about selected node of force object, both forward and back nodes.

Found a bug in the hbonding where 1 electron of an acceptor atom was preferred over a symmetrical one. Actually, the acceptor atom just keeps rotating. Could this be driven by the covalent wiggling? Changing the hbond force from 10 to 100 locked the bond in.

Instead of just applying random torques, as mentioned above, the script should try to correlate applied torque with the resulting movement of a node, to discover the nodes which are freely rotateable to some degree.

One problem?: the 2' hydro keeps trying to hbond with the O's in the phosphate backbone. We definitely need electrostatic repulsion. This should be fairly simple to add by adding acceptor-acceptor and donor-donor interactions in the hbond loop.

We've simply got to add base-stacking forces too.

Creating ring-stacking code.

Added a simple ring-stack where the center of each ring node uses 1/r^2 coloumb-type attraction to other ring nodes. A quick sim of one side of ahelix.pdb with hbonding turned off gives the bases all trying to cluster in a glob. Now, it's clearly time to add electrostatic repulsion between the phosphate oxy's and others to prevent this cluster-muck. The questions are where to place the electrostatic centers - at vdw edge of the oxy?

Adding CalcElectroForce().

After this, we could do some genetic algorithms to discover the ring-stack and electrostatic params needed to produce a helical form for a single strand of RNA.

Ran long sim w/ electroscale 50 and ringstack 100, got over-extended conformation.


Loryn and I are getting married!!!

Changed ring-stacking force to points of attraction above and below the ring c-o-m, and using the Hbond morse-like potential instead of coloumb attraction. Added display of ring stacking forces.

Done. After a couple of sims, it's clear we need to add a direction factor as well.

Added that, but stacking still not right.

Adding display of electro force. May be about to make a major conversion in the brace religion because my data definition in CRbqForceDisplay doesn't work ideally with my current brace style. I'd always thought that having the braces aligned with the content of the block made more sense because the boundaries of a box should be aligned with its contents, but I acknowledge that the boundaries of a box are always offset outward from the contents. If I change my style now, it will cause inconsistencies with the code that I've been writing for the last 8 years, but what the hell, being able to change is a good thing.

Added display of node forces and torques. There is an apparently anomaly on an O1P atom on a residue, a steric force with no apparent reaction force.

Next: steric reports.


Before starting on steric reporting, did selective disabling of the various forces and discovered that the source of the apparent anomaly is due to the electrostatic force. I didn't see it before because it was only displayed when showing electroforces on the next residue in the chain. Extending the interaction points of the non-bonded electron pairs out to the full vdw radius of the atoms is producing very large electrostatic repulsions.

The modeling possibilities for electrostatic interactions is endlessly complex. Perhaps we can just add a parameter which specifies the location of the nb electron pair at some fraction of the vdw boundary. The idea is to get a parameter set where only the most significant repulsions occur to prevent grossly unrealistic conformations.

Added 'nbeProject' param, setting to 0.5 and electroScaleForce to 10 results in more reasonable steric forces in ahelix init config. Doing another sim to work on ring-stacking. The rings are still blowing out.

Working with 2nt.pdb for easier debug. I think we need shadow points for ring-stacking too. Perhaps combined with a secondary coloumb attraction between node c-o-m's.

Finished dual-center ring-stack code, doing sim on ahelix. After 40K ts, got separation into 2 separate stacks tilted wrt each other. Cranked electrostatic repulsion up to 5 from 1.

Long sim (200kts), still no complete stack.


After running overnight, with all friction set to 0, we are now at 4.75kts, and the helix strand has settled into 2 separate stacked segments, the 4 C's and the 4 G's, separated by an extended backbone conformation. However, in the stacks, there is no helical twist. This may be due to the lack of a strong steric repulsion, currently only at r^6. Considering adding steric exponents as forcefield parameters.

First, however, something we really need is a way of saving the conformation of the dynamic segments as a pdb file. Done. It works.

Adding steric attract and repulse exponents to timestep context. Trying a new sim with steric repulse exp of 8.

Tried a steric repulse exp of 12, doesn't seem to be working.


Saved 600kts sim of ahelix.B to exp\dev\ahelix. Fixing code for recent-dir in gui file dialogs.

Started work on StericReport.lua.


Added global timestep movement flag to forcefield, prior to work on steric report. Added progress and report stream ptrs to timestep context. These 3 features now enable fairly simple reporting of detailed interactions between objects. The user can open a file and set a stream pointer to it for each pair of force objects, and timestep the forcefield for each pair in which reporting is to be done. This allows for simple situations, a specific type of interaction such as steric interaction, between a single pair of objects, to be done, and then combined with other simple reports to produce a comprehensive report of all types of interactions between all objects in the forcefield.

One annoying feature of the current implementation of timestepping the forcefield is that it is timer-event driven, and thus not directly controlled by lua scripts. I had tried to step the forcefield for each pair of force objects inside of a lua script, but this doesn't work because the forcefield only steps after the script completes. So, it requires that the reporting be run from a script object instead.

We could just add a function to allow direct stepping of the forcefield. Added it.

Ahh, found the bug where I wasn't setting the vdw exponents for CTorsionBodyTgaxFcon in CRbqNodeBsjForceObject::CalcExternalForce()!

Steric reporting is working!


Working on force object data reporting (to supplement steric reports). Added bond index packing and unpacking to CBnd in wkChem lib. Added more data output from CNodeBsjForceObject. Starting on perl script to generate an html report from force object text output.

Finished Added intra-residue steric reporting. Now we can create steric reports which can list atom pairs in order of largest to smallest force, etc.


Back from a beautiful vacation at Georgetown lake. Back to work on steric reporting. Finally added .cvsignore files so a zillion work files stop showing up in updates. Moved steric report stuff to exp\dev\report.


Working on Steric reports. One annoyance, because of the single context created for script objects, I have prevented the nested calling of scripts by the CRbqLua object. This is necessary so that script object variables are not corrupted, but in the future it may be desireable to have a context stack. For now, to call multiple lua script files, the user must directly call the lua 'dofile()' function instead of going through the rbq 'script run' interface.

Finally got an intra-residue steric report generated. Now for graphical annotation of the atom pairs, we can just call a script from the html page which sends annotation data to a graphical script object. One thing that needs to be added though, is a change to the http script object interface, where we can pass arguments as well as the filename of the script. In current implementation, only a filename is accepted, requiring a unique lua script file for every browser link.

Reading up on some existing forcefields. has a nice summary of some current forcefields. It's reassuring to know that the current models have a real tough time simulating B-form - A-form transitions for DNA, so maybe there is still some hope for my little monster.

Command-line args added to browser script requests. It works.

Finally got highlighting of atom pairs working. The first thing to note is that it seems that the atom pairs are being doubly-calculated. Yes, of course, the code in CTorsionBodyIteFcon is not doing subsequent atoms in the inner loop, why the heck not?? Ok, well, it's easily fixed.

Done. So, the largest intra-residue clashes are between atoms in the ring. Do we need to supplement exculsion of intra-node atoms as well as geminal atoms? They can't move wrt each other, but the large forces will swamp forces involving moveable atoms.


Looking over the iterative-token-exlusion algorithm, in CTorsionBodyIteFcon, which used bond info in packed format, as documented in CBnd::PackPartnerIndex(), there doesn't appear to be any clean way to skip atom-atom pairs where the atoms are common to a node. We can't just add node atom pairs as pseudo-bonds to the packed bond list, because this would cause skipping of a pair atom's bond partners which may be outside of the node. If we consider that the inter-node forces, in the case where the node is a ring, would tend to cancel each other out, perhaps we shouldn't really worry about this for now.

Added node selection in force object report.


Finally installed cvs and did a build on one of Drew's machines. Problems: 1. Needed to install Qt lib and set QT_DIR. 2. Needed to copy glut headers and libs to msdev dirs. 3. GetAtomName() caused problems clashing with windows.h def, Drew's machine must have different include order. 4. Create surface for chains is broken. 5. No pdbs were available because I hadn't checked them in to cvs. Need to add a separate 'static' project for them and the Qt and glut stuff.

Added uplink and stylesheet ref in generation of cmd_index html files.

It's time to start making movies. Added 'ff record' command group. Created class CRbqFfMovie.


Finishing up the movie code. After my previous try at doing forcefield movies in the molecule theatre project, this 2nd effort seems a lot cleaner and easier. I'm keeping it extremely simple by just outputting atom coordinates, without any complicated file formats or header info. Also trying to make the movie object as stateless as possible. Now that I've just realized that I forgot to use the binary flag in the ofstream, and use write() operator instead of the >> or << operators, which produce text output of course, I think it's going to work!

Movies are working! Starting long ahelix.B sim. Ended at 88kts. Played back the movie, now we have to deal with the electron vectors. arg. That is definitely more problematic. For now, they are just turned off when watching the movie.

After further thought, the better solution is to save the node frames to file instead of atom positions. This allows for calculation of forces during movie-set positions, unlike the current scheme. Also solves the electron problem. However, it will increase the movie sizes as the frames currently take up about 4 times as much as a position vector, though future use of quaternions might help that.


Changing movie data to node transforms. It works. Enhancing movie toolbar.

We need some kind of notification from the app to the CRbqFfMovie object for changes in the content of force objects (loading of a movie got stuck when tried to run it before creating force objects). Either that, or we can require explicit setting of current movie, which might eliminate the need for notifications. Frame size is now reset with setting of filename. However, we still need a way to save model info with movie coords. For simplicity though, this should probably be kept separate from the CRbqFfMovie object. It's simple and works just fine now, better not to mess with it. The syncing of model loading and force-object creation with movie loading should be done at a higher level, perhaps through lua scripting.

We need some way of selecting pdb residues for force object creation. Saving of force object indices will work if we have the same number of pdbs, loaded in the same order. So we need to save a pdb index-name file first of all. Actually, since we need the paths of the pdbs, we can start with an rbd file. Should we add force-object state to the rbd file? This would simply require loading of an rbd file with an associated movie file. This is the way to go, that is the purpose of the rbd file, to restore doc state.


Starting on save/restore of force object state. Should be fairly straightforward to save dyn segs with residue ranges. One complication is the need to save and restore the exact order of force objects in the force container as well, because it needs to be the same for proper movie playback.

This problem can be handled, but the real hassle is old issue of ownership of force objects in the force container, but referenced in pdb dynamic segments. Why aren't the force objects owned and deleted by the pdb objects? This is really a hassle, as witnessed by the awkward tramp params during normal dyn seg creation. Ok, transferred ownership and deletion of force objects to dynamic segments.

Now, we just have to add rbd force objects to the force container at load time. This is a good opportunity to use the client data scheme so CRbqDoc doesn't have to know anything about it.

Force object creation from .rbd file is working!

Did long sim of ahelix.B w/o hbonding and vdwRepulseExp = 12.

Wrote 'WatchForceObject.lua' script for following bases in the movie. Need to add code to look at a base in a specific orientation.


Started on script 'DrawTorsionAngles.lua'.

Got it working.

Started a long sim of tRNA.


After running the sim overnight, got up to around 25kts. But the tRNA was blowing apart. Need to do more steric analysis.

Finished script 'OutputSelFoDihedralsToFile', consolidated draw and reporting dihedral code to 'outputDihedrals.lua'. Added progress indicator because calculation is slow in lua and going through the rbq interface for force object properties. Output dihedral info for all residues of trna.pdb. Created perl script 'exp/dev/trna/', output and plotted trna frequencies in gnuplot. Hard to interpret with so few items, so now I want to plot dihedral frequencies for a larger model such as the 30S or 50S models and suddenly realize that the hit in creating force objects will be too great, so I now need to create a dihedral calculator script for static pdb residues.

Got some really nice text-to-speech going reading a SENS roundtable transcript, and no worries about trial-limited stuff in the windows version - yah GNU/Linux!!


Added pdb residue version of dihedral angle output. Refreshing my memory of cross-product vector ops to get the right sign for dihedral angles - I should really know this stuff cold by now, but a little test script, exp/dev/test/testCrossDir.lua refreshed for me the fact that when you use your right hand to cross vector a into vector b in the direction which has the smallest angle between them, this gives you the direction of the cross vector.

pdb residue dihedrals are working. Creating dihedral report script ''.

Did plot of dihedrals of 1fka.A, now we are seeing some nice trends. Also did report of 1ffk.0, with similar results. Next: dot plots of adjacent dihedrals.


Before doing adjacent dihedral plots, I'd like to get a sense of the variance of covalent bond lengths and angles for nucleotide atoms, in order to evaluate the current scheme of the covalent bonding in the program, which obtains equilibrium bond parameters from the initial atom positions in a crystal structure.

Added the bond code, then realized I didn't need it becuase it's better to output atom pair distances based upon user spec of atom names. Quickly wrote script 'outputSelResAtomDistToFile.lua' by modifying the dihedral code.

Output P-O5* atom pairs dists for 1fka.A, analyzing stats. Need to calc std deviation, but it looks like the variation is within 0.02 A of 1.593 A, except for one outlier at 1.316A (residue 76). That residue is at the end of an undefined region, so that makes sense.

If there significant variation, I was considering adding a smaller spring constant to produce a more flexible 'inner-range' of the covalent bond force function.

Wrote script '', got a nice plot of P-O5* distances in the range of 1.59 to 1.60 with an inteval size of 0.001. We get (0, 6, 43, 289, 741, 287, 71, 22, 11, 4, 0). So my estimate above is correct that the significant variation is no greater than 0.002 A. For a force constant of 1e5, however, this produces a force of 200.

Next: do comprehensive distance reports for all intra-residue atom pairs, ordered by nucleotide type. Then, do reporting of steric clashes using these distances and the default vdw radii from CElement. (Steric clashes between all atoms in residue and adjacent residue which are non-bonded and non-geminal). This stats will tell whether the vdw radii need to be adjusted. Also, must fix current electrostatic implementation to add positive charges.


After more thought about the electrostatic charge balancing, one idea is to consider each hb donor and acceptor as a dipole, and calculate all electrostatic forces from that. At the very least, before treating electrostatic force of hb donors, what should be done to the current code is to produce positive charges at the centers of the hb acceptor atoms to neutralize the charge of the projected electrons. This may help to fix the 'exploding-tRNA' observed in the sim above.

In adding this, I note the lack of an electrostatic threshold distance, which might explain the slower speed for large models such as tRNA.

One possible complication in implementing this more complex electrostatic force is that the current scheme involves applying the repulsive force at the acceptor atom centers, whereas the new approach must apply forces to the owner nodes at the electron-pair positions, but this is more realistic actually. It just makes analysis of component node forces more difficult, if such is ever needed. Also, there is the performance hit of calculating an additional torque for each force added.

Before adding the change, I'm doing a benchmark on the existing code. We're running around 0.4 fps on ribo3 simulating trna.pdb with default params. Perhaps we should add some actual interaction counts to the timestep context stats.

Added 4 stats + rate calcs to CRbqTimestepContext. Amazing how much simpler and easier it gets each time I do it.

Here are some stats for trna.pdb, chain a:

*** timestep 43 ( 2 seconds ): 
    1368 steric interaction(s) (684 ips )
    2494 hbond interaction(s) (1247 ips )
    1292 ringStack interaction(s) (646 ips )
  292155 electrostatic interaction(s) (146078 ips )

Wow, the electrostatic count is HUGE, much bigger than the atom-atom sterics!. Right, for a quick fix, we'll just use the hbond threshold for electrostatic interactions. Might need to add a specific one later.

Yes, that help a lot:

*** timestep 46 ( 0 seconds ): 
    1368 steric interaction(s) (0 ips )
    2494 hbond interaction(s) (0 ips )
    1292 ringStack interaction(s) (0 ips )
    3696 electrostatic interaction(s) (0 ips )

Implemented 4-point electrostatic calculation for hb acceptor - hbAcceptor interactions. Also updated force display code for that. A brief test shows that it appears to be working.

Started overnight sim of tRNA.


Sim got up to 49.3 kts, with 493 movie frames recorded. The tRNA starts to unravel, but much less than before the electrostatic mods. Now starting more detailed analysis of forces during the sim, so we can improve it.

Added multiple groups to the script which generates html docs for the rbq lua libs. This is necessary because many functions go in multiple categories.

Man, the perl pattern-matching operator just kicks ass for adding html references.

Added a bunch of seealso's and groups specs to the rbq lua lib modules.

We still need to update resetting of lua script context at some point.

Tried to generate steric data for all residues in trna.A (in script lua\StericReport.lua), but it is taking forever. Since we are stepping the forcefield once per residue or interaction, with reporting turned on for just that interaction, all force calcs for the other residues and interactions are just dead weight and slow things down hugely. One fix would be to add internal force calc and external force calc enable flags for each force object, allowing all objects except for the reporting one to be disabled each timestep.


Did another all-night run of tRNA, results appear fairly similar to previous run, though this time I added small amounts of friction. This was motivated by a fantastic result which occurred previously in a shorter run of ahelix single chain, which now runs so much faster after implementing the electrostatic threshold. The amazing event which occurred was the spontaneous formation of a stem-loop structure from the single strand. I hadn't even considered the possibility of this, though the sequence clearly shows the possibility: CCCCGGGG. This is perhaps one of the first 'unexpected' (at least to me) and realistic phenomena which has been produced by the program, so this is very gratifying if it leads to more of the same. It occurred after adding small amounts of friction and a steric repulsion exponent of 12.

Adding force calc enabling flags to force objects, and integrating into steric reporting script.

For better understanding of the complex behaviour of the trna trajectory, it will be necessary to have detailed energy reporting in addition to force reporting. I had thought that this would require laborious addition of energy calculating classes until I suddenly realized that detailed energy values is trivial to add to the current force calc classes. It can simply be an extra field in the atom pair record which is output to the report stream.

Well it's a good thing I've finally got back to doing detailed steric reporting, because after getting an error after trying to generate reports for the entire trna, I quickly see that bogus hydrogens have been created for the non-standard residues. As a result, it is not surprising that the all trna sims have been messed up!!

Found another bug in StericReport.lua, OutputForceObjectData() where call of command "ff fo report toFile" was outputting force object data for first selected force object when what we really need is output of specified force object index.


Added command to output force data for specified force objects. Adding code to specify bond definitions for non-standard residue types in CRbqDynamicSegment.

Just started reading Robert Bradbury's Nano@Home proposal, which is a well-thought-out and insightful plan for development of molecular nano-technology. It caused me to reflect on the potential for existing polymer-synthesis machines such as the ribosome to produce 3D mechanical templates of defined shape. Since the difficulty of diamondoid assemblers is still unknown, a ribosome-based system may have advantages. I'm envisoning the production of polypeptides which fold up into the classical protein secondary structures of alpha helices and beta sheets, with the additional step of somehow cross-linking the resulting structures to produce a more stable form. However, on the contrary side, after briefly looking at the Brenner potential and some applications of the fungimol program, it may be that design and molecular dynamics simulations of uniform hydrocarbon structures will be simpler because of the uniformity and regularity of the atoms.

Added drawing of atom names for static pdb residues.

Adding non-standard nucleic acid residues in 1tra.pdb

Finished adding non-standard nucleic acid residue definitions for 1tra.pdb, force object creation completed, did manual check of added hydros for all non-standard residues, looks ok.


Added creation of inter-residue steric reports. Added display of force vectors for atom pairs in inter-residue reports, and found that we need to handle the special case of adjacent residues because CTorsionBodyTgaxFcon passes ptrs in reverse order (nextObj, thisObj), because nextObj holds the covalent bond and geminal definitions. As a result, the order of the residue atoms is switched in the inter-residue steric data report. It was only when I added graphical display of the force vector that it became apparent, though the atom-pairs with max force seemed wrong too. Rather than messing with trying to change the order in CTorsionBodyTgaxFcon, I'll just hack the switch in the perl script, that's what Perl is for.

Added that fix, now the correct atom pairs appear to be reported, but the max-force inter-res atom pair appears to be wrong because it is a geminal relation (in 2nt.pdb, (C1.C3*, C2.P)). It's time to add dump of CNodeBsjForceObject::m_viPrevResBondAndGeminalList to force object data file.

Ok, so geminal pairs are not currently present in the list. Nowhere in the current code are geminal indices generated. I believe it was done previously, but seems to have been taken out. Hmm, maybe not. Anyhow, I'll add them tomorrow.


Added geminal definitions to force objects. It works, the max inter-res force is much smaller now. Did brief sim of full ahelix.pdb. It diverged from the canonical structure, but after 80kts, it is stacked and bonded in a different configuration, apparently stable. It' probably time for parameter evolution.

One thing we definitely need to add right away is some kind of annotated hydrogen bond indicators, because the current ones are simply wrong for movie playback.

Added max inter-residue force pair reporting to steric report.


Working on calculating energy values in forcefield functions. Also started documenting the forces in the specification html pages.

Added energy calc to CTorsionBodyTgaFcon and CTorsionBodyTgaxFcon. Added energy totals to rbq. Steric energy output is working.


Cleaned up inter-res and intra-res perl scripts to combine steric atom pair vdw and force vector display. It's getting easier to analyze the steric reports. Now, with energy display added, there is a discrepancy between the energy and the force. Probably a mistake in the definition of the energy function - need to do a simple unit test involving 2 atoms moved incrementally close together.


Created src/lib/wkEncon/tst/tst2Atoms.cpp to output a steric data file for 2 atoms which are moved incrementally towards each other. A plot of this data shows that the energy function is correct. I had mistakenly believed that negative energy values should not be associated with both positive and negative forces, but they are. The steric energy curve is a well with extreme repulsive forces on the left which go to zero at the middle of the energy curve, then, on the right, they turn into attractive forces which rise slightly, then gradually decay again to zero.

Added forcefield forceobject display icons to force display toolbar. Added force type enable icons to forcefield toolbar.

Note: there is a bug in updated box selection for force objects.


Removed 'AddAtomForce()' from hbond force calc so now all AddAtomForce() calls are for steric forces only. Also fixed a bug in hbond force calc where negative alignments will cause skipping of further force calc.

Been trying to think of a good way to exclude intra-node atom interactions in CTorsionBodyIteFcon and I believe there is a way, but it involves a pretty obscure hack, but at this point I need to just get moving on it. It works by adding the owner node index to the atom's covalent bond list. No, wait, there is a much simpler way, just pass in the owner node idx list in to the object! Yes, this is a much cleaner way with no overhead. Done.

Added display of covalent bonds, changed definition of recorded force vectors so that all vectors are displayed only for the selected force object (rather than drawing with reaction forces on other force object). This is much less confusing, and might be revealing a possible bug in the ring stack force. We need to create detailed ringStack reporting (as well as reports for other forces). No, probably not a bug. Need to add display of ringStack shadow points though.

Did a lot of working making visually-appealing force enable and display icons. Think I did a good job.

We might want to go back and try the single center-point attraction version of ring stacking however.


Tried to reproduce inter-res covalent stagger bug from last night with saved rbd, didn't repro. Added proper drawing of inter-residue covalent bonds.

Doing a sim of ahelix.pdb - full. For the first time ever, I believe, it appears that the sim produces a stable helix (so far, at 32kts). The only anomaly is a drift of the entire structure in a linear direction.

Well, I should have known it was too good to be true, subsequent sims of trna and ahelix single-strand are too stable - almost no movement at all. What the heck is going on?

Hope I found the problem - I did an optimization where I bypassed torque calc for single-atom nodes - wrong! Yes, that was it, whew.

Started overnight sim of 1tra with ringStackScale set to 20.


trna sim produced serious distortions. We need to do an exhaustive analysis of the default and subsequent structures. First, need to add url-encoding for '/' in browser scripts. Done. Still having problems with default path vs. base path in browser scripts. Thought of a way to handle it: create a new key 'absScriptFile' to specify skippping of default script path. It works.

Generated a complete steric report for 1tra pdb, it produced 6100 files and takes up 650 MB!! I had wanted to have archived reports to refer to, but there is not enough room on this laptop.

Things to add to steric reports:

Started creating notes on trna steric report.

Discovered a bug in detailed steric reporting: if an interaction is skipped because of outside of threshold distance, the cft data is invalid for that interaction (saw this from multiple atom pairs with the same interaction data). Fixed by a hack which sets the pair distance to -1 for pairs which are skipped.

Now that I'm finally getting around to some detailed observations, I'm becoming curious about other pdb models and note that the 1tra model is from 1986 and has a resolution of 3.0 A. It's time to check out 1ehz, with a resolution of 1.93 A from 2000.

Loaded 1ehz, aligned with 1tra using residues 1tra.A.PSU55 and 1ehz.A.PSU55. They're close, but there are differences.


Finally got around to protecting my windows drives in linux by mounting with umask=22 option.

Working on steric report again. It's getting complicated because there's so much information which can be analyzed. One thing I thought of adding is total steric energy for each atom. This would allow a nice graphic display of all atoms, colored by energy, where you could see the clashing atoms in red.

Getting rid of the -1 distance hack in detail reporting, we'll just report 0 values for force and energy, because that is the net effect. Otherwise, too many hacks and kruft.


Found bug where we are not setting the steric threshold for the steric force calc classes in CNodeBsjForceObject::CalcForce(). Fixed.

Added movie reverse play, fractional playback rate.


Cleaned up little bugs in movie code. Now I can conveniently play movies forward and back, at slow speeds. Recorded short movies for full ahelix to try to understand the distortion. Running the forcefield with forceobject movement turned off allows for continuous display of current forces while the movie updates the atom positions - very nice. A little inspection shows that there is something seriously wrong with the hydrogen bond force on the top base pair of the helix. Forces are very large, and not balanced.

No, on further inspection and thought, it's ok (the shadow force on one residue is balanced with the force on the OTHER residue, duh).

After watching hbond forces for a bit, I think what I might be seeing is a problem where large forces are trying to pull the atoms and the shadows together, when what should perhaps happen instead is for torques to produce rotations which would achieve the same thing, but with less disruption. Do we need to adjust the rotational inertia of nodes, relative to the translational inertia? Indeed, what is the rotational inertia of an atom about its covalent bond? If we consider just a single atom such as an oxygen, with no other bonds, all of its mass is concentrated in the nucleus, producing an extremely minimal moment of inertia, in comparison to a nitrogen with 2 hydrogens attached. After a little more thought, I have realized that many of these oxygens are double-bonded to base ring atoms and should not rotate at all relative to the ring node!! To address this should actually be quite simple, by adding the oxygens to the ring nodes, reducing the node count. Also, for extra performance via node reduction, we could consolidate added hydrogens to their parent atoms.

Added optional node consolidation to CTorGraph. Node consolidation is working and cuts the node count way down from ~22 to ~8!

Did a long sim of ahelix after node cons change. It hydrogen-bonds really really well now, but the stacking is messed up. I think the next thing is to go back to the electrostatic version of ring stack force.


Changed ring stack force to be electrostatic between ring coms, did a short sim of ahelix, seems to work fairly well. The initial structure changes, but perhaps not unrealistically so. Need to do a trna sim and also energy calcs.

Started trna sim. Added script 'OutputTotalEnergies.lua'. Adding energy calc for covalent, hbond, ringstack and electro forces, fairly easily.


After all-night sim of trna, we get a fairly bloated and distorted structure. However, I need a good quantitative way to express the distortion so that I can understand it. I think that I'll begin working with the anti-codon stem loop of the trna to simplify and speed up things (residues C25 - G45).

Created script 'exp\report\'. Working on script 'DrawFoDihedrals.lua', found bug in dihedral calculation code.

Fixed bug, checking dihedral angles for ahelix.pdb, found an interesting set of dihedrals for residue G5 which are different from all the other residues, but they still work to connect the residue into the A-Form helix.

Started on SetDihedral.lua, a script to set dihedral angle of a force object (and rotate all downstream objects). There is a weird select bug clicking on the connecting segment of a phosphorus - ahh, we're not setting the pick id in CRbqDynamicSegment.


Finished 'SetDihedral.lua' script, it works. Started on 'MakeAhelix.lua'. Running into problems rotating terminal dihedrals. Also, there appears to be a bug in missing electrons for O3*. This is due to lack of access to inter-residue bond when adding hb acceptors. Wasn't a problem for the other end of inter-residue bonds, the Phosphorus, because it isn't an hbond donor or acceptor. To set dihedrals epsilon and zeta, this requires rotation of next residue nodes, not current residue nodes.

Got script 'MakeAhelix.lua' working, started long sims on ribo3 and inga. Inga, a P4-2.2GHz machine, runs the asl model very quickly.

Removed 'N_M' from dynamic segment name format in CRbqPdbMol::GetDynSegIndexFromChainId(), but we need to add a residue name as a parameter in the future, to get the right dynamic segment when there are multiple segments which share a common static chain id.

Gave demo to the ribolab today, they liked it even though the movie didn't show any real folding behavior.

Tried to run the old cycleSim demo and found that it is broken because of the check I put in the forcefield which stops if no objects are in there. Perhaps I should change it to a warning. The whole 'enableAnimations' command is also rather misleading, as all that it does currently is to start the forcefield. Should I have a separate control (didn't I add 'script so gte' ? It looks like it's not there anymore. I should probably deal with this later, too tire to do an intelligent fix for now.


Finally fixed calculation of diehedral code. MakeAhelix.lua is working again.


Got full-time high-speed internet and router! Woo-hoo!


By incredibly good luck, I found that my default browser port number for lua script requests, 25546 (which is 19620810 % 65536) happens to be in an unassigned block! (, block 25010 - 25792). Cool. Though, would it have been better to have been in the 'Dynamic and/or Private Ports' range? (49152 - 65535)?

In trying to have scripts call other scripts with command-line args, I've figured out that the intermediate 'load( libFile )' calls totally blow away the current command-line args. And even when I fix that, because it's a raw set instead of a stack-based set, a script called from another script will blow away the caller's args. Arg. Well, I should just be able to reset the original args after the return from dofile() in runScript().


Adding to dihedral frequency reports. The current reports show statistics, plots and raw data. This allows for observation of interesting trends, such as 24 residues in 1fka.A which have a Beta dihedral angle of 180, when the most common values are around 356. To investigate further, creating script 'SelResWithDihedral.lua', which allows selection of residues which are within a param range of a param dihedral angle.

Reading the article 'A Complete Conformational Map for RNA' and noting the vastly different vanderwaals radii used makes me wonder if some of my MD problems result from excessively large vdw radii. In searching for a source for good vdw radii, I am considering getting it from statistics on actual closely packed atoms, as found in actual crystal structures. I could do the same sort of frequency distribution, using intervals of 0.01 angstroms, for all non-bonded atom pairs of various types in a structure. These types would be based upon element type and valence configuration (ex: sp3 C, sp2 O).


Working on 'CalcVwFreqs.lua'. Finished script, it works well. Takes a little while (~20mins), but collected all atom-type distance frequency counts with a resolution 0.1 A from 1fka.A. Next: write a perl script to condense the data from the 3655 atom pair types in the output file, hopefully to see some trends which will indicate what vanderwaal radii to choose.

Started on script '', which consolidates atom pair dist frequencies into element pairs. Finally found the cause of my occaisional split problems, where NULL field is returned when splitting on lines with leading whitespace. Careful reading of the split() function in the camel book reveals that leading whitespace is intentionally skipped for some reason. Now that I know how to use the pattern-match operator, it is no problem to strip the leading whitespace.

Created script '', which converts data from elPair output file into individual single el pair files with distance values suitable for plotting. Did some manual plots of C vs. C, C vs. N, etc. Interesting, but no striking trends yet. We may have to break it down to more specific atom type plots, such as C-sp3, N-sp2, etc.

Added code to output atomTypes file, going through and adding sp2 or sp3 designation based upon valence.


Got rid of eview lib (not being used any more, replaced by lua scripts and html reporting). Added mouse move rate menu items to Nav menu.

Was thinking on the way to lab meeting about how to add atom types to the existing forcefield. Right now, everything is based upon the very simplistic property of element type to determine force interactions. I've always resisted adding specific atom types, because I was afraid of the complexity that they might introduce. Still, it may be necessary and I conceived of a simple way to provide for them, with minimal disruption of the existing design. I could simple enhance the current definition of the base abstract class CAtm by adding Get/SetAtomType() functions. And there wouldn't even be any data overhead in the CFpoAtom class in the wkFastPdb lib because I can just replace the element type with a short int atom type and do GetElementFromAtomType() function internally to return the element for calls to GetElement().

Finished script script. Creating html reports for el and at freq data. Finished


Finally started creating a distribution package for rbo. Doing test run on inga, realized that perl and gnuplot were missing. For bio users, it's too much of a hassle to require download and install of these external components. Fortunately, I found a way to package a minimal distribution of perl in the rbo zip file. Current size is around 7.7M.


Added internal navigation links to, it makes working with and comparing reports a lot easier.

Started working on user manual.

Finally finished lua and perl scripts to produce atom distance frequencies, compared by valence type. There are lots of interesting plots. Now we need a script to select the individual atom pairs by distance, so that we can see what they are.

Finished script 'ReportAtomsAtDist.lua'.


Working on html reports for output of 'ReportAtomsAtDist.lua'.


Fixed bug in (wasn't looking at iPdb and iSeg when doing fixup for adjacent residue hack). Also fixed bug caused by changes to allow for individual force object reporting (maxNode.lst file wasn't being created).

Added '', to produce html report from atom pair dist data.


Added script 'hiDistPair.lua' to highlight atom pairs in html report produced by ''. Wrote half of the user manual.


Gave a lecture about Ribosome Builder in Steve's graduate biochemistry class, it went well. Released the program on the web!!!


Adding reading and writing of ff params from file. It works. Next: genetic algorithms to produce better forcefield params. But first, we have to add AtomType to CAtm and derived. For simplicity, just treating AtomType as an int, so it can old Element enum value as default. Finished initial replacement of element with atom type in CFpoAtom class. Thanks to encapsulation and abstract classes, the changes should not produce any unexpected side-effects. The trans-element atoms types will only be changed for pdb atoms which are wrapped by torsion atoms, and the type will be set in CRbqDynamicSegment during force object creation, so the lower-level libraries don't have to know anything about atom types. They just set the atom type to the element type during their initialization, just as was done previously with element type. The only impact should be a storage increase from byte to integer size in CFpoAtom.

Tagged release version in cvs as 'Release-0_1-2003_09_30', although the working version I did it from on beryllium may not have been completely in sync with what was released to the web.

Added sequence subdir to dist.lst (it's missing from rel ver 0.1).

Todo: rename default movie file and delete on startup. Done. Also, there are some bugs doing an initial rewind in the movie.


Added setting of atom types in CRbqDynamicSegment. Now just need to add setting of CElement atom type valences to CRbqLua interface, and we will have scripted control of vdw radii.


Added lua functions to set vdw radii for atom types.

Rbo project work is now focussed on supporting the Rkp project (w/ Scott Hennelly). Today, spent some time thinking about the major steric clashes that are still ocurring with the current rbq forcefield model. The definition of atom types, with customizable vdw radii, will not solve this problem as the steric clashes are typically between 1-4 atoms at very close distance relative to any reasonable vdw radial sum. The answer, I believe, is to simply skip 1-4 interactions in steric calculations, and replace it with some kind of torsion angle function, just as traditional molecular modeling trends indicate. Implementation of this should not be too problematic. For intra-residue steric calculation, the CTorsionBodyIteFcon class could be modified to do an extra recursion for bonded atoms in the token-exclusion algorithm. For CTorsionBodyTgaxFcon, 1-4 atom pair indices can be added to the existing exclusion list.

Did some work trying to secure my linux box.


Changed CTorsionBodyIteFcon to exclude bond partners to an arbitrary depth, set default to exclude 1-4 atom interactions. Change was easy to do. Added 1-4 atom pairs to inter-residue bond exclusion list. Also fairly easy to do after defining recursive function 'AddAtomPairsToList()' in CRbqDynamicSegment.

After finishing and verifying that 1-4 atom interactions are skipped for steric force, did another run with ASL of tRNAphe for 300 frames and still get major distortion. Subsequent analysis of steric report shows that there are still major steric clashes between various atom pairs. Brief research on the net show significantly smaller vdw radii than the defaults. Next step: create a script to read user vdw values from file. Started script 'SetAtomTypeVdwRadiusFromFile.lua". The script works. Also added script 'ReportAtomTypeVdwRadius.lua". In redoing steric report on ASL, it quickly becomes apparent that I need to add the non-standard nucleic types to the 'nucleic.atomTypes' file, as the customized atom type vdw radii are not being used for their atoms.

In creating the valence definitions for the non-standard residues for tRNAphe, I found that the force object valence for N20 of YG37 wasn't correct. Traced it back to a rule in the code from the old rb project which said to make the valence planar for a nitrogen which doesn't have double bonds but is bonded to a double-bonded atom. I think I added this rule to make planar nitrogens in the old code when I didn't explicit add double-bonds. Removed the rule to make N20 sp3 valence. Woah, that screws up the exocyclic amines in cytosine. I guess a nitrogen bonded to a planar atom must also be planar if it is part of a conjugated system, where the non-bonded electrons are delocalized into the system via resonance.

Created script 'ForceObjectReport.lua' when debugging the N20 YG37 problem.

Finished adding non-standard residue atom types to 'nucleic.atomTypes'. Ok, almost there, just need to override 'GetAtomType()' for CTorAtom to call member atom method so the atom type of the component CFpoAtom is retrieved. Done. After defining new vdw radii in 'newVdw.atomTypes' file, there are no more huge steric clashes in the 2 adjacent test residues in the ASL model.


Did an all-night run of the ASL using the murthy99Vdw.atomTypes vdw params. Got a scrambled structure the next morning after 117 kts. Analysis of the energy plot shows that the hydrogen-bond force is completely dominant, with the other forces undergoing little change relative to it. After thinking a while what is still wrong, I believe I'm finally coming to understand and appreciate the torsion potential. After elminating 1-4 atom steric interactions yesterday, I finally got rid of the major destabilizing forces, but now it is clear that we need something to fill in for the missing steric constraints. This is of course the point of the torsion potential, which I realize that I can determine by doing a rotation about the B-C bond and calculate the potential at a series angles. Then we can have the benefit of these 'tangential' clashes, without the huge radial forces which would act to disturb the covalent bond.

Creating class 'CRbqTorsionForce'.

Finished code to do torsion bond calculations.


Added code to create torsion bond definitions.


Debugging torsion bond forces. It's much easier because I thought to create a simple 4-atom residue from a.pdb. This gives just a single torsion interaction, which can be displayed with force arrows on the A and D atoms. Also, positioning and aligning the residue at the origin so that the vBC vector lines up with the z axis helps. Torsion force appears now to be working properly - the test residue went from cis to trans and stayed there. There is a small artifact, however, that causes the entire residue to slowly rotate around its center-of-mass.

In debugging the rotation artifact, I loaded up a.pdb, enabled only torsion and covalent forces, let it run for awhile, resulting in rotation, then disabld torsion forces so that only covalent forces are enabled, and it still keeps rotating. This could be due to either inertial, remaining because of the relatively small frictional values, or to some kind of asymmetry in the covalent bond linkages. Cranked up the linear and rotational friction from .1 to 10, and the nt quickly slowed to a stop. Then, after a long wait, reset back to .1.

With friction set to 10, and torsion turned on, we appear to have a fairly stable structure for a.pdb. Actually, on playback of a short movie recorded with those settings, there does appear to be some residual rotation still happening.

Added creation of rbo 'tmp' subdir, if needed, in 'Startup.lua'. TODO: add code to delete script object dirs in 'lua/tmp' subdir on startup!!

Adding creation of inter-residue torsion bonds to CRbqNodeBsjForceObject::CreateTorsionBonds().

Trying to build the release version, and save some memory, made hbond donor and acceptor enables conditional on debug version only, but used #ifdef DEBUG instead of #ifdef _DEBUG and all sorts of weird problems and crashes occurred. Why? Not sure, but changed define to _DEBUG and release version ran ok after that.

Added energy calc to torsion force. Started all-night sims on ahelix.pdb and asl.pdb.


The torsion force works!! We have stable structures!! They undergo some conformational change, but keep the fundamental conformation. The rest is most likely a matter of tweaking the parameters (and possibly adding cations).

After adding scripts to insert additional sub30 models in standard orientation, found bug where adjusted transform of the pdb model wasn't being propagated to force objects (still being done the old way, via torsion graph). Fixed bug. Also made 'monitor frame' of torsion graph an ifdef to save memory.

Started sim on 1i94.A helix 16.

Reorganized distribution into rbq, exp and pdb zip files.


Started overnight sims last night on ribomachine3-laptop (helix 16), ribomachine3-lab (helix 16 and 18), Inga-home (top of helix 44 and others), and Drew's machine (helix 44, full).

Preliminary observation of helix 16 sim on ribomachine3-laptop shows overall stability of starting structure, but changes come about from a gradual 'contraction' of the backbone, and also some specific base rearrangements as certain base pairs 'snapped' into the ideal WC conformation and other bases formed hydrogen bonds that were not existing, according to the simulation criteria, at the start of the simulation.

Finally added shifted range selection to CRbqCmdProcessor. It works!

Adding code to support display of interaction counts and rates, prior to adding multi-timestep per timerEvent tick to increase simulation speed.

Todo: add total number of atoms to selection reports.

Finished adding cumulative stats reporting, and script 'DisplayTsStats.lua'. Ran a 15 residue segment in 1tra ASL for 1000 timesteps on ribomachine3-laptop, got the following stats:

  • steric: 6.7e2 ips
  • torsion: 8.4e1 ips
  • covalent: 8.1e2 ips
  • electro: 3.6e3 ips
  • hbond: 8.1e2 ips
  • ringStack: 2.6e2 ips

    Next, setting timestepsPerTick to 10 and re-running, we get:

  • steric: 8.9e2 ips
  • torsion: 1.1e2 ips
  • covalent: 1.1e3 ips
  • electro: 4.7e3 ips
  • hbond: 1.0e2 ips
  • ringStack: 3.3e2 ips But this doesn't seem right, as it appeared to be much faster. But perhaps not, after re-running with tpt of 1, and getting same results. Perhaps the benefit will be more on faster machines/larger models.

    When I tried to set a larger tpt value on Inga in simulating a fairly large structure, the system became so unresponsive that I had to tfs and kill the program.

    Worked a little with Scott in the lab to investigate the long sim of helix 16 and 18 on 1i94. One of the bases where he got results happened to be flipped out in the crystal model, which is intriguing. Unfortunately, I didn't have the sequence maps setup for 1i94, or for 1j5e, which Scott has been working with. Then, when I tried to do an alignment between 1i94.A and 1j5e.A using clustalw, it didn't work!! As a result, I've had to spend precious time doing research on sequence alignment stuff.


    Downloaded BioPerl on beryllium and learning how to use it.

    Started doing some analysis of dynamics of the helix 16 sim on 1i94 on ribo3-laptop. One helpful means of interpreting what is happening is to load the initial and final structures as pdb models and display their backbones in different color. Then the playback of the force objects in the movie has a nice visual context. It also prompted me to think of trying to highlight the spatial and temporal fragments that show the greatest change during the sim. Such fragments might form the basis for the repetoire of movements. Not sure what mathematical tools exist for identifying such fragments. Normal Mode Analysis?


    Spent most of the day trying to get a good pairwise alignment tool to compile and run on Windows as well as linux, and also to understand why clustalw doesn't work on ( 1i94.A, 1j5e.A ) alignment. The globalS program from the seqaln library worked well to align the sequences using the parameters (1, 0, 0, 0) (for match, mismatch, alpha, beta). But at first, I didn't realize that the wrapper code for globalS was in the demo subdirectory and had problems compiling it. But after finding the wrapper, got it compiled and running fine on windows. After burning a lot of time trying to work with huge integrated systems such as bioperl and EMBOSS, I realize yet again the incredible value of simple, stand-alone programs compiled in C for portability and comprehensibility.

    Finally got sequence map calulated for 1j5e, filling out sequence info for other models. Started setting up modeling of h27 in 1j5e to try to discover the dynamics of the Lodmell switch.


    Showed up at the lab and checked on the simulation on ribomachine 3 of helices 16 and 18 of 1j5e. It had run for almost 200kts, after 3 days. The most significant observation is that the helices mostly contracted, as has been seen before. After a little reflection, I fell this is probably mostly due to vdw parameters that are too small. Previously, I had wanted to set them on the small side because of the continual instability, but I think that implementation of the torsion force has mostly solved that problem, so I am now running a simulation of ahelix.pdb (1rxb) with the murthy99 parameters increased by 10%, to try to stop the contraction.

    Another thing to try is lowering the ring-stack force, which currently is at 100.

    Started ahelix sim 002 on ribo3, with ring-stack scale set to 10, along with 1.1 murthy vdws.

    Fixed bug in hiding of ts count when ff stopped (state was getting out of sync between menu and ortho text when doing new document). Also fixing some annoying movie bugs.

    Thinking about how to add 'driving' forces to the forcefield, input by script objects. At the very least, we will need a second time-user tick loop, after the forcefield step, because the current one is before it, and all node forces are cleared at start of timestep. This will add to the complexity of the script objects, but that is preferable to increasing the already considerable complexity of the force object code if external force input were added there instead. Actually, it's still nasty as the script object has to apply the force in-between the CalcForces() and TimestepMove() sub-steps.

    Finished sim 002 of ahelix on ribo3, rss of 10 helped some, but still a lot of contraction. Next: sim003 with vdws of 1.2 murthy99.

    Finished sim 003 of ahelix on ribo3. With vdw 1.2 of murthy, we see a different kind of distortion, though just as pronounced. It appears that the larger vdw radii torque the resiudes in a way that forces 2 endpoints of opposite chains together, and the partner endpoints on the other chains apart. So just cranking up the vdw radii is not the solution.


    Did sim of ahelix on ribo4 where I tried increasing the nbeProject to 0.8, ess inc to 10, rss dec to 10, got a distortion in the opposite direction of prior contractions, so that is hopeful. What we really need are some scripts to characterize the geometry in terms of twist angle, base-pair step, and so on.


    Running more ahelix sims on inga. Starting on support for scripted input of forces to force objects.

    Researched purchase of a high-powered pc on the internet - looking at the Alpha64 system from abspc.

    Finished addding support for scripted input of forces.

    Checked long sim of helix 27 on ribo3. Examination of certain base-pairing disruptions and formation of new, destabilizing bonds raised the question of whether it is invalid to allow rotation of exocyclic amines on the bases. Since the nitrogen is in a planar configuration, does this mean that its bond to the ring should be constrained in rotation?

    Looked on the internet for some open source software to calculate geometrical parameters for RNA structures - didn't find anything.


    Adding extra documentation to the User Manual on Web Browser Interface, and I realize that I absolutely must fix the security vulnerability in the htsrv process so that it only accepts connections from the localhost. Did a quick test of doing a GET request from another machine on the LAN and observing how it can control the behaviour on the machine running the rbq app. Done. Added code to reject all connections from ips other than localhost (, so this should be safe unless the attacker is able to spoof the localhost IP.

    Added 'OutputCurSelIdxName.lua' support script so that we can get the residue names in perl reports such as ''. Also added mean torsion angle, to compare with values in Nacb (Blackburn and Gait, 1997). Also downloading additional RNA helix structures from the Nucleic Acid Database. Downloaded ar0020.pdb, a nice long RNA a-form helix. But it is strange, the base pairs have a significant amount of propeller distortion. Is this normal for a canonical helical structure? Added stdDeviation calc to ''.

    Starting on code to calculate geometrical parameters.


    Looking at the base-pairing of ( 1j5e.A.G885, 1j5e.A.C912 ) and seeing the same kind of propellar angle noted in ar0020.pdb, it causes me to wonder if it might be a way of reducing steric clash, while still maintaining a hydrogen bond? No, after doing some manual rotation of the nodes, it appears that the propeller angle is probably a result of the helix backbone geometry, which must be constrained by factors in addition to the WC base-pairing.

    Added fix to wkGrChem.lib CGrAtmUtil so that drawing of atom spheres reflects the atomType vdw radius instead of the element radius.

    Redesigned the online web page by adding a main menu and 'download', 'doc', 'screenshots' and 'about' pages. Built and released version 0.1.4.


    Added reporting of total atoms in selection report and report of total hydrogens created in force object creation.

    While doing some research on adding charge to phosphate O1P and O2P, and also on how to better define their valence structure, I think I came across the geometrical analysis software for nucleic acids that I was looking for the other day: 3DNA (


    Adding atom-centered charge calculations for electrostatic force. In doing so, added charge to CElement::AtomType, redefined atom type definitions in 'nucleic.atomTypes' file.

    Defined 'Charged-Atom' type of electrostatic force calculation, to replace the 'nbe' type (non-bonded electrons on hbond acceptor atoms).

    Charged-Atom electrostatic force calculation is working.

    Added save/restore of toolbar visibility state.

    Created a pdb file with a single sodium atom, started adding support for creation of force objects from metal residues. With just a few small additions, we have successful creation of a force object containing a single sodium atom, and steric forces work just fine in forcefield with 3nt.pdb!!


    Added d_iAtomType_Sodium, d_iAtomType_Magnesium. Charge-atom electrostatic interactions between sodium and O1P and O2P are working. Simulating test file 3nt-3na.pdb.

    Discovered GROMACS.

    Next: need to do auto-addition of Na ions to nucleic acid phosphate binding sites.

    Created script 'AddCounterIons.lua'. Talked with Scott to realize that counter-ions will be Potassium, not Sodium.

    Created counter-ions for ahelix.pdb and did short sim. We still get helix contraction, counter-ions seem to have no effect on that.


    Setup exp project for helix 27 in exp/dev/sub30/1j5e/h27/ls.

    Prior to setting up exp project for decoding center, fixing centerViewOnInsertedObject for model loading scripts, adding missing model load in std orientations scripts for 50S.

    Started organizing some ahelix movies in the exp web pages and found that some incompatibility has been introduced in the last few days so that the old movies do not playback properly. It's so much easier to just read 'Acts of the Apostles'.


    Fortunately because I had multiple old versions of the program on inga, it was easy to determine what changed after writing a small script 'ReportTotalNodes.lua' and running 'ForceObjectReport.lua'. The node count changed because I had added O2P to the extra bond definitions so that it would have the same valence as O1P. As a result, it was concatenated into the P node, reducing the node count. So now the question is whether there is an easy way to play old movies with the new code. Perhaps the best way is to not mess with the code, but write a utility to convert the old movie format into the new one. In this particular case, this would involve deleting the O2P node data from the coord file. However, considering the early stage of the forcefield, and the fact that the movies can still be played with older versions of the program, it may not be worth the effort to write a conversion utility at this time. While we're at it, should probably consolidate extra-cyclic amine nodes into the ring. Need to check with others though, to make sure the nitrogen does not rotate.

    In considering the contraction problem in ahelix.pdb, it's clear that it happens because the vdw radii are too small, as specified by murthy99Vdw.atomTypes. Scaling up by 1.2 (wrote script fills in the gaps between the base rings, but then we get large torsion forces on the ribose and backbone atoms. One nice solution to this is to use a vdw scaling factor for torsion interactions. This alteration seems legitimate because the steric interactions for 1-4 atoms are already treated differently with respect to radial vdw forces.

    Finally ordered an Athlon-64 system from ABS PC, will get it in a couple of weeks. Hopefully by then I'll be ready to do some serious simulations. Spent some of this afternoon trying to think of ways to speed up the simluation of the whole ribosome. One immediate area to consider is adding 'partner' lists for dynamic residues, instead of iterating O(N^2) pairs and skipping residue pairs that are beyond a certain threshold distance. Traditional MD programs use partner lists for each atom, and update the lists every M timesteps by doing a full O(N^2) iteration. Because the rbq program is currently committed to a residue-level of granularity, it's likely that time is being wasted on calculations steric interactions of atom pairs that are so far away that the interaction is insignificant. To assess the potential benefit of partner lists, I need to write some scripts that can calculate the difference in steric interactions that could be gained, for certain large reference models.

    Other more vague thoughts relating to radically improving the computational time touched upon the idea of 'torsional' and 'complementary' coupling between large numbers of atoms in a macromolecular system. The torsional coupling term represents the idea that atoms in a covalently-bonded chain of residues possess a conformation that is determined by the torsion angles. The 'complementary' coupling term represents the idea that the space of possible conformations is constrained by the requirement that the atoms are typically closely packed together in complementary surfaces. Also, is it possible to consider that the surface of a molecular conformation is 'implicitly' defined by the torsion angles of the molecule? Then, might it somehow be possible to create a representation of the molecule that consists of just a small number of torsion angles, and calculate the possible evolution of conformation over time with this smaller number of variables instead of the large number of coupled 3D coordinates of atoms? The difficulty seems to be how to calculate the implicit surface complementarity constraints in terms of the torsion angles.

    Talked with Scott about the rotating exocyclic amine question, and the valence geometry of the phosphate oxygens, he wasn't sure.

    TODO: add automatic output of ff params, vdw radii and perf stats to files in a log subdirectory everytime the forcefield is started and stopped.

    Added torsion vdw scaling factor. Did brief run of ahelix on ribo4, contraction seems better. Released version 1.5.


    Fixed bugs relating to creation of charged counter-ion force objects that resulted from the discrepancy of PDB ATOM record residue names having spaces in them, versus trimmed residue names in the code. Went throught CRbqDynamicSegment and changed all code and data to use trimmed residue names.

    Added lua function to do standalone rms calculation for 2 pdb chains (as opposed to multiple RMS calcs with persistent script object rms calculator). Wrote 'CalcChainRms.lua' script.


    Yesterday, I began to suspect that some of the stability of the sims I have been doing is the result of cranking up the friction from 0.1 to 10, and sure enough, after doing an overnight simulation of the ASL with friction of 0.1, found a lot of divergence from the initial structure. This is to be expected, given the current qualitatitive state of the forcefield parameters, but it poses a problem for doing useful simulations of ribosomal structure. One transitional step in dealing with this problem that I've started to think about is to freeze the movement of individual dynamic residues and instead transmit their forces and torques to the center of a larger unit, such as their parent dynamic segment. This would move things back to the 'frozen block' situation of earier stages of the program, but after allowing for 'docking' and rearangement of larger structures such as the tRNAs in the A and P site, then perhaps relative movement of individual residues could be allowed on a more restrictive and interactive basis, by trying to observe where the driving forces are occurring.

    With a little more thought, I realize that it is much better not to mess with the existing force object code to implement such 'larger block' movement. Instead, the way to go is to just disable force object movement, calculate the node forces and torques, and then accumulate and apply them via the scripting interface. Scripted interaction is necessary in any case for the analysis of the force and energy states of the interacting objects.

    On further reflection, that approach won't entirely work, because I don't believe that the node torques can be translated into the larger body - we will need to specify the larger body center-or-mass at the time of calculation of the torques. Still, it shouldn't be too big of a deal to specify the 'parent-transfer' of force, this has been done several times in previous implementations. Or instead, perhaps, a 'force monitor' object ptr that taps into force object force input functions. The monitor can be an fiTick script object that can calculate and do movement of the dynamic segments. The only question is the possible performance hit, if calls are made to the lua script object directly from the force object functions. If needed, we can create a C++ proxy object as the force and torque accumulator, and relay those to the script object at fiTick time.


    Added class CRbqCustomForceContainer. Added class CRbqForceGroup. Added support code. Create 'TestCfc.lua' (test custom force container).


    Finished 'TestCfc.lua' and ran the ah-2nt model in the custom force container and it works. However, it highlights one problem where the 2 nt's start out base pairing, and then over time separate due to gradually increasing instabilities. Of course, one could argue that a single base pair is inherently unstable, given background thermal motion, but we are not currently adding thermal motion, unless we consider the numerical inaccuracies as 'free thermal input'. In any event, given a deadline for presentation in a few days, I must press on with this new version for simulation of 30S initiation.

    After re-running the ah-2nt testCfc with intra-group movement on, the interaction is stable.

    Started setting up mRNA sim. Created script 'OutputChainResAtDist.lua', a script to select residues of a param chain that are at param dist from current selected residues.

    Did an all-night run of docking the 6 residues of 1jgo mRNA on 1j5e, it docked into a stable structure.

    Released version 0.1.6 to the web page.


    Started sim of 1j5e.A head on new Athlon64 ribomachine5.


    Started adding support for protein dynamic residues.


    Finished amino-acid atom type definitions in 'amino.atomTypes' file. Started creating dynamic amino acid residues. Running into a problem in CValenceShell where there are now too many bonds to carbon atoms, because I have been creating double bonds for all carbon atoms in 1.5 'resonance bond' structures such as ARG, where CZ has a double bond to each of its amino partners. It may be true now that the whole purpose of the 'CValenceShell' class, and addition of double bonds is unncessary with the use of atom types, which independently define a valence structure. Or at least, the geometry-determination portion of CValenceShell is not necessary, as we still need it for hydrogen addition and hbond vectors. Perhaps a simple fix to get the valence geometry from atom type instead of the module functions of geometry determination is all that is needed. This has been done and it works.

    Successfully created first amino-acid dynamic residue, arginine. Now we need to adjust charge and extra hydrogens. This will involve creating additional arginine-specific atom types for NE, NH1 and NH2.


    Changed dynamic segment creation so that sequential sets are determined by sequence number, not residue number. This was necessary because of the recent change in CRbqNodeBsjForceObject::SetPrevResBondData() that requires a non-NULL previous force object to be bonded to the force object. For the protein test dynamic segment using 1g7r, the creation was failing because of so many non-continguous segments.

    Added non-standard amino acid residue type 'MSE' (SelenoMethionine). Added Selenium atom type. Added script 'ReportInterAtomDistance.lua' to calculate maximum Selenium-Carbon bond lengths.

    Force object creation is now working for all residues in 1g7r.A except for ASN517, which has some atoms missing, and so failed in hydrogen addition. Since missing atoms will be common in PDB models, we must find a graceful way of dealing with this, instead of the current situation, which can fail if any selected residue has missing atoms. The way to do it is to pre-scan a static residue selection intended for dynamic segment creation and drop residues with missing atoms, reporting to the user.

    Added function 'ValidateForDynamicResidue()' to CRbqPdbMol. It works.

    Added selection of dynamic residues by sequence number.

    Next: we need to do inter-residue bond addition for amino acid residues between the the amino and carboxyl atoms, because currently hydrogens are being added to them.


    For some reason it was never a problem with nucleic acid residues, but adding inter-residue bonds prior to hydrogen addition is turning out to be a major pain for amino acids, because the inter-residue bonds are defined AFTER hydro addition. Ah, that might be the answer - just skip hydro addition for inter-residue atoms (N and C) and do them after inter-residue definition. However, that's problematic because inter-residue definition takes place after torsion graph and force object creation, and we need the created hydrogen atoms before that. The only answer seems to be prior definition of inter-residue bonds to the next residue.

    Added function CRbqDynamicSegment.cpp : GetAaInterResBonds(), this fixes the hydro addition problem for the protein backbone in dynamic segments. Still fixing resonant-bond structures in the side chains however. For Arginine, for example, there are crystal structures that show full hydrogens on the 3 aminos on the zeta carbon. Currently, the valence code is creating hbond acceptor vectors on these hydros because of the double bonds that are added. But now that valence geometry is determined by atom type, these double bonds are no longer needed, and I removed them. This produces the correct number of hydrogens on these nitrogens. Still one thing remaining: implement an atomType valence in place of the current element valence so we can prevent the addition of a hydrogen onto the zeta carbon. Added CElement::GetAtomTypeValence(), added new atom type d_iAtomType_Carbon_Arg_CZ.

    Added atom type d_iAtomType_Nitrogen_Lys_NZ.

    Now we are also needing inter-residue bond geometry to create the amino hydrogen of a residue in the same plane as the carboxyl of the previous residue! Arg. But this should be working, given the temporary addition of next residue bond, as mentioned above. There is some problem in CValenceShell.cpp : AddPlanarBondVectors()). Ok, it is a bug in adding the prev residue carbonyl carbon - by chance, a carbonyl is added, but the very first one, not the one in previous residue. Yes, of course, it's because we're using iRes instead of iResIdx in CRbqDynamicSegment.cpp : GetAaInterResBonds(). Duh. Ok, that's fixed. Did a short run of 2 adjacent dynamic lysines after altering the conformation so that the positively-charged termini were close together. Got the expected repulsive behavior and conformational change.

    Added atom types for carboxylic oxygens in aspartate and glutatmate. Now we need to contiue to improve dynamic segment selection code - can only select the first dynamic segment by residue name or number. Starting by adding validation of selection range for dynamic objects. We need a nice design pattern for index ranges.


    I'm thinking of creating a new class, CRbqIndexNode, that essentially represents the hierarchical indices of the pdb object tree. This class is intended to validate and iterate index ranges within the hierarchy. The class can use composition so that a node can be created for each CRbqPdbMol object and each of these can serve as components for a single node that represents all the indices for the document. I'm not sure if this is the best way to go, but I think for now it could simplify some of the current grungy code for validating and iterating index ranges. One additional complexity that needs to be simplified is the translation of the extended chain indices, that represent dynamic segments, into direct indices for dynamic segments. Perhaps some kind of slicing operator?


    Still struggling with cleaning up the selection of objects after taking a break for a few days to work on the Tch hypothesis (didn't have any luck with that, either). The initial design of the rbq project used a simple hierarchical numerical index in an attempt to simplify specification of objects, and this has worked well, in comparison to the sometimes byzantine code that evolved in the previous rb project. However, addition of dynamic objects to the hierarchy has complicated things, and the code is threatening to go byzantine on my ass again.

    I think I'm starting to figure out how to use the interface CRbqIndexNode to more cleanly validate ranges of objects in the hierarchy.


    Still working on CRbqIndexNode functions. It's taking a long time because I keep wondering if this is the right thing to do, if this interface and implementation of its virtual functions in CRbqDoc and CRbqPdbMol is worth it. I think so. The idea is to generalize code that uses numerical hierarchical indexes to specify different types of objects. The numerical index scheme fits well with the OpenGL name stack for picking objects in the graphics window. The numerical indexes are also readily extendible to multiple levels in a hierarchy and are conveniently held and managed with generic STL integer lists as parameters to functions. The notion of an object hierarchy is also a general one, as specified by the Composite design pattern. By accessing objects via numerical indices, we can validate object references by checking that they fall within validate endpoints of a numerical range. This also allows for iteration of objects within that range. The only somewhat confusing part is supporting multiple types of composite objects as separate hierarchies that are contained by a parent object. But a hierarchy parameter is necessary when a parent object contains multiple types of child objects that must be treated distinctly. The hierarchy parameter lets us iterate child objects of a common type, and stop before encountering the first object of the next type.

    Finishing up dynamic hierarchy validation and range translation.


    Dynamic segment selection is working. Adding selection reporting for dynamic segments.


    Released version 0.1.7 to the web. Started sim of 1j5e S19 on ribomachine 5.


    Started running a sim on inga for the alpha helix of 1j5e S19 and noticed right away that the backbone amino is in the SP3 configuration instead of SP2. Now this is strange, because I tried to repro on ribo4 and the aminos there are SP2. Well, the answer has been found, I forgot to add the 'amino.atomTypes' file to the distRbq.lst file. The strange thing is that no errors or warnings were reported about this missing file.

    Added missing files to distribution list and added error code for failure to initialize atom types.

    TODO: added absolute timing code to 'init' demo, it runs too fast on ribo5. Released updated version 0.1.7 to web.

    Trying to validate protein code by simulating one of the structures from a movie in molmovdb in a condition that mimics the other structure. Started with the pka movie, which has pdb models 1stc and 1q24.

    Downloaded and compiled the ce structural alignment program and tried it on 1stc and 1q24 and it works! Now I have a general-purpose structural alignment tool that I can use.


    Reading through the code for CE to understand how it works. This seems doable, but will take me a little time. In the mean time, I looked around the internet for other structural alignment tools. Found references to SSM, VAST and DALI in addition to CE, but these other tools were flawed because they didn't provide immediate access to their source code.

    So, prior to working more on CE, just for fun, I speculated on how to create a very simple structural alignment program. In exploring an idea, I created a simple cubical molecule pdb file and found a crashing bug in the rbq program, specifically, in wkGrChem lib, CGrPdbObj::DrawResidueBackbone(). Ha, it happened because just by chance, I defined a Phosphorus atom as the final atom in the cubemol single residue, and in the code I stupidly assumed that a multi-atom residue with Phosphorus as the backbone atom would not have the Phosphorus atom at the end of the atom list in the residue. Fixed the bug.

    Added drawing of spacefill mode with points to wkGrChem.

    Trying to kick off a full ribosome sim on ribo5, but running into weird problems with 'composite' residues in 1j5e.A: G129, U190, G1003, A1030, C1361. Finally got it started after deselecting these residues.


    Very painlessly used Nucleic Acid Builder to build a sequence-specific pdb model of Scott's mRNA in a-form RNA helix. However, when loading into rbq, the inter-residue bonds are not being created. Ok, it's the old 'spaces in pdb name' problem. We need to do space-trimming for atom names in the wkFastPdb lib. Hopefully, this won't break anything. This has been done for CFastPdbObj::FindAtomInResidue() and CFastPdbObj::FindAtomInPdb(). This fixed the inter-residue bond creation problem for the mRNA pdb model.


    Created document to align sph mRNA to 1jgo.1. Will start with initial alignment of residues (sph1.a.A21, 1jgo.1.U16) and incrementally align adjacent residues upstream and downstream, locking down aligned residues as they happen. However, to do the initial manual alignment of the first pair, need to add an option to the rotation code where the user can specify that rotation occurs around the center of a specified residue.


    Added documentation of structural alignment of subunits to the User Manual. Added documentation of user-defined force input to the User Manual.

    While documenting external force input, I realized that the current implementation has a problem in that the external force input is done after CRbqForceContainer::CalcForces(), which means that it happens after CRbqForceObject::EndForceCalc() processing, which is where CRbqNodeBsjForce objects calculate total node forces and torques from accumulated atom forces. The fix requires that external force input be done before the EndForceCalc() calls. This was done by moving the init and completion code out of CRbqForceContainer::CalcForces() int ForceCalcBegin() and ForceCalcEnd() functions (also done for CRbqCustomForceContainer). Finally, moved friction force calc from CRbqNodeBsjForceObject::EndForceCalc() function as well, because it can just as easily be done earlier, and then we will have a more consistent situation where all forces have been applied when the execution reaches CRbqForceObjet::EndForceCalc().

    Added additional documentation of script objects to the user manual.

    Working on align.lua script in exp/dev/mrna/rkp.

    There is a bug in drawing spacefill dots for force objects.

    After fixing broken rbq_AddNodeForce(), it looks like fiTick() script input of force on a force object is working, although display of node forces and external forces would be helpful. It worked. After about a 10 minute sim (debug mode), the phosphorus backbone atom of a single dynamic residue was pushed to a min distance threshold with a target static residue.


    Generalized exp\dev\mrna\rkp\align.fiTick.lua script to align variable numbers of atoms of a dynamic residue to a static residue. Started run to align 3 atoms of a residue. Incidentally, this should be a nice validation of the existing forces, because if the alignment fails, this could reveal a bug in the existing code.

    It appears that we may be having just such a problem - the 1st atom pair aligns in the script above, but the 2nd and 3rd pairs are not doing so.

    Adding a draw event script to malign script object to display applied forces. Script showed that dst atom position was always atom 0, revealing a bug in the fiTick code in the call to the _PdbUtil.lua function getAtomPos(), because it had a different form from the dynamic residue version getForceObj_AtomPos() ((table[4]) instead of (table[3], number)). Put a param check in the getAtomPos() function.

    There is still a bug in resetting force objects created from static pdb models that have been transformed - the force object when reset appears to move to the original untransformed position of the static pdb model.

    Ok, 3-atom alignment worked! This is a nice validation of both the external-force-input capability and the chemical force calculations.

    However, it looks like there is an inconsistent labelling of O1P and O2P as they seem to be reversed in 1jgo_1.1.U16 wrt to MRNA.a$.A21. I should check to see if this an error unique to NAB output number. In the meantime, I will just define a destination atom names to the source atom list.

    After doing this, and successfully aligning the phosphate node, there were 3 additional manual node rotations of the nodes downstream of it that were required to optimally align the residues, so for full-atom resolution residues, the alignment algorithm needs to be enhanced. In addition, this will require disabling of movement within a residue, at the node level. This will require modification to the core C++ code, in this case, a single byte of data to the CRbqNodeBsjForce::_NfData struct. However, I also needed to add optional recording of a node rotation and translation, so perhaps the node movement enable flag could be part of an optional data struct along with that recorded transform info. In addition, the recorded interaction vector lists should be moved in there.

    Moved optional data in CRbqNodeBsjForceData into a dynamically-allocated component to reduce memory load of dynamic residues.

    Added flag to enable/disable node movement in dynamic residues.

    Cleaning up project html home page (local version).

    Added 'rbq_AddNodeTorque()' function.


    Investigated bug of reset force objects. The reason is that the static pdb transform is copied to the dynamic residue node frames on creation, but is lost when a reset is done as the node frames are reset to identity instead of being reset to the initial frame. It looks like a copy of the initial frame must be held in the force object for a proper reset to occur. This will consume more memory, but perhaps the amount recently saved with the introduction of the OptionalData member variable will compensate for it.

    Fixed bug in drawing spacefill points (missing extra param in CGrTorGraph::DrawNode()). I need to start looking at compiler warnings.

    Added m_initTransform to CRbqNodeBsjForceObject.

    I've been confused on the best way to calculate the node rotations needed to complete the alignment of the first base of sph mRNA to 1jgo.1. I've been considering calculate the respective torsion angles and doing bond rotations until they become more equal, but the problem is that the 1st torsion angle, alpah, is not available because of the missing upstream atom on the previous residue. But now I've seen another way to do it: to apply a spring force on the src node backbone atom toward the dst atom and then calculate the torque from this force, about the backbone covalent bond. I think that all we need is the perpendicular vector from the src atom to the bond axis, and use this as the moment arm. But the resulting torque is not necessarily colinear with the bond axis, so we may also need to project it onto the bond axis.

    Fixed problem of script object creation failing because of pre-existing directory - trivial code change.

    Finally getting started on torque calculation for backbone bond alignments in align.fiTick.lua. It's close to working.


    Finally got a complete residue aligned in exp/dev/mrna/rkp/align.fiTick.lua. It took a little while to find the right termination scheme for node torque alignment. After some failed attempts trying to use +/- delta distance counts, I settled on terminating a node alignment when the total amount of distance change over some long time interval is below a threshold amount. It's slow, but it works. It took 140K timesteps to align a primary bb node, plus 3 more subsequent nodes, using a driving force factor of 10. I should try a higher factor to speed things up. Next, we have to add monitoring of terminal node movement, and application to disabled downstream dynamic residues.

    After creating 2nd dyn residue, I realize we will also need right away the use of the custom forcefield interactions. Note: at some point, the lua module 'ChemUtil.lua' should be renamed to 'ForceField.Util.lua' (or FfUtil.lua). Actually, I don't think we need custom forcefield interactions, just simple disabling of force calculation for a dynamic residue should be needed. That is good, as it should simplify things.

    Adding recording of node movement to CRbqNodeBsjForceObject.


    Added movement of downstream residues to exp/dev/mrna/rkp/align.fiTick.lua.

    It works!

    A reduction factor of 0.5 for primary node alignment seems to work best so far in align script, we got primary node alignment at 15 kts. Final alignment of nt1 (of 2nt segment) completed at 49 kts.

    Ok, the movement of downstream residues with the transform of the terminal node of the active aligining residue appeared to work, but actually, some serious distortions occurred in the relative atom positions of the downstream base. This was a good test of the accuracy of the geometrical transforms used, and problems with this accuracy have been revealed. It's not unexpected though, because the movement of the actively aligining residue is very incremental, occurring in 50 kts timesteps, and so 50 k transform multiply operations can be expected to accumulate a certain amount of error.

    At the worst, we can simply leave on forcefield interactions for all dynamic residues while doing the alignment. The entire process will run more slowly, but should bypass this error accumulation problem. Ok, I take it all back. Did a re-run to confirm, and it looks like the errors were do to something else, a brief alignment of the next residue without re-enabling ff interactions. Never mind.

    Started alignment of 2nd residue, but looks like NAB goofed on the O1P, O2P thing again. Also, looks like disabling of ff interactions for 1st residue isn't working.


    Fixed ff interaction bug above (inter-residue bond calc was being done inside of internal force calc member function of CRbqNodeBsjForce instead of in external force calc function).

    Added recording of intra-residue covalent bond forces. However, display of these overwhelms display of any inter-residue covalent forces, so we need an option to display ONLY inter-residue covalent forces.

    Well, the bug fix above introduced another one. I had put the inter-residue bond calc into the internal force calc function for a reason, that reason being that the inter-res bond calc is done from a residue to the previous residue, but the inter-residue interactions are done in a forward manner in an n*(n-1) loop. So when the calc was moved to the external function, the interaction with the previous residue was never done. The problem really arises from the misnomer of internal and external as applied to force calculation. They should actually be named 'determinate' and 'indeterminate' to reflect the fact that the 'external' force calc is really a calculation contingent upon physical proximity. Now, given that we are sticking with the current names at this point, I will move the inter-res covalent force calc back into the 'internal force calc' method, so that it will get called regardless of the state of indeterminate interactions, and simply do a check to skip it if 'external force calc' is disabled.

    Added command 'ff fo enable forceCalc'.

    On the O1P - O2P flip, it looks like the fault is with 1jgo.1 in this case. Added a hack for it to the align script.

    In disabling force calc for a dynamic residue, also needed to disable it in CRbqTorsionForce::CalcTorsionBondForce(), because this does inter-residue calculations in addition to intra-residue ones (I had done the force calc flag check in CBsjForce and CRbqNodeBsjForceObject, but forgot about CRbqTorsionForce).

    Hopefully the final debug in stopping movement of a residue after it has been aligned: the first residue was still moving after being aligned and disabling all force calc for it, because naturally it still had some residual velocity and angular velocity. Added rbq-lua functions 'setForceObjVelocity()' and 'setForceObjAngVelocity()'.

    Finally got a 2 nt alignment done.

    Released version 0.1.8.


    Started alignment run on ribo2 with 13 dyn res. Still kept getting drifting of nodes in residues that had completed alignment. Finally figured out what the problem was. The internal and external force calculations were disabled in fiTick(), and the velocity and angular velocities were set to zero, but the problem is that in CRbqNodeBsjForce::EndForceCalc(), which happens right after the fiTick() script, accumulated atom forces for that timestep are applied to the nodes, and so we will get a non-zero velocity again, resulting in subsequent movement.


    Added some documentation of scripted force input to the User Manual. Next, I will be creating a different version of the mRNA align script that does the alignment through the continual application of spring forces to the backbone atoms of residues along the chain, even after they have reached their aligned position. This will allow the residues to remain active in the forcefield, and produce a more realistic docking of subsequent residues by allowing a certain degree of settling to occur as residues are pulled in.

    Started on basAlign script. Completed basAlign script.

    After checking on previous align script running on ribomachine3, I found the alignment stuck at the 2nd residue, demonstrating a glaring problem with that particular script, where I had locked down the 1st residue movement after its alignment completed, but still let it interact in the forcefield with the next residue. The result was that the second residue was unable to complete its initial alignment of its phosphate atom, even when I cranked the driving force up to 50,000. Hopefully, the new basAlign script will not suffer from the same problem, although there may be some need to 'bias' the driving force of the currently aligning residue with respect to previously aligned ones.

    Running the new basAlign script on ribo 3, it appears to be working quite well on the first residue, with nearly complete alignment of all 5 backbone atoms at around 26 kts. The only thing needed right now is a means of recording and reporting the distances to the target atoms for the currently aligning residue so we can see where its stuck. One other mod, cranked up the force const from 10 to 50, because 10 seemed to be too little. Also increased distance threshold to 0.2, and that allowed completion of 1st residue. 2nd residue appears to be aligning well, with only minimal, temporary displacement of the 1st residue. This bodes well. Completed alignment of 2nd residue at 36 kts! 3rd residue seems to be stuck at the final bb atom. I wonder if its the backlash from the remainder of the segment in a distorted a-form helix config? Cranking force constant up to 75 (frame 487), then 100. But that final bb atom of the 3rd residue just didn't go. It looks like the next residue was butting up against it, also, the target sequence of the next residue was located at a sharp kink in the backbone (start of 2nd codon). I was about to increase the distance threshold to 0.3, but then was on the phone for about 10 minutes and when I came back, the final atom had docked and alignment of the next residue began. 4th residue alignment proceeding ok. It almost completed, but now the 1st bb atom of res 4 seems to be too far away, with a sharper kink in the backbone up to res 3, at 75 kts, so I am going to increase the distance threshold up to 0.3. Did it at 76 kts and now we are on res 5. Res 5 is taking a while, but seems to be getting there. One addition that could speed things up is to drag on O4* and C1* in addition to the backbone residues. Leavning it for now.


    Did overnight run of same script and model on ribo5, and things have gotten stuck at the first single-atom residue (res 7, A22). On inspection, it is clear that the position of the single phosphorous backbone atom for this residue is unreachable because the bond to O3* of res 6 is unrealistic. One thing we could do is to split the dynamic segment into two, with the second one starting at res 7. However, a better option might be to relax the sequential docking constraint once we get to the single-atom residues, and start applying forces to all single-atom downstream residues once we have docked res 6.

    Actually, a very simple fix requiring no code changes is to just manually adjust the minimum threshold distance (once all non-single-atom residues have been aligned). We could create a separate 'single-atom' threshold distance. Finished doing alignment of remaining dynamic residues to single-atom targets. Now we need to do the whole thing, plus the upstream residues. I think we need 2 distance threshold variables: one for determining when a residue is close enough to its target to stop driving it, and another to trigger docking of the next residue in the chain.

    Made changes to basAlign script to have 'goto-next-multi-atom/single-atom-residue' distance thresholds and optional reporting of max dist atom. Started alignment of full 27 residue dynamic segment to static chain, fForceConst = 100, fMaxForce = 200.

    Sim aborted because of network problems.


    Did overnight run of basAlign script, 27 res on inga. At 275 kts this morning, it was up to the 5th codon residue, but appeared to be aligning very slowly at that point. The remainder of the dynamic chain is all bunched up, and being slowly dragged along as the 5th codon residue tries to rotate into position. Perhaps another useful modification to the basAlign script is to do 'proximity-based' enabling of alignment of the residues, instead of 'sequential-based' enabling?

    Also, I really need to start doing some whole-translation process scripts of the ribosome and am thinking of how to go about it. The strict sequence of all the components and their movements is still undefined, so maybe I should create a bunch of individual scripts that load and move each component, and then combine these into various 'control panels' to assemble hypothetical sequences of translation. Created exp/dev/simpanel.

    Almost finished the very long run of basAlign on inga and got a lua error! Arg.

    Finally got completion of 27 residue alignment (with numerous manual distance threshold tweaks during the sim). Doing a repro on ribo3 with a new script, basrAlign (basAlign + selected ribose atoms C1* and O4* for extra torque on the residue).

    Completed basrAlign script, started sim on ribo 3. Also changed initial alignment of MRNA.pdb so that 1st dyn seg is lined up with target static residue (because rbd doc currently doesn't save adjusted dyn residue positions). In doing this, I rotated the MRNA so that the helix path was more closely aligned to the 1jgo.1 path, which could have a significant effect on the alignment trajectory.


    Implementing quaternions for interpolation of component positions in exp\dev\simpanel.

    Downloaded movie from ribo3 basrAlign run, it worked beautifully! Alignment also completed much faster than previous basAlign script. One thing: I may need to create a movie frame splicer tool because 3k frames were recorded after the alignment essentially completed.


    Added command 'ff movie writeFrames'.

    Started simulation of docked 27dyn res sph mRNA to static residues of 1j5e.A within 20 A (except for tail 8 residues at end of chain that docked in mRNA path) on ribo3. Simulation is slow because interactions between all 168 dynamic residues is being done. I need to create a custom forcefield interaction script to skip interactions in the 1j5e set of dynamic residues.


    'ff movie writeFrames' command is working. Exported 1st 1200 frames of basrAlign sim on ribo3. Creating demo page for it.

    Added documentation of user-defined force interactions to user manual.


    Fixing 'center-view-on-inserted-object' feature to use mru object to determine the extent instead of saving the geometrical extent, because the object position can be changed after insertion.

    Prior to more modeling on mRNA, I want to do some basic folding tests using a simple tetraloop motif. Found a pretty canonical GNRA loop in 1j5e.A helix 41, CCCG GCAA CGGG. Will create a sequence in a-form helix from NAB and simulate it on inga. If it doesn't fold properly, this may indicate the need for random thermal perturbation. Can also test folding by apply driving forces for base pairing.

    In creating a second RNA sequence with NAB, I realize that I need to add nucleic atom type definitions for the hydrogens - they are defaulting to generic hydrogens in dyn residue creation. But maybe this isn't a problem at this point?

    Prior to creating anti-shine-dalgarno sequence for 1j5e, I compared the 3' end to that of 1gix and created mod_1gix and mod_1j5e subdirs in exp/models. This also gives me some general ideas on how to do automated comparisons of PDB models, starting with basic features such as sequence gaps. Then, display of subsequences where the delta distance of backbone atoms is above a certain threshold. This can be a script for 'pairwise chain comparison report' (pccReport), which can generate an automated html report that can then be the basis for subsequent manual annotation. This may also provide the motivation to create residue definitions for the various significant features of the ribosome (anti-shine-dalgarno, P-site, A-site, etc.

    After 5 hour sim on inga of the tetraloop, it curled up into a ball. I think we must create a script to simulate thermal pertubation if there is any hope of seeing de-novo folding.

    Started 'thermal' force input script.

    Did overnight sim of tetraloop on inga with zero friction.


    Overnight sim of tetraloop with zero friction was a failure. Just continual agitation and a tumbling rotation, most likely due to the torsion force asymmetry. The thermal agitation is now the only hope to get proper folding using the current forcefield scheme.

    Finished initial draft of thermal script. Still need to fix array pre-allocation and insertion/removal of new/expired thermals.

    Looked at 1.545 kf sim of 1jgo-wrapped sph mRNA 27 dyn res dock to 20A 1j5e.A RNA. Making an exp dir for it and uploading the movie to the movie file page. Created exp/dev/mrna/dock30/001. However, the movie file is 94 MB, and the only part that moves is the mRNA, so I think I'll export it as a set of PDB files instead. However, that doesn't get me a playable movie. I guess the next step is to create a 'pdb movie player', probably as a script object, which reads a set of pdb files and stores the frame data in memory, probably just backbone atom positions at this point, and plays a 'backbone' movie. With the large amount of data that these simulations will be generating, I will need a much more lightweight movie data scheme.

    On the de-novo folding problem, in addition to possible help from thermal input, perhaps adding electrostatic attraction to the hydrogen bonding force will help in seeing base-pairing.

    Started 'folded' tetraloop sim on ribo3, to see how stable it is.

    Finished fixing thermal script. Fold tetraloop looks dead solid on ribo3, so I think I'll run the thermal script on the unfolded model on it overnight. Done. Then I'll run the thermal script on the folder tetraloop to see if it remains stable with that random force input.


    Tried to do overnight sim on folded tetraloop on inga, but it was wasted because I accidentally turned off the Steric force while selecting all force objects. This isn't the first time that this has happened. I need to rearrange the Forcefield menu items to prevent this from happening.

    After doing another short 100 kts run on the folded tetraloop, a fair amount of perterbation occurred, but the 3 base-pairs in the stem remained. Then I turned off the thermal input and started another run to see if the tetraloop would fold back into the initial conformation. One factor that may prevent it is the formation of a hydrogen bond to a phosphate oxygen. I should probably add counter-ions in future sims. In general, however, it should be informative to do a series of simulations with thermal perturbation of varying length and observe the tendency to fold back into the stable initial conformation.

    Created 'Enable Force' submenu under 'Forcefield' menu, moved enable items there.

    Prior to adding support for 'backbone' movies, I realize that I need to add rendering of backbone to dynamic segments, and further that there really needs to be saving of graphic state of dynamic residues in the Rbd document file.

    In observing the perturbed folded tetraloop not folding back to the initial state, it seems the current base-stacking forces are lacking. The single center-point of attraction for each base is probably too simplistic. I need to do some statistical analysis of base-stacking geometry to try to gain some insight into the mechanism. Also need to do the same for non-linearity of hydrgogen-bonded base-pair planes. And perhaps these two are correlated.


    Saving of dynamic residue draw state is working. Now adding rendering of dynamic segment backbones. Done. It works.


    Looking at the changes that occur in simulation of tetraloop, it may be helpful to do simulation of smaller components in the model such as 2 adjacent pairs, to see why deviation from a-form helix is occurring.

    Another interesting thing to try is to redesign the hbond hydro and nbes so that they can bend to some degree and see if hydrogen bonds form that are more like some of the 'bent' bonds seen in various crytal structures. In other words, does the existing model produce constraints, such as steric ones, that would maintain the existing position of the positions if only the hydrogen and nbes could bend to for a bond? Or, the alternative, are there missing constraints that should be added to prevent the change from the crystal structure bent configuration into the 'optimal' straight hbonding configuration that is seen?


    Investigating torsion forces. We need a 'torsion' report script, similar to steric report script. Fixing bug in steric report script. No, it's not a bug. Generated a steric report when steric force was disabled. Got an empty intra-residue force list. Added a warning to the report that the steric force is disabled.

    Added commands 'ff fo enable internalForceCalc', 'ff fo enable externalForceCalc'.

    Added option to create 'single-atom' nodes in dynamic residues.

    Did a long sim of tetraloop model with 'single-atom' nodes and noticed major distortions of base rings. Perhaps this could be a clue to some problem? There appears to be a serious error with the covalent endpoints for 'single-atom' node dynamic residues.


    The problem is that currently, covalent interactions are only defined by a 'child-parent' relationship and with rings, we need covalent bonds between sibling nodes.

    The fix for this may be fairly simple. Currently, the intra-residue covalent bond interactions are done by calculating the interaction between a node and its parent node, but there is no reason why we can't just iterate the bonds instead.

    Created a new function for calculating intra-residue covalent bond forces, it seems to work. Now, adding one more thing: a smaller force constant for hydrogen bonds.

    Done. Didn't notice much bending of hydros as a result, but the 'single-atom' nodes definitely help in allowing base-pairing of the tetraloop in a 'non-linear' conformation that is closer to the crystal structure.

    Added command to record max deviation of covalent bond distance.

    Added a periodic function to the thermal script so that the thermal input is done for a short period and then is turned off to allow relaxation to occur. This was done after observing the long sim on ribo3 of an unfolded tetraloop, which folded up into a ball and remained static in structure after that.


    Did overnight sim of unfolded tetraloop for 500 kts, using the new periodic thermal input. Not a single hydrogen bond was formed. The periodic thermal script appeared to work well to briefly perturb the structure into new conformations, but either the current forcefield is not correct enough to get it to move into a hydrogen bonded state, or a huge amount of simulation time is required, which currently is not an option. Also, while watching the sim, I observed 2 phosphate atoms come together without sufficient repulsion, it seemed to me, so I'm going to crank up the electrostatic repulsion factor from 50 to 250. Then, I'll do a sim of the folded tetraloop to check for stability with the new increased repulsion. Next, I want to add some electrostatic attraction to the hydrogen bond donor-attractor pairs to try to promote better hydrogen bond formation.

    Another thing to do is to write a script to see what it takes to flip a ribose from 3' endo to 2' endo, which is now possible with single-atom nodes. Turned default friction back down to 1 from 10 (I had cranked it up to try to prevent the long-term rotation resulting from torsion asymmetry, but with thermal input, it's not much of a factor I think).

    The drop in friction seems to be causing problems with the integration - the bases are a lot floppier and not pairing properly in the folded sim check for stability. This might explain the lack of hbond formation in the unfolded sims. Also, to what degree is this problem increased by the 'single-atom-per-node' model?


    Bugs: hbdonors for pre-existing hydrogens. Duh. This explains lack of hbond formation in unfolded sim. Also, lack of rotation of an oxygen node to restore hydrogen bonding.

    The lack of rotation of the oxygen node in hydrogen bonding may be due to accumulation of node angular velocity. Adding drawing of node velocity and angular velocity.

    Now, with hydro covalent bond factor back to 1, the hbonding seems ok at friction of 1. What changed? Is it just the excessive wiggle of hydro covalent bond factor of 0.1?


    Fixed hbdonor-pre-existing-hydrogen bug. Now, need to add an electrostatic attractive component to the hbdonor-hbacceptor interaction code.

    Short sim with electrostatic scale force of 500 shows a very interesting twisting motion of the backbone of a short ss rna in a-form helix.

    TODO: add auto-oscillate playing to ff movie.

    Looking at 3 day sim of unfolded tetraloop on ribo3 (version: 0.1.8, model: exp/dev/tetraloop/ribo3/unfolded/model_nohydros.rbd, movie: [same dir]model-nh.coord). This was a 5 Mts sim (50 kfms). 11 hydrogen bonds formed almost immediately (frame 1301) and the structure remained essentially constant after that, only turning slightly from subsequent thermal input. This is not what was desired. One reason is probably that I cranked the hbondScaleForce up to 100 to try to get better bonding, but this essentially 'locks' the structure. Another is that the max thermal force is only 500. I am going to rerun the sim with an hbond factor of 50 (the current default) and a thermal force constant of 1500. In the next sim, I hope to have added the electrostatic attractive component for hbond force, to aid longer-range hbonds. Also, metal ions might be useful.

    Tried to add counter-ions, got an assert in CValenceShell.cpp:846. Fixed.


    Added documentation of single-atom-node creation and forcefield parameters to the User Manual.

    I really need to add an optional ffsettings file so I don't have to keep typing in commonly used ones. Probably should be implemented through the script startup file.

    Added a 'Program Startup' section to the User Manual.


    Fixed ASSERT bug in surface rendering command when issued to dynamic segment torsion graphs.

    Working on rbolit database, found out how to adjust setting of 'security.checkloaduri' parameter in Mozilla Firebird 0.7 to get mouse click on PDF file listing in 'browse articles' page to load a ribosome pdf article in external pdf viewer.


    Stopped by the lab to check tetraloop folding sim on ribo3, running since 2003-12-29 with hbond factor back down to 50 and thermal max force at 1500. This time, the formation of hydrogen bonds occurred over a longer period, with the most-recently-formed bond occurring just before I checked stopped the sim. However, once bonds formed, they never broke and so there was no chance of forming base-pairing bonds. To address this, I started a new sim with a thermal max of 3000, and also anchored the molecule in the initial location, as that large thermal driving force was rapidly moving it out of the volume. After some additional thought, where I reflected that the current implementation of the hydrogen bond force is to strong, or at least the local gradient is too steep, I also remembered that the single-atom-node simulations seemed to have a looser bonding, so that is what I should try next, which will require releasing the next version, 0.1.9, which is fine, as lots of things have been done since 0.1.8.

    Also making progress on getting a good web interface setup to the rbolit mysql database on beryllium, so I can start organizing all my ribosome literature.


    Started exp/dev/test/testSlerp to test quaterinion and slerp functions, because I really need to get started on the complete simulation of the translation cycle.

    Completed testSlerp.lua and testSlerp2.lua scripts. Slerping workings for models with start quantitative rotations of 45 and 90 degrees about coordinate axes, but doing a manual rotation of an arbitrary amount with the mouse results in a small error between the 2 models after the final slerp of 1. ??

    There may be a bug in CGrTransform3f. Either that, or serious lack of precision. No, wait, it's the center-of-mass, which is not centered at the origin for the cubemol.pdb model. But, no, the center of mass should not be an issue. The problem is when doing a 'trans 1 0 0', the pdb transform becomes 1 0 0 0, 0 1 0 0, 0 0 1 0, 0.990508 -0.068411 -0.119215 1, which seems to be way too much error. Translation (100, 0, 0) gives a huge error in the y axis, -3.7!!! What the hell is going on?

    Duh, I was using the 'trans sel' command, not the 'trans selAbs' command. So that answers that question. Ok, I think I'm figuring it out - when I do manual rotation with the mouse, it is rotating around the model's center-of-mass, not the origin. This must explain the difference of slerping compared to slerping after a quantitative rotation about the origin.

    Yes. Quaternion slerping is now working!

    Working on SimPanel. Created 'ScriptTickEnable' command and icon so we can finally separate the running of scripts from the running of the forcefield. Of course, this necessitates creation of script object toolbar.


    Finished adding ScriptObects menu and toolbar. Also finally disabled display of Qt dock menu, because it conflicts with my own management of the toolbar show state.

    exp\dev\simpanel\interp.lua script is working, except that rotation is not occurring around object center. When interpolating the rotation matrix of a pdb object, the rotation is occurring around the origin. Perhaps the simple fix is to translate c-o-m to origin, for both beginning and ending matrices, get the slerped rotation matrix, then translate to original c-o-m?


    Created script lua\ReportPdbFrame.lua. After thinking and experimenting a bit, the proposed solution above does not see right. Instead, I think the right way to think about it is that every object has a rotation, always occurring about the origin, combined with a translation component to produce a homogeneous matrix so that the object is positioned at some location in the world frame with that rotation. The rotation is always the same, regardless of the object location in the world. What needs to be adjusted, after slerping the orientation, is the position of the object in the world frame. So what the interp script will do is to create a rotation matrix with the slerped orientation, then produce a homogeneous matrix with a zero translation component, so that this represents the object at the origin, then add a translation to this hmatrix so that the object is at the desired location.

    That doesn't work either - we need to use initial and final c-o-m's instead of the ptOrgs. Arg, we shouldn't have to do that - should be able to simply iterpolate using a starting and ending homogeneous transform matrix for huffs sake. But yes, that extra information is needed, because there are an infinite number of possible paths to interpolate from one frame to another, and we want the one where the center-of-mass travels in a straight line.

    Still working on the infernal interpolation of transforms. After using c-o-m, still not working because some pdb objects have transforms where the reset (identity) transform matrix is not centered at the origin. In this case, I think we must also calculate the offset of the c-o-m from the origin for the identity transform, to use as a correction.


    Got interpolation working! Needed to translate begin and end frames so that center-of-mass was at origin, also needed to lerp the translation component of the slerped frame between these two frames, and then finally add a translation to the resulting slerped matrix that was also a lerp between the center-of-mass points of the begin and end frames.


    Added loading and interpolation of IF1 (1hr0.W) to sim panel.


    Adding more components to the simpanel.

    Read a little of Genes VII during my coffee break and gleaned some nice summary info on initiation of translation. One point to note: the initiator tRNA is unique in its ability to enter the partial P-site (i.e., 30S half only). The factors that may contribute to this ability are the 3 G-C base pairs in the step and help from associated IF-2. Two things that would be good to do: 1: structural compairson between f-Met tRNA and normal tRNA. 2: structural comparison between free 30S site and 30S in 70 complex.


    Finally started adding new articles to my ribosome literature database. Currently, there are 53 articles entered. Currently, there are 53 articles entered. Next, I must add a keyword field.

    More work on simpanel, trying to find a good dock for the ternary complex on the 70S.


    Completed initial interpolated dock of ternary complex on 70S and interpoaltion of the tRNA from docked ternary position to A-sites on 70S.

    Built and released version 0.1.9.

    Installed ver 0.1.9 on Walt's machine. TODO: create a self-extracting exe with the full distribution.


    Added serial mode to interpolator object in sim panel. Created first sim sequence subdir, 'iseq001'.

    Added selection of 16S body, head, platform to 'Script', 'Features' menu.

    In the iseq001 subdir of simpanel, in addition to definition the fundamental sequence of movements, the directory can also provide supplemental scripts to do camera movements, adjust appearance of models, and display captions. This results in a complete and informative movie to present the details and meaning of the hypothetical sequence. Additional contents: origin of dock start and end points, analysis of 'goodness-of-fit' of the docking components, qualifications such as missing components, links to the literature.

    To rebuild missing anti-shine-dalgarno sequence, we need a new command for exporting to pdb files, namely, a way to consolidate components of a selection into a single chain. This will be done after aligning a segment created with NAB onto the 3' end of a 16S chain. Creating command 'file exportPdbSingleChain'.


    In thinking a little more about the consolidation into a single chain, I'm realizing that what we really need is to consolidate dynamic residues that originate from 2 different static chains into a single dynamic segment. One way to do this is to create the code as mentioned above to consolidate the residues in the static model first, but another option is to provide the means to consolidate dynamic residues from different dynamic segments into a single dynamic segment. This second option may also have the additional benefit of enabling dynamic separation and bonding of dynamic segments to new ones. I have to be careful, however, to avoid getting into time-consuming core code changes at this point, but time is running short. Also, the CRbqDynamicSegment module is among the most kludged and hacked at this point. And since dynamic segments are currently owned by the static pdb models they are created from, this more dynamic form of consolidation is not easily implemented at this time. I think for now, we must stick with the original plan of exporting into a single chain, and not touching the dynamic segment code. But it should be done at some future point.

    Added CRbqCmdProcessor::ExportStaticSelectionToSinglePdbChain(), command 'file exportToSinglePdbChain'. It works. The next thing to add, in order to enable reconstruction of the anti-shine-dalgarno portion of the 16S, is a means of manually rotating around user-specified center points such as a particular atom.

    Added window toolbar.

    Added User Manual documentation on rotation about covalent bonds in dynamic residues.

    Added command 'sel set rotCen', to enable manual rotation of selection around a user-defined center that can either be an absolute world point or an object name. Implementation was delayed by the need to add dynamic object support to CRbqDoc::GetObjectMassCenter(), CRbqDoc::GetObjectBoxCenter() and CRbqDoc::GetObjectExtent() member functions.


    Finished add dynamic object support to CRbqDoc::GetObjectMassCenter(), but work still remains for the other 2 functions. Manual rotation of selection around a user-specified center is working, though a fair amount of error is observable (drift of selection wrt to the center point). This is worrisome, but can't deal with it right now. Can it be fixed by explicit call to normalize the transform matrix of an object after every mouse move? Currently, for force objects, this normalization is done each timestep. Still, it seems that such a normalization shouldn't have to be done so frequently.

    Created antisd pdb, aligned with 1j5e.A.

    Created a consolidated static chain from tail end of 1j5e.A and antisd, but in trying to create a continuous dynamic segment from from this new static model (tail-9-11.pdb), it failed because the sequence numbers were discontinuous. I need to change the export function to create new residue numbering for the consolidated chain.

    This worked, but now, one more problem: trying to adjust the conformation of the dynamic segment by node rotation - only a single residue rotates, I thought I had provided a means for also rotating downstream residues, but it appears not.

    Fixed a bug in the 'sel sphere pos' command. Added documentation of the selection sphere tool to the user manual.

    Looking through the code on the node rotation problem, I didn't find any code to rotate downstream or upstream force objects when doing a node rotation. Perhaps I was thinking of the time when the entire dynamic segment was created as a single torsion graph. In any event, this capability must be added to allow for manual adjustment of the dynamic segment.

    Fixed it. Fortunately, this was just a very simple 6-line addition of code to CRbqNodeBsjForceObject::RotateAboutNode().

    Added additional documentation on manual manipulation of objects to the User Manual.


    Created 'setup-rbofull-0.1.9.exe', a self-extracting executeable for the 0.1.9 distribution that includes the source code, exp, pdb and core program in a single package.

    Couldn't transfer the thing to the bloody ribomachine1 server because a critical transfer error kept happening! Arg.

    Trying to keep working on the sim panel elongation sequence, in spite of constant interruptions. There is a new problem after adding the serial/parallel option: we need serial operation, but also some groups of objects need to be interpolated simultaneously.

    In thinking of a fix, I must also keep in mind the need for constant monitoring of the interpolator state for other purposes, such as cameras and labels. Perhaps we need a general purpose event queue or time line where lots of different events can be flexibly defined (within a particular interpolation sequence). Ah, perhaps that is the key - we only have a single interpolation sequence occurring at any given time (that is, increments from 0 to 1 of an interpolation variable), but we can drive multiple objects from such an interpolation sequence (of course, this would require that they are matched at the endpoints), or if we require truly independent interpoations, we need additional interp script objects? Then, in any given interpolation, we have some means of initiating supplementary actions such as cameras and labels during specifed values of the interpolation variable.


    I have a solution to the 'multiple pdb model in a single interp' problem discussed above. I can just redefine the pdb data in the interp script object to contain groups of pdbs within a single interp data string, where the pdb objects are delimited by '|' and the interp data are delimited by ','.

    Added groups to interpolation state to interp script object. It works. Now multiple PDB models can be interpolated simultaneously, which is useful when they move together to dock, and later one of them needs to leave without the other (as in ternary complex of EF-Tu, GTP, tRNA).

    Added draw script to interp object to display current interpolation value and pdb names.

    Adding camera and label script objects should be fairly simple too, as it will simply involve copying the interp script object tick and draw scripts, and defining camera and label data in a manner directly analogous to the interp object. In this first version, I will just define fixed cameras. Later, 'moving' cameras can be added, possibly being interpolated as well.


    Working on simpanel camera script (spCam.lua). Camera is working. When I finish the camera and label code, and add a few more models and interpolations, the hypothetical initiation sequence iseq001 will be nearly the same as the previous cycleSim demo, completed back in June of last year. The difference is that the amount of work and complexity for the current simpanel scheme is vastly simpler than for cycleSim. In addition, creation of multiple hypothetical sequences is easier. This is one case where object orientation is not necessarily the way to go, although perhaps it was just my initial attempt at object orientation in cycleSim that wasn't ideal.

    After doing 2 sims on tRNA-Phe structure on Inga in the last few days, it seems that an electroScaleForce value of 250 is needed, because the default value of 50 produced a very distorted structure (when using friction values of 1). Perhaps I never noticed this before because I had done sims with the larger friction value of 10? Changed default electroScaleForce value to 250 in the code.


    Created a faq page in the html docs.

    Researching possible dock locations of IF3. There is a bug in the force object creation code trying to create a dynamic segment for 1tig pdb.

    Came into the lab and found ribomachine5 (the Athlon64 machine) had been shutdown for some reason (power failure?). It had been doing a sim of the entire 30S since 2003-11-27 and produced a 2.225 GB file. Perhaps it crashed due to some 2^31 limit. In any event, when I restarted it and ran the rbq program, I wasn't thinking, because that wiped out the previous logfile. I need to change the logging code to rename the existing file, if any, before creating a new one.

    Reloaded the movie file and got -1589 total frames. That's not right. Ah yes, the CRbqMovie::m_iCurFrame variable is a signed integer, but no, that would only overflow if they were 1 byte frames. Hmmmm.. Found it. wkFileUtils::GetFileSize() returns an _off_t which defines to a long, which is only 2^31 as compiled on my current Win32 system in VC++ 6.0.

    At this point, I don't know if I want to bother with changing the movie code to use non-standard 64-bit code to solve the problem. I prefer to use the native integer and os-defined sizes for system calls and indeed, the simulation was running on a 64-bit system which would not have experienced the problem if compiled with a 64-bit compile and run on a 64-bit os on that system. For now, I can just change the code to stop recording at the max file size. Done.

    Used the xxcopy.exe utility to truncate the movie file to below 2GB limit on ribomachine5. This worked. After viewing the 1692 frame movie file, only a general contraction was observed (perhaps due to the inadequate electrostatic scale force of 50. Also, friction was at 10, limited the possiblity for any interesting conformational change. It's unfortunate that such an expensive and unique simulation of such a large structure wasn't more successful. For the short term, I'll probably use ribo5 for smaller sim jobs, such as tRNA docking.

    Uploading the 'rbofull-0.1.9.exe' package to the web server via direct LAN connection. Then I'll install this on ribo5.

    Todo: prevent reset of ff state on loading new document - this conflicts with the intent of FfInit.lua.

    Todo: create script to lock down endpoint residues for selected dynamic segments.

    There is a bug when selecting a dynamic residue by name which doesn't exist (need better error message, it translates to index num selection via static lookup, then fails - confusing).

    Started sim on ribo5 - we also need a good script to 'drag' the tRNA into the binding site instead of an awkward manual positioning, trying to avoid steric clashes.


    Fixing bug that happens in creating dyn segment for 1tig.a. The bug is happening because there is a bond between a created Hydrogen and a PDB hydrogen for some reason. This happened because the pdb hydrogen was unbonded due to lack of positive charge (and resulting extra valence) in its potential partner nitrogen (the terminal amino). Consequently, these 2 atoms didn't get added to the torsion graph. I need to update the code in CTorGraph to fail with informative error message if some unmoved atoms remain unconnected to the graph. Actually, for simplicity, I will just add that check to the code just after the CTorGraph::Create() call. This has been done.


    Trying to cleanly add charge to pdb terminal amino atom in CFastPdbObj code.


    Added hack to set atom type for first nitrogen in a pdb chain in CFastPdbObj::FinalizeCurrentResidue(). It appears to work, the nitrogen in 1tig.a.ILE83 is now bonded to all 3 hydrogens. Hopefully, the change will not introduce any new bugs.

    While reading (Yusupova 2001), got an idea for systematically and quantitatively analyzing flexibility of macromolecules such as the 30S: apply a force couple at selected atom pairs in the model and measure the resulting displacement. This might help to identify movement motifs such as the 'head-shoulder' closure, which could be identified by application of forces at the contact points and observing a significant opening or closing movement, relative to other force-couple induced movements. This approach could also be generalized to application of force in random directions at one or more locations in any model.

    Back to creating a dynamic model for 1tig.a, now it's failing at residue 1tig.a.LYS86, but this was expected, this is at the charged nitrogens in the amino acid side-chains, we must hack addition of charge for these atoms also. Actually, only need to hack for LYS. Done. Creation of dynamic segment for 1tig.a is finally working!

    While doing a short sim of IF3 1tig, noticed that hydrogen creation for arginines is wrong - there is an extra hydrogen being created for NH2. Fixed - this bug was created after adding the new d_iAtomType_Nitrogen_Charged to fix the terminal amino problem - forgot to watch the AtomType ordering linkage between CElement.h and CElement.cpp.

    Added model 1g7t.A to simpanel (IF2).

    Started first page of my doctoral thesis.

    Finally realized that I can use the CE alignment server to get sequence and structural alignments for all of my components in the simpanel! Arg, CE output pdb file uses multiple models and currently, ribosome builder only loads a single model. Not a super big deal, because I can split them into separate files easily enough.


    Added '' script to rbolit database. Added browsing of articles by keyword in ''.

    Finished 'tetherDep.lua' script to tether endpoints of selected dynamic segments with spring forces. Applied script to 2 new tRNA dock sims on ribo3 and ribo5.


    Finished adding keyword support to rbolit perl scripts.

    In adding my thesis doc to the rbo cvs repository, ran into a weird bug where my cvs on ribo4 doesn't see the added directory after checking it in from beryllium.

    While reading the RCSB PDB newsletter, I learned about the Protein Structure Initiative for the first time. It offers good prospects for the use of Ribosome Builder.

    Created composite IF3 model from 1tif and 1tig. Two recently added capabilities, 'file exportToSinglePdbChain' and 'sel set rotCenter', were indispensible in aligning the two separate pdb models so that the terminal residues were aligned in the conformation of a peptide bond. Then after exporting them to a common chain, I only needed to delete the ATOM records of one of the terminal carboxyl oxygens of the N-terminal fragment and two of the terminal amino hydrogens of the C-terminal fragment. Then, when I inserted the composite model, a covalent bond was automatically created between the two previously disconnected fragments!


    Working on simpanel.

    Changed 'Script' submenu 'Energy' to 'Dynamics'.

    Added script item to run mrnaWrap demo, and it was a bit of a pain because of the disconnect between single-atom-node creation being on or off. This might be a very annoying problem in the future. Should it be saved in the rbd document? Probably. For now, I'm just hacking it in the scripts.

    Came up with a new proxy docking location for IF3 using the new composite model, after reading (McCutcheon 1999).


    Checked tRNA dock runs on ribo3 and ribo5, neither were working properly. On ribo3, the model had exploded, on ribo5, no tethering was happening.


    Created simpanel billboard. It works. Took a little extra time to properly set the background around the text, it was never done quite right in the cycleSim code.

    Billboard almost working - some problems with script cmdline args.


    Fixed problem above - it turned out to be a bug in the lua function tokenize() in _StringUtil.lua. The current tools for displaying the initiation sequence are working finally - interpolator, camera and billboards. Now I'm thinking about the next steps. At some point, I must incorporate forcefield movements into the simulation, not just geometrical interpolation. The data required for this might become fairly extensive if a large number of incremental points along the interpolated trajectories are needed, and this might overwhelm the current inefficient and somewhat awkward interface of script objects, where all data is saved and restored in the form of strings that are held in the C++ side of the interface. The creation of another specialized C++ class might be the solution, but I haven't thought out the specifics. In the mean time, I will elaborate the existing data structure of the lua interpolator code to support checkpoints, while at the same time adding a couple of extra fields to support possible extensions such as movie playback data items.

    Got iseq001 working after adding sequence group names.

    Thinking more about the interpolation/guided forcefield approach, I think they can work in parallel, where the interpolation sequences define the components and endpoints for the forcefield simulations.

    Adding if2 and if3 to iseq001. One thing that is needed the scripting interface is return codes from scripts, so the caller script can detect an error.

    iseq001 is working with all initiation components. We still need some kind of 'director' component to monitor the completion of all scripts in the sequence and report and cleanup billboards.


    Had an idea somewhat related to the flexibility analysis idea mentioned on 2004-01-19 above. It involves the application of 'resticted movement' at various locations on the ribosome, and observation of the effect of such restriction on the movements of other portions of the model. This restriction analysis idea was motivated by reading about the possible mechanism of thiostrepton as 'locking up' the 50S in a particular conformational state and prevent its transition to a different one. The selective restriction could easily be applied with the external force input scheme.


    Built and released version 0.1.10 for Walt.

    Created batch files to build all distribution files.

    Spent some time on ribomachine1 trying to fix the webserver crash. Checked the 'restart silently' option and turned on debug files. Also install latest version of FileZilla ftp server.

    In thinking about the next step in simpanel sequences, a script needs to be created to drive the components in a forcefield simulation from the start to the endpoints defined in the interpolation scripts. This will require a means for dynamically adding and removing dynamic residues within some distance threshold of the primary component. I will create a script called 'proxFoSet', for 'the set of force objects in proximity to the main object'. As to how this affects the recording of movies, I still don't want to mess with the movie file formats. Instead, if the proxFoSet script object keeps a log of dynamic segments that are added and removed, then during playback this same sequence of dynamic objects can be created in sync with the movie file playback.

    Need to create a framerate test so that the interpolation rate can be set to a rate to give playback that is constant and independent of processor speed in the simpanel sequences. Also, it would be nice to add a looping option.


    Started defining support functions to do guided base pairing.

    Found bug in lua/AlignSelectedResidues.lua. Actually, it's a new bug caused by changes to the setting of the command line in lua scripts.


    Finished _GeomUtil::getBaseFrame(), created exp/dev/test/testBaseFrame.lua to test it. It works.

    While investigating hydrogen bonding for guided base pairing, a sim of a base pair from sph mRNA shows that the shadow point for the hydrogen atoms is extending too far from the expected location. Doing a full rebuild first before investigating. No, it's still there! What the hell?

    Ok, doesn't happen in ahelix.pdb where hydros were added. It must be a result of unknown atom type for mRNA hydros.

    No, found it. The bug was in CRbqNodeBsjForceObject.cpp, CalcHbondForce(). The distance of the hydrogen from the donor atom was being determined by a call to CValenceShell instead of calculating the actual distance of the hydrogen atom, which is not at the CValenceShell default for pre-existing hydros. Duh.

    However, this is now making me wonder if the current hydro default of 0.6 A from donor atom is incorrect and if I should use a 1.0 A distance instead, as is done by NAB.

    Doing a sim after adding the fix for the 1.0 A hydros actually looks better because there is a propellor twist that is maintained that probably results from the steric clash of the longer-bond hydro with the acceptor atom.

    After setting default created hydro dist to 1.0, in ahelix.pdb the acceptor electron shadow overlaps with the hydrogen, but the hydrogen shadow extends too far past the acceptor nbes over to the acceptor atom. This doesn't seem correct. But actually, it is. By design, the hydro shadow is optimal when aligned with the acceptor atom, not the nbes.


    After reading some literature and checking other models, I think we will stay with the 1.0 A default hydrogen distance - I'm not sure why I set it to 0.6 A. Looking back, it was that way in the old rb code. Looks like most of the initial hbond development happened around Feb 2001, but I haven't seen any explicit notes as to why hydros were created with bond length of 0.6. I think it must have been that in the old code, we were cacluated steric interactions for hydrogens, and at 1.0 A, the clash with the acceptor atom would be too large.

    Started on 'guideBasePairs.lua' script.

    Moved ff param init code out of Reset() code and into separate 'SetFfParamDefaults()' function so that loading a new document won't blitz user-defined ff settings as done in FfInit.lua.

    Changed frame data returned from _GeomUtil.lua : getBaseFrame() to specify center point at a reference atom instead of ring center, so it will be easier to apply forces using frame data.

    guideBasePairs script is working. Dragged one test base apart from its partner and the script successfully guided them together to form the middle hbond. Then the upper hbond formed shortly afterward. Then the lower hbond formed. This happened quickly enough to observe in real-time.

    Started work on doing guided base pairing for tetraloop.

    TODO: fix detailed sequence report (trimming spaces for residue names, add details for dynamic segments).

    Started guided base pairing of tetraloop. First movie is in exp/dev/tetraloop/001. At frame 257, increased force const from 1 to 3.


    Read several chapters in "An Introduction to Hydrogen Bonding". The capability for three-centered bonds and bent bonds should be investigated in the current hbond implementation in the Ribosome Builder code.

    Did two overnight sims of guided base-pairing of unfolded tetraloop model, one with thermal input, the other without. Neither was successful. The models became locked in configurations with a few hydrogen bonds, typically to the phosphate backbone, and no full watson-crick base pairs formed. Also, a very noticeable rotational artifact of the entire model was observed in both cases, certainly due to the assymetry of applied forces. This motivates the immediate modification to the guideBasePairs script where the reaction force will be applied to the target base at the shadow point. Also, sequential base-pairing may be necessary.

    Modified the guideBasePairs.lua script to apply reaction forces and do sequential base-pairing, started another sim on tetraloop and got 2 bonds of a g-c base pair so far at 21 kts. Final bond wouldn't happen though - we have got to add electrostatic attraction to the hbonding.

    Started on hbond electrostatic component.

    There is a small discrepancy between the displayed and reported position of the nbe electrons at the end of an hbond vector. Fixed.

    Found bug in rotating a terminal node - adjacent residues were also rotated. Also, there is a bug in rotating first node of a residue - code was never added to rotate subsequent residues. Fixed.


    Been thinking in the last day about how to implement attraction between hbdonor hydrogens and acceptor nbe electrons. Yesterday, started to implement an awkward scheme involving a 2 part-function of attraction with a linear hookes function on the close side of a distance threshold and a coloumb function on the far side. But it seemed messy. Last night, I thought that a nice alternative would be a lennard-jones type function with the attractive exponent equal to the electrostatic value of 2 and a repulsion exponent sufficient to prevent the excessive close approach of the hydrogen and nbe point. It naturally drives them to a desired equilibrium distance, which is really all that I want, I think, to supplement the existing hydrogen bonding function.

    Finished initial implementation of hbond electro calc force.

    TODO: add Sulfur to hb donor and acceptor candidates TODO: add a torsion function to peptide bonds

    Initial sims with the hb el force on the 'failing' hbond in the tetraloop mode (exp/dev/tetraloop/db-hbel.rbd) show that it's not working. The proper attractive forces are being displayed between the hydrogen and nbe point, but they don't seem to be able to cause the proper node rotation to happen to promote hbond formation. The initial guess as to the cause of this is that the forces are swamped by much larger forces on the node. I suppose I must add a scaling factor.

    Did that, still doesn't seem to work. One thing that may be figuring into it is the rotational inertia, but do I really want to mess with that?

    To properly debug this sort of problem, I really should add dynamic node state to the rbd file format.

    Tried a variety of exponents in the hbel function, but the damn nodes just won't rotate. In looking at the force and torque on the node, it must be due to the huge covalent forces, which swamp everything else. Although my 'two-point' covalent scheme has worked well, it may have certain fundamental incompatibilities with proper rotation of nodes about the covalent bond.

    Now, with a 4,8 exponential, I got gradual gradual rotation of the hydro and acceptor nodes that I think is finally leading to a 'lock'. Note: I also turned off a potential acceptor competitor on an adjacent base. Ok, finally got it. Now I need to do some long term comparison sims to see how much this new potential is really helping. At least it doesn't seem to be hurting. Note: the lock happened in conjunction with the sibling hydro on the guanine amino hbonding to a phosphate oxy. And watching the movie, it looks like that bond is what really drove the first one.

    Looking over the code for saving and reading 'dynamicResidueState' in the rbd file (which really is just the draw state information), I think I see a fairly simple way of saving the node transform states, and in a way that should be backwards-compatible!

    Node transform save/restore is almost working, but there are some funky electron vector endpoints for 9 hbond acceptor vectors.

    I think the problem above may reflect a flaw in my understanding of C++ and STL containers. In the new code, I reassign the value of a node transform using the assignment operator, but perhaps this is somehow changing the address of the transform, because the electron position is determined by a pointer to the frame address in CHBondAccept. Still, assigning new values shouldn't change the addresses of the frames in the frame container.

    Nope, it was just an overrun in reading the input data. Found the bug: it was a hardcoded 0 index hanging around in copied code that retrieved a pointer to a force object (in place of a variable index).

    Still not working, forgot to call CRbqNodeBsjForce::UpdateAtomPositions() after settting the node frame. There are places in the code where I grab the ref and assign directly to the transform. This should be replaced by a function call to localize access.

    It works!!


    Built version 0.1.11.

    After testing ver. 0.1.11 before release, I realize that I must add 'single-atom-creation' mode to the rbd doc also because the distributed db-hbel.rbd file in exp/dev/tetraloop is failing without it.

    In trying to simply implement this option, I realize that it is a little bit more complicated from a design standpoint in that the number of atoms created per node could be a fairly flexible parameter. The current design of the program does not allow for such flexible specification and so in specifying this option in the rbd document, it will be a fairly inflexible hack. At some point in the future, the idea of specifying parameterized creation of dynamic objects needs to be part of the initial design, so that in principle you could load a document consisting of multiple objects, created in a variety of different ways from each other. But the current state of this project is far to advanced to consider such complications. For now, we will mandate an 'all-or-nothing' policy in terms of creating single-atom nodes for dynamic models loaded from rbd documents. Determining the proper flag to be saved in the rbd document is currently a hack, but I have added these qualifications to a note in the User Manual. In the default case, where the mode is in its default setting or set just once in FfInit.lua, the user will not need know or care about this, and it should just work.

    It works!

    Testing hbonding problem on Inga again, now that dynamic model config can be loaded. With hbondElectrostatic force on, the 3rd hbond formed in 120 frames. With it turned off, the bond is currently still unformed at 318 frames, so it looks like it is working. Hopefully, it will prove helpful in doing guided base-pairing for multiple bases.

    No, it's causing problems. It interferes with formation of the first base pair. Not only that, but I failed to described the conditions that produced the movie that produced the first base pair so now I can't even repro it!!

    Re-running on ribo4, it looks like it might repro. Then again, maybe not. No, under the conditions I remember, the base pair is not forming after 730 frames.

    Trying again, this time setting guideBasePairs var fForceConst to 3, which I remembered I had done before. Now, with this value, we get the middle bond formed, which is good, but that appears to be it, so we have not quite repro'd the previous case.

    Now, retrying with hbel force again, this time scaled down to 50, and a gbp const of 5.

    Really need some kind of 'save-all-state' command which saves not just ff params, but also all script object vars to some record file.

    In latest sim on ribo4 mentioned above, got 1st 2 hbonds formed by 20 kts and it looks like hbelscale 50 will give us the 3rd. This is good.

    Started thermal script at frame 560, after no change in 3rd bond (top base bonded to adjacent base instead). At frame 655, cranked thermal force const from 1000 to 2000 because first application didn't break the bond.

    Have an idea to deal w/ torsion rotational drift problem: instead of applying asymmetrical forces between the A and D atoms, just apply symmetrical torques at the B-C bond.


    Adding code to support symmetrical torques mentioned above. Done. testing. Is torsion force displayed as steric? No, not currently displayed. Need to add it.

    Added incremental pairing to guideBasePairs.lua script.

    Dang ribo1 xitami web server crashed again yesterday, no indication why. Last access in the access log was from my machine at home around 10:30. Then around 11:30 it crashed with the same smtp sock error. After reading about it on a web archive, I implemented a little runloop batch file to restart the server if it crashes. Hopefully that will keep it running.

    Built yet another alpha version of 0.1.11, installed on ribo3. It looks like there is a bug in drawing the hydrogen donor vector. It's actually a drawing artifact that only shows up on ribo3, don't see it on ribo4. What the heck is the purpose of that vector anyhow? Other than to graphically indicate that the hydrogen is an hbond donor? I think the bug happened because the hydro used to be at a distance of 0.6A, and the vector was drawn from the donor atom along the vector for a distance of 1.5 * 0.6A = 0.9A, sticking out 0.3 A from the location of the hydro. So now, with the hydro at 1.0A, where should it be drawn? Currently, it's drawn at 1.5 A from the donor atom, coming very close to the acceptor vector endpoint. Instead, we want it to stick out just a bit when the hydro is drawin with the vdw radius of ball-stick, which is 0.12 of the vdw radius, which for hydrogen is 1.1 A, giving a ballstick radius of 0.132, so if it sticks out 0.2, this would be 0.332.

    TODO: give an information error message when trying to insert an .rbd file.

    Started tetraloop guideBasePair sim on ribo3 w/o thermal, another on ribo3 w/ thermal, for latest version 0.1.11 (torsion fix). Haven't had a chance to even test rotation drift fix yet.


    After overnight sim of ahelix, the torsion fix worked! No noticeable rotational drift occurred. However, on the zero-friction run on inga, considerable distortions in the ahelix structure happened, so we still need some friction at this point to maintain stability, unfortunately.

    Todo: write script to save state prior to a sim, as mentioned above, but also automatically generate the html files to document the sim.

    In doing a single-nt sim, it looks like the new torsion force may not be working. Need to add code to display it. Actually, it might be working, it's just that the rotations are happening so slowly, they are barely observeable in real time. There appears to be an unbalanced steric repulsive force on the C4* of 1tra_C75.pdb, but it might instead be a sum of many small attractive forces.

    Adding atom totals to steric report.

    Completed adding atom totals to steric report, and as expected, it reveals a discrepancy between the total steric force as reported and the displayed total atom force. Now, just need to track down the discrepancy.

    The only place in the current code that appears to add atom force is in the CalcHbondForce() function, which definitely needs to be fixed, but also doesn't seem to apply in this case. With all forces disabled except the steric force, the discrepancy is still there, so perhaps it is in the steric report code. Correction on adding atom force in CalcHbondForce(): that was only in the obsolete CRbqNodeRotForceObject.cpp file.

    Writing a separate perl script to independently calculate the steric force totals from the raw steric data file to eliminate or identify that as the source of the error. Done. Great, now I have 3 different totals!! Ok, down to 2 different totals - the debug script confirms the steric report script.

    Ahh, after looking at the wkEncon CTorsionBodyIteFcon.cpp code, I realize that when the atom is the second atom in the steric report, we must use the negation of the force on atom I. So it looks like the steric report is wrong. Yep, that was it. Now they match. Need to finish the 'displaySumOfForces' script.


    Adding display of torsion torque to the force display. Done. Displaying torques in c.pdb model, the largest torques are in the ribose ring, which makes sense.

    Debugging torsion torque on a glycine residue, we are not getting display of the expected greatest torsion torque between the carbonyl oxygen and the amine nitrogen. Found one bug - forget to clear recorded torsion data each timestep. Fixed. Now it looks like the direction of the torque vector is wrong. Nope, that is because with the current vdw torsion scaling factor (0.8), a steric clash can be slightly attractive for slight clashes. Perhaps, with the new implementation, we can revert to the same vdw radius as that used for steric interactions. The direction of the torsion torque is correct.

    Arg!!! Now we are getting a stupid transform matrix accumulation error when doing manual rotation of the ring of a cystosine nt. This occurred while running the forcefield with movement disabled and all forces disabled except for the torsion force. It also caused me to realize that such errors are largely compensated for during normal operation by my implementation of the covalent endpoints force. Also, currently, we are only doing renormalization of the rotation matrix in the TimestepMove() code, not during manual rotation. Looking at the current code, all that I can figure is that I thought matrix renorm was unncessary for manual rotation, so I only specified it in TimestepMove(), but now I see it is needed for manual ops, so I'm moving it into the UpdateAtomPositions() code.

    Ok, happily, that fixed the manual rotation bug. Now, dealing with a node torque vector not equal to the torsion vector when all other forces have been disabled. Ah, that's probably because I was looking at the torques in logscale. In normal scale, it looks like they are adding up.

    Ran friction-less ahelix sim with new torque function and factor, but still see the same kind of distortion unfortunately.


    Ran a sim on inga of ahelix without the torsion force enabled and it didn't seem to make much difference to the structure, except maybe it was a little less distorted from the initial structure. All that recent work on the new torsion function and the only good it does is to get rid of the rotation junk from the previous version. Molecular dynamics can be frustrating sometimes.


    Some hope today for the worth of the current md code. Yesterday, after running without friction on ahelix after it came to equilibrium, it remained stable. Then, after adding a little energy by briefly turning on the torsion force, the structure was perturbed, but the fluctuating movements remained stable around the equilibrium structure when running with zero friction, indicating that the forcefield is simulating a genuine local minimum. Perhaps its the case that when running with zero friction, and a large initial input of energy that results from being far from equilbrium, that the junk structures observed that are very different from the expected ahelix structure simply mean that it is stuck in one of the zillions of local minima that can occur. Perhaps what I really need to do is to add algorithms for finding better energy minimums instead of expecting the forcefield to automatically move it to the desired one.

    After a long sim on ribo5 with the alpha version of 0.1.11 (without the torsion fix), got a number of temporary base-pairings in conjunction with the thermal script. Now I need to write an analysis script to re-run the movie with forcefield running and identify the successful base-pairings and the context in which they occur.

    In looking over the current hbond code, I noticed the 'lockout' trick I used, which causes a disconnect with the calculated energy. I wonder if I can get rid of it now that I've added the electrostatic component of hbonding. Perhaps I should wait till the next version.

    Building and releasing the hopefully final version of 0.1.11, re-running guide + thermal + tetraloop sims on ribo5 and ribo3.

    Released version 0.1.11 to the web.


    While preparing for my talk on eIF4A and noticing an annoying lag once again on my laptop WinME system, in desperation of trying to find the cause of the occaisional lag, I fire up the very limited system monitor available in WinME and find that rbq eats 100% processor time! Even though the forcefield isn't running. I wonder why.

    While doing some manual definition of the secondary structure of the eIF4A protein, I'm thinking up some good ways to graphically annotate the structure. Creating script 'annProtss.lua'. It works. For now, it looks best just drawing the ss element name next to the final residue of the element, which gives minimal additional visual clutter and still provides a directionality indicator.


    Reading about DEAD-box helicase mechanisms, I get the out-of-the-blue idea in thinking about my old tch hypothesis about whether the primordial ribosome was an RNA polymerase. Not quite sure of the details yet, but I'm going to think about it.


    There is a bug in the 'sel name' command, can't select residue '2pjr.a.SO4901'.


    Looking at bug mentioned above, it is a bug in the wkFastPdb lib. For some reason, the residue name is being parsed as 'SO4' instead of 'SO' and the residue seq num is 901 instead of 4901. Ah, well, in looking at the actual residue name in the pdb file, the name IS 'SO4' and the residue sequence number is '901'. The code in CRbqPdbMol::GetResidueIndexFromSeqName() assumes that the sequence number submitted in the full residue name+sequence param is consists of all the numerical characters in the end of the string. This fails for residue names that have a digit in the residue name. I'm not sure if I want to bother fixing this problem at this time. I don't know how many non-standard residues have numbers in the residue name. SO4 must be Silicon tetraoxide (tetrasilane?), isn't that used in NMR? I think for now, I'll just put a caveat in the User Manual and tell the user to select by index. Done.

    There is a bug in the script 'watchSelCenter.lua' (doesn't work after being re-run in the same session).

    Starting on exp/dev/tetraloop/ptf.lua script (permute tetraloop folding).


    Still working on ptf script. Ran into a problem of trying to run the thermal.lua and guideBasePairs.lua scripts from within the ptf.lua script. This happned because I tried to run the scripts from the 'inputCommand()' call instead of the through the 'runScript()' function. This resulted in trying to run the scripts from the CRbqLua::RunScript() function, which failed because it tries to set the lua global var context prior to running the script, and it will refuse to do this if another script is already running, because the single global context will be changed. This protection is needed when running script object scripts, which need their global vars restored and saved, but is not needed for 'single-run' scripts, which do not have a persistent context. This distinction needs to be made clear in the user manual docs. The 'runScript()' function doesn't have this problem, because it just does a direct 'dofile()' call on the param script code.


    Created ptf script object code. Fixed bug in adding new time users while inside of iteration of existing time users.

    TODO: fix bug that has to do with removing time users while iterating time user code.

    Actually, the bug mentioned above was not the problem. The program crashed while running the ptf.tick.lua script. The cause of the problem is more complicated and disturbing. When script objects are created, they are added as annotations to the graphics window. The set of annotations is currently linked to the open document, so when a document is closed, the set of annotations is deleted. The problem happens because the ptf script object opens a new document inside of its 'tick' event. This causes the annotations for the existing document to be deleted, resulting in invalidation of the tick object.

    Somehow, I must change the script object design so that script objects cannot be deleted during the execution of script object event code, and further more, allow script objects to be persistent indepedently of document state. Either that, or prohibit or warn the user not to close the current document from inside of script object code, which seems less satisfactory (but perhaps simpler?). I think the latter solution is what I must do for now, no time for such redesigns.

    It worked, at least for the ptf script.

  • new watchSel script
  • use variable friction for conformational search
  • add 'common param' table to ptf script Looked at results of the over-the-weekend sim of tetraloop folding on ribo5.

    Added fail state checking of thermal and guideBasePair script in ptf script.

    Hopefully almost there with the ptf script. Now we have the problem of deleting the helper script objects from inside of the the ptf script tick event. This requires something more than the 'pendingRemoveTimeUsers' list that I added in the CRbqMainWindow::RemoveTimeUser() function, because, unlike when adding a time user, the deletion of the removed time user must also be made pending. Currently, it's deleted immediately in the call. So I have to prohibit this deletion as well, and at this point I just have to hack it in. Luckily, I only have to hack it in at two points in CRbqCmdProcessor(). Done. But then I need to think of a way for the ptf script object to do a posted delete. Arg. What a pain. Either that, or just let them exist and reset their vars to a default state.


    Added code to init as desired the helper script object vars by defining tables in ptf script. Added a function to write all script object vars and values to file.

    Finally completed initial version of ptf script. Started runs on inga. Next, need sim analysis, adding waters, ff boundary, better selWatcher, variable friction.

    In thinking about how to improve the selWatcher script the other day, I finally realized, while manually following a wandering tetraloop model by translating and zooming the view, that no rotation of the camera is needed at all to stay centered upon an object wandering randomly through space. In retrospect, of course, this improvement in the selWatcher algorithm is obvious, but it always amazes me how such solutions can evade my conceptual capabilities at first (I suppose this is due to my limitations in evaluating my conceptual capabilities).

    Anyhow, all that I need to do for the new version of the selWatcher script is to project a vector along the current orientation of the camera for a desired distance, then translate the camera so that this projected point is coincident with the selection center. This should allow simultaneous rotation of the camera about the selection center by use of the mouse, and scripted translation of the camera to keep it looking at the selection center from a constant offset distance.

    Created new version of 'WatchSelCenter.lua', copied old version to 'LockWatchSelCenter.lua'. The change would have been easy except that we are lacking good functions for translating the view using world frame vectors. Only support for view frame vectors currently exists.

    Created vec_ViewToWorld() and vec_WorldToView(), but they don't work. However, I think I can just use the setViewCenter() for now and worry about my chronic frame dementia problems later. Ok, that works. It's nice now watching movies while tracking the movie model because you can rotate the view. Still can't zoom though. I suppose the script could somehow hook the zoom command and adjust the fOffset value.


    I thought about implementing the ff volume bounce in the force object movement code, but then a little reflection on some of the anticipated simulations of mRNA cause me to think that this won't be all that useful, as a large ff volume box would be require to wrap a large extended mRNA, and it wouldn't serve to localize metal ions or waters near the mRNA, which is one of the reasons for ff volume bounce. Perhaps instead, a script object could be used to 'corral' waters and ions within the vicinity of a dynamic model. This might also serve as a better hydrophobic effect.

    Copied a couple of the inga sims over to ribo4 and looking at the movies. One of the things that is problematic is that there is no record of the applied forces. I'll have to think about that a little bit. Probably will implement it by having the script objects append their applied forces to a file, perhaps with the current movie frame. Then a movie playback helper script object can be responsible for reading and playing back such applied forces. It would have to be able to search for the current movie frame in a file when the movie frame is changed.

    Speaking of script objects to solve every problem, I also want to specify that the movie automatically oscillate within some specified interval. Rather than modifying the movie code, yet another script object can be created to implement this.

    On the current tetraloop folding sims, I am going to leave out the thermal input for now and look in more detail at where things get stuck at or after the first base pair formation. In conjunction with this, I thought up last night a 'pulsed' guiding force at the point where things get stuck, so that display of forces will also show the pulsed reaction forces that are blocking the movement.

    Creating 'OscMoviePlay.lua' script.

    After examining one of the non-thermal folding sims from inga, in conjuction with the possible efficiencies of corralling, I think the next step should be implementation of waters. This should help in preventing 'non-productive' interactions between nucleic acid hydrogen bonding atoms and hopefully will provide the missing hydrophobic effect that will allow everything to start folding beautifully. Presumably, implementation of waters also should not require much additional work (knock on head).

    Adding waters for dynamic creation. Initial required work was totally minimal - we have dynamic waters. They are hydrogen bonding! Next up: writing a script to fill a region around a model with waters. Started script 'AddWaters.lua'. At 100 kts, the waters are forming pentagonal complexes.

    Started on script 'AddWaters.lua'.


    Went to a sad ribomeeting today: Walt's grant renewal got the axe. We are all out of a job July 1, 2004, barring a miracle. But we will carry determinedly till then, trying for a turnaround. I am comitted to putting out two papers in the next 2 or 3 months.

    Checked ptf sims on ribo5 and ribo3. Ribo5 was up to config 49, ribo3 was on config 19. The conformations of both models looked like crap. Fortunately, it wasn't anything too serious. The first 20 configs were a 0.1 increment in the vdwTorsionScale from 0 to 1.9, and due to a bug in the ptf code, all configs subsequent to 19 had vdwTorsionScale of 1.9, which totally torques things out of control, making all these subsequent sims worthless (should have done an 'ff setDefaultFfParams' command in ptf BeginSim()).

    Fixed ff init bug in ptf.lua script.


    Finished script to generate waters around selected dyn residues. It works. Slow, but it works. However, there seems to be a bug where dynamic residues of one pdb are deleted when a different static pdb is deleted.

    Did a short sim of waters around a single adenine residue. Now we need the horsepower of ribo5. Built and installed 0.1.12.alpha.3 on ribo5.

    Before running new water sim of tetraloop folding, did a brief look at the first 14 sims from the ptf set where the vdwTorsion param was inc'd from 0 to 1.4 in 0.1 incs. 0.2 and 0.3 were the only ones that gave terminal base pair formation, though that may have been accidental. By 1.2 and 1.3, the distortion of the base rings started to become noticeable, and at 1.4, the simulation was total crap because of the excessive torsion forces.

    Started sim with 268 waters around unfolded tetraloop with vdwTorsionScale of 0.3 on ribo5.


    Working on initiation and elongation sequences in exp/dev/simpanel.

    Added GPL license declaration and files to the project.


    Wrote scripts to append earlier portions of ribosome builder and rbq project logs to existing html log file. It's a little tricky because there was a 5 month overlap between rb log in rbq.cpp and rbq log in history.txt, and an additional overlap between the rbq log in history.txt and the projectLog.html files.

    Trying to figure out how to implement jumping to particular sequence points in iseq001. I think we can add a 'run-to-timepoint' option to the interp, spCam and spBoard script objects without too much kludge.

    Added it to interp and it works. Defined 'go-to-sequence-point-start' for all iseq001 sequence points. Now, just need to get spCam and spBoard to sync up when going to a sequence point.


    Did run with 0.01 friction on ribo5 with water, all the waters flew away.

    Adding volume bounce to forcefield. Done. Initial attempt for reversing velocity at the node level didn't work very well because the nodes just end up vibrating at the boundary (because of covalent reaction forces from adjacent bonded nodes). Instead, we need to implement an 'all-or-none' reversal of velocity of all nodes of a force object when its final node crosses the boundary.


    I don't think velocity reversal will work with the current situation of nodes connected by bonds. It worked fine in earlier forcefields where force objects were rigid bodies with few or no connections to other independently moving bodies. However, instead of trying to use an external scripted approach, I think it's important to be able to enforce volume containment from within the core forcefield code. I think the way to go is to apply forces on the nodes of a force object instead of velocity reversal. Also, we need some kind of hysteresis, so that the force object doesn't just jitter at the volume boundary. But I don't want to keep any kind of history of volume boundary proximity associated with force objects. So one way of doing this 'stateless hysterical bounce' could be to apply a force to all nodes of a force object as long as any one of its nodes is outside of the boundary. Or, for the sake of efficiency, apply force to all nodes only if ALL nodes are outside of the boundary, because then we only typically need to check the position of a single node for objects inside of the boundary.

    Also, I'm now realizing that this method of volume bounce has the added advanatge of providing a form of thermal input to the system. And in thinking about the role of friction in recent simulations, I'm beginning to feel that the right combination of friction and temperature is what is needed to enable productive folding and transition from one stable conformation to another.

    Tried the new volume bounce scheme on a sim with 2 nt's in close proximity to induce a large repulsive movmement and it worked, although only after setting the volume bounce force magnitude to 1000 so that it was competitive with the large intra-residue forces. Will have to experiment with more normal situations to see if a lower bounce force value can be used.

    Did brief folding sim with waters, volBounceForce = 100, friction = 0.01. Didn't see much hbond formation.

    Trying to fix ff cum interaction stats.

    Checked 1-day sim of uf tetraloop on ribo5, without water, done to investigate the noticeable drift observed on some previous sims with water. The non-water sim didn't have much drift after an initial small movement of the c-o-m of about 20A in the first 2 Kfms. But in the remaining ~50 Kfms, the structure of the folded chain was largely unchanging, but the c-o-m underwent some unusual oscillations involving a back-and-forth wiggle about one axis and a gradual rotation about another. Perhaps it is a result of floating-point error in conjunction with a constant small vibration of portions of the model?

    Cum interaction stats finally working. Now, need to ren existing 'addWaters.lua' script ot 'addWrapWaters.lua', create 'addCubeWaters.lua'.

    Installed version 0.1.12.alpha.4 on ribo5, started another water sim.


    After reading the (Word 1999) on contact dots, I see that their table has vdw radii significantly smaller than my current values for C, N and H, and also longer C-H bonds. I had increased the radii in my program because of the unacceptable shrinkage that I saw with the small radii, but after reading how they emphasize the importance of explict hydrogen contacts for non-polar hydrogens, I'm wondering if I can reduce the radii down to the smaller values they use and do limited hydrogen steric interactions to maintain a-form helix conformation.

    Getting ideas on how to write a script to do display of 'rotamer-type' dihedrals. Now is the time to move the Dihedral lua code into its own module. And although this will be a troublesome change, now is also the time to rename ChemUtil to ForceFieldUtil, and split some functions out to ForceObjectUtil. And, actually, there are a few chem properties, but for that's too much change for now.


    Finished split out of ChemUtil.lua to Ff and Fo files. Working on dihedral code.

    There is a bug in vectorAngle(). Fixed.

    DrawFoTorsions.lua script is working, and haven't noticed too much disruption yet from the ChemUtil split. Next: write a script to set the view to a standard orientation for showing a particular torsion angle.


    Added script 'ReportSelDynAtomPairDistance.lua'.

    Working on 'TorsionRefView.lua' script.

    Ok, holding off on 'TorsionRefView.lua' and moving on to 'DrawFosTorsions.lua' (draw force object suite). Also got a good idea of drawing a backbone segment from the suite start point to the suite endpoint and coloring portions of the segment to reflect the suite torsion values.

    Created DrawFosTorsions.lua. Creating RNA rotamer table in html.


    Finished RNA rotamer table, with colors. Looks good. Next, to see how applicable the table is, by writing a script to calculate the torsions for a selection and the corresponding RNA rotamer if any, and the resulting deviations for the calculated rotamers.

    Started on 'DrawFosRotamer.lua' script, initial version is working.

    I had thought that discovering the rotamer codes for the folded tetraloop would magically provide me with a scheme for driving from the unfoled to the folded state, but now after quickly observing the rotamers of the folded tetraloop, it appears that only a single rotamer, (G1266, C1267) changes from 17 to 9, which is only a single torsion angle changing, alpha, going from m to t.

    Well, this actually might be useful, as changing just this angle in the unfolded model to the folded value looks like it might set things up for quick movement to the folded state. The rotamer code may prove to be useful.


    Creating new script for tetraloop folding, 'torqueS12a.lua' (torque alpha angle in residue suite 1,2 in the GNRA tetraloop).

    TODO: create script to align dynamic models from selected dynamic residues.

    Initial version of 'torqueS12a.lua' script is working. But the backbone is not changing as I expected.

    Observed latest water sim on ribo5, even with zero-friction, the conformation of the model is amazingly static. It appears to be fairly-well 'locked-in' by the hydrogen-bonded water network around it. Started a new sim where the hydrogen bond scale factor was reduced by a factor of 10, from 30 to 3, leaving all other parameters the same.

    While looking at the SRL in 1kpj, and trying to get the rotamer code for 1kpj.0 (A2633, G2634), I'm finding the conformation (3' p pmm 3'), which doesn't show up in the table at all. The closest ones are (3' p ptp 3') and (3' p p(110)t 3'). Since this is part of the bulged-G motif, I'm worried that the Rotamer table doesn't include it. But perhaps I have the wrong interpretation of the code.

    It's time to redo the torsion frequency plots for 16S and 23S. Added scripts to output torsion angles for selected static and dynamic residues. Then, when trying to generate new torsion reports comparable to the old dihedral reports, I see that the old scripts are buried inside particular pdb model subdirs. I need to make a more general script, ala steric report, for torsion reports.


    Added pucker phase output to torsion scripts. Finally started writing the rbo paper.

    Created '' and '' in exp/dev/report.

    Created script ''. Ran it on 1j5e.A and it produced a number of codes not mentioned in the (Murray 2003) paper. I think I need to consider all possible (P1 z a b c P2) (3'-2')(4 * m-p-t)(3'-2') slots and generate a frequency table for these slots, as well as to calculate the deviation of residue suites that fall within a particular slot. This should help me to determine how well actual measurements correlate with the proposed Word rotamers.

    There are 2 * 3^4 * 2 possible slots = 324 possible slots, assuming that there is only a single peak within each mpt trisector.

    Before doing more work on the rotamer perl scripts, I thought a little about the issue of supporting accumulation of statistics from multiple models, as this should only improve the identification of a rotamer code. To enable this, I need to save the residue records associated with a particular rotamer in separate files in each model subdir. Then the multi-model report can iterate the model subdirs for each rotamer to compile deviations of individual residues. I also need to distinguish between the 42 rotamers defined by (Murray 2003) from the more general 324 rotamers. To do this, I'll designate the former as 'M-rotamers' and the latter as 'G-rotamers'.

    Script 'exp/dev/report/' and driving lua scripts in 'exp/dev/rotamer/models/1j5e' are working. Next: a script to read the grotamer records and collate them into grotamer bin files: 'PxxxxP.grot' in the torData subdir. Script name: ''.

    Does the squeak in my ear when I'm hiking and wearing headphones mean that I'm gonna pop a vessel in my brain and turn from a ribosome builder to a no-ones-home drooler? More interestingly, can such a squeak be useful as a diagnostic tool for strokes in the brain?

    Binning script works. The 4 largest bins from 1j5e.A are 1mmtp1 (a-form helix), 1mttt1 (m-rotamer 14 : GNRA suite 4-5), 1mttp1 (m-rotamer 9: GRNA suite 1-2), and 1tmtp1 (m-rotamer 15). This is reassuring, that the top 4 g-rotamers are also m-rotamers. The most abundant non-m-rotamer is 1tptp1. This bin contains 10 records, 6 of which are within a 20 degree range of the 1(-140)ptp1 m-rotamer 2. However, there are a total of 92 different g-rotamers, with the least having a single record each. This potential for non-canonical rotamers could pose some problems when trying to implement a 'rotamer' torsion potential in the forcefield.

    Next, '' and script objects to apply torsion springs to dynamic residues.

    Was the first mRNA poly-A, because it made poly-lysine, an RNA-loving peptide? Probably not.


    Started calculating grotamer stats, then ran into the issue that mean and stddev don't apply to torsion angles. Finally found a solution in (Doker 1999), which described how to calculate circular mean and stddev for torsion angles.


    I realize that the solution proposed by Doker is even simpler in my case for calculating the mean for the g-rotamers, as the range of angles is known (within one of the m, p or t trisectors) and so I need to do just a single shift of the origin at the start of the trisector, as opposed to trying an origin at every single degree to find the minimum stddev, as described by Doker.

    Started on 'torsionSpring' script object.

    You know, I really should add a script to draw residue names. Now that I've defined a good way to place text next to a residue at a predictably visible location (as done in DrawRotamer.lua), it should be trivial to do so.

    Arg. Almost had torsionSpring script done and something appears to be stepping on DihedralUtil lua data, because getTorsionAngle() stops working after doing a forcefield timestep.

    After doing lua printf debugging, looks like an entry in the dihedral global data table g_tBbPlanes was being modified. An extra item was inserted. One unfortunate thing about lua is not having const declarations. Though I think it is possible to monitor table inserts. Don't have time to get into that though. Arrg.

    Ok, think I might have found it. I was assigning a tRet to the global table ref instead of copying it, in DihedralUtil.lua : getTorsionBondAtomNames().

    Got initial version of torsionSpring running on unfolded tetraloop, but it is SLOOOOW (67 torsion angle forces, all script driven). Oh well.

    In the process of modifying exp/dev/tetraloop/torqueS12a.lua, I realized that it needs to do exactly the same thing as the new torqueSpring script object, except that it must act as an independent object with different data. A simple way to use the same scripting code is to include a new script object name as the first argument on the command line. I suppose that I should have been doing it this way for previous script objects for quite some time.

    Looks like multi-so torqueSpring is working.

    TODO: implement shifted range selection for dynamic segments!!

    Checked out the water tetraloop sim on ribo5 and it looks like the machine rebooted yesterday during the sim. Don't know why. The movie file was up to 1G, but that shouldn't have done it. On the results of the sim, which had 0 friction and hbond force down to 3 from 30, it looks like a little intra-chain hbonding started to happen as the energy gradually increased during the first few thousand timesteps so that the residue broke free of bonds to the surrounding water, as intended. But then, all hbonding quickly disappeared as the energy continued to increase, for the remaining 10 Kfms. If I had been calculating the energy as well, that brief hbonding point could have been identified for subsequent sims.

    Built and downloaded ver 0.1.12.alpha.5 to ribo5 to test out the new torsionSpring tl folding.

    Sim on ribo5 appears to be working. A little further along, it appears that the tlRestrain object is failing to keep the residues in a-form torsion, with the default fMaxForce of 500. Increasing to 5000 at frame 35. Still looks messed up. Will probably have to debug with just a single residue or torsion angle.


    Adding code to do scripted movement of individual nodes in a dynamic residue, prior to debugging the torsion spring problem.

    Checked working state of the two demos currently defined, added accelerator key to pause script object events. TODO: added lua functions to insert an ortho text label and also a msgbox() function.

    Something is messed up in the init trans demo now, but I don't have time to fix it right now.


    The cycleSim code is an incomprehsible mess. It's way too complicated. Rather than fixing it, I think I will just enhance the init demo in sim panel and hook that up to the demo menu.

    Sent some example code for htsrv to glenn kreisel.

    Creating script 'LockNabNodes.lua' (lock nucleic acid backbone nodes).

    While creating DihedralUtil.lua function getTorsionIndexFromAtomName(), I may have found the glaring bug explaining why torsion springs doesn't work (getTorsionBondAtomNames() was returning the wrong dihedral planes).

    There is a bug in converting from numeric index to name when selecting dynamic nodes.


    I'm wrong about the bug in getTorsionIndexFromAtomName(), the existing code was correct.

    After I am now sure that the torsionSpring script is working as intended, I still observed great instability, using a variety of force constants, when applying the script to the unfolded tetraloop, with 67 torsion springs. Then, I have been working at the other end of complexity by doing simulations involving successively greater number of springs on the 2nt model, which has been stable, currently with 4 springs. I suspect that the instability may be a natural consequence of long chains of multiple torsion angles. If so, I hope that I can find a way to make it work in spite of the inherent instability.

    All 8 torsion angles are stable for 2nt sim. 16 torsion springs on the 1st 3 residues of uf tetraloop go to hell, even with movement of subsequent residues frozen. 2 residues and 10 torsion springs is also unstable. Woops, scratch that, those tl results were using a force const of 1000. Rerunning 2 res with force const 100. No, that's still unstable. Hmm, inspection of the sAppliedForces shows that the fMaxForce value doesn't seem to be clamping the torques. Also, it was drawing torques in log scale and I didn't even realize it. Ah, wasn't doing a sign check when clamping max force. Clamping is working now.

    2nt, 10 angles at top of ul tetraloop, with forceConst 100, maxForce 1000 appears to be stable now!

    Building new alpha version for ribo5.

    Started tlRestrain sim on ribo5 with version 0.1.12.alpha.6. Strcture appears fairly stable, but distortions were occurring that appeared to be possibly due to my ring stack force, so I turned it off at movie frame 89.


    Did a tl ts sim on inga with the s12a angle driving to trans and the tl folded over, with each side remaining in roughly a-form helix, I think (need to analyze the angles), which is a great success. However, the t-l stem base-pairing didn't happen because I think it folded the opposite way. Need to re-run with driving the twist in the opposite direction.

    Added code to specify user dir in torsionSpring.fiTick.lua GetAngleDiff(). Started new sim on Inga.

    Looked at sim on ribo5 which applied eq torsion springs to all bb angles in uf tl except for the s12 angle. The results were interesting, it flopped from the initial a-form helix state to one in which segements of the chain were sort of stacked, but there were definite kinks between these segments. It might be a clue to some flaws in the parameters of some of the forces in the current forcefield.

    Also, it may indicate the need to use a stronger force constant, now that the stability problem appears to be solved. Looking at the initial and final torsion angles of a particular residue suite (A8 - C9), initial torsion angles are (d 84, e -152, z -74, a -62, b -180, g 48, d 83), final angles are (d 80, e -150, z -80, a -59, b 152, g 54, d 82), giving a delta of (d 4, e 2, z 6, a 3, b 31, g 6, d 1). The large delta b is especially curious.

    Starting 'reverse-twist' uf tl torsion spring sim on ribo5.


    Preparing for guest lecture in CS495/595 (Computer Simulation and Modeling). Wrote a neat perl script, splitPage.html, to split out one long html doc into linked pages.

    Debugging the cycleSim demo so I can show it tomorrow. It looks like it broke when I fixed a bug vectorAngle() in lua/_VectorUtil.lua to return 180 instead of 0 for angles close to 180.

    Also, for some reason, I wasn't calling makeUnitVector() on orthogonal vectors calculated from a crossProduct(), so some of these vectors were nearly zero.

    And CPdbModel.interpToOrientation() also has a bug now, resulting from the vectorAngle() change.

    Finally, had to do a hack on calcRotVector(), and now the init demo is working again.


    Gave a lecture on the RB project to Jesse Johnson's CS495/595 class (Computer Simulation and Modeling). Released version 0.1.12


    Finished second lecture on the RB project to the CS495/595 class.

    Started oscMoviePlay.lua script.


    Created new lua module 'MovieUtil.lua'.

    oscMoviePlay.lua script is working.

    Starting tata.lua (torsion angle timestep analysis).


    Renamed tata.lua to outputMovieTorsions.lua, created associated perl scripts to generate html reports. They work. Created report for most recent torsion spring tetraloop sim on inga (ts-004.coord) and looked at the reports. They are informative. They indicate that the torsion springs successfully maintain the initial torsion angles of the residues, except for the target s12a angle, which tries to go to a trans conformation, but seems to overshoot and recoil several times instead. The movie frames at which this happens are easliy observable from the plots, in contrast to user observation of the movie. This information, in conjunction with the oscMoviePlay script, should guide the problem-solving to the next step.

    Using oscMoviePlay and display of steric forces to observe large change of torsion angle A of residue C6 in uf tetraloop from movie frame 250 to frame 350. It's still hard to see what might be causing this. Perhaps finishing script TorsionRefView.lua, and making it dynamic, can help.

    Actually, looking a little more carefully and reducing the osc play interval to [280, 300], it looks like the change may be due to a large steric clash between the phosphate oxygens and the endo face of the ribose moiety of C6.

    The ultimate source of the problem may be that although the final configuration shows only a single angle difference (alpha from minus to trans), the transition of that angle from minus to trans cannot be done by just changing that single angle by itself. Transition of an torsion bond from a starting angle to and ending angle may require the temporary change of angles of adjacent torsion bonds.

    However, this speculation must be qualified by the observation that the adjacent torsion angle beta did not remain at its eq value. Instead, perhaps the torsionSpring script must be conditional in its application to allow adjacent restrained angles to remain at their desired equilibrium position.

    Creating 'tlDriver.lua', a master script object in exp/dev/tetraloop to monitor max angle deviations in tlRestrain and disable tlTorqueS12a if a deviation exceeds a certain threshold.


    Did an overnight sim on ribo4 with the new tlDriver script. However, because I didn't save the previous script object var settings on the most recent inga tl sim, I don't think I used the correct values in this latest sim. I reduced the fMaxForce value of torqueS12a from 1000 to 100, and so the sim, after 411 movie frames, appears to be stuck due to hydrogen bonding. There are two observed hydrogen bonds. The first is a bond from A7.O2P (is this the pro-R oxy?) to G11.N2. The second is a bond from A8.O2P to C9.N4.

    This bonding involving phosphate oxys makes me wonder again how correct my non-bonded electron configuration for these oxygens is. Does the current implementation let them rotate? I forget. And if not, how do I define the relative orientation of the nbe planes of the two oxygens? Is it currently done at random? How should it be done?

    I believe that O2P is the pro-r oxy, because after reviewing my notes on S-R configuration and looking at the phosphate with the C5* atom away, and the O3* atom at the top, O2P is clockwise from O3* and O1P is counter-clockwise. Thus, giving O2P a higher priority than O1P would result in an R config. This appears to be confirmed by comments in a paper by (Torres 1998 PNAS) "Molecular dynamics study near in-line attack conformations in the hammerhead ribozyme self-cleavage reaction", which makes near explicit reference to the pro-r oxy as O2P.

    I really need to write a 'save-all-state' script that will create a bunch of files in a param directory such as values of all script object vars and ff params.

    Wrote script 'WriteScriptObjectVarsToFile.lua'. After dumping script objects vars for tlRestrain, I see that there is some kind of bug in the new fMaxAngleDev variable that I added to torsionSprings.lua. It has the value of -360, which doesn't make sense. The intent is that it should never be greater than 180. Must be something wrong in my GetAngleDiff() function. Since I can't seem to grok simple algebraic implications, I will just write a perl script to output results for all possible inputs and see how it is possible to get this value.

    Ok, the perl script 'exp/dev/test/' immediately reveals the flaw in my reasoning, and thus invalidating all torsionSpring sims to date. The algorithm used the idea of projecting angle I forward 360 degrees to test for an alternate minimum difference from angle J, but this only works if angle I is less than angle J. If angle J is less than angle I, this alternate minimum distance will not be found. All I need to do to fix it is to use the signed minimum param angle as angle I. That appears to work.

    Testing new torsionSpring folding on inga with ver 0.1.13.alpha.1.

    Duh, that sim was wasted because I forgot to update the torsionSpring file.

    Finally found a good fix for the file flushing problem in ResMovieTorsionReport perl script: just do a while loop testing for file existence until the damn thing shows up.


    Did another overnight sim on inga with tlDriver. Finally it appears that the torsionSpring code may be functioning as desired. In conjunction with the angle deviation - disable function of the tlDriver, the a-form eq angles of all residues of the unfolded tetraloop appear to be maintained, and the conditional torquing of the single S12a angle could clearly be observed, as it tried to push past the steric collisions of the adjacent residues. The one thing that still might not be working quite correctly is the userGAD() function in torsionSpring.fiTick.lua, after the most recent fix to the GetAngleDiff() function. I need to check that.

    With regard to the question of above, whether double-bonded / sp2 oxygens allowed to rotate, the answer is definitely yes. There is currently nothing done to prevent that, although there may need to be the application of such restraints. In an overnight sim done on ribo4 with eq torsion springs applied to all angles of the uf tl, without torqueS12a, the a-form helix conformation appear to be largely maintained, but 2 hbonds formed during the sim, involving adjacent C-G residues, (C3.N4 - G4.O6) and (C9-N4 - G10.O6). This is because both the N4 and the O6 atoms were able to rotate their nbes out of the base plane, which may not happen in real bases.

    Created stub nucleotide 'testTorSpring1.pdb' in exp/dev/test, to do simple torsionSpring testing. This required changing the Phosphorous covalent bond count in CValenceShell.cpp : AddEmptyBondVectors() from 5 to 4, in order to successfully create it as a force object (also had to do a hack by setting it's residue type to GLY). Don't remember why that hard-coded value of 5 was in there, hopefully it won't cause any bugs.

    Well, that 'exp/dev/test/testTorSpring1.lua' script quickly reveals an ongoing bug in torsionSpring. Man, why is this so freakin difficult for me to get right? Wait, it's not a bug, it's simply that the overshoot of more than 100 deg led me to believe that the direction of applied torque was still wrong, but it appears that it isn't, it's simply that the overshoot was more than I expected. Ok, looks like the sign of applied torque is correctly, but it still is another significant bug in the torsionSpring script. Shouldn't have such a large oscillating overshoot. Oh wait, sure there can be, in this case, because I was defining an eclipsed conformation as the eq angle, and it's the large steric repulsion causing the overshoot. Duh. In any event, this simple and easily observable test should allow me to nail down any remaining bugs in torsionSpring.

    Ah, another interesting observation from this test, the angular velocity was great enough to cause a second elipse on the second go-around of the rotating bond, which definitely shouldn't happen. This points to a bug in the torsion code (or more likely, the need for parameter adjustment).

    Arg, no steric forces are showing up! Duh again. Not supposed to have steric interactions between torsion atoms.

    Re-running testTorSpring1.lua with Torsion force turned off, still get overshoot of 125 deg. This is with fForceConst 100, fMaxForce 1000.

    While observing some of the small oscillations of 'exp/dev/test/testTorSpring1.lua', right at the zero-crossing the beta torsion angle reported by 'DrawFoTorsions.lua' momentarily becomes 180 and -180. This must be some bug in _DihedralUtil.lua : getFoDihedral().

    Ok, found the bug. I was doing a dot-product on the cross-product of the plane normals with the vBC bond vector to determine if the cross-product was in the same or the opposite direction as the vBC bond vector. But when the vector between the planes normals is exactly 0 or 180, the cross-product is zero, so this doesn't work. So the fix is easy, if cross-product is zero, just calculate the dot-product from the plane normals instead.

    There is a bug in drawing atom torsions - script reports failure to get total atoms when a node is selected instead of the entire residue.

    Why does 'zero-velocity' cause the covalent bonding to spazz-out?

    As currently defined, the fMaxAngleDev value recorded by the torsionSpring script appears to be (fEqAngle - fCurAngle). When iGAD_UserDir is 0 or 1, the direction of the torque vector on the B atom is in the vCB dir, for a cur torsion angle that is negative with respect to the eq torsion angle. If I point my thumb of my right hand in the direction of this torque vector, my fingers curve in the direction that will torque the B atom in the direction toward the eq angle. If the iGAD_UserDir variable is -1, the torque vector points in the opposite direction, as intended. This is the situation for an eq angle of 0 and a cur angle of -20 deg (resulting in a GAD difference angle of +20 deg). When the eq angle is 0 and cur angle is +20 deg (resulting in a GAD difference angle of -20 deg), the results are opposite, as intended. Thus, for this eq and two cur angles, the UserGAD() function works. Still need more testing though. And with the current overshoot, the general UserGAD scheme for torqueS12a isn't going to work. Should really change the fUserGAD_DeltaMinMag so that it is used to bypass the GAD_UserDir only when the user signed angle becomes less than 180.


    Did an overnight sim on inga on uf tl, starting at the partially-folded config from the previous sim. In that sim, with tlDriver fLowerDev/fUpperDev values of 5/10 degrees. The torsion of s12a bond could not rotate the downstream portion past the initial collisions of G5 and C6. The overnight sim tried to produce greater progress by increasing the fLowerDev/fUpperDev values to 10/30. Additional rotation was achieved, but not enough to move into the final folded tl conformation. And another consequence was much greater variation of tlRestrain torsion angles (up to 131 degrees) and distortion of covalent bond angles. Visual analysis of steric clashes did not result in an understanding of what was preventing the rotation.

    After reflecting on this most recent failure in folding, I considered what would be the next approach to solve the problem. One idea is to reduce the number of residues in the oligo to just the first two at the folding joint (G5 and C6), and on successful folding, gradually add residues at each end and observe where the clashes occur.

    Another approach is to freeze upstream residues and inhibit movement of nodes and residues downstream from the s12a angle so that we only need to apply a single torsion spring at the folding joint. This would require the completion of the lockNabNodes.lua script.

    However, before proceeding with either of these approaches, the first thing that I want to do is to create a 'torsionInterp.lua' script, which will do geometrical interpolation of a set of torsion angles from starting angles to ending angles. This will allow a quick and successful transition of the uf tl to the target folded state, where it can be compared to the crystal structure. It should also highlight the angle changes that occur for all the non s12a angles, which may be of significance even though they all remain in the 3'emmtp3' a-form rotamer configuration.

    Finally, while thinking about this simple geometrical torsion interpolation, I realized that this would be a very simple solution to the simulation of mRNA translocation in the 70S ribosome, by specifying a target torsion angle of each residue to be the current torsion angle of the residue 3 positions upstream from it, and then applying an increment of global translation of all residues of the mRNA in conjunction with the interpolated torsion angle rotations.

    Created script 'torsionInterp.lua' without too much trouble, but now running into problems with DihedralUtil.lua : setFoDihedralAngle(). It's not setting desired dihedral angle when doing a rotation about the owner node of atom C of the torsion bond.

    This error doesn't happen when I set interpolate a single angle. After a little reflection, I think I see the problem: when interpolating multiple angles, the initial angle value for subsequent angles will not be the initial value of the initial conformation. After the interpolation of each angle in the backbone, the uninterpolated value of subsequent angles in the backbone will change? No, they shouldn't?

    Regardless, there is still a problem with setFoDihedral(), as I now have gotten an error when setting just a single angle.

    I realize that I have never quantitatively tested the node rotation code in CRbqNodeBsjForceObject. Instead, I've done manual rotations with the mouse, and one would think that significant errors would quickly show up visually, as was observed in the past when I failed to normalize the rotation matrix. However, that kind of error occurred as the result of multiple small accumulations. In this case, the error happens with a single rotation, and is quite significant, 1.5 degrees or more. The problem can be either in the rotation code, the torsion angle calculation code, or both.

    The debug approach will be as I have been doing recently. Instead of embedding printf() reporting in the core code, I will instead attempt to reproduce the operations in external scripting code, to produce an expected set of intermediate data.

    Independent repro code produced the correct angle. Adding printf to setFoDihedral().

    Ok, tracked it. Immediate post-rotation call of rotateForceObject() in setFoDihedralAngle(), the angle is correct. It has to be a bug in the subsequent downstream node/res rotation code. That's it! The core code already handles the downstream rotation of nodes and res! I was duping it in the lua code.

    Actually, that code is needed for setting torsion angle 5, that's why I didn't see the error before. Anyhow, skipping that duped ds rot for ta 0-4 works for single angle set, but the interp script is still getting errors of greater than 10 degrees for interpolated rate of 0.1, so something else is still going on. Getting closer to a working torsion interpolation script though.


    To answer the question of whether subsequent backbone torsion angles would be affected by the rotation of a torsion angle, the answer is definitively no, because although rotation about the central BC bond will rotate the direction of the normal for plane ABC, the normal for plane BCD will rotate in the exact same way, so that the dihedral angle will not change.

    Today, I investigated the error in torsion angle interpolation. By doing a full interpolation of the torsion angles for the unfolded tetraloop, and then writing a perl script '', the errors were easily highlighted. They are all in the delta torsion angle. Subsequent manual rotation of the delta torsion angle revealed a bug in the implementation, where the rotation is not occurring about the vBC bond 'C4* - C3*', but instead is rotating about the bond 'C2* - C3*', presumably because the C2* node is the parent of the C3* node. All other backbone torsion errors were less than 0.15 degrees.

    In looking at the node rotation code in the core routines (CRbqNodeBsjForceObject::RotateAboutNode()), it seems that when rotating about a node, only the child nodes are rotated, not the node itself. If this is the case, it seems that it could cause a significant problem where the covalent shadow points of the node are not rotated with the child nodes, thus producing a large instability and a natural resistance to rotation about a node.

    However, manual rotation of nodes with covalent forces displayed does not seem to confirm this problem. Instead, the only significant change in covalent bond force on manual node rotation is the force pair associated with the node's parent, where the two atoms have not moved visibly, so the resulting forces must be due to small errors in the rotation. This would indicate that the node itself is rotating about the bond, along with its descendant nodes. Ah, more careful inspection of the node rotation code reveals that the node is rotated along with its descendant nodes.

    In debugging the new code to set dihedral for delta, I just found a huge bug in getForceObj_AtomIndexFromName(). Why wasn't this horrible bug known before! What other problems has it been causing? Actually, the bug isn't as huge as I thought. The function has been working. No, it hasn't. Wrote and ran exp/dev/test/testGfo_AtomIndexFromName.lua and all values are wrong for dyn residues in 2nt.rbd. Unbelievable! Currently, grep reports 8 files in lua dir that mention this function, including torsionSpring.fiTick.lua. I still find it hard to believe. I'm going to do a reboot and a full rebuild and recheck.

    The errors repro after reboot and rebuild. It doesn't make sense though, because torsionSpring.fiTick.lua should fail on receiving a nil value for an atom index. Ok, found one possible explanation. If the name is trimmed, the function works. torsionSpring uses trimmed hardcoded names. Need to check other usages to see if they do the same. Added appropriate caveats to getForce_AtomName().

    Ok, now I'm looking at a possible bug in getForceObj_AtomOwnerNode(). No, that works too. It must be some weird local var overlap in _DihedralUtil.lua : setFoDihedralAngle(). No, it's just the idiot programmer different iNodeRot index var bug instead.

    Now we're just back to debugging the manual rot in setFoDihedral(). I know that CGrTransform3f works for applying a rotation about a center point. Trying to do the same thing with hm matrices and frames does not appear to work. Creating lua function 'getGrtRotation()' so I can compare.

    This has been done. Down to a difference in the translation component in the matrix. After fixing the init translation in the frame code, it's the same.

    SetFoTorsion.lua is working for setting a delta angle! Full interpolation of torsion angles of unfolded tetraloop now results in a structure very close to the folded tl. Torsion comparison report confirms it.


    Improved color coding of torsion angle comparison, did a comparison between unfolded and folded tetraloop models, which I suppose I should have done quite some time ago, because even though all angles except s12a are classified as the same rotamer between the two models, there are still significant variations.

    Checked latest run on ribo5 where I was trying to repro the basrAlign mRNA dock with the most recent build. The first couple of attempts failed because of hydrogen bonding. In this most recent sim, I upped the fForceConst from 100 to 200 and the fMaxForce from 100 to 500, and reducing the hbondScaleForce from 30 to 3. This rapidly succeeded in aligning the mRNA in less than 100 movie frames.

    The next sim on ribo5 will be to apply torsion springs to all tl angles except s12a, with the eq angles being those of the folded tl. Doing this probably requires development of an intermediate init script that can read the torsion angles from a tl file and use these for the initialization of the torsionSpring script.

    Starting script 'initTorsionSpringsFromFile.lua'.

    In applying significant torques for all 68 angles in new uffo torsionSpring (because eq angles are now the folded angles), a new problem occurs in the script object data implementation. A single var, sAppliedTorques, has been used to hold all applied torques and positions, and it's now overflowing the string size limit because there are 68 * 6 floats, each with 16+ digits. We obviously need a different way to hold this data, or perhaps just store selective values, as the string conversion time overhead must be humongous as well. Some of this limitation appears to actually be display of the string in the status window as opposed to the limit on the string length. I need to check and document both of these limits.


    Changed order of intialization of lua module load flags so that infinite include recursion is avoided.

    Trying to create a nice lua 'wrapper' script to run lua and perl scripts to generate a movie torsion report, but running into annoying problems with all the impedance mismatch and glue code needed for argument marshaling and process execution, as well as handling return codes. I suspect some of this is due to dealing with a retarded DOS command-line, but my own patchwork knowledge of tool chaining may also be to blame.

    Found the problem with my use of the 'runPerlScript()' function. This function allows the caller to specify the working directory, but uses the hardcoded relative perl pathname 'perl/bin/perl' to run the perl executable, which fails because it is not found from the user working directory. This should be pretty easily fixed by pre-pending the absolute application base path to the perl exe.

    Done, MovieTorsionsReport.lua is working.

    Well, not quite. Wild-card expansion still doesn't seem to be working correctly, even with quoting of the argument. I'll just have to hardcode the "*.tta" in the script.

    Done and works, but now my stripped-down perl is acting flaky. It is complaining about the $a and $b references used by sort() and conflicting with the Can't fix it and still get sorting to work. I ended up just commenting out 'use strict', which is pretty damn bogus. All these little tool problems are really starting to annoy me when I have to get on with the job of trying to figure out tetraloop folding.

    After finally generating and examining the movie torsions report for the overnight sim on inga, a 4nt sim called 'uf4', all tlRestrain angles appeared to remain nearly constant, with the small exception of the beta angle of the first residue, G4, which shows a variation from an initial value of 180 quickly oscillating down to around 125. This is strange though, because I don't think we should even HAVE a beta value for the first residue? No, visual examination shows that we have a P, O5*, C5* and C4*, all the atoms needed. So now the question is why the script failed to maintain the eq angle of 180. It may be that the beta angle was left out of the tlRestrain script for uf4. Yes, examination of uf4-001.tlRestrain.vars script verifies this. The only other issue notable from the movie torsion report is that it is difficult to view the plots of angles near the (-180, 180) border, because of multiple cross-over lines. A fix for this might be to draw the dihedral plot in addition.

    The single driven angle, C6.alpha, only showed a slight change from its initial eq value of -60 to a final value of -26, which is in the opposite direction from what was intended. This may be due to the low driving value of a fMaxForce of 100 (the fForceConst was actually increased to 200, but a little reflection shows that this won't change a damn thing if the force is clamped to 100, duh). The max force must definitely be increased for torqueS12a in future sims, though it would be useful to know what the dominating forces are, in this minimal driving case, that actually produce the reverse rotation of 35 degrees. In contrast to the ts12a, the tlRestrain params were fForceConst 200, fMaxForce 500.

    Another possible problem is the ongoing hydrogen-bonding that is happening between adjacent residues on the chain because of the allowed rotation of the N6 amino hydrogens and the O6 nbe vectors. These should probably be restrained somehow.

    In the 1-day uffo sim on ribo5, the report showed a completely successful driving of the uffo torsionSpring script of the angles from the unfolded conf to the folded conf (excepting s12a of course). The max deviation is 5 degrees, and the average seems to be around 2.5 degrees. The torsionSpring params were fForceConst 100, fMaxForce 1000.

    Starting new sim 'uffoTs12-001' on ribo5 with uffo, using same params, and in addition, a torqueS12a with fForceConst of 200, fMaxForce 500.


    Overnight sim of tetraloop folding finally succeeded!! The backbone was in close approximation to the folded tetraloop. However, it did not produce the expected base-pairing in the stem loop except for the terminal pair. Continuing simulation with some additional thermal input to try to get base pairing. The rotation of the base ring oxygens is also probably preventing expected base pair by forming non-standard hbonds in the rotated conformations.


    Started 'SaveSimState.lua' script.


    Started work on the Ribosome Builder paper and its going well. Just got a nice idea about one of the goals that I can talk about in the paper, while reading the Transmeta section of Rebel Code, by Glyn Moody. The basic gist is the need to make molecular dynamics coding more accessible to bioinformatics developers and users. Current MD software is accurate, but also complex and difficult to understand and interact with. I will assert that a simple implementation of MD has value for the larger field of MD software development, even if it is not accurate or capable of producing accurate simulation results. The value comes from the greater accessibility and use of the simpler aspects of MD by a larger community of researchers, because it will accelerate the development process, both through greater feedback to developers and through a greater exploration of a variety of ideas and applications involving MD. The simpler aspects are the general concepts, operations and data concerned with the dynamic movement of atoms over time. Current MD techniques and software are not being used by the larger population of molecular biology researchers because of the steep learning curves associated with them. The investigation and exploration of dynamic activity of molecules with 'trivial' and 'inaccurate' implementations of MD can possibly stimulate a much greater involvement of researchers than is currently happening with static, visualization software. Something like that.


    Finished 'run-to-timepoints' code in simpanel iseq001 (for interp, still need to do cam and billboard jumps). Added more documentation of simpanel implementation.


    Working on eseq001. After adding code to load and position models, and first working sequence interp, I realize the need again for some kind of 'director' script object to handle things that aren't done by interp, spCam and spBoard. One such thing is the selective hiding and showing of different models, such as hiding 1ttt_D and showing 1gix_B for the 'trna_ternary_dock30' interpolation. That will bring the script object count up to 4 for the simpanel implementation, hope it doesn't start to become too complicated like the cycleSim did. 'interp' clearly handles the movement (interpolated movement). Perhaps one more 'worker' function, like 'spShow', to handle the concept of appearance. But maybe it's just better to wrap every additional requirement not handled by 'interp', 'spCam' and 'spBoard' into a common 'director' object? Because I'm sure other distinct kinds of tasks will come up.

    Thinking a little more about that. Analogies to animation, where everything is synced to a master clock (keyframing). Another way of implementing things is to simply define command strings associated with a particular timepoint for everything: setCamCmd, setBillboardCmd, setDrawStateCmd. For now, think I will just define another script object to set appearance: spDraw. This is nice in one sense in that it allows any one of this functionalities to be disabled independently, as might be done with spCam if the user wants to control the view instead. Conceptually, it seems clean as well.

    Added spDraw. Initial version of eseq001 is working.


    After reading the first third of 'Sorrows of Empire' last night because I couldn't sleep, I am getting a PDDINP (Possible Dangerous Distracting Idea for a New Project): promoting and possibly becoming involved in an open source project to turn SOE into a political game/simulation that can be hopefully completed before November.

    Defined 'run to timepoints' for eseq001.


    Continuing with work on simpanel eseq001, I want to fix a problem with the 'run-to-timepoints' feature where currently the interp script object disables the global script object tick after running the interpolation to the specified timepoint. The problem is that in the current implementation, the CRbqScriptObject::Tick() checks the global enable flag, so that it is an immediate effect. As a result, the remaining script objects in the current tick cycle do not get called. I think what might be better is to do the check in CRbqMainWindow::timerEvent() instead, at the start of iterating all time users. This would allow the remaining objects in the iteration to finish their work for that timer tick before the disable takes effect. I don't believe that this change should cause any problems. Done. It works.

    Another issue that probably needs to be addressed soon: currently, every interpolation event in the sequence takes the same amount of time, but we may need to add scaling factors so that one can happen more rapidly than another.

    Started working on next stage of elongation sequence where the tRNAs are in the PTC. It's hard to show what's going on because of the density of the pocket. Created a surface mesh for 1ffk.0 residues within 20A of 1gix_C.A76. Then I realized I finally must add backside rendering of the surface mesh so the user can tell where they are when looking around. This required a few additions to the CWkSmoothColorMesh and CGrPdbObj code.

    Drawing the inside of surfaces is working, and it helps. Much less confusing now when I zoom through a surface boundary.

    Another idea to help show things might be to create a 'shell' surface where the residues for the surface are within a shell of 2 given radii instead of a simple spherical selection. This would allow for ball-stick rendering for the 23S residues inside of the shell and show their interations with the tRNA residues.


    Added color-keyed transparency to surface mesh drawing. It works, but I am coming to the opinion that just showing the local region of the PTC without any surface may be the clearest at this point.

    Working on adding RTT support to spCam, spBoard and spDraw in simpanel. I think the obvious way to do it is to just add the sRtt var to those script objects, in a way identical to the interp object. One problem with this: currently, the spCam object doesn't necessarily have a set of views that are in a one-to-one correspondence with interp sRtt timepoints.

    Great success in the most recent tetraloop uffoTs12a sim with zero friction! Observed lots of base-pairing in the stem. Zero-friction seems to be a lot better at producing this than the thermal script, at least with the parameters that were tried so far.

    Started a new sim with 0.001 friction and hbondScaleForce of 30 instead of 10, to see if we get the same results.


    This morning, thought of a solution to the Rtt problem above. Although not ideal, it seems simplest in the current scheme. We have the interp script object, which defines the sequence. The sequence is composed of a list of names, one for each interpolated group in the sequence. These groups will be referred to as 'sequence items'. Then we have the 'dependent' objects: spCam, spBoard, spDraw. These objects are intended to produce actions that occur during the interpolation sequence. An action is defined to occur within a particular sequence item, at a specific timepoint. Currently, a dependent object may have zero or more actions defined for any given sequence item. This is a problem when trying to 'run to a timepoint' in the the interp sequence. If we RTT to a timepoint in a sequence item in the interp object, and there is no definition for that sequence item in one of the dependent objects, how does the dependent object know how to skip ahead, as needed, to remain in sync with the interp object? Each dependent object must have the information of where its action items are in relation to all the sequence items of the interp sequence.

    One way that I had thought of was to define 'nul' action items in every dependent object so that there is an action item for every possible sequence item. But in more clearly stating the problem now, I have thought of perhaps a cleaner way. This second way would be for each dependent object to query the interp object to get the temporal value of the current action item in relation to the param RTT item. This would eliminate the need to define 'nul' action items, which seems messy and error prone.

    This solution does however reveal an additional limitation of the current script object architecture. This limitation is that only data is accessible from the script object interface. It would be helpful for one script object to be able to call a function of another script object. However, there is no time to implement this functionality at the present time. One alternative, that can avoid the dreaded code dup, is to put common code into a single lua file and do a 'dofile()' on it. Then all the simpanel script objects should be able to call these common functions.


    Created spCode.lua, with functions that the dependent sp script objects can call to implement Rtt. Added Rtt function to spCam and it works.


    Added Rtt function to remaining dep so spBoard and spDraw. Rtt appears to be working now for interp and all helper script objects in simpanel.

    While I would really like to leave off on additional work on simpanel functionality, and produce with definition of hypothetical sequences, it seems that there is an additional functionality that would be good to have. In elongation sequence 001, when the aa-tRNA has been delivered to the 70S by the ternary complex, and is ready to undergo accomodation of its 3' end into the 50S A-site, the current chem draw state of the 50S is a large, obscuring surface representation. To better show the 3' ends of the tRNAs, the surface needs to be turned off. However, an abrupt removal looks somewhat confusing. Ideally, I would like to have an incremental increase in transparency of the surface over time, so that it just 'fades out' to show the backbone.

    The question is how to cleanly implement this additional functionality. In thinking about it, I came up with some better descriptions of the overall process of doing these hypothetical simulations. In this process, we have 'Model Events' and 'Presentational Events'. The Model Events (MEs) are event directly concerned with the molecular activity, such as the interpolation of a static PDB model from one location to another. The Presentational Events (PEs) are the associated activities of the program that help the user to understand what is happening, such as camera movements, change in graphical representation of the models and display of descriptive captions. Furthermore, events can be either interpolated or discrete. Currently, the only interpolated events are the geometrical interpolation of the static pdb models, as implemented by the interp script object. However, additional types of interpolation can be done. An additional ME interpolation would be a torsion angle interpolation from one conformation to another. A PE interpolation would be the transparency fade out described above. At present, all the PEs are discrete events.

    Another must-have option: add interp-rate scaling factors to individual interp groups.

    Another presentational option: devise some means of re-running a particular model interp from different viewpoints and other presentational aspects.


    The re-run feature mentioned above is most likely a much more difficult thing to implement, with likely a large cost in complexity. However, in thinking about how to implement IPEs (interpolated presentational events), a fairly simple extension might be possible, at least for producing simple IPEs. This would be the definition of a script object to handle IPEs, probably to be named spIpe. It would work in the following way: an IPE would be defined to begin at a particular timepoint in a model interpolation event. For simple IPEs, the implementation would be done with a simple string command. For example, to produce a transparent fade out of a molecular surface, the command 'draw surf decTrans' would be defined. Obviously, for more complex operations, such as camera repositioning, a simple command string would not suffice. Some means of executing a sequence of commands or a pre-defined block of code should be done at some point. But for now, the single command string will be done. The IPE will be interpolated from 0 to 1, using an interpolation rate and increment on each timer tick of the spIpe object. One additional option will be to suspend the interp tick event, in order to freeze the current model interpolation until the IPE has completed. When completed, it will be removed from the spIpe list, just as is done for other helper so's in the simpanel. Rtt implementation should also be similar and straightforward.

    Creating script object 'lineLabels', which draws a set of lines and associated text labels that connect to descriptive targets in a static pdb model. Initially created to display labels for domains in eEF2 for my upcoming talk on eukaryotic ribes.

    TODO: added function 'isValidObjectIndex()' (to prevent ASSERTs in CRbqDoc when selecting invalid objects via lua IF).


    Did some more documentation of simpanel. Starting on spIpe support so. Now that I've actually started, it becomes a litter trickier. Can't just define a command that is executed for a collection of tick events, because I need to ensure that the event is completed in an arbitrary number of ticks, as the interpolation rate can be variable. It's almost as if the IPE command must include a floating point parameter, which will be set to the interpolation value for the IPE, at any given timer tick. Should probably review the VRML spec on interpolation for some additional ideas, too.


    Completed first draft of manuscript for journal article about Ribosome Builder.


    In playing around with a surface rep of the 30S and the 1jgo chain through it, I'm thinking of adding an option to surface mesh creation where it only uses atoms of visible residues to create the mesh. This would be a simple way of eliminating undesireable parts of a model when surface meshing. The immediate example would be the 3' end of the 16S, which is lying in the mRNA path. The solution up to this point has been to export the desired subset to a new pdb file, but this seems like a pain.

    Still, perhaps I should just do that for now, because messing with core code stuff like that is probably not a good idea when I have so much else to do and there is a reasonable work-around, which the export option certainly is. Hmm, maybe I'll forget about it for now.

    Created file pdb/1j5e-m6.pdb.

    Transparency really fails with multiple surfaces - I really should make a note about that in the FAQ. Also would be nice to fix it - seems like there would have to be a global 'transparency drawing' object that the application would submit mesh triangles to, so they would be globally sorted. But of course, no way is there time to do that now.

    Hey, solid protein blobs and backbone RNA looks like a nice way to display movements because it prompts one to imagine how the RNA skeleton must move, for events such as latching or unlatching the mRNA. Also, with all the protein blobs, the naked RNA backbone looks less visually confusing (more landmarks).

    This also motivates me to create a script to do a full 30S sim on ribo5 with each protein in a custom force container group, with all intra-group interactions disabled, and movement disabled, but still with a way to move each rigid block using the net force and torque on the entire group from external interactions. Seems like an awful lot of work though. I wonder how much speed-up it would compared to just simulating the entire 30S? Perhaps it would be better to try a full 30S sim, but using an external force to pry open the latch? As far as the driving force, one idea I just got is to push a particular mRNA residue at the center of the latch in an outward direction that is defined by a vector orthogonal to the up-down vector defined by latch residues above and below the latch opening, and also orthogonal to a transverse direction along the latch edge, defined by another pair of vectors in the latch.


    Registered rbuilder project with SourceForge.

    Yesterday, started a new all-30S sim on ribo5 and realized I needed to fix the force object creation code because the reporting of hydrogen addition slowed it down far too much. Changed the code so it only is done with '-v' verbose option.

    Did 1600 frame overnight sim of tetraloop folding on inga with zero friction and default hbondScaleForce of 30 and didn't get full base-pairing in the stem, confirming the need to lower it to 10, as done in the prior successful pairing sim.

    SourceForge project 'rbuilder' has been approved!

    Next, I need to get the project in a better buildable state (build on NT,XP in addition to my current ME system).

    Fixed glut.h and glut32.lib references in project makefiles.

    Started downloading new visualc++ toolkit for building on inga.

    Uploaded initial web page to sourceforge site.


    Been doing research on how to compile the program with more recent tools. I'm finding out that the current situation looks like an orphan because of being trapped in hideous Windows land. I can currently compile it with VisualC++ 6.0 and Qt NC 2.3 and that looks like the only way it will be compilable on Windows platforms. I've downloaded the free MS VisualC++ 2003 toolkit, which turned out to be a total trap. Later found out that it probably wouldn't have worked with NC 2.3 anyhow. Also, I downloaded MingW, but it seems this will only work with Qt 3.3 Evaluation. So, instead of messing around anymore, I will just stipulate that the current windows development simply requires that other people have a copy of VC6.0, which is bogus, but the main thing is to get it the hell over to GNU/Linux as soon as possible.

    Fortunately, I was able to do a clean build of the program on Windows XP without any trouble, and finally fixed the annoying glitch where mkdir caused the build to abort because of the weird pathnames (used the - modifier in front of the mkdir command in the makefile).

    Added demo instructions to help menu.

    Added iseq001 demo to demo menu.

    Fixing 'Rtt' for simpanel iseq001. Done.

    Now, just need to add individual rate factors to the IMEs and add a timing calibration script for the global interp rate.

    First, need to fix existing iseq001 and eseq001 scripts to cleanly reset after running the other one (ie: delete (or hide) existing all models and info that is not needed).

    Another nice (and probably necessary) feature to have for interp sims is to stop the sim at the display of each new billboard, allowing the user to view it before proceeding. This should be quite simple to implement, just another variable in the spBoard object to stop the script object tick event after setting each new board.

    With that solution, there is still the problem of skipping billboards when the interp rate is larger than a set of closely-spaced billboards. However, don't think that I want to worry about that now. Work on the fine points of the interp system could go on forever.

    The next thing to do is to report real-time intervals for the current seqs on ribo4, to build a baseline for calibration.

    'pause at new board' option works.


    Ran into a problem between the old version of the init demo (cycleSim) and the new simpanel version where the old version was loading a different pdb , but with the same name, (exp/sim/cycleSim/1jgo_1.pdb vs pdb/1jgo_1.pdb) so that the new one didn't load the expected model, and the transforms were different. I dont' want to constantly reload models if they are already there, because that's time consuming, but the best way to address that is to be able to detect what the original pdb file of a currently-loaded model is, and load that if needed. Not just the original file, but the actual path associated with it, and I don't think that info is currently saved in the pdb data. Hmmm. Actually, looking at the docs, it looks like the pathname is reported. Just need to add a lua function to get at it.

    Done. Also added 'deleteImposters.lua' to exp/dev/simpanel. Man this is a lot of work to do such simple stuff. Switching between demos is now working.

    Finally getting around to adding recorded time info to interp. Almost have the calibration strategy worked out.

    Finally have times for iseq001 sim on ribo4. They range from 31 seconds for mRNA to 23 seconds for IF2.

    It's nitpicking, but I'm changing the code in CRbqDoc::Select() and callers to return status via param var, to be consistent with command status suppression in CRbqCmdProcessor(). No, that is a TODO item, I am just not going to get into that right now. Too much housekeeping.

    Added code to interp to output times to file. Creating script 'lua/CalibrateInterpRate.lua'.

    Created new settings file 'LocalEnv.set'. Works. Now that the interp demos can be calibrated, perhaps I can actually release to sourceforge. Would like a better init demo though.


    Local host machine interp rate slowdown adjustment is working.

    Found a bug in 'draw surf createForChains' (it's turning off surface display of non-selected models). Fixed.

    Tried changing iseq001 surfaces to transparent, with backbones showing, like done in old cycleSim demo, but the transparencies don't always overlap properly, even between pdbs.

    In running the new and old ti demos, I noticed that the mRNA slots into the 30S a lot better in the old demo, which is using 1fka instead of 1j5e. Think I will use that model in the new demo. Also, it motivates the creation of an interpolation between the 2, perhaps giving the latch-closing that I need.

    First, created 'AdjustInterpRate.lua' simpanel script for manual adjustment of interp rate.

    Finally put together the demo dynSims for tetraloop and mrnaWrap.

    Released ver. 0.1.13.

    Did first File Release on sourceforge for ver. 0.1.13.


    Yesterday, worked on manually removing CVS directories from the tarball source tree until I later realized that the cvs export command does that.

    Also spent yesterday putting some online documentation up on the rbuilder home page on sourceforge and reading the site docs. Today I did the first commits to CVS after learning how to modify the cvswrappers file in CVSROOT to handle binary files. Then I imported the web page docs into a new module, 'web'. Then I spent the rest of the day figuring out how to do SSH access to CVS on WIN32 systems, because although my main emphasis will be on doing the unix port, I will also need to periodically build the program on Win32 to verify that it is still working.

    The sourceforge site docs are excellent, with step-by-step instructions on recommended software and setup. Downloaded and installed putty and WinCvs, figured out to generate SSH keys and use pageant, and finally, I can do command-line cvs ops using pageant, plink and cvs95.exe on ribo4 and ribo5.

    Now, I will focus on reading the Autoconf, Automake, Libtool book to get some background on how to change the existing source and build structure to support multi-platforms.