More Examples

See the Release Notes for the latest changes. This document describes version 2.0, which will be released shortly.  The tutorial has not yet been updated to this version.


Many programs consist of a set of steps that can be thought of as representing the evolution of the calculation in time. PyHistory is a Python language facility enabling the user of a Python program to create a series of samples, at different times, of the values of Python expressions. Such a series is called the history of the expression, and each expression whose history is to be taken is called an item. The simplest item can be thought of as the name of a variable whose values are to be collected.

The user may choose a particular medium in which the history will be collected. Five interesting media that are provided are:

  1. TextFile, a text file containing a series of records. Each record contains item names and the sampled values.
  2. ColumnarFile, a variant of TextFile in which the item histories appear as columns, with the first line containing the names of the items.
  3. Memory, in which the history is kept in memory.
  4. Event, which does nothing! The Event medium is used to support the event tag, which triggers actions at predetermined times or when certain conditions are detected.
  5. PDBfile, a file in the Pact/PDB format. These are self-defining portable binary data files invented by S.A. Brown of Lawrence Livermore National Laboratory. Pact is required to use PDBfile; it is available from ftp://west.llnl.gov at no charge.

A tag is a group of items which are to be stored in a particular medium, and sampled at the same times. A tag is the basic unit that the user deals with, and in fact most users will deal mostly with the interface of class Tag. A tag contains:

A condition governing the frequency at which the tag is collected.
A logical condition governing collection, allowing the samples to be taken only if certain expressions are true.
A medium to which it is to write the samples.
A collector with which it is to register itself when it is created. A standard collector is provided by default. The collector object is then called repeatedly, at the end of each "time step", with the current cycle number and time as arguments. The collector in turn tests each tag registered with it, and collects samples from those whose conditions and logical conditions are in an appropriate state. A collector can also test each tag for an appropriate alternate state that is designed to be used to collect final samples at the end of the program, even if the particular frequency of collection for that tag would normally not correspond to the current time.This is done to ensure that the range of the sampled data covers the full time of the computation.

A user creates one or more tags, usually via a function that creates the tag with a certain medium. Then, the user adds items to each tag and sets the frequency of collection and possibly the logical condition desired for that tag. Finally, the program calls the sample method of the standard collector object at the end of each time step, and the sample_final method at the end of the calculation.


In this example, a single tag named tag1 is created that will be stored in a text file. (Since the file name is not specified, textfile_tag calculates it as history_tag1.txt.) The tag has two items named "x" and "y" and will be sampled every 5 cycles beginning at cycle 10 and ending at cycle 50 (inclusive). However, samples will only be taken if the expression "x > 1.4" is true. An additional time-invariant item "s" will be collected only once at the first opportunity.

from history import *
mytag = textfile_tag ("tag1")

mytag.item ("x")
mytag.item ("y", "x*x")
mytag.item_static ("s", "'hello world'")
mytag.frequency (10, 50, 5)
mytag.when ("x > 1.4")          
for i in range (100):
    x = .2 * i
    time = i/10.
    cycle = i
    collector.sample (cycle, time)
collector.sample_final (cycle, time)          

You may never need to go beyond the interface shown here. However, if necessary you can create new media, create complicated conditions governing the collection of tags, and use the package to call functions rather than collect items.

To use Pact/PDB files in this example, rather than a text file, we would simply change the first two lines to:

from pdb_history import *
mytag = PDBfile_tag ("tag1")          

Installation and Use

LLNL's set of Python extensions is available at no cost. The package, including this documentation, has been released for free redistribution by the Regents of the University of California. Please see the legal notices in the source files for details.

To obtain PyHistory, ftp://ftp-icf.llnl.gov/pub/python/LLNLDistribution.tgz. Unzip and untar it to get a directory tree rooted at LLNLDistribution. PyHistory is a subdirectory of this directory.

PyHistory itself contains only Python source files. There is no C extension to build. To add the PyHistory package to your program, place its Python source files somewhere in the search path of the application. They can be added to the python lib directory, for example.

If you wish to use pdb_history.py, you must install the PyPactPDB package and PACT. This is explained in the PyPactPDB documentation.

The history package itself consists of these modules:

history.py -- defines class Tag, and the standard collector, and four functions for creating various kinds of tags: memory, text file, columnar file, and event.
history_collector.py -- defines class HistoryCollector, containing the sample method.
history_medium.py -- defines HistoryMedium and its heirs Textfile, Event
history_condition.py -- defines HistoryCondition and its heirs such as Times, Cycles, TimeList, CycleList, When, And, Or, and Not.
history_item.py -- defines Item, the basic expression to be sampled and its context.
context.py -- contains a utility function used to resolve different ways of expressing context into an actual dictionary. A context is the global context dictionary that will be used to evaluate the expression in an item.

In addition there are modules defining optional media:

pdb_history.py -- Function PDBfile_tag can be used to define a PDBfile history-medium based tag.

Each of the modules contains a test routine, and there are several stand-alone test routines.

Learning to Use PyHistory

Reading the section PyHistory -- A More Elaborate Example is the best way to learn to use PyHistory. If you decide to use the PactPDB modules, you will need to read the documentation for PyPactPDB to learn how to read the files it produces with Python, PDBView, or Yorick. (See the module PR.py in PyPactPDB).  There is also a tutorial set of viewgraphs available. (Acrobat 3 Format).

Please see the Legal Disclaimer.

UCRL-12859, Part 3