4. misc

Code for various useful things that don’t fit anywhere else. Currently this includes:

  • Automatically printing the status of long loops
  • Grouping number arrays by id or generating neighbor lists effiently

4.1. Example Usage

The StatusCounter class can be used either directly as an iterator, or can be explicitly created and then iterated over. The latter approach also allows outputing a variable message during the computation.

from ilpm import misc
import numpy as np
import time

#These are the values over which we are going to compute stuff.
values = np.linspace(0, 1.0, 10000)


#Use the status counter as an iterator -- this automatically prints the
#  status message as we loop!
for val in misc.StatusCounter(values, 'Squaring stuff...'):
    square = val**2 #Do something
    time.sleep(1E-3) #This something is too fast, so lets slow it.


#Create it as a named object so we can change the print message
stat = misc.StatusCounter(values, 'Squaring stuff...')
for val in stat:
    square = val**2 #Do something
    stat.message('%.3f -> %.3f' % (val, square)) #Print the result as we compute.
    time.sleep(1E-3) #This something is too fast, so lets slow it.

The first loop outputs the following message as it is computing:

Squaring stuff... 49% (0:00:05 remaining)

The second includes an ongoing status message, e.g.:

Squaring stuff... 49% (0:00:05 remaining)  [0.498 -> 0.248]

4.2. Overview

StatusCounter(count[, msg, min_time]) A class for printing status messages for long computations.
GroupById(ids[, values, missing]) Create an object which returns the values of objects with a given id.
NeighborList(cutoff, points) Generate a object for finding point neighbors quickly.

4.3. Classes

class ilpm.misc.StatusCounter(count, msg='Calculating...', min_time=0.03333333333333333)[source]

Bases: object

A class for printing status messages for long computations.

Parameters:

count : int or iterable object

The number of items or the items over which to iterate.

msg : string

The status message

min_time : float, optional (default: 1./30)

The minimum time before a new mssage is printed. Used to prevent very fast updates from slowing down computations (print to stderr can be slow!)

Methods

message(msg) Change the print message during a computation.
next()
print_msg(msg[, final]) Print the message (usually handled automatically.)
update([extra_msg]) Increment the counter manually (usually handlded automatically.)
message(msg)[source]

Change the print message during a computation.

print_msg(msg, final=False)[source]

Print the message (usually handled automatically.)

update(extra_msg='')[source]

Increment the counter manually (usually handlded automatically.)

class ilpm.misc.GroupById(ids, values=None, missing=None)[source]

Bases: object

Create an object which returns the values of objects with a given id.

After it is created, behaves like a dictionary object which returns numpy arrays of values with varying length, where missing values return the value specified in missing.

Items may also be accessed with lists or arrays of ids.

  • Lists of keys return lists of numpy arrays
  • Arrays of keys return a concatenated array of the values

Example usage:

from ilpm import misc, vector

#Create some random points
X = (np.random.rand(100, 3) - 0.5) * 10

#Our id is going to be numbered by radial shell, e.g. a point with radius
#  r=5.2... will have id 5.
ids = vector.mag(X).astype('i')

#Make the group
X_by_r = misc.GroupById(ids, X)

#Lets see whats in there.
for ir in sorted(X_by_r.keys()):
    X = X_by_r[ir]
    r = vector.mag(X)
    print 'key: %d, %2d values ranging from r = %.2f - %.2f' % (ir, len(r), r.min(), r.max())

#What if we wanted all particles with radii from 2-5?
ids = np.arange(2, 5)
X = X_by_r[ids]
r = vector.mag(X)
print 'keys: %s, %2d values ranging from r = %.2f - %.2f' % (repr(ids), len(r), r.min(), r.max())

Sample output:

key: 1,  2 values ranging from r = 1.45 - 1.65
key: 2,  2 values ranging from r = 2.35 - 2.96
key: 3, 17 values ranging from r = 3.00 - 3.93
key: 4, 23 values ranging from r = 4.11 - 4.99
key: 5, 32 values ranging from r = 5.03 - 5.90
key: 6, 18 values ranging from r = 6.05 - 6.97
key: 7,  6 values ranging from r = 7.13 - 7.75
keys: array([2, 3, 4]), 42 values ranging from r = 2.35 - 4.99 
Parameters:

ids : 1D numpy array

A list of id’s.

values : (len(id), ...) numpy array, optional

The value which correspond to each id. If not specified, indices are returned instead of values (i.e. value = arange(len(id)))

missing : any object, optional (default: empty numpy array)

The default value to return if there are no objects with this id. If not specified, returns an empty numpy array with the same data type as values.

Methods

keys() Return the keys which have items in them.
keys()[source]

Return the keys which have items in them.

class ilpm.misc.NeighborList(cutoff, points)[source]

Bases: object

Generate a object for finding point neighbors quickly.

Note: using this class is only faster than brute force for > 1000 points. However, for very large numbers of points (> 10,000) it is quite fast.

Parameters:

cutoff : float

The default radius to consider a particle a “neighbor”. Although different radii may be requested later, this sets the box width for the cell-list, so optimially it is the average required radius. Note: the cutoff should be more than 2**20 ~ 1E6 times the total separation.

points : vector array

Points to put in the list

Methods

indices_within_r(P0[, r]) Return the indices of all points within a specified radius.
indices_within_r(P0, r=None)[source]

Return the indices of all points within a specified radius.