Python tips and tricks
Contents:
Something equivalent to the IDL "where" procedure
There are (at least) two possibilities with Python to extract an array of indexes from an array - which is what the IDL "where" procedure does, or to do some very basic operations on the elements of an array which match a given condition.
- to get an array of indexes where the elements of an array A match a condition, one can use the nonzero() function
- to do something like set to a given value the elements of an array B corresponding to those of an array A matching a condition, one can use the choose() function

These two different ways are illustrated in the following example.

# *******************************************************************
from random import *
from Numeric import *

# generate data
size_array = 20
random_array = zeros(size_array)        # type: int
for i in range(size_array):
  random_array[i] = uniform(0,10)       # random values between 0 and 10

# it's possible to build an array of indexes corresponding to
# elements which match a given condition (here: greater than 5)
# by using the nonzero() function:
bad = nonzero(greater(random_array,5))

# then to do something like set the corresponding flags
# to -1, I didn't find how to avoid using a loop
flags = ones(size_array)
for num_bad in bad:
  flags[num_bad] = -1

# or... the choose function can be used to generate the
# array of flags in only one step:
flags2 = choose(greater(random_array,5),(1,-1))

# display results:
print random_array
print flags
print flags2
# *******************************************************************

The second method (with the choose function) is much (a factor around 4) faster than the first one, where an additional loop is required. This is shown in the following table.

Size Time 1 Time 2
1000 0.000827 s 0.000122 s
5000 0.003483 s 0.000528 s
50000 0.031095 s 0.007709 s
500000 0.376974 s 0.080725 s
5000000 3.368866 s 0.839101 s

BUT: the choose() function can be used only when the action to be performed on the selected elements is to set them to a given value. It is also possible to use arrays instead of only one value, like in the following example where the value of flags3 is that of the input array when it is less than 5, -1 otherwise:

flags3 = choose(greater(random_array,5),(random_array,-1))

But it is not possible to perform any more complicated operation.

Save and restore Python objects
It is possible to save and restore python objects by using the pickle module, or better (faster) the cPickle module. I send you a short example script below. Apparently, one can store several variables in the same file, but they can only be restored in the same order as they were written. Thus we have to think about a strategy to save and restore all the objects for which this can be useful. We can define two commands ('save' and 'restore') that the command handler can interpret, but we need to know the names of the variables existing at a time, and to find a way to flag those that one may want to save.

# *******************************************************************
import mbfits
import Entities
import cPickle

f = mbfits.FitsFile("20020928_9843_MB.fits")
res1 = f.getObservation(9843,1,'MAMBO II-ABBA')
obs = Entities.ObsEntity()
obs.fill(res1[1])

# one other variable to save
l = ['test','save','and','restore','variables',222]

f = file('obs.sav','w')
cPickle.dump(obs,f,1)   # in binary format
cPickle.dump(l,f,1)
f.close()

# *******************************************************************
# then quit python... and start it again
import cPickle

f = file('obs.sav')
oo = cPickle.load(f)
test = cPickle.load(f)
f.close()
print oo
print test

# *******************************************************************