Exemplo n.º 1
0
    def sky2pix(self, coordinate, origin=0):
        r"""
        Calculates the Pixel corresponding to a given coordinate.

        Parameters
        ----------
        coordinate : list
            Either ['RA','DEC'], e.g. ['1:34:7.00', '+30:47:52.00'] in
            equatorial coordinates or [RA, DEC] in GRAD.
        origin : int
           ``0`` or ``1``; this steers how the first pixel is counted
           ``0`` is for usage with python as it starts to count from zero.
           ``1`` is the fits standart.

        Returns
        -------
        pixel : List
            [x, y]; the pixel coordinates of the map.
        """
        # Equatorial_to_degrees is only possible to execute if coordinate is in
        # the correct form for RA DEC.
        self.log.debug("Calculate map pixel for coord. {}".format(coordinate))
        try:
            self.log.debug("Test trying to convert coord. to degrees")
            coordinate = astFunc.equatorial_to_degrees(coordinate)
            self.log.debug("Calculated coordinate in "\
                           "Degrees: {}".format(coordinate))
        except AttributeError:
            self.log.debug("Conversion to degrees failed. "\
                           "This does not have to be a problem.")
        coordinate = np.array([[coordinate[0], coordinate[1]]], np.float_)
        self.log.debug("Retrieving the pixels of the map at given coordinate")
        sky2pix_result = self.wcs.wcs_world2pix(coordinate, origin)
        pixel = sky2pix_result[0]
        # The pixels are floats. To get integers we get the floor value
        # of the floats
        pixel = [int(math.floor(float(pixel[0]))),
                 int(math.floor(float(pixel[1])))]
        self.log.debug("Output pixel {}".format(pixel))
        return pixel
Exemplo n.º 2
0
    def read_aperture(self, position, apertureSize=0, backgroundSize=0,
                      output=False, annotation=False, newAnnotation=False):
        # TODO: needs better scheme for the header keywords. Migth not work
        # with all maps.
        r"""
        Extract the sum and mean flux inside an aperture of a given size
        and at a given position..

        This function can be used to read the flux in the area of a circular
        aperture, as well as to correct for the background flux.

        Parameters
        ----------
        position : list
            The position in RA,DEC where the aperture is to be applied.
            The Format has to be either:

                * ['RA','DEC'] with strings representing equatorial
                  coordinates, e.g. ['01:34:32.8', '+30:47:00.6'].

            or:

                * [RA, DEC] where RA and DEC being the coordinates in Grad.

        apertureSize : float [arcsec]
            The diameter of the aperture to be applied.

        backgroundSize : float [arcsec]
            The Size of the Anulli in which the background is to be
            estimated. The number to be given here correspond to the diameter
            of the circle in [arcsec ] descibing the outer border of the
            annuli, measured from the position given in position. Thus, the
            background is measurd in the ring described by apertureSize and
            backgroundSize. Default is 0 and thus **no background substaction**
            is applied.

        output : True or False
            If True the function reports the calculated values during
            execution.

        annotion : logical
            If True a kvis annotation file ``"apertures.ann"`` containing the
            aperture used to integrate the flux is created. Default is False,
            i.e. not to create the aperture.

        newAnnotation : logical
            If True ``"apertures.ann"`` is overwritten. If False an old
            ``"apertures.ann"`` is used to append the new apertures. If it not
            exists a new one is created. The latter is the default.

        Returns
        -------
        List :  [Sum, Mean, Number of pixels]

        Notes
        -----

        The pixel sizes have to be quadratic for the algorithm to work. It
        measures a circle by counting the pixels from the central pixel
        corresponding to the given coordinate.

        """
        self.log.debug(
            "Determining the Flux at position: {}; "\
            "in aperture of size {} and background of {}".format(
                position, apertureSize, backgroundSize)
        )
        # Calculate the x,y Pixel coordinate of the position.
        xCenter, yCenter = self.sky2pix(position)
        # Read the pixel Size (normaly in Grad FITS-Standard)
        try:
            self.pixSize1 = float(self.header['CDELT1'])
            self.pixSize2 = float(self.header['CDELT2'])
        except:
            # sometimes the header keywords are different.
            try:
                self.pixSize1 = float(self.header['XPIXSIZE'])
                self.pixSize2 = float(self.header['YPIXSIZE'])
                self.pixSize1 = self.pixSize1 / 60 / 60
                self.pixSize2 = self.pixSize2 / 60 / 60
            except:
                print 'No Header keyword for the pixsize found'
                sys.exit()
         # Check if the pixel size is quadratic, if not the function does not
         # work correctly (yet)
        if ((((self.pixSize1) ** 2 - (self.pixSize2) ** 2) ** 2 <
             ((self.pixSize1) ** 2) * 0.01)):
            if output is True:
                print ('Pixel Size X: ' + str(self.pixSize1 / (1. / 60 / 60))
                       + ' arcsec')
                print ('Pixel Size Y: ' + str(self.pixSize2 / (1. / 60 / 60))
                       + ' arcsec')
                print ('Pixel Size quadratic to 1%, Go on with '
                       'calculation of Apertures')
        else:
            if output is True:
                print self.pixSize1, self.pixSize2
                print ('Pixel Size *NOT* quadratic: Exit the program, '
                       'please regrid!')
            sys.exit()
        # Convert the apertureSizes to Grad f
        apertureSizeInGrad = (1. / 60 / 60) * (apertureSize) / 2
        # Calculate how many pixels are needed to cover the radius of the
        # aperture
        apertureSteps = math.sqrt(math.floor(apertureSizeInGrad /
                                             self.pixSize1) ** 2)
        # same for the backround annuli
        if backgroundSize != 0:
            backgroundSizeInGrad = (1. / 60 / 60) * (backgroundSize) / 2
            backgroundSteps = math.sqrt(math.floor(backgroundSizeInGrad /
                                                   self.pixSize1) ** 2)
            x_max, x_min = xCenter + backgroundSteps, xCenter - backgroundSteps
            y_max, y_min = yCenter + backgroundSteps, yCenter - backgroundSteps
        else:
            x_max, x_min = xCenter + apertureSteps, xCenter - apertureSteps
            y_max, y_min = yCenter + apertureSteps, yCenter - apertureSteps
        # calculate the x and y range in Pixel coordinates that are needed at
        # most for the calculation of the aperture and background
        # Now: Initialize variables
        sum = 0  # will store the sum of all Pixels in the aperture
        N = 0   # counts the number of pixels in the aperture to be able to
                # calculate the mean
        sumBackgnd = 0  # the sum of all pixels in the background
        NBackgnd = 0   # number of pixels in the background
        # calculate the background
        if backgroundSize != 0:
            for x in range(int(x_min), int(x_max)):
                for y in range(int(y_min), int(y_max)):
                    if ((math.floor(math.sqrt((xCenter - x) ** 2 +
                                              (yCenter - y) ** 2)) <
                         backgroundSteps and math.floor(math.sqrt((xCenter - x)
                                                                  ** 2 +
                                                                  (yCenter - y)
                                                                  ** 2))
                         > apertureSteps)):
                        sumBackgnd += self.data[y][x]
                        NBackgnd += 1
            backgndMean = sumBackgnd / NBackgnd
            print backgndMean
        # caclulate the sum in the aperture
        for x in range(int(x_min), int(x_max)):
            for y in range(int(y_min), int(y_max)):
                if (math.floor(math.sqrt((xCenter - x) ** 2 + (yCenter - y) **
                                         2)) < apertureSteps):
                    if backgroundSize != 0:
                        sum += self.data[y][x] - backgndMean
                    else:
                        sum += self.data[y][x]
                    N += 1
        if backgroundSize != 0:
            mean = (sum / N) - backgndMean
            sumcorrected = sum - (N * backgndMean)
            result = [sum, mean, N]
        if backgroundSize == 0:
            mean = (sum / N)
            result = [sum, mean, N]
        if output is True:
            print ('Sum:', result[0], 'Mean:', result[1],
                   'Number of Pixel:', result[2])
        if newAnnotation is False:
            fileout = open('apertures.ann', 'a')
        if newAnnotation is True:
            fileout = open('apertures.ann', 'w')
        if annotation is True:
            position = astFunc.equatorial_to_degrees(position)
            apertureString = ('CROSS ' +
                              str(position[0]) + ' ' +
                              str(position[1]) + ' 0.0008 0.001 \n'
                              'circle  ' +
                              str(position[0]) + ' ' +
                              str(position[1]) + ' ' +
                              str(apertureSize * (1. / 60 / 60) / 2) + ' \n'
                              'text ' +
                              str(position[0] + (1. / 60 / 60)) + ' ' +
                              str(position[1] + (1. / 60 / 60)) + '\n')
            fileout.write(apertureString)
            fileout.close()
        return result