Exemplo n.º 1
0
        def sidlst_to_csd(sid, lst, sid_ref, t_ref):
            """
            Convert an integer DRAO sidereal day and LST to a float
            CHIME sidereal day

            Parameters
            ----------
            sid : int
                DRAO sidereal day
            lst : float, in hours
                local sidereal time
            sid_ref : int
                DRAO sidereal day at the reference time t_ref
            t_ref : skyfield time object, Julian days
                Reference time

            Returns
            -------
            output : float
                CHIME sidereal day
            """
            csd_ref = int(
                ephemeris.csd(ephemeris.datetime_to_unix(
                    t_ref.utc_datetime())))
            csd = sid - sid_ref + csd_ref
            return csd + lst / ephemeris.SIDEREAL_S / 24.0
Exemplo n.º 2
0
    def __init__(self):

        super(FilterExisting, self).__init__()

        self.csd_list = []
        self.corr_files = {}

        if mpiutil.rank0:
            # Look for CSDs in the current directory
            import glob

            files = glob.glob("*")
            if self.existing_csd_regex:
                for file_ in files:
                    mo = re.search(self.existing_csd_regex, file_)
                    if mo is not None:
                        self.csd_list.append(int(mo.group(1)))

            # Search the database to get the start and end times of all correlation files
            from chimedb import data_index as di
            from chimedb.core import connect
            from ch_util import ephemeris

            connect()
            query = (di.ArchiveFile.select(
                di.ArchiveAcq.name,
                di.ArchiveFile.name,
                di.CorrFileInfo.start_time,
                di.CorrFileInfo.finish_time,
            ).join(di.ArchiveAcq).switch(di.ArchiveFile).join(di.CorrFileInfo))

            for acq, fname, start, finish in query.tuples():

                if start is None or finish is None:
                    continue

                start_csd = ephemeris.csd(start)
                finish_csd = ephemeris.csd(finish)

                name = os.path.join(acq, fname)
                self.corr_files[name] = (start_csd, finish_csd)

            self.log.debug("Skipping existing CSDs %s", repr(self.csd_list))

        # Broadcast results to other ranks
        self.corr_files = mpiutil.world.bcast(self.corr_files, root=0)
        self.csd_list = mpiutil.world.bcast(self.csd_list, root=0)
Exemplo n.º 3
0
    def add_file(self, filename):

        # Make sure this file is not currently in the transit tracker
        if self.contains_file(filename):
            return

        # Read file time range
        with h5py.File(filename, 'r') as handler:
            timestamp = handler['index_map']['time']['ctime'][:]

        timestamp0 = np.median(timestamp)

        # Convert to right ascension
        ra = ephemeris.lsa(timestamp)
        csd = ephemeris.csd(timestamp)

        # Loop over available sources
        for name, src in self.iteritems():

            src_ra, src_dec = ephemeris.object_coords(src.body,
                                                      date=timestamp0,
                                                      deg=True)

            src_ra = (src_ra + src.shift) % 360.0

            # Determine if any times in this file fall
            # in a window around transit of this source
            hour_angle = ra - src_ra
            hour_angle = hour_angle + 360.0 * (hour_angle < -180.0) - 360.0 * (
                hour_angle > 180.0)

            good_time = np.flatnonzero(np.abs(hour_angle) < src.window)

            if good_time.size > 0:

                # Determine the csd for the transit contained in this file
                icsd = np.unique(
                    np.floor(csd[good_time] - (hour_angle[good_time] / 360.0)))

                if icsd.size > 1:
                    RuntimeError("Error estimating CSD.")

                key = int(icsd[0])

                min_ha, max_ha = np.percentile(hour_angle, [0, 100])

                # Add to list of files to analyze for this source
                if key in src.files:
                    src.files[key].append((filename, hour_angle))
                    src.file_span[key][0] = min(min_ha, src.file_span[key][0])
                    src.file_span[key][1] = max(max_ha, src.file_span[key][1])

                else:
                    src.files[key] = [(filename, hour_angle)]
                    src.file_span[key] = [min_ha, max_ha]
Exemplo n.º 4
0
def test_csd():
    """Test CHIME sidereal day definition."""
    # csd_zero = 1384489290.908534
    # csd_zero = 1384489290.224582
    csd_zero = 1384489291.0995445
    et1 = ephemeris.datetime_to_unix(datetime(2013, 11, 14))

    # Check the zero of CSD (1e-7 accuracy ~ 10 milliarcsec)
    assert ephemeris.csd(csd_zero) == approx(0.0, abs=1e-6)

    # Check that the fractional part is equal to the transit RA
    assert (360.0 * (ephemeris.csd(et1) % 1.0)) == approx(
        ephemeris.chime.unix_to_lsa(et1), abs=1e-7
    )

    # Check a specific precalculated CSD
    csd1 = -1.1848449724498247

    assert ephemeris.csd(et1) == approx(csd1, abs=1e-7)

    # Check vectorization
    test_args = np.array([csd_zero, et1])
    test_ans = np.array([0.0, csd1])
    assert ephemeris.csd(test_args) == approx(test_ans, abs=1e-7)
Exemplo n.º 5
0
    def setup(self, files):
        """Divide the list of files up into sidereal days.

        Parameters
        ----------
        files : list
            List of files to load.
        """

        self.files = files

        filemap = None
        if self.comm.rank == 0:

            se_times = get_times(self.files)
            se_csd = ephemeris.csd(se_times)
            days = np.unique(np.floor(se_csd).astype(np.int))

            # Construct list of files in each day
            filemap = [(day, _days_in_csd(day, se_csd, extra=self.padding))
                       for day in days]

            # Filter our days with only a few files in them.
            filemap = [(day, dmap) for day, dmap in filemap if dmap.size > 1]
            filemap.sort()

        self.filemap = self.comm.bcast(filemap, root=0)

        # Set up frequency selection.
        if self.freq_physical:
            basefreq = np.linspace(800.0, 400.0, 1024, endpoint=False)
            self.freq_sel = sorted(
                set([
                    np.argmin(np.abs(basefreq - freq))
                    for freq in self.freq_physical
                ]))

        elif self.channel_range and (len(self.channel_range) <= 3):
            self.freq_sel = list(range(*self.channel_range))

        elif self.channel_index:
            self.freq_sel = self.channel_index

        else:
            self.freq_sel = None
Exemplo n.º 6
0
    def view(self):
        if self.lsd is None:
            return panel.pane.Markdown("No data selected.")
        try:
            sens_container = self.data.load_file(self.revision, self.lsd,
                                                 "sensitivity")
        except DataError as err:
            return panel.pane.Markdown(
                f"Error: {str(err)}. Please report this problem.")

        # Index map for ra (x-axis)
        sens_csd = csd(sens_container.time)
        index_map_ra = (sens_csd - self.lsd.lsd) * 360
        axis_name_ra = "RA [degrees]"

        # Index map for frequency (y-axis)
        index_map_f = np.linspace(800.0, 400.0, 1024, endpoint=False)
        axis_name_f = "Frequency [MHz]"

        # Apply data selections
        if self.polarization == self.mean_pol_text:
            sel_pol = np.where((sens_container.index_map["pol"] == "XX")
                               | (sens_container.index_map["pol"] == "YY"))[0]
            sens = np.squeeze(sens_container.measured[:, sel_pol])
            sens = np.squeeze(np.nanmean(sens, axis=1))
        else:
            sel_pol = np.where(
                sens_container.index_map["pol"] == self.polarization)[0]
            sens = np.squeeze(sens_container.measured[:, sel_pol])

        if self.flag_mask:
            sens = np.where(self._flags_mask(index_map_ra).T, np.nan, sens)

        # Set flagged data to nan
        sens = np.where(sens == 0, np.nan, sens)

        if self.mask_rfi:
            try:
                rfi_container = self.data.load_file(self.revision, self.lsd,
                                                    "rfi")
            except DataError as err:
                return panel.pane.Markdown(
                    f"Error: {str(err)}. Please report this problem.")
            rfi = np.squeeze(rfi_container.mask[:])

            # calculate percentage masked to print later
            rfi_percentage = round(np.count_nonzero(rfi) / rfi.size * 100)

            sens *= np.where(rfi, np.nan, 1)

        if self.divide_by_estimate:
            estimate = np.squeeze(sens_container.radiometer[:, sel_pol])
            if self.polarization == self.mean_pol_text:
                estimate = np.squeeze(np.nanmean(estimate, axis=1))
            estimate = np.where(estimate == 0, np.nan, estimate)
            sens = sens / estimate

        if self.transpose:
            sens = sens.T
            index_x = index_map_f
            index_y = index_map_ra
            axis_names = [axis_name_f, axis_name_ra]
            xlim, ylim = self.ylim, self.xlim
        else:
            index_x = index_map_ra
            index_y = index_map_f
            axis_names = [axis_name_ra, axis_name_f]
            xlim, ylim = self.xlim, self.ylim

        image_opts = {
            "clim": self.colormap_range,
            "logz": self.logarithmic_colorscale,
            "cmap": process_cmap("viridis", provider="matplotlib"),
            "colorbar": True,
            "xticks": [0, 60, 120, 180, 240, 300, 360],
        }
        if self.mask_rfi:
            image_opts["title"] = f"RFI mask: {rfi_percentage}%"

        overlay_opts = {
            "xlim": xlim,
            "ylim": ylim,
        }

        # Fill in missing data
        img = hv_image_with_gaps(index_x,
                                 index_y,
                                 sens,
                                 opts=image_opts,
                                 kdims=axis_names).opts(**overlay_opts)

        if self.serverside_rendering is not None:
            # set colormap
            cmap_inferno = copy.copy(matplotlib_cm.get_cmap("viridis"))

            # Set z-axis normalization (other possible values are 'eq_hist', 'cbrt').
            if self.logarithmic_colorscale:
                normalization = "log"
            else:
                normalization = "linear"

            # datashade/rasterize the image
            img = self.serverside_rendering(
                img,
                cmap=cmap_inferno,
                precompute=True,
                x_range=xlim,
                y_range=ylim,
                normalization=normalization,
                # TODO: set xticks like above
            )

        if self.mark_day_time:
            # Calculate the sun rise/set times on this sidereal day

            # Start and end times of the CSD
            start_time = csd_to_unix(self.lsd.lsd)
            end_time = csd_to_unix(self.lsd.lsd + 1)

            times, rises = chime.rise_set_times(
                skyfield_wrapper.ephemeris["sun"],
                start_time,
                end_time,
                diameter=-10,
            )
            sun_rise = 0
            sun_set = 0
            for t, r in zip(times, rises):
                if r:
                    sun_rise = (unix_to_csd(t) % 1) * 360
                else:
                    sun_set = (unix_to_csd(t) % 1) * 360

            # Highlight the day time data
            opts = {
                "color": "grey",
                "alpha": 0.5,
                "line_width": 1,
                "line_color": "black",
                "line_dash": "dashed",
            }

            span = hv.HSpan if self.transpose else hv.VSpan
            if sun_rise < sun_set:
                img *= span(sun_rise, sun_set).opts(**opts)
            else:
                img *= span(self.xlim[0], sun_set).opts(**opts)
                img *= span(sun_rise, self.xlim[-1]).opts(**opts)

        img.opts(
            # Fix height, but make width responsive
            height=self.height,
            responsive=True,
            bgcolor="lightgray",
            shared_axes=True,
        )

        return panel.Row(img, width_policy="max")