Sunday, July 17, 2011

Updated DXCC Status

The following table contains my current DXCC status. Complete details regarding all confirmed DXCC entities and additional information regarding the DXCC awards program can be found by clicking here.

Mixed 157 Confirmed 135 Awarded 22 Pending (18 LotW, 4 Card)
CW 127 Confirmed 100 Awarded 27 Pending (24 LotW, 3 Card)
Phone 131 Confirmed 118 Awarded 13 Pending  (8 LotW, 5 Card)
RTTY  78 Confirmed  66 Awarded 12 Pending (12 LotW, 0 Card)
80m  20 Confirmed  18 Awarded  2 Pending  (2 LotW, 0 Card)
40m  92 Confirmed  70 Awarded 22 Pending (21 LotW, 1 Card)
20m 117 Confirmed 102 Awarded 15 Pending (14 LotW, 1 Card)
15m 129 Confirmed 112 Awarded 17 Pending (15 LotW, 2 Card)
10m 104 Confirmed  93 Awarded 11 Pending  (7 LotW, 4 Card)

 

Sunday, July 10, 2011

Automated Astrophotography with Python - Part 7

FOCUSING WITH FOCUSMAX
Achieving great focus is undoubtedly one of the most critical operations for any astronomical imaging application. Using the free application, FocusMax, this step can be reduced to a simple, repeatable, and highly effective operation. Fortunately, FocusMax provides all of the necessary interfaces to quickly automate this important step. The following listing shows a new class named 'cFocuser'. This class is responsible for controlling all aspects of the focus operation. The listing for the 'cFocuser' class is shown below:
import time
import pythoncom
import win32com.client

FOCUSMAXTIME = 150
LASTFOCHFD = -1

ERROR   = True
NOERROR = False

##------------------------------------------------------------------------------
## Class: cFocuser
##------------------------------------------------------------------------------
class cFocuser:
    def __init__(self,printlog):
        printlog.log(0,"Connecting to FocusMax...")
        self.__FM = win32com.client.Dispatch("FocusMax.FocusControl")

    def checkFocusStar(self,printlog):
        printlog.log(0,"Checking focus by measuring HFD...")
        HFD = []
        count = 0
        # take 7 HFD measurements, sort the list, report the median value
        while count < 7:
            busy = self.__FM.SingleExposeAsyncStatus        
            self.__FM.SingleExposeAsync()
            # wait for measurement to end
            startTime = time.time()
            busy = -1
            while busy == -1 and (time.time() - startTime) < FOCUSMAXTIME:
                time.sleep(1)
                busy = self.__FM.SingleExposeAsyncStatus
            if self.__FM.SingleExposeAsyncStatus != 1:
                printlog.log(0,"HFD Measurement failed or timed out")
                return -1        
            result = self.__FM.HalfFluxDiameter
            flux = self.__FM.TotalFlux
            time.sleep(0.5)
            printlog.log(1,"HFD Measurement: %0.2f  Total Flux: %d" %
                         (result,flux))
            if flux > 20000:
                HFD.append(result)
                count = count + 1
        HFD.sort()
        j = len(HFD)
        if not j%2:
            median = (HFD[(j/2)-1]+HFD[j/2])/2.0
        else:
            median = HFD[j/2]
        focuserPos = self.__FM.Position
        printlog.log(0,"Median HFD = %0.2f at Pos = %d" % (median,focuserPos))
        return median

    def focusStar(self,printlog):
        global LASTFOCHFD
        printlog.log(0,"Starting FocusMax Focus method...")
        try:
            busy = self.__FM.FocusAsyncStatus        
            start = self.__FM.FocusAsync()
        except pythoncom.com_error, (hr, msg, exc, arg):
            printlog.log(0,"ERROR: %s" % exc[2])
            return ERROR
        else:
            if start:
                # wait for focus method to end
                startTime = time.time()
                busy = -1
                while busy == -1 and (time.time() - startTime) < FOCUSMAXTIME:
                    time.sleep(1)
                    busy = self.__FM.FocusAsyncStatus
                if self.__FM.FocusAsyncStatus != 1:
                    printlog.log(0,"Focus method failed or timed out.")
                    return ERROR        
                printlog.log(0,"FocusMax Focus method complete...")
                tgtHFD = self.__FM.HalfFluxDiameter
                if tgtHFD > 0.5:
                    median = self.checkFocusStar(printlog)
                    if median == -1:
                        return ERROR
                    elif median < 0.5 or median > 4.0:
                        printlog.log(0,"ERROR: Focus results out of range.")
                        return ERROR
                    else:
                        LASTFOCHFD = median
                        return NOERROR
                else:
                    printlog.log(0,"ERROR: Focus method failed.")
                    return ERROR
            else:
                printlog.log(0,"ERROR: FocusMax Focus method failed to start.")
                return ERROR

##
## END OF 'cFocuser' Class
##
The constructor for 'cFocuser' is called whenever a new object of the class is instantiated and is used to create a new object (__FM) that is bound to the FocusMax object (FocusControl) required by this class. Following the constructor, the 'checkFocusStar()' method performs a check of focus quality by invoking the 'SingleExposeAsync()' method. This method is called multiple times to take a series of measurement of a suitable focus star that has previously been centered in the field of view. After waiting for the exposure to complete, the method checks the properties that holds the measurement's HFD and total flux (brightness). The measurements are written to the screen and to the log file and the HFD value is appended to a list data structure. After seven measurements are collected, the HFD list is sorted and the median value is extracted and returned to the method's calling routine.

The other method in this class is named 'focusStar()' and performs the actual focus operation (nearly equivalent to clicking on the 'Focus' button on FocusMax's front panel). This method invokes the FocusMax 'FocusAsync()' method to kick off the focus operation. The method then polls the 'FocusAsyncStatus' property to determine when the focus operation is complete. If the focus star's HFD is a reasonable value, the 'checkFocusStar()' method is called to determine the median of seven consecutive HFD measurements. The median value is then assigned to a global variable, 'LASTFOCHFD'.

UNIT TESTING
Unlike unit tests for modules presented up to this point, the unit test for this class can not be simulated. Therefore, actual stars must be available to adequately verify the operation of this module. Due to poor weather and equipment failures I have been unable to generate and verify a unit test for the 'cFocuser' class. As soon as I am able, I will update this post with a unit test.

WHAT'S NEXT?
In the next post, I will demonstrate the method that I use to automatically select focus stars. This method will work with previous modules and result in a means to select a suitable focus star near the object to image, slew to the star, focus and determine median HFD, then slew to the main object to begin imaging. This procedure, along with periodic slews back to the focus star to check and ,if necessary, re-focus, is the main sequence of events that I use for my astronomical imaging script.