Пример #1
0
    def mopup(self):
        """Deleting tmp-files, copying SPC's, STP's"""

        # get the root name of the dispersed image
        root_name = self.dispersed_image.split('.fits')[0]

        #  get the root name of the simulated image
        result_root = self.simul_grisim.split('.fits')[0]

        # move and rename the SPC-file
        out_spc = config_util.getOUTPUT(root_name + '_2.SPC.fits')
        result_spc = config_util.getOUTSIM(result_root + '_2.SPC.fits')
        shutil.move(out_spc, result_spc)

        # move and rename the STP-file
        out_stp = config_util.getOUTPUT(root_name + '_2.STP.fits')
        result_stp = config_util.getOUTSIM(result_root + '_2.STP.fits')
        shutil.move(out_stp, result_stp)

        # delete the background subtracted
        # grism image
        os.unlink(config_util.getDATA(self.dispersed_image))

        # delete the GOL, the OAF and the PET
        result_cat = config_util.getOUTPUT(root_name + '_2.cat')
        if os.path.isfile(result_cat):
            os.unlink(result_cat)
        result_oaf = config_util.getOUTPUT(root_name + '_2.OAF')
        if os.path.isfile(result_oaf):
            os.unlink(result_oaf)
        result_pet = config_util.getOUTPUT(root_name + '_2.PET.fits')
        if os.path.isfile(result_pet):
            os.unlink(result_pet)
Пример #2
0
    def _check_dpps(self, back=False):
        # go over all inputs
        for one_input in self.axe_inputs:
            # load the config file and get the extension information
            conf = configfile.ConfigFile(
                config_util.getCONF(one_input['config']))
            ext_info = config_util.get_ext_info(
                config_util.getDATA(one_input['grisim']), conf)

            # derive the aXe names
            axe_names = config_util.get_axe_names(one_input['grisim'],
                                                  ext_info)
            # check the DPP file
            if not os.path.isfile(config_util.getOUTPUT(axe_names['DPP'])):
                # error and out
                err_msg = (
                    f"{self.taskname}: The DPP file: {config_util.getOUTPUT(axe_names['DPP'])}"
                    f" does not exist!")

                raise aXeError(err_msg)

            # check for the background DPP file
            if back and not os.path.isfile(
                    config_util.getOUTPUT(axe_names['BCK_DPP'])):
                # error and out
                err_msg = (
                    f"{self.taskname}: The DPP file: {config_util.getOUTPUT(axe_names['BCK_DPP'])}"
                    f" does not exist!")
                raise aXeError(err_msg)
Пример #3
0
    def mopup(self):
        """Deleting GOL and OAF files"""

        # get the root name of the dispersed image
        pos = self.dirname.rfind('.fits')
        root_name = self.dirname[:pos]

        # delete the GOL, the OAF and the PET
        result_cat = config_util.getOUTPUT(root_name + '_2.cat')
        if os.path.isfile(result_cat):
            os.unlink(result_cat)
        result_oaf = config_util.getOUTPUT(root_name + '_2.OAF')
        if os.path.isfile(result_oaf):
            os.unlink(result_oaf)
Пример #4
0
    def _make_drzgeocont(self, ext_info):
        # get the aXe names
        axe_names = config_util.get_axe_names(self.grisim, ext_info)

        # for the name of a special contamination OAF
        cont_oaf = config_util.getOUTPUT(axe_names['OAF'].replace(
            '.OAF', '_{0:s}.OAF'.format(int(self.params['drzfwhm'] * 10.0))))

        # run GOL2AF,
        # getting the special OAF as output
        axetasks.gol2af(grism=self.grisim,
                        config=self.config,
                        mfwhm=self.params['drzfwhm'],
                        back=False,
                        orient=self.params['orient'],
                        slitless_geom=self.params['slitless_geom'],
                        exclude=self.params['exclude'],
                        lambda_mark=self.params['lambda_mark'],
                        dmag=self.dmag,
                        out_af=cont_oaf,
                        in_gol=None)

        # run PETCONT,
        # using the special OAF as input
        axetasks.petcont(grism=self.grisim,
                         config=self.config,
                         cont_model=self.params['cont_model'],
                         model_scale=self.params['model_scale'],
                         spec_models=None,
                         object_models=None,
                         inter_type=self.params['inter_type'],
                         lambda_psf=self.params['lambda_psf'],
                         cont_map=True,
                         in_af=cont_oaf)
Пример #5
0
    def _check_files(self, dpp_list):
        """check for the existence of all DPP's"""

        for one_dpp in dpp_list:
            # make the full path name
            full_path = config_util.getOUTPUT(one_dpp)

            # check for existence
            if not os.path.isfile(full_path):
                # complain and out
                err_msg = 'Can not find the DPP file: %s!' % full_path
                raise aXeError(err_msg)
Пример #6
0
    def run(self, silent=False):
        """Make the SEX2GOL transformations"""
        if not silent:
            _log.info("py_SEX2GOL:  Start processing ...\n", )
        else:
            sout = open(self.stdout, 'w+')
            sout.write(str(self) + "\n")
            sout.write("py_SEX2GOL:  Start processing ...")

        # copy the relevant data to the GOL catalog
        self._copy_catalog()

        # check whether something can be done
        if (self.iol and self.gol):
            # transfer the coordinates
            self._transfer_coos()

            # store the GOL
            # This needs to be stored in the same way as SEXTRACTOR
            outfile = getOUTPUT(self.out_sex)
            if os.access(outfile, os.F_OK):
                os.remove(outfile)
            _log.info("Saving {} objects to {}".format(len(self.gol), outfile))
            of = open(outfile, 'w')
            for num, name in zip(range(len(self.gol.colnames)),
                                 self.gol.colnames):
                of.write("# {0:d} {1:s}\t\t{2:s}\t\t[{3:s}]\n".format(
                    num + 1, name, self.gol[name].description,
                    str(self.gol[name].unit)))
            self.gol.write(of, format='ascii.no_header', overwrite=False)
            of.close()

        else:
            # if there are no objects, just copy the empty table
            # header to the GOL
            #self._treat_NULL_table(getOUTPUT(self.out_sex))

            # give feedback
            if not silent:
                _log.info("\npy_SEX2GOL:  Warning! Empty table copied to GOL")
            else:
                # open stdout/stderr
                sout.write("pysex2gol:  Warning! Empty table copied to GOL")

        # give feedback
        if not silent:
            _log.info("     Done")
        else:
            sout.write("     Done\n")
            sout.close()
Пример #7
0
    def _get_contam_model(self):
        """Get the contamination model from in DPP"""

        # make a default return
        contam_model = None

        # open the fits and get the header
        fits_img = fits.open(config_util.getOUTPUT(self.dpp_list[0]),
                             'readonly')
        fits_head = fits_img[0].header

        # transfer value, if possible
        if 'CONTAM' in fits_head:
            contam_model = fits_head['CONTAM']

        # close the fits
        fits_img.close()

        # return the contamination model
        return contam_model
Пример #8
0
    def _decorate_PET(self):
        """Write the 'CONTAM'-keyword into the PET

        The method determines the name of the PET and
        sets the contamination keyword in the zero-extension header
        """
        # get the root name of the dispersed image
        root_name = self.dispersed_image.split('.fits')[0]

        # compose the name of the PET
        result_pet = config_util.getOUTPUT(root_name + '_2.PET.fits')

        # open the PET
        pet_fits = fits.open(result_pet, mode='update')

        # update the PET header
        comment_str = 'dummy flag - no quantitative contamination'
        pet_fits[0].header['CONTAM'] = ('GEOM', comment_str)

        # close and out
        pet_fits.close()
Пример #9
0
    def _subtract_wfc3irsky(self, ext_info):
        """Special sky subtraction for WFC3 IR images"""
        # get the axe names
        axe_names = config_util.get_axe_names(self.grisim, ext_info)

        # check for a previous background subtraction
        try:
            fits.getval(self.grisim, 'AXEPRBCK', exten=ext_info['fits_ext'])
            _log.info(
                f"WARNING: Image {self.grisim} seems to be already background "
                "subtracted! Continuing anyways...")
        except KeyError:
            _log.info(
                "Previous subtraction not recorded, proceeding with background subtraction."
            )

        scalebck = axelowlev.aXe_SCALEBCK(
            os.path.split(self.grisim)[-1],
            os.path.split(axe_names['MSK'])[-1],
            os.path.split(self.config_name)[-1],
            os.path.split(self.master_bck)[-1])
        try:
            scalebck.runall()
        except aXeError:
            _log.info("There was a problem with the background subtraction, "
                      "continuing without it")
            return False

        # check whether the background image exists
        bckfilename = config_util.getOUTPUT(axe_names['SGRI'])

        if not os.path.isfile(bckfilename):
            err_msg = ("The background image: {0:s} does NOT exist!".format(
                bckfilename))
            raise aXeError(err_msg)

        fits_image = fits.open(bckfilename, ext=0, mode='readonly')
        sky_frac = fits_image[0].header["FRACFIN"]
        scal_val = fits_image[0].header["SCALVAL"]
        bck_data = fits_image[1].data
        fits_image.close()

        if sky_frac < 0.1:
            _log.info(
                "Low fraction of sky pixels found (<10%) continuing WITHOUT"
                " sky subtraction")
            return False

        # Subtract the scaled background image from the grism image
        grism_file = fits.open(self.grisim, mode='update')
        grism_file[ext_info['ext_version']].data -= bck_data
        grism_header = grism_file[ext_info['fits_ext']].header

        # write some information into the
        # grism image header
        grism_header['AXEPRBCK'] = (
            'Done', 'flag that background subtraction was done')
        grism_header['SKY_IMG'] = (self.master_bck,
                                   'name of the 1st master background image')

        # write some scaling information into the header
        grism_header['F_SKYPIX'] = (float(sky_frac),
                                    'fraction of pixels used for scaling')
        grism_header['SKY_CPS'] = (
            float(scal_val), 'scale used for master sky == sky value [cps]')
        # close the grism image and sacve and the scaled image
        grism_file.close()
        return True
Пример #10
0
    def _subtract_nicsky(self, ext_info):
        """Special sky subtraction for NICMOS images"""
        # get the axe names
        axe_names = config_util.get_axe_names(self.grisim, ext_info)

        # check for a previous background subtraction
        fits_img = fits.open(self.grisim, 'readonly')
        fits_head = fits_img[ext_info['fits_ext']].header
        # npix = int(fits_head['NAXIS1']) * int(fits_head['NAXIS1'])

        if 'AXEPRBCK' in fits_head:
            # warn that this is the second time
            _log.info(
                f"WARNING: Image {self.grisim} seems to be already background "
                "subtracted!")

        # close the fits
        fits_img.close()

        # do the special background fitting for NICMOS
        if self.params['backped'] is not None:
            nicback = axelowlev.aXe_NICBACK(self.grisim, self.config_name,
                                            self.master_bck,
                                            self.params['backped'])
        else:
            nicback = axelowlev.aXe_NICBACK(self.grisim, self.config_name,
                                            self.master_bck)
        nicback.runall()
        del nicback

        # check whether the background image exists
        if not os.path.isfile(config_util.getOUTPUT(axe_names['NBCK'])):
            err_msg = ("The background image: {0:s} does NOT exist!".format(
                config_util.getOUTPUT(axe_names['NBCK'])))
            raise aXeError(err_msg)

        # Subtract the scaled background image from the grism image
        # copy the image to the output directory first
        sci_file = fits.open(self.grisim, mode='update')
        bck_file = fits.open(config_util.getOUTPUT(axe_names['NBCK']),
                             'readonly')
        sci_file['SCI', ext_info['ext_version']].data -= bck_file[1].data
        sci_file.close()
        bck_file.close()

        # open the background image
        fits_img = fits.open(config_util.getOUTPUT(axe_names['NBCK']),
                             'readonly')
        fits_head = fits_img['BCK'].header

        # open the grism image and isolate the correct extension header
        grism_img = fits.open(self.grisim, mode='update')
        grism_header = grism_img[ext_info['fits_ext']].header

        if 'SKY_SCAL' in fits_head and 'F_SKYPIX' in fits_head:

            # transfer important keywords
            # to the grism image
            grism_header['SKY_SCAL'] = (float(fits_head['SKY_SCAL']),
                                        'scaling value of background')
            grism_header['F_SKYPIX'] = (float(fits_head['F_SKYPIX']),
                                        'fraction of pixels used for scaling')

        # close the fits again
        fits_img.close()

        # write some keywords
        grism_header['AXEPRBCK'] = (
            'Done', 'flag that background subtraction was done')
        grism_header['SKY_IMG'] = (self.master_bck,
                                   'name of the 1st master background image')
        if self.params['backped'] is not None:
            grism_header['SKY_IMG2'] = (
                self.params['backped'],
                'name of the 2nd master background image')

        # close the image again
        grism_img.close()

        return True
Пример #11
0
    def _subtract_sky(self, ext_info, flag=-1.0e10):
        """Perform a classical background subtraction."""

        # Derive the name of all aXe products for a given image
        axe_names = config_util.get_axe_names(self.grisim, ext_info)
        msk_image_sc = axe_names['MSK'] + '[SCI]'

        # check for a previous background subtraction
        with fits.open(self.grisim, mode='update') as grism_file:
            if 'AXEPRBCK' in grism_file[ext_info['fits_ext']].header:
                # warn that this is the second time
                _log.info("WARNING: Image %25s seems to be already background "
                          "subtracted!".format(self.grisim))

            # Compute the ratio of the grism SCI image to the background image
            sci_data = grism_file['SCI', ext_info['ext_version']].data
            sci_header = grism_file['SCI', ext_info['ext_version']].header
            npix = int(sci_header["NAXIS1"]) * int(sci_header["NAXIS2"])

            bck_data = fits.getdata(self.master_bck)
            ratio_data = sci_data / bck_data

            # Flag pixels in the ratio image based on the grism image DQ array
            grism_dq_data = grism_file['DQ', ext_info['ext_version']].data
            ratio_data[grism_dq_data > 0.5] = flag

            # Flag pixels in the ratio image based on the grism image MSK file
            msk_file = fits.open(
                config_util.getOUTPUT(msk_image_sc.split("[")[0]), 'readonly')
            msk_data = msk_file['SCI'].data
            msk_file.close()

            ratio_data[msk_data < -900000] = flag

            # Flag pixels in the background image based on the grism image DQ
            # and MSK file
            bck_data[grism_dq_data > 0.5] = flag
            bck_data[msk_data < -900000] = flag

            # Compute stats for the ratio image
            stats = imagestats.ImageStats(ratio_data[ratio_data > flag],
                                          fields='midpt,stddev,npix',
                                          lower=None,
                                          upper=None,
                                          nclip=3,
                                          lsig=3.0,
                                          usig=3.0,
                                          binwidth=0.01)

            # Compute stats for the background image
            bstats = imagestats.ImageStats(bck_data[bck_data > flag],
                                           fields='midpt,stddev,npix',
                                           lower=None,
                                           upper=None,
                                           nclip=3,
                                           lsig=3.0,
                                           usig=3.0,
                                           binwidth=0.01)

            # Subtract the scaled background from the grism image
            # Reload a clean version of background
            bck_data = fits.getdata(self.master_bck)

            grism_file['SCI',
                       ext_info['ext_version']].data -= bck_data * stats.midpt
            grism_header = grism_file['SCI', ext_info['ext_version']].header

            # write some header iformation
            grism_header['SKY_SCAL'] = (float(
                stats.midpt), 'scaling value for the master background')
            grism_header['SKY_MAST'] = (float(
                bstats.midpt), 'average value of the master background')
            grism_header['SKY_IMG'] = (self.master_bck,
                                       'name of the master background image')
            grism_header['F_SKYPIX'] = (float(stats.npix) / float(npix),
                                        'fraction of pixels used for scaling')
            grism_header['AXEPRBCK'] = (
                'Done', 'flag that background subtraction was done')
        return 0
Пример #12
0
    def __init__(self,
                 grisim,
                 config,
                 in_sex=None,
                 dirname=None,
                 out_sex=None,
                 spec_hdu=None,
                 dir_hdu=None):
        """
        Parameters
        ----------
        grisim : str
            input grism/prism image
        config : str
            axe configuration filename
        in_sex : str
            name of the object file
        dirname : str
            direct image name
        out_sex : str
            overwrites the default output object catalog name
        spec_hdu : int
            grism/prism image extension to be used
        dir_hdu :  int
            direct image extension to be used

        Returns
        -------
        Creates output catalog files in source extractor format

        Notes
        -----
        There are three different kinds of Input Object List that
        can be fed into aXe:

        * an Input Object List (in SExtractor format) of objects on a
          direct image covering (roughly) the same field as the grism image
        * an Input Object List in SExtractor format, which gives the objects
          on the grism image in world coordinates (RA, Dec and theta_sky)

        The image coordinates of the objects on the grism image will be
        recomputed using the WCS information of the grism image and the
        direct image. This approach therefore relies on the accuracy of
        the WCS information given in those images.

        """

        # store some parameters
        self.grisim = grisim
        self.config = config
        self.in_sex = None
        self.out_sex = None
        self.dirname = dirname
        self.iol = None
        self.gol = None

        # determine the grism image extensions
        self.grism_extinfo = self._get_grism_ext_info(grisim, config, spec_hdu)

        # determine the grism image extensions
        self.dirname, self.dirname_extinfo = self._get_dirname_information(
            dirname, config, grisim, self.grism_extinfo, dir_hdu)

        # get information on the input and output lists
        self.in_sex, self.out_sex = self._resolve_list_names(
            self.dirname, self.dirname_extinfo, self.grisim,
            self.grism_extinfo, in_sex, out_sex)

        # save a name for stdout
        self.stdout = getOUTPUT("pysex2gol.stdout")