Sunday, May 22, 2011

Automated Astrophotography with Python - Part 1a

GETTING THINGS TO WORK
The very first step in this process is to verify that Python and Python Extension for Windows are properly communicating with a suitable Windows application. In this case, we will use MaxIm DL and its built-in camera simulator.

THE cCAMERA CLASS
The first piece of code that we will look at is the 'cCamera' class. The Python code for 'cCamera' is shown below. (Note: Docstrings have been removed from this listing for brevity and readability purposes.)
import time
import win32com.client

ERROR = True
NOERROR = False

##------------------------------------------------------------------------------
## Class: cCamera
##------------------------------------------------------------------------------
class cCamera:
    def __init__(self):
        print "Connecting to MaxIm DL..."
        self.__CAMERA = win32com.client.Dispatch("MaxIm.CCDCamera")
        self.__CAMERA.DisableAutoShutdown = True
        try:
            self.__CAMERA.LinkEnabled = True
        except:
            print "... cannot connect to camera"
            print "--> Is camera hardware attached?"
            print "--> Is some other application already using camera hardware?"
            raise EnvironmentError, 'Halting program'
        if not self.__CAMERA.LinkEnabled:
            print "... camera link DID NOT TURN ON; CANNOT CONTINUE"
            raise EnvironmentError, 'Halting program'

    def exposeLight(self,length,filterSlot):
        print "Exposing light frame..."
        self.__CAMERA.Expose(length,1,filterSlot)
        while not self.__CAMERA.ImageReady:
            time.sleep(1)
        print "Light frame exposure and download complete!"

    def setFullFrame(self):
        self.__CAMERA.SetFullFrame()
        print "Camera set to full-frame mode"
        
    def setBinning(self,binmode):
        tup = (1,2,3)
        if binmode in tup:
            self.__CAMERA.BinX = binmode
            self.__CAMERA.BinY = binmode
            print "Camera binning set to %dx%d" % (binmode,binmode)
            return NOERROR
        else:
            print "ERROR: Invalid binning specified"
            return ERROR
            
##
##    END OF 'cCamera' Class
##
The first two lines of the listing are 'import' statements that identify and allow use of the 'time' and 'win32com.client' library objects in the script. The listing for the 'cCamera' class follows the 'import' statements and consists of four methods. The '__init__' method is the constructor method for 'cCamera' and is executed whenever an instance of the cCamera object is created. This method creates a '__CAMERA' object that is an instance of MaxIm DL's 'CCDCamera' object. The '__CAMERA' object then can be used to access all the properties and methods found in the scripting section of MaxIm DL's help file (for CCDCamera object). This method also uses 'try' and 'except' statements to determine if a link has been successfully established to the program. If MaxIm DL has not already been loaded and connection to the camera established manually, the script will load MaxIm DL and make the camera connection automatically.

Next in the listing is the 'exposeLight' method that takes as arguments a length of exposure (float) and an integer that specifies the filter to use for the exposure (zero-based). This method uses MaxIm DL's 'Expose' method to start the exposure and polls the 'ImageReady' parameter to determine when the exposure and image download have completed (indicated when 'ImageReady' goes True).

The third method of 'cCamera' calls the MaxIm DL method 'SetFullFrame' and the last method sets the 'BinX' and 'BinY' properties. For more details regarding 'SetFullFrame()', 'BinX', and 'BinY' refer to MaxIm DL help under 'Scripting' and under 'CCDCamera' methods or properties.

cCAMERA UNIT TEST
The listing given below is inserted onto the end of the source listing and allows unit testing the 'cCamera' class. The first step is to create an instance of the 'cCamera' object called 'testCamera'. In turn, the 'setFullFrame' and 'setBinning' methods of 'testCamera' are called to set MaxIm to full-frame mode and to set binning to 1x1. If 'setBinning' finished without error, the 'exposeLight' method is called and initiates a 12.5 second exposure through the simulator's blue filter (slot 2).
if __name__ == "__main__":

    # Create an instance of the cCamera class
    testCamera = cCamera()

    # Setup MaxIm DL to take a full frame image 
    testCamera.setFullFrame()
    # Setup binning for 2x2
    if not testCamera.setBinning(2):
        # Expose filter slot 2 (Blue) for 12.5 seconds
        testCamera.exposeLight(12.5,2)
    else:
        print "Image not taken due to previous error"
RUNNING THE SCRIPT
Follow the steps below to execute the script described in this post:
  1. Download and extract the script from cCamera_1a.zip.
  2. Start MaxIm DL and open the Camera Control window. Under 'Setup Camera' for Camera 1, choose 'Simulator' and under 'Setup Filter' for Camera 1 choose 'Simulator' also. For Camera 2, choose 'Simulator' and under 'Setup Filter' for Camera 2 leave unselected.
  3. Change focus to the IDLE window containing your script listing, click the 'Run' menu item and pull down to 'Run Module', or simply press the F5 key.
  4. If everything is working correctly, you should see MaxIm DL kick off a 12.5 second exposure through the blue filter and eventually display an image from the simulated camera. You can inspect the FITS header to verify the binning, exposure, and filter for this image.
  5. Modify the parameters in the unit test section of the listing to take exposures of different lengths, through different filters, using different binnings to verify that all work as expected.
WHAT'S NEXT?
In the next post I will continue to expand the 'cCamera' class by introducing methods that allow saving light images to disk. I will also expand the unit test listing to verify correct operation of the new features added to this class.

CLICK HERE FOR NEXT POST IN THIS SERIES

No comments:

Post a Comment