Exemple #1
0
def test_level1_processor_generate_filename(config, product):
    config.get.side_effect = [td.soop.DIR, '.']
    processor = FitsL1Processor('some/path')
    config.get.side_effect = [td.soop.DIR, '.']
    product.control.colnames = []
    beg = SCETime(coarse=0, fine=0)
    end = SCETime(coarse=1, fine=2**15)
    avg = beg + (end - beg) / 2
    product.obt_beg = beg
    product.obt_avg = avg
    product.obt_end = end
    product.obs_beg = beg.to_datetime()
    product.obs_avg = avg.to_datetime()
    product.obs_end = end.to_datetime()
    product.type = 'ql'
    product.scet_timerange = SCETimeRange(start=SCETime(0, 0),
                                          end=SCETime(coarse=0,
                                                      fine=2**16 - 1))
    product.utc_timerange = product.scet_timerange.to_timerange()
    product.level = 'L1'
    product.name = 'a_name'
    filename = processor.generate_filename(product, version=1)
    assert filename == 'solo_L1_stix-ql-a-name_20000101_V01.fits'
    product.type = 'sci'
    filename = processor.generate_filename(product, version=1)
    assert filename == 'solo_L1_stix-sci-a-name_20000101T000000-20000101T000001_V01.fits'
Exemple #2
0
    def _get_time(self):
        # Replicate the start time of each for the number of samples in that packet
        base_coarse, base_fine = zip(
            *[([ct] * ns, [ft] * ns) for ns, ct, ft in self[
                ['num_samples', 'scet_coarse', 'scet_fine']]])
        base_coarse = np.hstack(base_coarse)
        base_fine = np.hstack(base_fine)
        bases = SCETime(base_coarse, base_fine)

        # Create start time for each time bin by multiplying the duration by the sample number
        deltas = SCETimeDelta(
            np.hstack([(np.arange(ns) * it)
                       for ns, it in self[['num_samples', 'integration_time']]
                       ]))

        # Create integration time for each sample in each packet by replicating the duration for
        # number of sample in each packet
        durations = SCETimeDelta(
            np.hstack([
                np.ones(num_sample) * int_time for num_sample, int_time in
                self[['num_samples', 'integration_time']]
            ]))

        # Add the delta time to base times and convert to bin centers
        times = bases + deltas + (durations / 2)

        # Create a time range object covering the total observation time
        tr = SCETimeRange(start=bases[0],
                          end=bases[-1] + deltas[-1] + durations[-1])

        return times, durations, tr
Exemple #3
0
    def _get_time(cls, control, num_energies, packets, pad_after):
        times = []
        durations = []
        start = 0
        for i, (ns, it) in enumerate(control['num_samples',
                                             'integration_time']):
            off_sets = packets.get_value('NIX00485')[start:start + ns] * it
            base_time = SCETime(control["scet_coarse"][i],
                                control["scet_fine"][i])
            start_times = base_time + off_sets
            end_times = base_time + off_sets + it
            cur_time = start_times + (end_times - start_times) / 2
            times.extend(cur_time)
            durations.extend([it] * ns)
            start += ns

        time = np.array([(t.coarse, t.fine) for t in times])
        time = np.pad(time, ((0, pad_after), (0, 0)), mode='edge')
        time = SCETime(time[:, 0], time[:, 1]).reshape(-1, num_energies)
        duration = SCETimeDelta(
            np.pad(np.hstack(durations),
                   (0, pad_after)).reshape(-1, num_energies))

        scet_timerange = SCETimeRange(start=time[0, 0] - duration[0, 0] / 2,
                                      end=time[-1, -1] + duration[-1, 0] / 2)

        return duration, time, scet_timerange
Exemple #4
0
def test_level0_processor_generate_filename():
    with patch('stixcore.products.level0.quicklookL0.QLProduct') as product:
        processor = FitsL0Processor('some/path')
        product.control.colnames = []
        product.type = 'ql'
        product.scet_timerange = SCETimeRange(start=SCETime(0, 0),
                                              end=SCETime(1234, 1234))
        product.level = 'LB'
        product.name = 'a_name'
        filename = processor.generate_filename(product, version=1)
        assert filename == 'solo_LB_stix-ql-a-name_0000000000_V01.fits'

    with patch('stixcore.products.level0.scienceL0.ScienceProduct') as product:
        product.type = 'sci'
        product.control.colnames = []
        product.obs_avg.coarse = 0
        product.level = 'L0'
        product.name = 'a_name'
        product.scet_timerange = SCETimeRange(start=SCETime(12345, 6789),
                                              end=SCETime(98765, 4321))
        filename = processor.generate_filename(product, version=1)
        assert filename == 'solo_L0_stix-sci-a-name_0000012345-0000098765_V01.fits'

        dummy_control_data = {
            'request_id': [123456],
            'tc_packet_seq_control': [98765]
        }

        product.control.__getitem__.side_effect = dummy_control_data.__getitem__
        product.control.colnames = ['request_id']
        filename = processor.generate_filename(product, version=1)
        assert filename == 'solo_L0_stix-sci-a-name' \
                           '_0000012345-0000098765_V01_123456.fits'

        product.control.colnames = ['request_id', 'tc_packet_seq_control']
        filename = processor.generate_filename(product, version=1)
        assert filename == 'solo_L0_stix-sci-a-name' \
                           '_0000012345-0000098765_V01_123456-98765.fits'
Exemple #5
0
def test_level1_processor_generate_primary_header(config, product):
    config.get.side_effect = [td.soop.DIR, '.']
    processor = FitsL1Processor('some/path')
    beg = SCETime(coarse=683769519, fine=0)
    end = SCETime(coarse=beg.coarse + 24 * 60 * 60)
    beg + (end - beg) / 2
    product.scet_timerange = SCETimeRange(start=beg, end=end)
    product.utc_timerange = product.scet_timerange.to_timerange()
    product.raw = ['packet1.xml', 'packet2.xml']
    product.parent = ['l01.fits', 'l02.fts']
    product.level = 'L1'
    product.type = "ql"
    product.service_type = 1
    product.service_subtype = 2
    product.ssid = 3

    test_data = {
        'FILENAME': 'a_filename.fits',
        'OBT_BEG': beg.as_float().value,
        'OBT_END': end.as_float().value,
        'DATE_OBS': product.utc_timerange.start.fits,
        'DATE_BEG': product.utc_timerange.start.fits,
        'DATE_AVG': product.utc_timerange.center.fits,
        'DATE_END': product.utc_timerange.end.fits,
        'STYPE': product.service_type,
        'SSTYPE': product.service_subtype,
        'SSID': product.ssid,
        'TIMESYS': 'UTC',
        'LEVEL': 'L1',
        'OBS_ID': 'SSTX_040A_000_000_5Md2_112;SSTX_040A_000_000_vFLg_11Y',
        'OBS_TYPE': '5Md2;vFLg',
        'OBS_MODE': 'STIX_ANALYSIS;STIX_BASIC',
        'SOOPNAME': '',
        'SOOPTYPE': '',
        'TARGET': '',
        'RSUN_ARC': 1589.33,
        'HGLT_OBS': -0.32,
        'HGLN_OBS': -66.52,
        'RAW_FILE': 'packet1.xml;packet2.xml',
        'PARENT': 'l01.fits;l02.fts'
    }

    header = processor.generate_primary_header('a_filename.fits', product)
    for name, value, *comment in header:
        if name in test_data.keys():
            if isinstance(value, float):
                assert np.allclose(test_data[name], value)
            else:
                assert value == test_data[name]
Exemple #6
0
def test_timerange():
    tr = SCETimeRange(start=SCETime(coarse=100, fine=0), end=SCETime(coarse=200, fine=0))
    tp_in = SCETime(coarse=150, fine=0)
    tr_in = SCETimeRange(start=SCETime(coarse=150, fine=0), end=SCETime(coarse=160, fine=0))
    tr_out = SCETimeRange(start=SCETime(coarse=150, fine=0), end=SCETime(coarse=250, fine=0))
    tp_out = SCETime(coarse=250, fine=0)
    assert tp_in in tr
    assert tp_out not in tr
    assert tr_in in tr
    assert tr_out not in tr

    tr.expand(tp_out)
    tr.expand(tr_out)

    assert tp_out in tr
    assert tr_out in tr
Exemple #7
0
def test_level0_processor_generate_primary_header(datetime, product):
    processor = FitsL0Processor('some/path')
    datetime.now().isoformat.return_value = '1234-05-07T01:02:03.346'
    product.obs_beg = SCETime(coarse=0, fine=0)
    product.obs_avg = SCETime(coarse=0, fine=2**15)
    product.obs_end = SCETime(coarse=1, fine=2**15)
    product.scet_timerange = SCETimeRange(start=product.obs_beg,
                                          end=product.obs_end)
    product.raw = ['packet1.xml', 'packet2.xml']
    product.parent = ['lb1.fits', 'lb2.fts']
    product.service_type = 1
    product.service_subtype = 2
    product.ssid = 3
    product.level = 'L0'

    test_data = {
        'FILENAME': 'a_filename.fits',
        'DATE': '1234-05-07T01:02:03.346',
        'OBT_BEG': 0.0,
        'OBT_END': 1.5000076295109483,
        'DATE_OBS': '0000000000:00000',
        'DATE_BEG': '0000000000:00000',
        'DATE_AVG': '0000000000:49152',
        'DATE_END': '0000000001:32768',
        'STYPE': 1,
        'SSTYPE': 2,
        'SSID': 3,
        'TIMESYS': "OBT",
        'LEVEL': 'L0',
        'RAW_FILE': 'packet1.xml;packet2.xml',
        'PARENT': 'lb1.fits;lb2.fts'
    }

    header = processor.generate_primary_header('a_filename.fits', product)
    for name, value, *comment in header:
        if name in test_data.keys():
            assert value == test_data[name]
Exemple #8
0
 def scet_timerange(self):
     return SCETimeRange(
         start=self.data['time'][0] - self.data['timedel'][0] / 2,
         end=self.data['time'][-1] + self.data['timedel'][-1] / 2)
Exemple #9
0
    def __call__(self, *args, **kwargs):
        if len(args) == 1 and len(kwargs) == 0:
            if isinstance(args[0], (str, Path)):
                file_path = Path(args[0])
                header = fits.getheader(file_path)

                service_type = int(
                    header.get('stype')) if 'stype' in header else 0
                service_subtype = int(
                    header.get('sstype')) if 'sstype' in header else 0
                parent = header.get('parent').split(
                    ';') if 'parent' in header else ''
                raw = header.get('raw_file').split(
                    ';') if 'raw_file' in header else ''
                try:
                    ssid = int(header.get('ssid'))
                except (ValueError, TypeError):
                    ssid = None
                level = header.get('Level')
                header.get('TIMESYS')

                hdul = fits.open(file_path)
                control = read_qtable(file_path, hdu='CONTROL', hdul=hdul)

                # Weird issue where time_stamp wasn't a proper table column?
                if 'time_stamp' in control.colnames:
                    ts = control['time_stamp'].value
                    control.remove_column('time_stamp')
                    control['time_stamp'] = ts * u.s

                data = read_qtable(file_path, hdu='DATA', hdul=hdul)

                if level == 'LL01':
                    # TODO remova that hack in favor for a proper header information after
                    # https://github.com/i4Ds/STIXCore/issues/224 is solved
                    if "lightcurve" in args[0]:
                        service_type = 21
                        service_subtype = 6
                        ssid = 30
                    if "flareflag" in args[0]:
                        service_type = 21
                        service_subtype = 6
                        ssid = 34

                if level not in ['LB', 'LL01']:
                    data['timedel'] = SCETimeDelta(data['timedel'])
                    offset = SCETime.from_float(header['OBT_BEG'] * u.s)

                    try:
                        control['time_stamp'] = SCETime.from_float(
                            control['time_stamp'])
                    except KeyError:
                        pass

                    data['time'] = offset + data['time']

                energies = None
                if level == 'L1':
                    try:
                        energies = read_qtable(file_path, hdu='ENERGIES')
                    except KeyError:
                        logger.info(
                            f"no ENERGIES data found in FITS: {file_path}")
                idb_versions = defaultdict(SCETimeRange)
                if level in ('L0', 'L1'):
                    try:
                        idbt = read_qtable(file_path, hdu='IDB_VERSIONS')
                        for row in idbt.iterrows():
                            idb_versions[row[0]] = SCETimeRange(
                                start=SCETime.from_float(row[1]),
                                end=SCETime.from_float(row[2]))
                    except KeyError:
                        logger.warn(f"no IDB data found in FITS: {file_path}")

                Product = self._check_registered_widget(
                    level=level,
                    service_type=service_type,
                    service_subtype=service_subtype,
                    ssid=ssid,
                    control=control,
                    data=data,
                    energies=energies)

                return Product(level=level,
                               service_type=service_type,
                               service_subtype=service_subtype,
                               ssid=ssid,
                               control=control,
                               data=data,
                               energies=energies,
                               idb_versions=idb_versions,
                               raw=raw,
                               parent=parent)
Exemple #10
0
    def __call__(self, *args, **kwargs):
        if len(args) == 1 and len(kwargs) == 0:
            if isinstance(args[0], (str, Path)):
                file_path = Path(args[0])
                header = fits.getheader(file_path)
                service_type = int(header.get('stype'))
                service_subtype = int(header.get('sstype'))
                parent = header.get('parent').split(';')
                raw = header.get('raw_file').split(';')
                try:
                    ssid = int(header.get('ssid'))
                except ValueError:
                    ssid = None
                level = header.get('Level')
                header.get('TIMESYS')

                hdul = fits.open(file_path)
                control = read_qtable(file_path, hdu='CONTROL', hdul=hdul)

                # Weird issue where time_stamp wasn't a proper table column?
                if 'time_stamp' in control.colnames:
                    ts = control['time_stamp'].value
                    control.remove_column('time_stamp')
                    control['time_stamp'] = ts * u.s

                data = read_qtable(file_path, hdu='DATA', hdul=hdul)

                if level != 'LB':
                    data['timedel'] = SCETimeDelta(data['timedel'])
                    offset = SCETime.from_float(header['OBT_BEG'] * u.s)

                    try:
                        control['time_stamp'] = SCETime.from_float(
                            control['time_stamp'])
                    except KeyError:
                        pass

                    data['time'] = offset + data['time']

                energies = None
                if level == 'L1':
                    try:
                        energies = read_qtable(file_path, hdu='ENERGIES')
                    except KeyError:
                        logger.info(
                            f"no ENERGIES data found in FITS: {file_path}")
                idb_versions = defaultdict(SCETimeRange)
                if level in ('L0', 'L1'):
                    try:
                        idbt = read_qtable(file_path, hdu='IDB_VERSIONS')
                        for row in idbt.iterrows():
                            idb_versions[row[0]] = SCETimeRange(
                                start=SCETime.from_float(row[1]),
                                end=SCETime.from_float(row[2]))
                    except KeyError:
                        logger.warn(f"no IDB data found in FITS: {file_path}")

                Product = self._check_registered_widget(
                    level=level,
                    service_type=service_type,
                    service_subtype=service_subtype,
                    ssid=ssid,
                    control=control,
                    data=data,
                    energies=energies)

                return Product(level=level,
                               service_type=service_type,
                               service_subtype=service_subtype,
                               ssid=ssid,
                               control=control,
                               data=data,
                               energies=energies,
                               idb_versions=idb_versions,
                               raw=raw,
                               parent=parent)