Exemplo n.º 1
0
    def readFitsData(self, fitsPath):
        """
        readFitsData reads the fits file with the image and tries to get some key
        fields out of the header for preparing the solver.

        :param fitsPath: fits file with image data
        :return: raHint, decHint, scaleHint
        """

        with fits.open(fitsPath) as fitsHDU:
            fitsHeader = fitsHDU[0].header

            # todo: there might be the necessity to read more alternative header info
            # todo: the actual definition is OK for EKOS

            scaleHint = float(fitsHeader.get('SCALE', 0))
            ra = fitsHeader.get('RA', 0)
            dec = fitsHeader.get('DEC', 0)
            raHint = transform.convertToAngle(ra, isHours=True)
            decHint = transform.convertToAngle(dec, isHours=False)

        self.log.info(
            f'RA: {raHint} ({ra}), DEC: {decHint} ({dec}), Scale: {scaleHint}')

        return raHint, decHint, scaleHint, ra, dec
Exemplo n.º 2
0
    def writeHeaderToGUI(self, header=None):
        """
        writeHeaderToGUI tries to read relevant values from FITS header and possible
        replace values and write them to the imageW gui

        :param header: header of fits file
        :return: hasCelestial, hasDistortion
        """

        name = header.get('OBJECT', '').upper()
        self.ui.object.setText(f'{name}')

        ra = header.get('OBJCTRA', 0)
        ra = transform.convertToAngle(ra, isHours=True)
        dec = header.get('OBJCTDEC', 0)
        dec = transform.convertToAngle(dec, isHours=False)
        self.ui.ra.setText(f'{transform.convertToHMS(ra)}')
        self.ui.dec.setText(f'{transform.convertToDMS(dec)}')

        scale = header.get('SCALE', 0)
        rotation = header.get('ANGLE', 0)
        self.ui.scale.setText(f'{scale:5.3f}')
        self.ui.rotation.setText(f'{rotation:6.3f}')

        ccdTemp = header.get('CCD-TEMP', 0)
        self.ui.ccdTemp.setText(f'{ccdTemp:4.1f}')

        expTime1 = header.get('EXPOSURE', 0)
        expTime2 = header.get('EXPTIME', 0)
        expTime = max(expTime1, expTime2)
        self.ui.expTime.setText(f'{expTime:5.1f}')

        filterCCD = header.get('FILTER', 0)
        self.ui.filter.setText(f'{filterCCD}')

        binX = header.get('XBINNING', 0)
        binY = header.get('YBINNING', 0)
        self.ui.binX.setText(f'{binX:1.0f}')
        self.ui.binY.setText(f'{binY:1.0f}')

        sqm = max(header.get('SQM', 0),
                  header.get('SKY-QLTY', 0),
                  header.get('MPSAS', 0),
                  )
        self.ui.sqm.setText(f'{sqm:5.2f}')

        flipped = bool(header.get('FLIPPED', False))
        self.ui.isFlipped.setEnabled(flipped)

        # check if distortion is in header
        if 'CTYPE1' in header:
            wcsObject = wcs.WCS(header, relax=True)
            hasCelestial = wcsObject.has_celestial
            hasDistortion = wcsObject.has_distortion
        else:
            wcsObject = None
            hasCelestial = False
            hasDistortion = False

        self.ui.hasDistortion.setEnabled(hasDistortion)
        self.ui.hasWCS.setEnabled(hasCelestial)

        return hasDistortion, wcsObject
Exemplo n.º 3
0
def test_convertToAngle_4():
    value = transform.convertToAngle('+12:00:00.0')
    assert value.degrees == 12
Exemplo n.º 4
0
def test_convertToAngle_4():
    value = transform.convertToAngle('12:00:00.0', isHours=True)
    assert value.hours == 12
Exemplo n.º 5
0
def test_convertToAngle_3():
    value = transform.convertToAngle(180, isHours=True)
    assert value.hours == 12
Exemplo n.º 6
0
def test_convertToAngle_2():
    value = transform.convertToAngle(180)
    assert value.degrees == 180
Exemplo n.º 7
0
def test_convertToAngle_2():
    parameter = 180
    value = transform.convertToAngle(parameter, isHours=True)
    assert value.hours == 12
Exemplo n.º 8
0
def test_convertToAngle_1():
    parameter = 180
    value = transform.convertToAngle(parameter)
    assert value.degrees == 180
Exemplo n.º 9
0
    def getSolutionFromWCS(self,
                           fitsHeader=None,
                           wcsHeader=None,
                           updateFits=False):
        """
        getSolutionFromWCS reads the wcs fits file and uses the data in the header
        containing the wcs data and returns the basic data needed.
        in addition it embeds it to the given fits file with image. it removes all
        entries starting with some keywords given in selection. we starting with
        HISTORY

        :param fitsHeader:
        :param wcsHeader:
        :param updateFits:
        :return: ra in hours, dec in degrees, angle in degrees, scale in arcsec/pixel
                 error in arcsec and flag if image is flipped
        """

        self.log.info(f'wcs header: [{wcsHeader}]')
        raJ2000 = transform.convertToAngle(wcsHeader.get('CRVAL1'),
                                           isHours=True)
        decJ2000 = transform.convertToAngle(wcsHeader.get('CRVAL2'),
                                            isHours=False)

        angle, scale, flipped = self.calcAngleScaleFromWCS(wcsHeader=wcsHeader)

        raMount = transform.convertToAngle(fitsHeader.get('RA'), isHours=True)
        decMount = transform.convertToAngle(fitsHeader.get('DEC'),
                                            isHours=False)

        # todo: it would be nice, if adding, subtracting of angels are part of skyfield
        deltaRA = abs(raJ2000._degrees - raMount._degrees) * 3600
        deltaDEC = abs(decJ2000.degrees - decMount.degrees) * 3600
        error = np.sqrt(np.square(deltaRA) + np.square(deltaDEC))

        solve = {
            'raJ2000S': raJ2000,
            'decJ2000S': decJ2000,
            'errorRA_S': deltaRA,
            'errorDEC_S': deltaDEC,
            'angleS': angle,
            'scaleS': scale,
            'errorRMS_S': error,
            'flippedS': flipped
        }

        if not updateFits:
            return solve, fitsHeader

        fitsHeader.append(('SCALE', solve['scaleS'], 'MountWizzard4'))
        fitsHeader.append(('PIXSCALE', solve['scaleS'], 'MountWizzard4'))
        fitsHeader.append(('ANGLE', solve['angleS'], 'MountWizzard4'))
        fitsHeader.append(('FLIPPED', solve['flippedS'], 'MountWizzard4'))

        fitsHeader.extend(wcsHeader, unique=True, update=True)

        # remove polynomial coefficients keys if '-SIP' is not selected in CTYPE1 and CTYPE2
        # this might occur, if you solve a fits file a second time with another solver

        if 'CTYPE1' not in fitsHeader or 'CTYPE2' not in fitsHeader:
            return solve, fitsHeader
        if '-SIP' in fitsHeader['CTYPE1'] and '-SIP' in fitsHeader['CTYPE2']:
            return solve, fitsHeader

        for key in list(fitsHeader.keys()):
            if key.startswith('A_'):
                del fitsHeader[key]
            elif key.startswith('B_'):
                del fitsHeader[key]
            elif key.startswith('AP_'):
                del fitsHeader[key]
            elif key.startswith('BP_'):
                del fitsHeader[key]

        return solve, fitsHeader