示例#1
0
    def transform(self, image: Image):

        if not self.requirements_check(image):
            raise ValueError(
                "Missing required transformations on image. Need:" +
                str(self.REQUIRES))
        if "dark" in image.processing_parameters:
            raise AttributeError("dark correction already applied")
        img = fits.open(image.fixed_parameters["path"])
        values = img[0].data - image.get_exposure() / self.image.get_exposure(
        ) * self.dark
        header = img[0].header

        # path and filename
        old_path = image.fixed_parameters["path"]
        new_path = old_path.parent
        new_file_name = old_path.stem + "d.fits"
        new_path = new_path / new_file_name
        image.fixed_parameters["path"] = new_path
        # overrwriting old one
        if os.path.exists(new_path) and CONFIG["OVERWRITE"]:
            os.remove(new_path)

        # writing image to fits and creating image object
        fits.writeto(image.fixed_parameters["path"], values, header)
        image.processing_parameters["dark"] = True
        return image
示例#2
0
    def get_list(self):
        # data type and corrections
        if self.type in ["flat", "dark", "data"]:
            processing_pars = {}
        elif self.type in ["cdata", "dfdata"]:
            processing_pars = {"flat": True, "dark": True}
            self.type = "data"
        else:
            processing_pars = {"dark": True}
            self.type = "data"

        p = self.path
        paths = list(p.glob(self.selector))

        image_list = []
        for im_path in paths:
            image = fits.open(im_path)
            exposure = image[0].header["EXPOSURE"]
            time_jd = image[0].header["JD"]
            fixed_pars = {
                "time_jd": time_jd,
                "path": im_path,
                "type": self.type,
                "exposure": exposure,
                "id": im_path.stem
            }
            image_list.append(
                Image(fixed_parameters=fixed_pars,
                      processing_parameters=processing_pars))

        image_list.sort(key=lambda x: x.get_time_jd())
        # TODO: logging debug - images
        # TODO: logging info - len images
        return image_list
示例#3
0
    def get_list(self):
        if self.type in ["cdata", "dfdata"]:
            processing_parameters = {"flat": True, "dark": True}
        elif self.type is "ddata":
            processing_parameters = {"dark": True}
        else:
            processing_parameters = {}
        image_list = []
        for path in self.pathlist:
            image = fits.open(path)
            exposure = image[0].header["EXPOSURE"]
            time_jd = image[0].header["JD"]
            fixed_pars = {
                "time_jd": time_jd,
                "path": path,
                "type": self.type,
                "exposure": exposure,
                "id": path.stem
            }

            image_list.append(
                Image(fixed_parameters=fixed_pars,
                      processing_parameters=processing_parameters))

        image_list.sort(key=lambda x: x.get_time_jd())
        # TODO: logging debug - images
        # TODO: logging info - len images
        return image_list
示例#4
0
 def create_master_flat(images: [Image],
                        save_path: str = CONFIG["FLAT_PATH"]):
     """
     Static method to create master flat from given flat images. Save path specified in Config.FLAT_PATH
     Overwrites flat image in Config.FLAT_PATH !
     :param images: Flat images list
     :param save_path: Optional save path
     :return: master flat as Image type object
     """
     flat_filename = "master_flat" + datetime.now().strftime(
         "_%H-%M-%Y-%d-%m") + ".fits"
     save_path = Path(save_path) / flat_filename
     counter = 0
     values = []
     for image in images:
         values.append(fits.open(image.fixed_parameters["path"])[0].data)
         counter += 1
     flat_data = np.median(values, axis=0)
     flat_data = flat_data / np.mean(flat_data)
     hdu = fits.PrimaryHDU(flat_data)
     if os.path.exists(save_path) and CONFIG["OVERWRITE"]:
         os.remove(save_path)
     hdu.writeto(save_path)
     return Image(
         {
             "time_jd": 0,
             "exposure": 0,
             "type": "flat",
             "path": save_path,
             "id": "mflat"
         }, {})
示例#5
0
    def transform(self, image: Image):

        if not self.requirements_check(image):
            raise ValueError(
                "Missing required transformations on image. Need:" +
                str(self.REQUIRES))
        # INIT
        from pyraf import iraf
        iraf.noao.digiphot(_doprint=0)
        iraf.noao.digiphot.daophot(_doprint=0)
        capable.OF_GRAPHICS = False

        # File handling
        temp_final_out = CONFIG["FILE_DUMP"] + 'TempPhotOut.dat'
        if os.path.exists(temp_final_out):
            os.remove(temp_final_out)

        base = image.fixed_parameters["path"].split('/')[-1]
        dao_phot_out = CONFIG["FILE_DUMP"] + base + ".mag.dat"
        phot_txt_out = CONFIG["FILE_DUMP"] + base + "PhoTxOut.dat"

        # Setting pyraf phot parameters
        photpars = iraf.photpars.getParList()
        iraf.photpars.setParam('apertures', CONFIG["APERTURE"])
        iraf.phot.setParam('image', image.fixed_parameters["path"])
        iraf.phot.setParam('coords', self._get_coordinates_file(image))
        iraf.phot.setParam('verify', 'no')
        iraf.phot.setParam('output', dao_phot_out)
        iraf.phot.setParam('interactive', 'no')

        if os.path.exists(dao_phot_out):
            os.remove(dao_phot_out)

        # Running IRAF task
        dump = iraf.phot(mode='h', Stdout=1)

        if os.path.exists(phot_txt_out):
            os.remove(phot_txt_out)

        # Getting better formatted file with magnitudes
        iraf.txdump(dao_phot_out,
                    'XCENTER,YCENTER,MAG,MERR',
                    'yes',
                    Stdout=phot_txt_out)

        # Getting results from output file
        with open(phot_txt_out) as output_file:
            results = {}
            i = 0
            for lines in output_file:
                parts = lines.split()
                results[self.objects[i].fixed_parameters["id"]] = (
                    float(parts[2]) if parts[2] != "INDEF" else None,
                    float(parts[3]) if parts[3] != "INDEF" else None)
                i += 1

        image.processing_parameters["photometry"] = results
        return image
示例#6
0
    def transform(self, image: Image):
        if not self.requirements_check(image):
            raise ValueError(
                "Missing required transformations on image. Need:" +
                str(self.REQUIRES))
        shifts = {}
        for id, value in image.get_photometry().items():
            star = self.find_star_with_id(id)
            if star is None:
                continue
            cat_mag = star.get_catalog_magnitude()
            shifts[id] = (cat_mag[0] - value[0],
                          np.sqrt(cat_mag[1]**2 + value[1]**2))

        image.processing_parameters["shifts"] = shifts
        image.processing_parameters["shift"] = ShiftTransform.calculate_shift(
            image)
        return image
示例#7
0
    def transform(self, image: Image):
        img = fits.getdata(image.get_path())
        xpos, ypos = self._get_coordinates_arrays(image)
        mag, magerr, flux, fluxerr, sky, skyerr, badflag, outstr = \
            aper.aper(img, xpos, ypos, phpadu=1, apr=self.aperture, zeropoint=25,
                      skyrad=[40, 50], badpix=[-12000, 1060000],
                      exact=True)
        results = {}
        i = 0
        for o in self.objects:

            results[o.get_id()] = (
                float(mag[i]) if mag[i] is not "nan" else None,
                float(magerr[i]) if magerr[i] is not "nan" else None)
            i += 1

        image.processing_parameters["photometry"] = results
        # workaround for single object photometry
        try:
            image.processing_parameters["src_flux"] = (float(flux[0]),
                                                       float(fluxerr[0]))
            image.processing_parameters["sky"] = (float(sky[0]),
                                                  float(skyerr[0]))
        except IndexError:
            image.processing_parameters["src_flux"] = (float(flux),
                                                       float(fluxerr))
            image.processing_parameters["sky"] = (float(sky), float(skyerr))
        return image
示例#8
0
 def _load_images(self):
     image_list = []
     db_image_list = self.session.query(db.Frame).all()
     # TODO: logging debug - list query
     # TODO: logging info - len of loaded images
     for db_image in db_image_list:
         image_list.append(
             Image(fixed_parameters={
                 "time_jd": db_image.time_jd,
                 "exposure": db_image.exposure,
                 "id": db_image.id,
                 "type": db_image.type,
                 "path": Path(db_image.path)
             },
                   processing_parameters=eval(db_image.additional)))
     return self._string_ids(image_list)
示例#9
0
    def _get_coordinates_arrays(self, image: Image):
        """ Creates coordinates arrays for photometry using wcs coordinates in FITS header.

        :return: filename
        """
        header = fits.getheader(image.get_path())
        w = WCS(header)
        pixel_coordinates_ra = []
        pixel_coordinates_dec = []

        for o in self.objects:
            x, y = w.wcs_world2pix(o.fixed_parameters['ra'],
                                   o.fixed_parameters['dec'], 1)

            pixel_coordinates_ra.append(float(x))
            pixel_coordinates_dec.append(float(y))
        return np.array(pixel_coordinates_ra), np.array(pixel_coordinates_dec)
示例#10
0
    def _get_coordinates_file(self, image: Image):
        """ Creates coordinates file for photometry using wcs coordinates in FITS header.

        :return: filename
        """
        filename = CONFIG["FILE_DUMP"] + "xy_coords_file.txt"
        header = fits.getheader(image.get_path())
        w = WCS(header)
        pixel_coordinates = []

        for o in self.objects:
            x, y = w.wcs_world2pix(o.fixed_parameters['ra'],
                                   o.fixed_parameters['dec'], 1)

            pixel_coordinates.append([float(x), float(y)])
        np.savetxt(filename, pixel_coordinates)
        return filename
示例#11
0
    def create_master_dark(images: [Image],
                           exposure=20,
                           save_path=CONFIG["DARK_PATH"]):
        """
        Static method to create master flat from given flat images. Save path specified in Config.DARK_PATH

        :param images: Dark images list
        :param save_path: Optional save path
        :param exposure: exposure of input dark images to be selected and combined
        :return: master flat as Image type object
        """
        dark_filename = "master_dark" + datetime.now().strftime(
            "_%H-%M-%Y-%d-%m") + ".fits"
        save_path = Path(save_path) / dark_filename
        counter = 0
        values = []
        for image in images:
            if image.get_exposure() == exposure:
                values.append(
                    fits.open(image.fixed_parameters["path"])[0].data)
                counter += 1
        if counter == 0:
            raise RuntimeError("No darks with given exposure")
        dark_data = np.median(values, axis=0)
        hdu = fits.PrimaryHDU(dark_data)
        if os.path.exists(save_path) and CONFIG["OVERWRITE"]:
            os.remove(save_path)
        hdu.writeto(save_path)
        return Image(
            {
                "time_jd": 0,
                "exposure": 20,
                "type": "dark",
                "path": save_path,
                "id": "mdark"
            }, {})
示例#12
0
def stacking_procedure(images: [Image]):
    """stacks images in list into single one and writes file
    header will be from middle image in the list.
    Time will be between start of first and end of last exposure with exposure length of this difference.

    :param images list of Image list objects to stack
    """

    # go through images and collect info
    names = []
    i = 0
    half = len(images) // 2

    tfirst = images[0].get_time_jd()
    tlast = images[-1].get_time_jd() + images[-1].get_exposure() / 86000
    timejd_mid = (tfirst + tlast) / 2
    timecoverage = (tlast - tfirst) * 86000  # s

    for image in images:  # get stack names
        if "stack" in image.processing_parameters:
            for name in image.get_stack():
                names.append(name)
        else:
            names.append(str(image.get_path()))
        i += 1
        if i == half:
            header = fits.getheader(image.get_path())

    midpoint_WCS = WCS(header)

    reprojected = []
    # reproject all images onto the middle one
    for image in images:
        data = fits.getdata(image.get_path())
        header_wcs = fits.getheader(image.get_path())
        ccddata = ccdproc.CCDData(data, wcs=WCS(header_wcs), unit="adu")
        reprojected.append(wcs_project(ccddata, midpoint_WCS))

    combiner = ccdproc.Combiner(reprojected)
    final_image_data = combiner.average_combine()
    final_image_data.wcs = WCS(header)
    header["EXPTIME"] = timecoverage
    header["EXPOSURE"] = timecoverage
    header["JD"] = tfirst

    filename = "stack-" + str(timejd_mid) + "-e" + "{:.0f}".format(
        timecoverage) + ".fits"

    path = Path("/tmp")
    path = path / filename

    if os.path.exists(path):
        os.remove(path)
    fits.writeto(path, final_image_data, header)

    stacked_image = Image(fixed_parameters={
        "path": path,
        "exposure": timecoverage,
        "time_jd": tfirst,
        "type": "data",
        "id": filename
    },
                          processing_parameters={
                              "flat": True,
                              "dark": True,
                              "stack": names
                          })
    return stacked_image