Getting Started with O

Let's face it, O is not the friendliest program in the entire world. It lacks documentation (or more precisely most of the documentation is for version 5 and some of us run version 9). Consequently I've tried to summarise very briefly some of the central features of O. The O tutorials "O for morons" and "O for the structurally challenged" cover some of the same ground, and should also be read.

Historical Note

Alwyn Jones wrote a graphics program called Frodo while in Robert Huber's lab in Martinsreid back in the 1970's. Although other primitive graphics programs existed at the time, Frodo was sufficiently powerful that it became rather popular. It also sprouted several offshoots, notably Phil Evans' version of Frodo, and Christian Cambillou's version now called Turbo Frodo. The latter program may be the cause of some contention, since Cambillau sells Turbo and rumor has it that the code is extensively derived from Alwyn's original program. Alwyn went on to write Tom, a Frodo derivative, and Flo Quiocho's group also made a version of the same program.

O is the logical successor to Frodo and Tom, making it's first appearance in the late 1980's, although I'd guess that little of the original code still exists (only Alwyn knows for sure). A measure of the popularity of O is that there are very few competing programs to do building (XtalView is popular, mainly on the west coast).

No, you do not get a prize for spotting Lord of the Rings references in the naming of these programs.

Web Resources

Starting from scratch

The version I personally know most about is version 7. Version 9 is similar and is the most recent stable version. Versions 8 and 9 are available on Linux. Versions 5.10.3, 7 and 9 are available on the SGIs. Some people still use version 5. I refer to those people as luddites but I'm not a whole lot better.

Type "which ono" or "which O" to see if O is already set up for you. If it is, ignore the rest of this paragraph. If it is not, place something like the following in your .cshrc:

alias ono '~xtal/O7/bin/ono'
and open a new shell. On Linux, the default version of O is v8 as /home/xtal/O/bin/ono with v9 as /home/xtal/O9/bin/ono. If you feel the urge to use stereo on Linux, make sure that
setenv STEREO ON
is in your .cshrc. If you want to use the dials, use the ono_dials script in place of ono in the directories above.

To start O from scratch just invoke the program ("ono") and hit carriage return a whole bunch of times. The script that you will be running sets up hooks for ODAT and OMAC so you don't have to do that yourself. It looks somewhat like this on startup:

... Running SGI O version 7
... No bindkey.macro file found

... Link to odat directory not found
... Making a soft link to the odat directory for you

... Link to omac directory not found
... Making a soft link to the omac directory for you
... ODAT not set
... Setting ODAT to /xtreme1/usr1/xtal/O7/data/:/xtreme1/usr1/xtal/O7/omac/:/xtreme1/usr1/xtal/pdb/distr/
... Executing /xtreme1/usr1/xtal/O7/bin/sg_ov701
... For phil on ximpact1 at Mon Jun 9 15:57:02 EDT 2003
... ODAT /xtreme1/usr1/xtal/O7/data/:/xtreme1/usr1/xtal/O7/omac/:/xtreme1/usr1/xtal/pdb/distr/
 no error 
  O > Use of this program implies acceptance of conditions
  O > described in Appendix 1 of the O manual
  O > O version 7.0.1 , Build 000518
  O > Define an O file (terminate with blank): 
  O > Menu names are not defined.
  O > Enter file name [/xtreme1/usr1/xtal/O7/data/menu.o]: 
  O >  menu.o file for O version 7.0 build 000226
  O > Startup file was never loaded
  O > Enter file name [/xtreme1/usr1/xtal/O7/data/startup.o]: 
  O >  startup.o file for O version 7
  O > Access file was never loaded
  O > Enter file name [/xtreme1/usr1/xtal/O7/data/access.o]: 
  O > *******************************************
  O > Program version does not match the database
  O > Database is: O version 7.0.0
  O > Read in new startup.o and menu.o files!
  O > *******************************************
  O > Chassis id: 1762290277
  O > File_display_connectivity is not defined.
  O > Enter file name [/xtreme1/usr1/xtal/O7/data/all.dat]: 
  O > Maximum inter-residue link distance = 2.00
  O >  There were   23 residues.
  O >              175 atoms.
  O > Do you want to use the display? [Yes]: 
  O >
  O > Making visibility data structures.
  O > Making visibility data structures.
  O > Macro in computer file-system.
 As4> ...... Startup message from Alwyn
 As4> 000226  NEW VERSION
 As4> ....... needs a new menu and rotamer database
 As4> ....... use these files menu.odb and rsc.odb
 As4> ......
 As3> File not found in path: on_startup
 As3> Indirect file does not exist.
The first bits just say that they are setting up ODAT and OMAC and which version you are running. Since you are starting from scratch, O will prompt for the files menu.o, startup.o, access.o and all.dat. Just hit return until it asks if you want to use the display, and hit return once more. Since you're running O v7.01, ignore the whining about the menu.o and startup.o database versions - they are identical even if it doesn't think so.

The graphics window will launch. Congratulations, you've started O. Now comes the tough part.

The Database

O stores most of it's data in a database. This data includes: your coordinates, your skeletons, various settings for the program. It does not include the electron density maps. This database can be loaded into the program at startup:
 % ono binary.o 
This makes O read binary.o on startup - binary.o is the traditional name for a O database. Similarly O saves this database if you type "save" or if you exit the program using "stop". If you type "quit" or hit ESCAPE it will not be saved. WARNING: if you rename a binary.o file it will re-save to the old name if you read it and write it back out from O, because the file name itself is stored in the database. The database is fairly convenient because it saves some aspects of the graphics state between invocations: e.g. the screen center, so you can start up next time where you left off. The downside of the database is that it sometimes gets corrupted. O also crashes fairly often, so it's good to save the database frequently using the save command. If you are doing a lot of building, the only way to ensure you have the revised PDB file is to write the PDB file to disk (pdb_write or sam_atom_out).

The command backup will create a copy of the current database from memory. Sometimes useful.

Doing Something

O is not a substitute for Rasmol, but if you issue the following commands it will quickly read a file into memory and draw a Calpha trace:
pdb_read myfile.pdb test ; ;
mol test ca ; end
(Note that v9 will automatically draw the Calpha trace for the first pdb-read molecule, but apparently not subsequent ones).

This is fairly cryptic. What O does here is reading myfile.pdb into a molecule called test and then creating an object (also called test) from this molecule and display it on the screen as a series of connected Calpha atoms. The semicolons ";" are interpreted by the O parser as meaning "carriage return" i.e. you just accepted the defaults.

pdb_read is the preferred method of reading a PDB file into a molecule. An older (more or less equivalent) command is sam_atom_in. Pdb_read reads the contents of myfile.pdb and shoves them in a molecule called test. Molecules store the actual coordinates, whereas objects are just graphical representations of the molecule. You can give it any molecule name you want, except that the name should be no longer than 6 characters and have no special characters in it. The mol command tells O to take the molecule test, make a graphics object by the same name and draw a Calpha plot. The semi-colon (;) character is equivalent to hitting a return on the command line. O has two basic drawing modes, either "ca" for a calpha trace or "zone" for an all-atom trace. To make more than one representation for a molecule you must give at least one object a different name, otherwise the default object (same name as the molecule) keeps getting overwritten:

mol test obj calpha ca ; end
mol test obj all    zone ; end
This makes two objects from the molecule "test", one is a Calpha trace called "calpha" and the other is an all-atom representation called "all". The commands:
mol test ca ; end
mol test zone ; end
just create an object named "test" (from the molecule of the same name) with an all-atom representation, i.e. the Calpha trace gets overwritten on the second invocation of the mol command because the default object name (test) is the same. This probably isn't what you wanted to do.

In order to see something on the screen you might have to zoom down and translate a little until the molecule is visible. Or use cen-xyz (e.g. cen_xyz 10. 20. 24.) to center on a specific point in cartesian space, or cen-id to click on an atom about which to center, or cen-at to center on a named atom (e.g. cen_at A130). Underscore (_) and hyphen (-) are used interchangably in the new version of O. The full name of cen-at is centre-atom but you can abbreviate it as long as it is unique.

The difference between Molecules and Objects

The coordinate data that you read into O is stored in the database as a molecule. Nothing is drawn on the screen when you create a new molecule. The graphics items associated with molecules are called objects. Multiple objects can be created from each molecule, but each object is only associated with one molecule. Note that when a molecule changes (e.g. you move an atom or residue) the object usually updates the reflect the changes. However in some cases (e.g. where covalent connectivity changes, on mutation or deletion) you must redraw the object for the change to be seen. The mutate_replace and mutate_delete commands delete the objects associated with a molecule if you modify the molecule, so you need to recreate them after each mutation/deletion.

Graphics manipulation

The O window looks like this:

at the very top the ">" symbol indicates that you can type text into the screen and it will interpret it as a command. The next line is a message line and the next line is an info line. Below that are the pull-down menus (Controls, Display etc...).

To pull down the menu click the left mouse button on the text. To deselect the menu click elsewhere in the screen. Lower left on the window is the mapping of commands to the dials box. If you don't have a dials box you can use the "Fake Dials" option in the "Menu" menu. The right mouse button also maps to these dials:

Mouse Modifiers Movement Usual mapping
Right none Up/Down Rotate X (horizontal axis)
Right none Left/Right Rotate Y (vertical axis)
Right+Middle none Left/Right Rotate Z (pointing at you)
Right CTRL Left/Right Translate X
Right CTRL Up/Down Translate Y
Right+Middle CTRL Left/Right Translate Z
Left+Middle none Up/Down Zoom
Left+Middle none Left/Right Slab
Left none just click Picking

The CTRL-mouse movements actually map to the commands associated with certain dials positions (namely lower right). Thus typically you use CTRL-mouse to move or rotate a fragment by flipping through alternative sets of dials commands using the O commands dial_previous and dial_next. Note that the mouse movements changed somewhat between O verion 5 and O version 6. A lot of things changed between version 5 and version 6.....

O provides to other useful menus: the object menu and the user menu. Both are accessed from the O "Menus" window. If you pull the Object menu up it looks something like:

(depends what you have loaded, here the objects CA, DI, SKEL amd BTN are all turned off)

If you click on that small square at the top left of the menu, the menu will stick around, not disappear like the other menus after a command is completed. If you click on that (top left) box once more the menu vanishes again. Once the menu is posted a box at the top right of each menu allows you to move the menu around after you click on it.

The same thing lets you post the Fake Dials menu, the User Menu and indeed any of the other menus in O. Mostly Objects, User and Fake Dials are the only ones you might want. You can add or delete commands from the user menu using "menu command". You can insert macros (a filename preceded by an @ will be read in and executed) and O commands into the user menu. A common ploy is to build a database with your favorite commands in the user menu, then save this database and copy it as a template for use later. My one is ~phil/O7_binary.o. Copy this to binary.o in your directory and use it, if you want. Remember that the SGI database cannot be used under Linux and vice versa.

The following function keys are defined:

Expert users might consider redefining the on_escape macro to avoid the latter indesirable behavior.

Moving around

Note that cen-atom by default centers on a residue in the most recently created molecule, and on the Calpha atom within that residue. Thus you may need to specify the molecule explicitly or the atom explicitly (or both):
Cen-atom dna D1 P
centers on atom P of residue D1 within molecule dna. Most of the time something like:
Cen-atom D100
will work since it centers on the Calpha atom of residue D100 in the most recently declared molecule. BEWARE: if you have multiple residues in your molecule with the same number/chain, then O will always center on the first one in the PDB file, even if you click on the desired one on the screen.

Drawing Electron Density Maps

I traditionally create an O macro file "maps.omac" which contains something like the following commands:
map_file mad_dm2i.omap 

map_obj mad_l
map_param 40 40 40 0.7 steel_blue ; ;

map_obj mad_m
map_param 40 40 40 1.0 red ; ;

map_obj mad_h
map_param 40 40 40 1.5 green ; ;

Which specifies three contour levels (0.7, 1.0, 1.5) of the MAD map in a box of 40 Angstroms on each edge. I can then invoke this macro by typing "@maps.omac" or by including this command in the User Menu within O. Basically the commands do the following:

Your map format must be in BRIX/DSN6 format, typically generated by a program like MAPMAN (6d_mapman on SGI, lx_mapman on Linux). For CCP4 maps:

6d_mapman << EOF
read m1 2fofc.ccp4 ccp4
norm m1
brix m1 2fofc.omap
and for CNS maps
6d_mapman << EOF
read m1 cns
norm m1
brix m1 2fofc.omap

Drawing Electon Density Maps - Fast Map commands

These are a group of new commands that work with electron density maps. They differ from the map_* and rsr_* commands in what they do and how they do it. When a user works with these commands, the electron density map is kept in computer memory, and will remain there until it is explicitly removed, or the program stops. If the user defines the space group, and provides a crystallographic asymmetric unit, one can work anywhere in space, i.e one is not limited to be within the volume of defined by the map envelope.

Fm_file can read the old DSN6 (brix) format, but also CCP4, CNS, TNT and EZD formats. To define the file, try doing:

fm_file 2fofc_3.omap q1
(Things seem to work better if you use one of the predefined map names). There are a total of five possible maps (Q1-Q5). Then do fm_setup to define the number of contour levels, their level and color etc. Then do fm_draw to draw the map initially. The map parameters may be dynamically modified using the Density pull-down menu on the screen by clicking on the specific map (e.g. Q1).

On program restarts, the user needs to redefine the file being worked with (command fm_file) and ,in the case of contouring, the parameters being used (fm_setup). This can be done with the on_startup macro, for example.

Some of the commands are used for real time contouring of electron densities, some for real-space refinement of models into density, one for secondary structure identification, one for secondary structure building, and one assisting in determining the chain directionality.

The Fm contouring commands should, in general, replace contouring with the Map_* and Qmap_* commands. However, at present, the Fm contouring commands cannot generate crystallographically symmetry-related electron density, and require that the envelope of density covers the molecule of interest. At present, the levels used in Fm are in sigma units, so if one needs to contour at an absolute level, you need to do some arithmetic (this will change).

The Fm RSR commands do not subtract neighbouring atoms from the density before refinement. Residue based goodness of fit indicators are not yet available.

Summary of Fm commands:


Until a very recent epiphany concerning the use of Baton to build structures (see below), I generally adhered to the "cheap, fast and out of control" method of building polypeptide chains. I would identify parts of the structure that look like (e.g.) beta sheet, find where they were in (x,y,z), translate an arbitrary piece of beta sheet, rebuild it and then write it out and append it to my model. Thus each piece of secondary structure was cobbled together into a resultant PDB file. Connecting these pieces up was a somewhat time-consuming process including copy, paste and editing the coordinate locations by hand. What I describe here is a bunch of commands that I use to do this.

Firstly, bones or map skeletonization, is often useful to navigate your way around a map before you've built a partial model. In good maps it can reveal the molecular boundary too. Make bones within MAPMAN:

~xtal/bin/6d_mapman << EOF
read map mad_dm.ccp4 ccp4
norm map
bones skel map 0.9 0.9 100
bones connect bones.odb skel 5
quit yes
This creates the bones data with the name "skel". Read this into O using:
read bones.odb

1 3

This defines the bone object as "skel" and tells O you want to draw 60 Angstrom radius with levels 1 and 3. Type bone_draw to draw the bones around the current center.

Use centre_id to center on bones atoms. Draw the map(s) at your current location (@maps.omac macro, as given above). Use a simple program like PEEK2 to move your structural template to somewhere close, then pdb_read (or sam_atom_in) the file into O. In the early stages of tracing I nearly always just display a Calpha trace.

pdb_read myfragment.pdb frag1
mol frag1 obj frag1 ca ; end
I move and manipulate the coordinates using the move commands (move-zone, move-atom) and reduce the violence I have done to their geometry with the lego commands (e.g. lego-ca, lego-side). I do some additional tweaking with mutate commands (mut-rep).

move_zone lets you move whole ranges of residues, useful to get the fragment close to where you want to start. Then move_zone can move single residues if you click twice on the same Calpha atom. I just move the Calpha to where I think it will sit and hit "yes". Then I move the next Calpha in the chain. I think this method is equivalent to doing move_atom on a Calpha trace, but the former moves the entire residue while the latter moves just the Calpha.

Once you have moved all the Calphas into place, do lego_ca and select the first and last amino acid of the stretch you want to regularize. Lego-ca works by finding similar Calpha arrangements in a database of well-refined protein structures. They can essentially put good geometry for the backbone in for a piece of structure that you've built just on the Calpha atoms. This is an exceptionally fast way to proceed. If the stretch that you've rebuilt in your fit of enthusiasm is long, do lego_auto_mc which fits whole stretches in pieces - the local fit is often better.

Write your newly-built piece of backbone out and append it to your existing "best" model. The simple program PEEK2 (~phil/bin/peek2) will let you do that sort of thing and also other convenience things like changing chain labels and renumbering, somewhat frequent actions during rebuilding.

Sometimes you will want to trim the ends of your fragments, and for this you want to use mutate_delete. Use this with care and make sure you are deleting the right residues from the right molecule within O (this being a rather common mistake). I build poly-Alanine traces at first but later on when you do side-chain interpretation you will want to use mutate_replace to change the amino acid sequence to reflect the real one. The displayed object gets deleted each time you mutate, so you have to redraw it each time. If this gets tedious I create a "draw.omac" macro file containing my draw commands and stick it in the User Menu as @draw.omac. The command mutate_insert should let you insert residues into your sequence but I've rarely used it.

Once you have built an approximate backbone trace, you will want to go back and redraw the model in full atom representation. Go through the model one residue at a time and by careful application of move_atom and move_zone you should adjust the residue positions as carefully as possible. The Lego commands will help if you end up doing a fair amount of main-chain modification (lego_loop, lego_ca). Calpha atoms should be 3.8 Angstrom apart. If they differ much more than that you're probably going to have problems during the initial stages of refinement.

Eventually you will want to change the sequence. Do mutate_replace to change the identity and then lego_side to scroll through the list of possible rotamers for the residue. Rotamers are preferred orientations for side-chains based on empiricism and stereochemical considerations. Things like Leu are nearly always found in or near rotameric conformations. Things like Arg are found in pretty much any physically reasonable orientation. The command tor_residue lets you change the dihedral angles (including the main-chain phi and psi) angles for the residue, and is also useful when fine tuning your model.

I have never come up with a spectacularly efficient way of connecting secondary structure fragments to each other. What I tend to do is edit the PDB file using an editor like jot, copying and pasting little PDB fragments, shifting the coordinates manually so they don't overlap on existing parts of the model. Then I read the model back in, use move_zone to move the residues, and lego_ca to regularize geometry. Probably careful use of mutate_insert and lego_loop could probably speed this process up considerably. Anyone got good methods for this ?

Refinement will go much more smoothly and your R-free will be much lower if you spend time tinkering with your model using the above commands and make it fit the experimental electron density as closely as possible before dropping the whole thing into REFMAC or CNS.

Crystal Symmetry

A traditional problem with building structures is building the same, but symmetry-related, thing twice (or more, if you're really unlucky). Therefore at various points in building one should display symmetry related molecules. This is done fairly easily in O, using the symm commands.

symm_set defines the symmetry for the molecule. Symm_set prompts you for the molecule name, the cell dimensions, and the space group. O seems to spend a lot of time forgetting the space group. O often manages to read the cell dimensions from PDB file headers (and sometimes the space group too).

symm_obj is the display command I find the most useful. It requests the name of an object that is being displayed - typically a Calpha trace, and a radius for checking for symmetry-related molecules. It also asks for the name of the object to be created (I usually call it symm). Symm_obj concatenates all symmetry related copies of the original object into this new object, meaning that you can simply toggle the whole thing on and off in the object menu.

By contrast symm_sphere takes basically the same arguments as symm_obj but it draws each symmetry-related molecule as a separate object. Sometimes this is useful, and sometime this involves wrangling a rather large number of new objects. Use whichever command suits your style best.

Faster building methods - Baton

Baton is a faster way to build backbone than the "cut and paste" method I outlined above and works very well on good maps where you can clearly see the Calpha positions. (Calpha positions are points in the main-chain where the side-chain brances off - center the Calpha in the middle of the backbone "tube" centered underneath the branch-off point).

To supplement the somewhat minimal description on the O website... Baton is a simple yet powerful main-chain building algorithm that lets you construct protein chains very quickly by use of a 3.8 Angstrom "baton" which maps to the standard Calpha-Calpha distance in a protein. You need to do a few preparatory steps: define the sequence, initialise the molecule, load the dipeptide. Then just build. By default, the object BTN will contain the molecule that you are building in BTN, so you shouldn't have another molecule by that name in the database. Similarly, DI is the name of the baton itself, so you don't want your own object to have that name either.

First, put something like this in a file called "sequence.o" to define the amino acid sequence. Typically it will be poly-Ala like below. The name "BTN_RESIDUE_TYPE" defines a sequence for the molecule BTN. You should then use this name for the subsequent commands (as in this example). Here is the contents of sequence.o:

BTN_RESIDUE_TYPE         C         100 (1x,5a)             
 ALA   ALA   ALA   ALA   ALA   
 ALA   ALA   ALA   ALA   ALA   
 ALA   ALA   ALA   ALA   ALA   
 ALA   ALA   ALA   ALA   ALA   
 ALA   ALA   ALA   ALA   ALA   
 ALA   ALA   ALA   ALA   ALA   
 ALA   ALA   ALA   ALA   ALA   
 ALA   ALA   ALA   ALA   ALA   
 ALA   ALA   ALA   ALA   ALA   
 ALA   ALA   ALA   ALA   ALA   
 ALA   ALA   ALA   ALA   ALA   
 ALA   ALA   ALA   ALA   ALA   
 ALA   ALA   ALA   ALA   ALA   
 ALA   ALA   ALA   ALA   ALA   
 ALA   ALA   ALA   ALA   ALA   
 ALA   ALA   ALA   ALA   ALA   
 ALA   ALA   ALA   ALA   ALA   
 ALA   ALA   ALA   ALA   ALA   
 ALA   ALA   ALA   ALA   ALA   
 ALA   ALA   ALA   ALA   ALA   
If you change the number of ALA lines, change the "100" in the above script to reflect the total number of ALA entries you are reading. Then execute the following series of commands to import this sequence, and initialize a molecule called BTN which will have this sequence. Then draw an object of name CA with the BTN structure (which does not exist so far). The object name CA is special, in that Baton updates this object as you build.
read sequence.o
sam_init btn
mol btn obj ca ca ; end
Now, read the di-peptide model and draw it. This is the template dipeptide that you move around during chain building.
read di.o
mol di ca ; end
Now center on one Ca away from where you want to start building, or indeed anywhere near where you want to start building. Baton effectively throws away the first position, and you might as well start where you want to. Launch the baton_build command:
The red-green bar that is the dipeptide will move to where you centered, with the red end at the display center. Use FRAG_MOVE and FRAG_ROT dials to move and rotate the peptide. Flip between these two dial sets using the DIAL_NEXT and DIAL_PREVIOUS commands. O will put a new Calpha position at the green end of the dipeptide if you hit YES. It will then translate the baton so that the read end of the baton sits where you just created the new Calpha.

My ploy is as follows: start by putting the green end of the dipeptide at the position of the first Calpha using FRAG_MOVE. Hit YES. The dipeptide translates so the red end is on the Calpha you just built. Note that the Calpha trace for BTN is updated (there is often one atom at the 1500,1500,1500 - don't worry about that - it'll be off the screen). Then use FRAG_ROTZ (and other rotations if you want) to put the green end of the dipeptide where the next Calpha will be. Hit YES again. Lather, rinse, repeat. With a good map I can get an approximate chain trace very fast with this method. From time to time (4-5 Calphas) I have to use the FRAG_MOVE dials to tweak the next Calpha position back into register.

To terminate building hit NO, and the write out your new coordinates using pdb_write or sam_atom_out (you want to write out the molecule BTN):

s-a-o frag1.pdb btn ; ; ; ;

You've only built Calpha's here but you can generate the backbone trivially using LEGO_CA or LEGO_AUTO_MC.


If you have a file called on_startup in the current directory, then O will execute it as a macro when starting. This can be very useful when working with Fast Maps (Fm_ commands) since you need to redefine the maps each time. For example you could put:
fm_fil ../CNS/ F P6122
fm_set ; 20 ;; 2.5 red
fm_dr ;

fm_fil ../CNS/ 2F P6122
fm_set ; 20 ;; 1.0 blue
fm_dr ;

window_open object_menu -1.40  1.00
window_open dial_menu   -1.40  0.20
window_open user_menu    1.10  1.00
win_open density_1       0.80 -0.35
win_open density_2       0.80 -0.68
In your .startup file and it configures two existing fast-map maps, plus opens five menus at pre-determined points. Cute huh ?

Fixing the SLAB in O

Sometimes O gets a little confused about the slab value. The relatively simple fix for this is to simply write out it's value, reset it and read it back in. The slab value is the 28th value in the datablock .gs_real. Write it out using:
write .gs_real gs_real.o ;
Now edit the file, changing the last number on the last line to 0.5 while preserving the formatting (e.g. 0.50000E+00 with the appropriate spacing) and then read it back into O:
read gs_real.o
Note that "write" and "read" are short for write_formatted and read_formatted respectively and should not be confused with pdb-write and pdb-read.