Q: Is there a way to construct a volume (3-D) EMData object from a bunch of 2-D images ?
A: Yes, EMData objects can be 1, 2 or 3-D. Effectively the data is stored as a single array of floats with x varying first, y second, z third. If nz=ny=1 then the image is 1-D, etc. Most 3-D data in cryo-EM comes from volumetric reconstructions from projections rather than slice data as in a lot of optical microscopy. Nonetheless, constructing a volume from a stack of slices can be done in a wide range of different ways. I'd say the easiest way would be to use 'insert_clip()'. This will take one EMData object (of any dim) and insert it into another (of any dim).
You can try it in 2-D like this (you should just be able to paste this into an interactive 'e2.py' session):
a=test_image(1,size=(256,256)) b=test_image(0,size=(128,128)) display((a,b)) # middle-click for control panel a.insert_clip(b,(32,32)) #now pan the display around with RMB to trigger a refresh (auto refresh got broken recently)
a=test_image_3d(size=(128,128,128)) # 3-D 'axes' b=test_image_3d(size=(32,32,32)) c=test_image(0,size=(32,32)) # 2-D 'noisy S' display(b) # middle-click for control-panel, lmb rotate a.insert_clip(b,(24,24,24)) a.insert_clip(c,(70,70,70)) display(a)
The insert_clip() method replaces the contents of the target in the overlapping pixels/voxels. ie - to construct a 3-D image from a set of slices:
slices=[test_image(size=(64,64))/(fabs(i-32)+1) for i in range(64)] volume=EMData(64,64,64) for z,slice in enumerate(slices): volume.insert_clip(slice,(0,0,z)) display(volume)
While not directly related, also note that you can access individual pixels/voxels in an EMData object like this:
a=test_image_3d(size=(128,128,128)) print a[64,64,64] a=test_image(size=(64,64)) print a[32,32]
You can also set image attributes:
a["myattr"]="alphabet" # attributes can be int, float, int list, float list, string, string list print a["myattr"]
Note that attributes are preserved when saved to HDF and BDB files (other formats lack space in the header for this). While we do support TIFF in general, we just use libtiff, and don't support very complex features. It isn't a widely used format other than for raw CCD frames in the cryo-EM community.