Commits

Stefan Scherfke committed 04c4ed8

Finished the documentation

Comments (0)

Files changed (4)

collectors/storage/pytables.py

         
         """
         return self.h5file.createEArray(self.group, name,
-                tables.Atom.from_kind(self.dtypes[index]), (0,))
+                tables.Atom.from_sctype(self.dtypes[index]), (0,))
 How to use *Collectors* with *SimPy*
 ====================================
 
-foobar
+If you have read and understood the previous sections, you won’t have any trouble using *Collectors* to monitor your simulation processes.
+
+We’ll now discuss two examples that show different ways *Collectors* can be used: You can either use one collector instance per process or let one instance monitor multiple processes at once.
+
+You should one collector per process if each process belongs to another class or if each process collects its data at another time. If your processes are all instances of the same class and if each instance collects data at the same time, you only need to use one collector instance. That might save you some memory.
+
+
+One collector per process
+-------------------------
+
+In the following example a :class:`~SimPy.Simulation.Process` is created. In
+each step, it generates some random numbers and then holds for a random amount
+of time (that’s why we need one collector per process here).
+
+The process also creates one collector (``self.monitor``) which will collect the
+simulation time, the values for ``a`` and ``b``, the manually passed values for
+``diff`` and finally the square of ``c``. The resulting collector instance will
+thus have the attributes ``time``, ``a``, ``b``, ``diff`` and ``square``.
+
+After the simulation has finished, `NumPy <http://numpy.scipy.org/>`_ arrays
+will be created and show how you can easily work with them or create some charts
+using `Matplotlib <http://matplotlib.sourceforge.net/>`_.
+
+    >>> import random
+    >>> 
+    >>> import matplotlib.pyplot as plt
+    >>> from numpy import array, float64
+    >>> from SimPy.Simulation import Simulation, Process, hold
+    >>> 
+    >>> from collectors import Collector, get, manual
+    >>> 
+    >>> 
+    >>> class MyProc(Process):
+    ...     def __init__(self, sim):
+    ...         Process.__init__(self, sim=sim)
+    ...         self.a = 0
+    ...         self.b = 0
+    ...         self.c = 0
+    ...
+    ...         self.monitor = Collector(
+    ...             ('time', sim.now),
+    ...             get(self, 'a', 'b'),
+    ...             ('diff', manual),
+    ...             ('square', lambda: self.c ** 2),
+    ...         )
+    ...
+    ...     def run(self):
+    ...         while True:
+    ...             self.a += random.random()
+    ...             self.b += random.randint(1, 2)
+    ...             self.c += random.randint(2, 4)
+    ...
+    ...             self.monitor(diff=self.c-self.b)
+    ...
+    ...             yield hold, self, random.randint(1, 4)
+    ... 
+    >>> # Run the simulation
+    >>> random.seed(42)
+    >>> sim = Simulation()
+    >>> proc = MyProc(sim)
+    >>> sim.activate(proc, proc.run())
+    >>> sim.simulate(until=10)
+    'SimPy: Normal exit'
+    >>> 
+    >>> # NumPy helps you with the statistics and other calculations.
+    >>> # Note: specification of dtype gives you a massive speed-up!
+    >>> a = array(proc.monitor.a, dtype=float64)
+    >>> # NumPy: average, std. deviation, variance
+    >>> print 'a stats:', a.mean(), a.std(), a.var()
+    a stats: 2.04867732762 0.947900129333 0.898514655189
+    >>> 
+    >>> # This one creates a multi-dimensional array
+    >>> np_mon = array(proc.monitor, dtype=float64)
+    >>> # Get the average of all monitored proc.b
+    >>> print 'b stats:', np_mon[2].mean()
+    b stats: 5.57142857143
+    >>> # Get the std. deviation of all monitored proc.c
+    >>> print 'c stats:', np_mon[3].std()
+    c stats: 3.09047252183
+    >>> 
+    >>> # Matplotlib plots your data:
+    >>> # Either directly from a monitor ...
+    >>> p = plt.plot(proc.monitor.time, proc.monitor.a, 'b')
+    >>> # ... or the NumPy array
+    >>> p = plt.plot(np_mon[0], np_mon[2], 'r')
+    >>> plt.show()
+
+
+One collector for multiple processes
+------------------------------------
+
+This example shows a very simple process whose PEM will be executed each time
+step. This enables us to use one collector instance to monitor the attribute
+``a`` of all processes and the simulation time.
+
+We also use SimPy’s brand-new :meth:`~SimPy.Simulation.Simulation.peek` and
+:meth:`~SimPy.Simulation.Simulation.step` methods here which will be introduced
+with version 2.1.
+
+    >>> from SimPy.Simulation import Simulation, Process, hold
+    >>> from collectors import Collector, get_objects
+    >>> 
+    >>> class MyProc(Process):
+    ...     """docstring for MyProc2"""
+    ...     def __init__(self, sim, pid):
+    ...         Process.__init__(self, sim=sim)
+    ...         self._pid = 'p%d' % pid
+    ...         self.a = 0
+    ...         
+    ...     def run(self):
+    ...         while True:
+    ...             self.a += 1
+    ... 
+    >>> sim = Simulation()
+    >>> procs = [MyProc(sim, i) for i in range(10)]
+    >>> for proc in procs:
+    ...     sim.activate(proc, proc.run())
+    ...     
+    >>> # This coll. will have the attributes "t", "p0_a", "p1_a", ..., "p9_a"
+    >>> # and monitor the simulation time as well as the values of "a" for each
+    >>> # process.
+    >>> monitor = Collector(('t', sim.now), get_objects(procs, 'pid', 'a'))
+    >>>     
+    >>> # Run the simulation by using the band-new "peek()" and "step()".
+    >>> while sim.peek() < 10:
+    ...     sim.step()
+    ...     monitor()

docs/storages.txt

     $ make
     $ sudo make install
     
-3. Finally install *PyTables*
+3. Finally install *PyTables:*
 
 .. sourcecode:: bash
 
     ...     b = 2
     ...
     >>> spam = Spam()
-    >>> h5file = tables.openFile('example.h5', mode='w')
+    >>> h5file = tables.openFile('/tmp/example.h5', mode='w')
     >>>
     >>> collector = Collector(get(spam, 'a', 'b'),
     ...         backend=storage.PyTables(h5file, 'spamgroup', ('int', 'int'))
 HDF5 file.
 
 You also need to specifiy the data types of the observed variables. They must be
-passed as list of strings (like e.g. ``'int'``, ``'float'`` or ``'string'``, see
-`here <http://www.pytables.org/docs/manual/ch04.html#id343491>`_ for more
-details).
+passed as list of strings (like e.g. ``'int'``, ``'float'`` or ``'bool'``, see
+the `NumPy Docs <http://docs.scipy.org/doc/numpy/reference/arrays.scalars.html
+#built-in-scalar-types>`_ for more details).
 
 The *series* are now `EArrays
 <http://www.pytables.org/docs/manual/ch04.html#EArrayClassDescr>`_ instead of
 simple lists. The ``read`` function returns the complete series for that
-variable as a NumPy array.
+variable as a NumPy array so you can do further calculations on them very fast.
+
+
+MS Excel
+--------
+
+The :class:`~collectors.storage.excel.Excel` storage allows you to store your
+data directly in an Excel file.
+
+To use this storage backend, you need to install ``xlwt`` (like “Excel
+Write”—``xlrd`` (“Excel Read”) can be used to read from an Excel file):
+
+.. sourcecode:: bash
+
+    $ sudo pip install xlwt
+    
+Example
+^^^^^^^
+
+    >>> from xlwt import Workbook
+    >>> from collectors import Collector, get, storage
+    >>> 
+    >>> w = Workbook()
+    >>> 
+    >>> class ObserveMe(object):
+    ...     pass
+    ... 
+    >>> obj = ObserveMe()
+    >>> c = Collector(get(obj, 'value_a', 'value_b'), 
+    ...         backend=storage.Excel(w, 'my collected data'))
+    >>> 
+    >>> for a, b in zip(range(10), reversed(range(10))):
+    ...     obj.value_a, obj.value_b = a, b
+    ...     c()
+    ... 
+    >>> w.save('/tmp/example.xls')
+
+Using the the Excel storage is quite easy. Just create a new ``Workbook`` and
+pass it with a name for the sheet to :class:`~collectors.storage.excel.Excel`
+constructor. Alternatively, you can create a sheet with
+``workbook.add_sheet('name')`` and pass the sheet instance instead of a string
+with the sheet’s name.
+
+When you are done collecting data, save the Workbook to a file by calling its
+``save()`` method.
+
+
+What’s next?
+------------
+
+*Collectors* was originally developed to use it with `SimPy
+<http://simpy.sourceforge.net/>`_, so we’ll show how both packages can be used
+together in the next section.
+

examples/examples.py

     # ... or the NumPy array
     plt.plot(np_mon[0], np_mon[2], 'r')
     plt.show()
+    
+def simpy_example2():
+    from SimPy.Simulation import Simulation, Process, hold
+    from collectors import Collector, get_objects
+    
+    class MyProc2(Process):
+        """docstring for MyProc2"""
+        def __init__(self, sim, pid):
+            Process.__init__(self, sim=sim)
+            self._pid = 'p%d' % pid
+            self.a = 0
+            
+        def run(self):
+            while True:
+                self.a += 1
+
+    sim = Simulation()
+    procs = [MyProc2(sim, i) for i in range(10)]
+    for proc in procs:
+        sim.activate(proc, proc.run())
+        
+    # This collector will have the attributes "t", "p0_a", "p1_a", ..., "p9_a"
+    # and monitor the simulation time as well as the values of "a" for each
+    # process.
+    monitor = Collector(('t', sim.now), get_objects(procs, 'pid', 'a'))
+        
+    # Run the simulation by using the band-new "peek()" and "step()" methods.
+    while sim.peek() < 10:
+        sim.step()
+        monitor()
 
 def storage_release_example():
     print 'Storage release example (this is really more of a test)'
         b = 0
 
     obj = ObserveMe()
-    h5file = tables.openFile('example.h5', mode='w')
+    h5file = tables.openFile('/tmp/example.h5', mode='w')
     collector = Collector(get(obj, 'a', 'b'),
             backend=storage.PyTables(h5file, 'groupname', ('int', 'int'))
     )
     h5file.close()
 
 def excel_example():
-    print '- Excel example'
-
     from xlwt import Workbook
-
     from collectors import storage
 
     w = Workbook()
         obj.value_a, obj.value_b = a, b
         c()
 
-    print 'Writing result to example.xls'
-    w.save('example.xls')
+    w.save('/tmp/example.xls')
 
 if __name__ == '__main__':
     simpy_example()