Пример #1
0
def test_fgs_cal_frametime():
    """These tests apply to the FGS CAL apertures only. ACQ1, ACQ2, ID,
    TRK, and FG are not yet supported
    """
    fgs_full = calc_frame_time('fgs', 'FGS_', 2048, 2048, 4)
    assert np.isclose(fgs_full, 10.73677, rtol=0., atol=1e-5)

    fgs_128 = calc_frame_time('fgs', 'FGS_', 128, 128, 1)
    assert np.isclose(fgs_128, 0.1820, rtol=0., atol=1e-5)

    fgs_32 = calc_frame_time('fgs', 'FGS_', 32, 32, 1)
    assert np.isclose(fgs_32, 0.01254, rtol=0., atol=1e-5)

    fgs_8 = calc_frame_time('fgs', 'FGS_', 8, 8, 1)
    assert np.isclose(fgs_8, 0.00126, rtol=0., atol=1e-5)
Пример #2
0
    def calculate_exposure_time(self):
        """Calculate the total exposure time of the observation being
        simulated. Include time for resets between integrations

        Returns
        -------
        exposure_time : float
            Exposure time for the total exposuure, including reset frames,
            in seconds
        """
        self.frametime = utils.calc_frame_time(self.instrument, self.aperture,
                                               self.seed_dimensions[1],
                                               self.seed_dimensions[0],
                                               self.namps)
        return self.frametime * self.total_frames
Пример #3
0
def test_niriss_frametime():
    """Test NIRISS exposure times
    """
    nis_full = calc_frame_time('niriss', 'NIS_CEN', 2048, 2048, 4)
    assert np.isclose(nis_full, 10.73677, rtol=0., atol=1e-5)

    nis_80 = calc_frame_time('niriss', 'NIS_SUB80', 80, 80, 1)
    assert np.isclose(nis_80, 0.07544, rtol=0., atol=1e-5)

    nis_64 = calc_frame_time('niriss', 'NIS_SUBTAAMI', 64, 64, 1)
    assert np.isclose(nis_64, 0.05016, rtol=0., atol=1e-5)

    nis_wfss64r = calc_frame_time('niriss', 'NIS_WFSS64R', 64, 2048, 4)
    assert np.isclose(nis_wfss64r, 0.34061, rtol=0., atol=1e-5)

    nis_wfss64c = calc_frame_time('niriss', 'NIS_WFSS64C', 2048, 64, 1)
    assert np.isclose(nis_wfss64c, 1.55800, rtol=0., atol=1e-5)

    nis_wfss128r = calc_frame_time('niriss', 'NIS_WFSS128R', 128, 2048, 4)
    assert np.isclose(nis_wfss128r, 0.67597, rtol=0., atol=1e-5)

    nis_wfss128c = calc_frame_time('niriss', 'NIS_WFSS128C', 2048, 128, 1)
    assert np.isclose(nis_wfss128c, 2.87000, rtol=0., atol=1e-5)
Пример #4
0
def test_nircam_frametime():
    """Test NIRCam exposure times
    """
    nrc_full = calc_frame_time('nircam', 'NRCA1_FULL', 2048, 2048, 4)
    assert np.isclose(nrc_full, 10.73677, rtol=0., atol=1e-5)

    nrc_640 = calc_frame_time('nircam', 'NRCA1_SUB640', 640, 640, 1)
    assert np.isclose(nrc_640, 4.18584, rtol=0., atol=1e-5)

    nrc_320 = calc_frame_time('nircam', 'NRCA1_SUB320', 320, 320, 1)
    assert np.isclose(nrc_320, 1.06904, rtol=0., atol=1e-5)

    nrc_160 = calc_frame_time('nircam', 'NRCA1_SUB160', 160, 160, 1)
    assert np.isclose(nrc_160, 0.27864, rtol=0., atol=1e-5)

    nrc_64 = calc_frame_time('nircam', 'NRCB4_SUB64P', 64, 64, 1)
    assert np.isclose(nrc_64, 0.05016, rtol=0., atol=1e-5)

    nrc_32 = calc_frame_time('nircam', 'NRC_SUB32TATS', 32, 32, 1)
    assert np.isclose(nrc_32, 0.01496, rtol=0., atol=1e-5)

    nrc_subgrism256_1 = calc_frame_time('nircam', 'NRC_SUBGRISM256', 2048, 256,
                                        1)
    print(nrc_subgrism256_1, 5.31480)
    #assert np.isclose(nrc_subgrism256_1, 5.29420, rtol=0., atol=1e-5)

    nrc_subgrism256_4 = calc_frame_time('nircam', 'NRC_SUBGRISM256', 2048, 256,
                                        4)
    print(nrc_subgrism256_4, 1.34669)
    #assert np.isclose(nrc_subgrism256_4, 1.34669, rtol=0., atol=1e-5)

    nrc_subgrism128_1 = calc_frame_time('nircam', 'NRC_SUBGRISM128', 2048, 128,
                                        1)
    print(nrc_subgrism128_1, 2.67800)
    #assert np.isclose(nrc_subgrism128_1, 2.6574, rtol=0., atol=1e-5)

    nrc_subgrism128_4 = calc_frame_time('nircam', 'NRC_SUBGRISM128', 2048, 128,
                                        4)
    assert np.isclose(nrc_subgrism128_4, 0.67597, rtol=0., atol=1e-5)

    nrc_subgrism64_1 = calc_frame_time('nircam', 'NRC_SUBGRISM64', 2048, 64, 1)
    assert np.isclose(nrc_subgrism64_1, 1.35960, rtol=0., atol=1e-5)

    nrc_subgrism64_4 = calc_frame_time('nircam', 'NRC_SUBGRISM64', 2048, 64, 4)
    assert np.isclose(nrc_subgrism64_4, 0.34061, rtol=0., atol=1e-5)
def validate(xml_file, output_dir, gseg_uncal_files):
    """MAIN FUNCTION"""
    pointing_file = xml_file.replace('.xml', '.pointing')
    gseg_rate_files = [f.replace('uncal', 'rate') for f in gseg_uncal_files]

    catalogs = {'nircam': {'sw': 'nothing.cat', 'lw': 'nothing.cat'}}

    observation_list_file = os.path.join(output_dir, 'observation_list.yaml')
    apt_xml_dict = get_observation_dict(xml_file,
                                        observation_list_file,
                                        catalogs,
                                        verbose=True)

    observation_list = set(apt_xml_dict['ObservationID'])
    int_obs = sorted([int(o) for o in observation_list])
    str_obs_list = [str(o).zfill(3) for o in int_obs]

    for observation_to_check in str_obs_list:
        print('')
        print('')
        print('OBSERVATION: {}'.format(observation_to_check))
        print('')

        good = np.where(
            np.array(apt_xml_dict['ObservationID']) == observation_to_check)

        try:
            total_expected_files = calculate_total_files(
                apt_xml_dict, good[0][0])
            print('Total number of expected files: {}'.format(
                total_expected_files))
        except IndexError:
            print("No files found.")
            continue

        # The complication here is that the table created by Mirage does not have a filename
        # attached to each entry. So we need a way to connect an actual filename
        # to each entry
        subdir_start = 'jw' + apt_xml_dict['ProposalID'][
            good[0][0]] + observation_to_check.zfill(3)
        matching_uncal_files = sorted([
            filename for filename in gseg_uncal_files
            if subdir_start in filename
        ])
        matching_rate_files = sorted([
            filename for filename in gseg_rate_files
            if subdir_start in filename
        ])
        print('Found uncal files:')
        for i in range(len(matching_uncal_files)):
            print(matching_uncal_files[i])
        print('')
        print('Found rate files:')
        for i in range(len(matching_rate_files)):
            print(matching_rate_files[i])
        print('')

        # Check to see if any files are missing
        if len(matching_uncal_files) != total_expected_files:
            print(
                "WARNING: Missing uncal files for observation {}. Expected {} files, found {}."
                .format(observation_to_check, total_expected_files,
                        len(matching_uncal_files)))
        if len(matching_rate_files) != total_expected_files:
            print(
                "WARNING: Missing rate files for observation {}. Expected {} files, found {}."
                .format(observation_to_check, total_expected_files,
                        len(matching_rate_files)))

        # Deal with the case of matching_uncal_files and matching_rate_files having
        # different lengths here. In order to loop over them they must have the same length
        if len(matching_uncal_files) != len(matching_rate_files):
            (matching_uncal_files, matching_rate_files) = equalize_file_lists(
                matching_uncal_files, matching_rate_files)
            print('Equalized file lists (should have a 1:1 correspondence):')
            for idx in range(len(matching_uncal_files)):
                print(matching_uncal_files[idx], matching_rate_files[idx])

        # Create siaf instance for later calculations
        siaf = pysiaf.Siaf('NIRCam')

        for uncal, rate in zip(matching_uncal_files, matching_rate_files):
            good_uncal = uncal != None
            good_rate = rate != None

            if good_uncal:
                print("Checking {}".format(os.path.split(uncal)[1]))
                print('-----------------------------------------------')
            elif good_rate:
                print("Checking {}".format(os.path.split(rate)[1]))
                print('-----------------------------------------------')

            if good_uncal:
                data, header, sci_header = get_data(uncal)
                detector_from_filename = uncal.split('_')[-2].upper()
                header_detector = header['DETECTOR']
                if 'LONG' in header_detector:
                    header_detector = header_detector.replace('LONG', '5')
                if header_detector not in header['APERNAME']:
                    print((
                        "WARNING: Detector name and aperture name in file header appear to be incompatible: {}, {}"
                        .format(header['DETECTOR'], header['APERNAME'])))
                    print("Detector listed in filename: {}".format(
                        detector_from_filename))
                    print(
                        'If the aperture is incorrect then the calculated subarray location from pysiaf will also be incorrect.'
                    )
                data_shape = data.shape

                # Get info from header to be compared
                header_vals = uncal_header_keywords(header)

                # Get matching data from the exposure table
                table_vals = uncal_table_info(apt_xml_dict, good[0][0])

                # Make some adjustments to the exposure table info

                # Calucate the exposure time
                aperture = header[
                    'APERNAME']  # could also try APERNAME, PPS_APER

                print('Aperture listed in header is: {}'.format(aperture))

                num_amps = 1
                frametime = calc_frame_time('NIRCam', aperture, data_shape[-1],
                                            data_shape[-2], num_amps)
                table_vals['EFFEXPTM'] = frametime * int(table_vals['NGROUPS'])

                # NAXIS
                table_vals['NAXIS'] = len(data.shape)
                header_vals['NAXIS'] = sci_header['NAXIS']

                # Use pysiaf to calculate subarray locations
                try:
                    xc, yc = sci_subarray_corners('NIRCam',
                                                  aperture,
                                                  siaf=siaf)
                    table_vals['SUBSTRT1'] = xc[0] + 1
                    table_vals['SUBSTRT2'] = yc[0] + 1
                    table_vals['SUBSIZE1'] = siaf[aperture].XSciSize
                    table_vals['SUBSIZE2'] = siaf[aperture].YSciSize
                except KeyError:
                    print(
                        "ERROR: Aperture {} is not a valid aperture in pysiaf".
                        format(aperture))
                    xc = [-2, -2]
                    yc = [-2, -2]
                    table_vals['SUBSTRT1'] = xc[0] + 1
                    table_vals['SUBSTRT2'] = yc[0] + 1
                    table_vals['SUBSIZE1'] = 9999
                    table_vals['SUBSIZE2'] = 9999

                # Create FASTAXIS and SLOWAXIS values based on the detector name
                fast, slow = find_fastaxis(header_vals['DETECTOR'])
                table_vals['FASTAXIS'] = fast
                table_vals['SLOWAXIS'] = slow

                # Remove whitespace from observing template in file
                header_vals['TEMPLATE'] = header_vals['TEMPLATE'].replace(
                    ' ', '').lower()
                table_vals['TEMPLATE'] = table_vals['TEMPLATE'].lower()

                # Adjust prime/parallel boolean from table to be a string
                if not table_vals['EXPRIPAR']:
                    table_vals['EXPRIPAR'] = 'PRIME'
                else:
                    table_vals['EXPRIPAR'] = 'PARALLEL'

                # Change exposure type from table to match up with
                # types of strings in the file
                table_vals['EXP_TYPE'] = adjust_exptype(table_vals['EXP_TYPE'])

                # Set the DETECTOR field to be identical. This info is not in the
                # exposure table, so we can't actually check it
                table_vals['DETECTOR'] = header_vals['DETECTOR']

                # Compare the actual data shape to the shape given in the header
                header_shape = (header_vals['NINTS'], header_vals['NGROUPS'],
                                header_vals['SUBSIZE2'],
                                header_vals['SUBSIZE1'])
                if header_shape != data_shape:
                    print(
                        "WARNING: Shape of data in the file does not match that specified in the header."
                    )
                    print('Data shape: {}'.format(data_shape))
                    print('Header shape: {}'.format(header_shape))

                # Now compare the data in the dictionary from the file versus that
                # from the exposure table created from the APT file
                err = False
                for key in header_vals:
                    if header_vals[key] != table_vals[key]:
                        if key not in FLOAT_KEYWORDS and key not in FILTER_KEYWORDS:
                            err = True
                            print(
                                'MISMATCH: {}, in exp table: {}, in file: {}'.
                                format(key, table_vals[key], header_vals[key]))
                        elif key in FLOAT_KEYWORDS:
                            if not np.isclose(header_vals[key],
                                              table_vals[key],
                                              rtol=0.01,
                                              atol=0.):
                                err = True
                                print(
                                    'MISMATCH: {}, in exp table: {}, in file: {}'
                                    .format(key, table_vals[key],
                                            header_vals[key]))

                        if key in ['LONGFILTER', 'LONGPUPIL'
                                   ] and 'LONG' in header_vals['DETECTOR']:
                            err = True
                            print(
                                'MISMATCH: {}, in exp table: {}, in file: {}'.
                                format(key, table_vals[key], header_vals[key]))
                        if key in ['SHORTFILTER', 'SHORTPUPIL'
                                   ] and 'LONG' not in header_vals['DETECTOR']:
                            err = True
                            print(
                                'MISMATCH: {}, in exp table: {}, in file: {}'.
                                format(key, table_vals[key], header_vals[key]))

                if not err:
                    print('No inconsistencies. File header info correct.')

            print('')
            print('')