Пример #1
0
 def test_time_formatting(self):
     mpc_time = "2000 01 01.000001"
     iso_time = "2000-01-01 00:00:00.0864"
     t1 = Time(mpc_time, format='mpc', scale='utc', precision=6)
     t2 = Time(iso_time, format='iso', scale='utc', precision=6)
     t3 = t2.replicate(format='mpc')
     t3.precision = 6
     self.assertEquals(mpc_time, str(t1))
     self.assertEquals(t2.jd, t1.jd)
     self.assertEquals(mpc_time, str(t3))
Пример #2
0
 def test_time_formatting(self):
     mpc_time = "2000 01 01.000001"
     iso_time = "2000-01-01 00:00:00.0864"
     t1 = Time(mpc_time, format='mpc', scale='utc', precision=6)
     t2 = Time(iso_time, format='iso', scale='utc', precision=6)
     t3 = t2.replicate(format='mpc')
     t3.precision = 6
     self.assertEquals(mpc_time, str(t1))
     self.assertEquals(t2.jd, t1.jd)
     self.assertEquals(mpc_time, str(t3))
Пример #3
0
    def _get_time(self):
        # Replicate packet time for each sample
        base_times = Time(
            list(
                chain(*[[
                    scet_to_datetime(
                        f'{self["scet_coarse"][i]}:{self["scet_fine"][i]}')
                ] * n for i, n in enumerate(self['num_samples'])])))
        # For each sample generate sample number and multiply by duration and apply unit
        start_delta = np.hstack([
            (np.arange(ns) * it)
            for ns, it in self[['num_samples', 'integration_time']]
        ])
        # hstack op loses unit
        start_delta = start_delta.value * self['integration_time'].unit

        duration = np.hstack([
            np.ones(num_sample) * int_time for num_sample, int_time in self[
                ['num_samples', 'integration_time']]
        ])
        duration = duration.value * self['integration_time'].unit

        # TODO Write out and simplify
        end_delta = start_delta + duration

        # Add the delta time to base times and convert to relative from start time
        times = base_times + start_delta + (end_delta - start_delta) / 2
        # times -= times[0]
        return times, duration
Пример #4
0
 def from_fits(cls, fitspath):
     header = fits.getheader(fitspath)
     control = QTable.read(fitspath, hdu='CONTROL')
     data = QTable.read(fitspath, hdu='DATA')
     obs_beg = Time(header['DATE_OBS'])
     data['time'] = (data['time'] + obs_beg)
     return cls(control=control, data=data)
Пример #5
0
    def from_packets(cls, packets, eng_packets):
        # Header
        control = Control()
        scet_coarse = packets['NIX00445']
        scet_fine = packets['NIX00446']
        start_times = Time([
            scet_to_datetime(f'{scet_coarse[i]}:{scet_fine[i]}')
            for i in range(len(scet_coarse))
        ])

        control['summing_value'] = packets['NIX00088']
        control['averaging_value'] = packets['NIX00490']
        control['index'] = range(len(control))

        delta_time = ((control['summing_value'] * control['averaging_value']) /
                      1000.0)
        samples = packets['NIX00089']

        offsets = [
            delta_time[i] * 0.5 * np.arange(ns) * u.s
            for i, ns in enumerate(samples)
        ]
        time = Time(
            np.hstack(
                [start_times[i] + offsets[i] for i in range(len(offsets))]))
        timedel = np.hstack(offsets).value * u.s

        # Data
        try:
            data = Data()
            data['time'] = time
            data['timedel'] = timedel
            data['cha_diode0'] = packets['NIX00090']
            data['cha_diode1'] = packets['NIX00091']
            data['chb_diode0'] = packets['NIX00092']
            data['chb_diode1'] = packets['NIX00093']
            data['control_index'] = np.hstack(
                [np.full(ns, i) for i, ns in enumerate(samples)])
        except ValueError as e:
            logger.warning(e)
            return None

        return cls(control=control, data=data)
Пример #6
0
def observable2dict(nrm, multi=False, display=False):
    """ Convert nrm data in an Observable loaded with `ObservablesFromText` into 
        a dictionary compatible with oifits.save and oifits.show function.
    nrm:   an ObservablesFromText object, treated as a target if nrm_c=None
    multi:  Bool. If true, do not take mean or median of slices
            (preserve separate integrations)
    """

    info4oif = nrm.info4oif_dict
    ctrs_inst = info4oif['ctrs_inst']
    t = Time('%s-%s-%s' %
             (info4oif['year'], info4oif['month'], info4oif['day']), format='fits')
    ins = info4oif['telname']
    filt = info4oif['filt']

    wl, e_wl = oifits.GetWavelength(ins, filt)

    bls = nrm.bls
    # Index 0 and 1 reversed to get the good u-v coverage (same fft)
    ucoord = bls[:, 1]
    vcoord = bls[:, 0]

    D = 6.5  # Primary mirror display

    theta = np.linspace(0, 2*np.pi, 100)

    x = D/2. * np.cos(theta)  # Primary mirror display
    y = D/2. * np.sin(theta)

    bl_vis = ((ucoord**2 + vcoord**2)**0.5)

    tuv = nrm.tuv
    v1coord = tuv[:, 0, 0]
    u1coord = tuv[:, 0, 1]
    v2coord = tuv[:, 1, 0]
    u2coord = tuv[:, 1, 1]
    u3coord = -(u1coord+u2coord)
    v3coord = -(v1coord+v2coord)

    bl_cp = []
    n_bispect = len(v1coord)
    for k in range(n_bispect):
        B1 = np.sqrt(u1coord[k] ** 2 + v1coord[k] ** 2)
        B2 = np.sqrt(u2coord[k] ** 2 + v2coord[k] ** 2)
        B3 = np.sqrt(u3coord[k] ** 2 + v3coord[k] ** 2)
        bl_cp.append(np.max([B1, B2, B3]))  # rad-1
    bl_cp = np.array(bl_cp)

    flagVis = [False] * nrm.nbl
    flagT3 = [False] * nrm.ncp

    if multi == True:
        nrmd2c = populate_NRM(nrm, method='multi') # RAC 2021
    else:
        nrmd2c = populate_NRM(nrm, method='med')

    dct = {'OI_VIS2': {'VIS2DATA': nrmd2c.vis2,
                       'VIS2ERR': nrmd2c.e_vis2,
                       'UCOORD': ucoord,
                       'VCOORD': vcoord,
                       'STA_INDEX': nrm.bholes,
                       'MJD': t.mjd,
                       'INT_TIME': info4oif['itime'],
                       'TIME': 0,
                       'TARGET_ID': 1,
                       'FLAG': flagVis,
                       'BL': bl_vis
                       },

           'OI_VIS': {'TARGET_ID': 1,
                      'TIME': 0,
                      'MJD': t.mjd,
                      'INT_TIME': info4oif['itime'],
                      'VISAMP': nrmd2c.visamp,
                      'VISAMPERR': nrmd2c.e_visamp,
                      'VISPHI': nrmd2c.visphi,
                      'VISPHIERR': nrmd2c.e_visphi,
                      'UCOORD': ucoord,
                      'VCOORD': vcoord,
                      'STA_INDEX': nrm.bholes,
                      'FLAG': flagVis,
                      'BL': bl_vis
                      },

           'OI_T3': {'TARGET_ID': 1,
                     'TIME': 0,
                     'MJD': t.mjd,
                     'INT_TIME': info4oif['itime'],
                     'T3PHI': nrmd2c.cp,
                     'T3PHIERR': nrmd2c.e_cp,
                     'T3AMP': nrmd2c.cpamp,
                     'T3AMPERR': nrmd2c.e_cp,
                     'U1COORD': u1coord,
                     'V1COORD': v1coord,
                     'U2COORD': u2coord,
                     'V2COORD': v2coord,
                     'STA_INDEX': nrm.tholes,
                     'FLAG': flagT3,
                     'BL': bl_cp
                     },

           'OI_WAVELENGTH': {'EFF_WAVE': wl,
                             'EFF_BAND': e_wl
                             },

           'info': {'TARGET': info4oif['objname'],
                    'CALIB': info4oif['objname'],
                    'OBJECT': info4oif['objname'],
                    'FILT': info4oif['filt'],
                    'INSTRUME': info4oif['instrument'],
                    'ARRNAME': info4oif['arrname'],
                    'MASK': info4oif['arrname'], # oifits.py looks for dct.info['MASK']
                    'MJD': t.mjd,
                    'DATE-OBS': t.fits,
                    'TELESCOP': info4oif['telname'],
                    'OBSERVER': 'UNKNOWN',
                    'INSMODE': info4oif['pupil'],
                    'PSCALE': info4oif['pscale_mas'],
                    'STAXY': info4oif['ctrs_inst'], # as-built mask hole coords
                    'ISZ': 77,  # size of the image needed (or fov)
                    'NFILE': 0,
                    'PA': info4oif['pa'],
                    'CTRS_EQT':info4oif['ctrs_eqt'] # mask hole coords rotated to equatotial
                    }
           }

    if display:
        plt.figure(figsize=(14.2, 7))
        plt.subplot(1, 2, 1)
        # Index 0 and 1 reversed to get the good u-v coverage (same fft)
        #lt.scatter(ctrs[:, 1], ctrs[:, 0], s=2e3, c='', edgecolors='navy')
        plt.scatter(ctrs[:, 1], ctrs[:, 0], s=2e3,       edgecolors='navy')
        #lt.scatter(-1000, 1000, s=5e1, c='',
        plt.scatter(-1000, 1000, s=5e1,      
                    edgecolors='navy', label='Aperture mask')
        plt.plot(x, y, '--', color='gray', label='Primary mirror equivalent')

        plt.xlabel('Aperture x-coordinate [m]')
        plt.ylabel('Aperture y-coordinate [m]')
        plt.legend(fontsize=8)
        plt.axis([-4., 4., -4., 4.])

        plt.subplot(1, 2, 2)
        #lt.scatter(ucoord, vcoord, s=1e2, c='', edgecolors='navy')
        plt.scatter(ucoord, vcoord, s=1e2,       edgecolors='navy')
        #lt.scatter(-ucoord, -vcoord, s=1e2, c='', edgecolors='crimson')
        plt.scatter(-ucoord, -vcoord, s=1e2,       edgecolors='crimson')

        plt.plot(0, 0, 'k+')
        plt.axis((D, -D, -D, D))
        plt.xlabel('Fourier u-coordinate [m]')
        plt.ylabel('Fourier v-coordinate [m]')
        plt.tight_layout()

        Plot_observables(nrm, display=display)
        #if nrm_c: Plot_observables(nrm_c=display)  # Plot calibrated or single object raw oifits data
    return dct
Пример #7
0
 def to_time(self):
     return Time(self.to_datetime())
Пример #8
0
    def from_packets(cls, packets, eng_packets):
        # Control
        control = Control.from_packets(packets)

        control['pixel_mask'] = np.unique(_get_pixel_mask(packets), axis=0)
        control['detector_mask'] = np.unique(_get_detector_mask(packets),
                                             axis=0)
        control['rcr'] = np.unique(packets['NIX00401']).astype(np.int16)
        control['index'] = range(len(control))

        e_min = np.array(packets['NIXD0442'])
        e_max = np.array(packets['NIXD0443'])
        energy_unit = np.array(packets['NIXD0019']) + 1
        num_times = np.array(packets['NIX00089'])
        total_num_times = num_times.sum()

        cs, ck, cm = control['compression_scheme_counts_skm'][0]

        counts, counts_var = decompress(packets['NIX00268'],
                                        s=cs,
                                        k=ck,
                                        m=cm,
                                        return_variance=True)
        counts = counts.reshape(total_num_times, -1)
        counts_var = counts_var.reshape(total_num_times, -1)
        full_counts = np.zeros((total_num_times, 32))
        full_counts_var = np.zeros((total_num_times, 32))

        cids = [
            np.arange(emin, emax + 1, eunit)
            for (emin, emax, eunit) in zip(e_min, e_max, energy_unit)
        ]

        control['energy_bin_mask'] = np.full((1, 32), False, np.ubyte)
        control['energy_bin_mask'][:, cids] = True

        dl_energies = np.array([[ENERGY_CHANNELS[ch]['e_lower']
                                 for ch in chs] +
                                [ENERGY_CHANNELS[chs[-1]]['e_upper']]
                                for chs in cids][0])

        sci_energies = np.hstack(
            [[ENERGY_CHANNELS[ch]['e_lower'] for ch in range(32)],
             ENERGY_CHANNELS[31]['e_upper']])
        ind = 0
        for nt in num_times:
            e_ch_start = 0
            e_ch_end = counts.shape[1]
            if dl_energies[0] == 0:
                full_counts[ind:ind + nt, 0] = counts[ind:ind + nt, 0]
                full_counts_var[ind:ind + nt, 0] = counts_var[ind:ind + nt, 0]
                e_ch_start = 1
            if dl_energies[-1] == np.inf:
                full_counts[ind:ind + nt, -1] = counts[ind:ind + nt, -1]
                full_counts_var[ind:ind + nt, -1] = counts[ind:ind + nt, -1]
                e_ch_end -= 1

            torebin = np.where((dl_energies >= 4.0) & (dl_energies <= 150.0))
            full_counts[ind:ind + nt, 1:-1] = np.apply_along_axis(
                rebin_proportional, 1, counts[ind:ind + nt,
                                              e_ch_start:e_ch_end],
                dl_energies[torebin], sci_energies[1:-1])

            full_counts_var[ind:ind + nt, 1:-1] = np.apply_along_axis(
                rebin_proportional, 1, counts_var[ind:ind + nt,
                                                  e_ch_start:e_ch_end],
                dl_energies[torebin], sci_energies[1:-1])

            ind += nt

        if counts.sum() != full_counts.sum():
            raise ValueError(
                'Original and reformatted count totals do not match')

        delta_time = (np.array(packets['NIX00441'], np.uint16)) * 0.1 * u.s
        closing_time_offset = (np.array(packets['NIX00269'],
                                        np.uint16)) * 0.1 * u.s

        # TODO incorporate into main loop above
        centers = []
        deltas = []
        last = 0
        for i, nt in enumerate(num_times):
            edge = np.hstack([
                delta_time[last:last + nt],
                delta_time[last + nt - 1] + closing_time_offset[i]
            ])
            delta = np.diff(edge)
            center = edge[:-1] + delta / 2
            centers.append(center)
            deltas.append(delta)
            last = last + nt

        centers = np.hstack(centers)
        deltas = np.hstack(deltas)

        # Data
        data = Data()
        data['time'] = Time(scet_to_datetime(f'{int(control["time_stamp"][0])}:0')) \
            + centers
        data['timedel'] = deltas

        ts, tk, tm = control['compression_scheme_triggers_skm'][0]
        triggers, triggers_var = decompress(packets['NIX00267'],
                                            s=ts,
                                            k=tk,
                                            m=tm,
                                            return_variance=True)

        data['triggers'] = triggers
        data['triggers_err'] = np.sqrt(triggers_var)
        data['counts'] = full_counts * u.ct
        data['counts_err'] = np.sqrt(full_counts_var) * u.ct
        data['control_index'] = 0

        return cls(control=control, data=data)
Пример #9
0
    def from_packets(cls, packets, eng_packets):
        # Control
        control = Control.from_packets(packets)
        control.remove_column('num_structures')
        control = unique(control)
        if len(control) != 1:
            raise ValueError()
        control['index'] = range(len(control))

        data = Data()
        data['control_index'] = np.full(len(packets['NIX00441']), 0)
        data['delta_time'] = (np.array(packets['NIX00441'],
                                       np.uint16)) * 0.1 * u.s
        unique_times = np.unique(data['delta_time'])

        # time = np.array([])
        # for dt in set(self.delta_time):
        #     i, = np.where(self.delta_time == dt)
        #     nt = sum(np.array(packets['NIX00258'])[i])
        #     time = np.append(time, np.repeat(dt, nt))
        # self.time = time

        data['rcr'] = packets['NIX00401']
        data['pixel_mask1'] = _get_pixel_mask(packets, 'NIXD0407')
        data['pixel_mask2'] = _get_pixel_mask(packets, 'NIXD0444')
        data['pixel_mask3'] = _get_pixel_mask(packets, 'NIXD0445')
        data['pixel_mask4'] = _get_pixel_mask(packets, 'NIXD0446')
        data['pixel_mask5'] = _get_pixel_mask(packets, 'NIXD0447')
        data['detector_masks'] = _get_detector_mask(packets)
        data['integration_time'] = (np.array(packets['NIX00405'])) * 0.1

        ts, tk, tm = control['compression_scheme_triggers_skm'][0]
        triggers, triggers_var = decompress(
            [packets[f'NIX00{i}'] for i in range(242, 258)],
            s=ts,
            k=tk,
            m=tm,
            return_variance=True)

        data['triggers'] = triggers.T
        data['triggers_err'] = np.sqrt(triggers_var).T

        tids = np.searchsorted(data['delta_time'], unique_times)
        data = data[tids]

        num_energy_groups = sum(packets['NIX00258'])

        # Data
        vis = np.zeros((unique_times.size, 32, 32), dtype=complex)
        vis_err = np.zeros((unique_times.size, 32, 32), dtype=complex)
        e_low = np.array(packets['NIXD0016'])
        e_high = np.array(packets['NIXD0017'])

        # TODO create energy bin mask
        control['energy_bin_mask'] = np.full((1, 32), False, np.ubyte)
        all_energies = set(np.hstack([e_low, e_high]))
        control['energy_bin_mask'][:, list(all_energies)] = True

        data['flux'] = np.array(packets['NIX00261']).reshape(
            unique_times.size, -1)
        num_detectors = packets['NIX00262'][0]
        detector_id = np.array(packets['NIX00100']).reshape(
            unique_times.size, -1, num_detectors)

        # vis[:, detector_id[0], e_low.reshape(unique_times.size, -1)[0]] = (
        #         np.array(packets['NIX00263']) + np.array(packets['NIX00264'])
        #         * 1j).reshape(unique_times.size, num_detectors, -1)

        ds, dk, dm = control['compression_scheme_counts_skm'][0]
        real, real_var = decompress(packets['NIX00263'],
                                    s=ds,
                                    k=dk,
                                    m=dm,
                                    return_variance=True)
        imaginary, imaginary_var = decompress(packets['NIX00264'],
                                              s=ds,
                                              k=dk,
                                              m=dm,
                                              return_variance=True)

        mesh = np.ix_(np.arange(unique_times.size), detector_id[0][0],
                      e_low.reshape(unique_times.size, -1)[0])
        vis[mesh] = (real + imaginary * 1j).reshape(unique_times.size,
                                                    num_detectors, -1)

        # TODO this doesn't seem correct prob need combine in a better
        vis_err[mesh] = (np.sqrt(real_var) +
                         np.sqrt(imaginary_var) * 1j).reshape(
                             unique_times.size, num_detectors, -1)

        data['visibility'] = vis
        data['visibility_err'] = vis_err

        data['time'] = Time(scet_to_datetime(f'{int(control["time_stamp"][0])}:0')) \
            + data['delta_time'] + data['integration_time'] / 2
        data['timedel'] = data['integration_time']

        return cls(control=control, data=data)
Пример #10
0
    def from_packets(cls, packets, eng_packets):
        # Control
        ssid = packets['SSID'][0]

        control = Control.from_packets(packets)

        control.remove_column('num_structures')
        control = unique(control)

        if len(control) != 1:
            raise ValueError(
                'Creating a science product form packets from multiple products'
            )

        control['index'] = 0

        data = Data()
        data['delta_time'] = (np.array(packets['NIX00441'],
                                       np.int32)) * 0.1 * u.s
        unique_times = np.unique(data['delta_time'])

        data['rcr'] = np.array(packets['NIX00401'], np.ubyte)
        data['num_pixel_sets'] = np.array(packets['NIX00442'], np.ubyte)
        pixel_masks = _get_pixel_mask(packets, 'NIXD0407')
        pixel_masks = pixel_masks.reshape(-1, data['num_pixel_sets'][0], 12)
        if ssid == 21 and data['num_pixel_sets'][0] != 12:
            pixel_masks = np.pad(pixel_masks,
                                 ((0, 0), (0, 12 - data['num_pixel_sets'][0]),
                                  (0, 0)))
        data['pixel_masks'] = pixel_masks
        data['detector_masks'] = _get_detector_mask(packets)
        data['integration_time'] = (np.array(packets.get('NIX00405'),
                                             np.uint16)) * 0.1 * u.s

        # TODO change once FSW fixed
        ts, tk, tm = control['compression_scheme_counts_skm'][0]
        triggers, triggers_var = decompress(
            [packets.get(f'NIX00{i}') for i in range(242, 258)],
            s=ts,
            k=tk,
            m=tm,
            return_variance=True)

        data['triggers'] = triggers.T
        data['triggers_err'] = np.sqrt(triggers_var).T
        data['num_energy_groups'] = np.array(packets['NIX00258'], np.ubyte)

        tmp = dict()
        tmp['e_low'] = np.array(packets['NIXD0016'], np.ubyte)
        tmp['e_high'] = np.array(packets['NIXD0017'], np.ubyte)
        tmp['num_data_elements'] = np.array(packets['NIX00259'])
        unique_energies_low = np.unique(tmp['e_low'])
        unique_energies_high = np.unique(tmp['e_high'])

        # counts = np.array(eng_packets['NIX00260'], np.uint32)

        cs, ck, cm = control['compression_scheme_counts_skm'][0]
        counts, counts_var = decompress(packets.get('NIX00260'),
                                        s=cs,
                                        k=ck,
                                        m=cm,
                                        return_variance=True)

        counts = counts.reshape(unique_times.size, unique_energies_low.size,
                                data['detector_masks'][0].sum(),
                                data['num_pixel_sets'][0].sum())

        counts_var = counts_var.reshape(unique_times.size,
                                        unique_energies_low.size,
                                        data['detector_masks'][0].sum(),
                                        data['num_pixel_sets'][0].sum())
        # t x e x d x p -> t x d x p x e
        counts = counts.transpose((0, 2, 3, 1))
        counts_var = np.sqrt(counts_var.transpose((0, 2, 3, 1)))
        if ssid == 21:
            out_counts = np.zeros((unique_times.size, 32, 12, 32))
            out_var = np.zeros((unique_times.size, 32, 12, 32))
        elif ssid == 22:
            out_counts = np.zeros((unique_times.size, 32, 4, 32))
            out_var = np.zeros((unique_times.size, 32, 4, 32))

        # energy_index = 0
        # count_index = 0
        # for i, time in enumerate(unique_times):
        #     inds = np.where(data['delta_time'] == time)
        #     cur_num_energies = data['num_energy_groups'][inds].astype(int).sum()
        #     low = np.unique(tmp['e_low'][energy_index:energy_index+cur_num_energies])
        #     high = np.unique(tmp['e_high'][energy_index:energy_index + cur_num_energies])
        #     cur_num_energies = low.size
        #     num_counts = tmp['num_data_elements'][energy_index:energy_index+cur_num_energies].sum()
        #     cur_counts = counts[count_index:count_index+num_counts]
        #     count_index += num_counts
        #     pids = data[inds[0][0]]['pixel_masks']
        #     dids = np.where(data[inds[0][0]]['detector_masks'] == True)
        #     cids = np.full(32, False)
        #     cids[low] = True
        #
        #     if ssid == 21:
        #         cur_counts = cur_counts.reshape(cur_num_energies, dids[0].size, pids.sum())
        #     elif ssid == 22:
        #         cur_counts = cur_counts.reshape(cur_num_energies, dids[0].size, 4)
        #
        dl_energies = np.array([
            [ENERGY_CHANNELS[lch]['e_lower'], ENERGY_CHANNELS[hch]['e_upper']]
            for lch, hch in zip(unique_energies_low, unique_energies_high)
        ]).reshape(-1)
        dl_energies = np.unique(dl_energies)
        sci_energies = np.hstack(
            [[ENERGY_CHANNELS[ch]['e_lower'] for ch in range(32)],
             ENERGY_CHANNELS[31]['e_upper']])

        # If there is any onboard summing of energy channels rebin back to standard sci channels
        if (unique_energies_high - unique_energies_low).sum() > 0:
            rebinned_counts = np.zeros((*counts.shape[:-1], 32))
            rebinned_counts_var = np.zeros((*counts_var.shape[:-1], 32))
            e_ch_start = 0
            e_ch_end = counts.shape[-1]
            if dl_energies[0] == 0.0:
                rebinned_counts[..., 0] = counts[..., 0]
                rebinned_counts_var[..., 0] = counts_var[..., 0]
                e_ch_start += 1
            elif dl_energies[-1] == np.inf:
                rebinned_counts[..., -1] = counts[..., -1]
                rebinned_counts_var[..., -1] = counts_var[..., -1]
                e_ch_end -= 1

            torebin = np.where((dl_energies >= 4.0) & (dl_energies <= 150.0))
            rebinned_counts[..., 1:-1] = np.apply_along_axis(
                rebin_proportional, -1,
                counts[...,
                       e_ch_start:e_ch_end].reshape(-1, e_ch_end - e_ch_start),
                dl_energies[torebin], sci_energies[1:-1]).reshape(
                    (*counts.shape[:-1], 30))

            rebinned_counts_var[..., 1:-1] = np.apply_along_axis(
                rebin_proportional, -1,
                counts_var[..., e_ch_start:e_ch_end].reshape(
                    -1, e_ch_end - e_ch_start), dl_energies[torebin],
                sci_energies[1:-1]).reshape((*counts_var.shape[:-1], 30))

            energy_indices = np.full(32, True)
            energy_indices[[0, -1]] = False

            ix = np.ix_(np.full(unique_times.size, True),
                        data['detector_masks'][0].astype(bool),
                        np.ones(data['num_pixel_sets'][0], dtype=bool),
                        np.full(32, True))

            out_counts[ix] = rebinned_counts
            out_var[ix] = rebinned_counts_var
        else:
            energy_indices = np.full(32, False)
            energy_indices[unique_energies_low.min(
            ):unique_energies_high.max() + 1] = True

            ix = np.ix_(np.full(unique_times.size,
                                True), data['detector_masks'][0].astype(bool),
                        np.ones(data['num_pixel_sets'][0], dtype=bool),
                        energy_indices)

            out_counts[ix] = counts
            out_var[ix] = counts_var

        #     if (high - low).sum() > 0:
        #         raise NotImplementedError()
        #         #full_counts = rebin_proportional(dl_energies, cur_counts, sci_energies)
        #
        #     dids2 = data[inds[0][0]]['detector_masks']
        #     cids2 = np.full(32, False)
        #     cids2[low] = True
        #     tids2 = time == unique_times
        #
        #     if ssid == 21:
        #         out_counts[np.ix_(tids2, cids2, dids2, pids)] = cur_counts
        #     elif ssid == 22:
        #         out_counts[np.ix_(tids2, cids2, dids2)] = cur_counts

        if counts.sum() != out_counts.sum():
            import ipdb
            ipdb.set_trace()
            raise ValueError(
                'Original and reformatted count totals do not match')

        control['energy_bin_mask'] = np.full((1, 32), False, np.ubyte)
        all_energies = set(np.hstack([tmp['e_low'], tmp['e_high']]))
        control['energy_bin_mask'][:, list(all_energies)] = True
        # time x energy x detector x pixel
        # counts = np.array(
        #     eng_packets['NIX00260'], np.uint16).reshape(unique_times.size, num_energies,
        #                                                 num_detectors, num_pixels)
        # time x channel x detector x pixel need to transpose to time x detector x pixel x channel

        sub_index = np.searchsorted(data['delta_time'], unique_times)
        data = data[sub_index]

        data['time'] = Time(scet_to_datetime(f'{int(control["time_stamp"][0])}:0')) \
            + data['delta_time'] + data['integration_time'] / 2
        data['timedel'] = data['integration_time']
        data['counts'] = out_counts * u.ct
        data['counts_err'] = out_var * u.ct
        data['control_index'] = control['index'][0]
        data.remove_columns(['delta_time', 'integration_time'])

        data = data['time', 'timedel', 'rcr', 'pixel_masks', 'detector_masks',
                    'num_pixel_sets', 'num_energy_groups', 'triggers',
                    'triggers_err', 'counts', 'counts_err']
        data['control_index'] = 0

        return cls(control=control, data=data)
Пример #11
0
    def from_packets(cls, packets, eng_packets):
        control = Control.from_packets(packets)

        control.remove_column('num_structures')
        control = unique(control)

        if len(control) != 1:
            raise ValueError(
                'Creating a science product form packets from multiple products'
            )

        control['index'] = 0

        data = Data()
        data['start_time'] = (np.array(packets.get('NIX00404'),
                                       np.uint16)) * 0.1 * u.s
        data['rcr'] = np.array(packets.get('NIX00401')[0], np.ubyte)
        data['integration_time'] = (np.array(
            packets.get('NIX00405')[0], np.int16)) * 0.1 * u.s
        data['pixel_masks'] = _get_pixel_mask(packets, 'NIXD0407')
        data['detector_masks'] = _get_detector_mask(packets)
        data['triggers'] = np.array(
            [packets.get(f'NIX00{i}') for i in range(408, 424)], np.int64).T
        data['num_samples'] = np.array(packets.get('NIX00406'), np.int16)

        num_detectors = 32
        num_energies = 32
        num_pixels = 12

        # Data
        tmp = dict()
        tmp['pixel_id'] = np.array(packets.get('NIXD0158'), np.ubyte)
        tmp['detector_id'] = np.array(packets.get('NIXD0153'), np.ubyte)
        tmp['channel'] = np.array(packets.get('NIXD0154'), np.ubyte)
        tmp['continuation_bits'] = packets.get('NIXD0159', np.ubyte)

        control['energy_bin_mask'] = np.full((1, 32), False, np.ubyte)
        all_energies = set(tmp['channel'])
        control['energy_bin_mask'][:, list(all_energies)] = True

        # Find contiguous time indices
        unique_times = np.unique(data['start_time'])
        time_indices = np.searchsorted(unique_times, data['start_time'])

        # Create full count array 0s are not send down, if cb = 0 1 count, for cb 1 just extract
        # and for cb 2 extract and sum
        raw_counts = packets.get('NIX00065')
        counts_1d = []
        raw_count_index = 0
        for cb in tmp['continuation_bits']:
            if cb == 0:
                counts_1d.append(1)
            elif cb == 1:
                cur_count = raw_counts[raw_count_index]
                counts_1d.append(cur_count)
                raw_count_index += cb
            elif cb == 2:
                cur_count = raw_counts[raw_count_index:(raw_count_index + cb)]
                combined_count = int.from_bytes(
                    (cur_count[0] + 1).to_bytes(2, 'big') +
                    cur_count[1].to_bytes(1, 'big'), 'big')
                counts_1d.append(combined_count)
                raw_count_index += cb
            else:
                raise ValueError(
                    f'Continuation bits value of {cb} not allowed (0, 1, 2)')
        counts_1d = np.array(counts_1d, np.uint16)
        # raw_counts = counts_1d

        end_inds = np.cumsum(data['num_samples'])
        start_inds = np.hstack([0, end_inds[:-1]])
        dd = [(tmp['pixel_id'][s:e], tmp['detector_id'][s:e],
               tmp['channel'][s:e], counts_1d[s:e])
              for s, e in zip(start_inds.astype(int), end_inds)]

        counts = np.zeros(
            (len(unique_times), num_detectors, num_pixels, num_energies),
            np.uint32)
        for i, (pid, did, cid, cc) in enumerate(dd):
            counts[time_indices[i], did, pid, cid] = cc

        # Create final count array with 4 dimensions: unique times, 32 det, 32 energies, 12 pixels

        # for i in range(self.num_samples):
        #     tid = np.argwhere(self.raw_counts == unique_times)

        # start_index = 0
        # for i, time_index in enumerate(time_indices):
        #     end_index = np.uint32(start_index + np.sum(data['num_samples'][time_index]))
        #
        #     for did, cid, pid in zip(tmp['detector_id'], tmp['channel'], tmp['pixel_id']):
        #         index_1d = ((tmp['detector_id'] == did) & (tmp['channel'] == cid)
        #                     & (tmp['pixel_id'] == pid))
        #         cur_count = counts_1d[start_index:end_index][index_1d[start_index:end_index]]
        #         # If we have a count assign it other wise do nothing as 0
        #         if cur_count:
        #             counts[i, did, cid, pid] = cur_count[0]
        #
        #     start_index = end_index

        sub_index = np.searchsorted(data['start_time'], unique_times)
        data = data[sub_index]
        data['time'] = Time(scet_to_datetime(f'{int(control["time_stamp"][0])}:0'))\
            + data['start_time'] + data['integration_time']/2
        data['timedel'] = data['integration_time']
        data['counts'] = counts * u.ct
        data['control_index'] = control['index'][0]

        data.remove_columns(['start_time', 'integration_time', 'num_samples'])

        return cls(control=control, data=data)