Пример #1
0
def test_L0_defaults():
    # Confirm that the output is the same when the default settings are explicitly set
    defaults = sun.L0('1992-Oct-13')
    explicit = sun.L0('1992-Oct-13',
                      light_travel_time_correction=True,
                      aberration_correction=False,
                      nearest_point=True)
    assert defaults == explicit
Пример #2
0
def test_L0_jpl_horizons():
    # Validate against values from JPL Horizons, which does not apply the aberration correction
    # for observer motion.
    # https://ssd.jpl.nasa.gov/horizons_batch.cgi?batch=1&TABLE_TYPE=OBSERVER&OBJ_DATA=NO&QUANTITIES=%2714%27&COMMAND=%22Sun%22&CENTER=%27Geocentric%27&START_TIME=%222013-01-01+TT%22&STOP_TIME=%222013-12-31%22&STEP_SIZE=%221d%22
    jpl_values = {
        '2013-01-01': 326.989970,
        '2013-02-01': 278.789894,
        '2013-03-01': 270.072186,
        '2013-04-01': 221.440599,
        '2013-05-01': 185.306476,
        '2013-06-01': 135.303097,
        '2013-07-01': 98.221806,  # NOQA
        '2013-08-01': 48.035951,  # NOQA
        '2013-09-01': 358.289921,
        '2013-10-01': 322.226009,
        '2013-11-01': 273.315206,
        '2013-12-01': 237.836959
    }
    sun_L0 = sun.L0(Time(list(jpl_values.keys()), scale='tt'),
                    light_travel_time_correction=True,
                    aberration_correction=False,
                    nearest_point=True)
    assert_longitude_allclose(sun_L0,
                              list(jpl_values.values()) * u.deg,
                              atol=0.01 * u.arcsec)
Пример #3
0
def test_hgc_self_observer():
    # Test specifying observer='self' for HGC
    obstime = Time('2001-01-01')
    hgc = HeliographicCarrington(10*u.deg, 20*u.deg, 3*u.AU, observer='self', obstime=obstime)

    # Transform to HGS (i.e., observer='self' in the source frame)
    hgs = hgc.transform_to(HeliographicStonyhurst(obstime=obstime))

    # Manually calculate the post-transformation longitude
    lon = sun.L0(obstime,
                 light_travel_time_correction=False,
                 nearest_point=False,
                 aberration_correction=False)
    lon += (hgc.radius - _RSUN) / speed_of_light * sidereal_rotation_rate

    assert_quantity_allclose(Longitude(hgs.lon + lon), hgc.lon)
    assert_quantity_allclose(hgs.lat, hgc.lat)
    assert_quantity_allclose(hgs.radius, hgc.radius)

    # Transform back to HGC (i.e., observer='self' in the destination frame)
    hgc_loop = hgs.transform_to(hgc.replicate_without_data())

    assert_quantity_allclose(hgc_loop.lon, hgc.lon)
    assert_quantity_allclose(hgc_loop.lat, hgc.lat)
    assert_quantity_allclose(hgc_loop.radius, hgc.radius)
Пример #4
0
def test_hgs_hgc_roundtrip():
    obstime = "2011-01-01"

    hgsin = HeliographicStonyhurst(lat=10*u.deg, lon=20*u.deg, obstime=obstime)
    hgcout = hgsin.transform_to(HeliographicCarrington(obstime=obstime))

    assert_quantity_allclose(hgsin.lat, hgcout.lat)
    assert_quantity_allclose(hgsin.lon + sun.L0(obstime), hgcout.lon)

    hgsout = hgcout.transform_to(HeliographicStonyhurst(obstime=obstime))

    assert_quantity_allclose(hgsout.lat, hgsin.lat)
    assert_quantity_allclose(hgsout.lon, hgsin.lon)
Пример #5
0
def test_L0_array_time():
    # Validate against published values from the Astronomical Almanac (2013)
    sun_L0 = sun.L0(
        Time([
            '2013-01-01', '2013-02-01', '2013-03-01', '2013-04-01',
            '2013-05-01', '2013-06-01', '2013-07-01', '2013-08-01',
            '2013-09-01', '2013-10-01', '2013-11-01', '2013-12-01'
        ],
             scale='tt'))
    assert_quantity_allclose(
        sun_L0,
        [
            326.98, 278.78, 270.07, 221.44, 185.30, 135.30, 98.22, 48.03,
            358.28, 322.22, 273.31, 237.83
        ] * u.deg,
        atol=5e-3 * u.deg)
Пример #6
0
def test_L0_astronomical_almanac():
    # Validate against published values from the Astronomical Almanac (2013)
    aa_values = {'2013-01-01': 326.98,
                 '2013-02-01': 278.78,
                 '2013-03-01': 270.07,
                 '2013-04-01': 221.44,
                 '2013-05-01': 185.30,
                 '2013-06-01': 135.30,
                 '2013-07-01':  98.22,  # NOQA
                 '2013-08-01':  48.03,  # NOQA
                 '2013-09-01': 358.28,
                 '2013-10-01': 322.22,
                 '2013-11-01': 273.31,
                 '2013-12-01': 237.83}
    sun_L0 = sun.L0(Time(list(aa_values.keys()), scale='tt'),
                    light_travel_time_correction=True,
                    aberration_correction=True,
                    nearest_point=False)
    assert_longitude_allclose(sun_L0, list(aa_values.values()) * u.deg, atol=5e-3*u.deg)
Пример #7
0
def hmi2pfsspy(dt,
               rss=2.5,
               nr=60,
               ret_magnetogram=False,
               data_dir=DefaultPath):
    #Input : dt (datetime object), rss (source surface radius in Rs)
    YYYYMMDD = f'{dt.year}{dt.month:02d}{dt.day:02d}'
    filepath = glob.glob(
        f'{data_dir}/hmi.mrdailysynframe_small_720s.{YYYYMMDD}*.fits')[0]
    stdout.write(f"Read in {filepath}\r")
    hmi_fits = fits.open(filepath)[0]
    hmi_fits.header['CUNIT2'] = 'degree'
    for card in ['HGLN_OBS', 'CRDER1', 'CRDER2', 'CSYSER1', 'CSYSER2']:
        hmi_fits.header[card] = 0

    hmi_map = sunpy.map.Map(hmi_fits.data, hmi_fits.header)
    hmi_map.meta['CRVAL1'] = 120 + sun.L0(time=hmi_map.meta['T_OBS']).value
    br_hmi = extract_br(hmi_map)
    if ret_magnetogram: return br_hmi
    peri_input = pfsspy.Input(br_hmi, nr, rss, dtime=dt)
    peri_output = pfsspy.pfss(peri_input)
    return peri_output
Пример #8
0
def test_L0():
    # Validate against a published value from Astronomical Algorithms (Meeus 1998, p.191)
    assert_quantity_allclose(sun.L0('1992-Oct-13'),
                             238.63 * u.deg,
                             atol=2e-2 * u.deg)
Пример #9
0
def test_L0_array_time():
    # Validate against published values from the Astronomical Almanac (2013)
    sun_L0 = sun.L0(Time(['2013-04-01', '2013-12-01'], scale='tt'))
    assert_quantity_allclose(sun_L0[0], 221.44 * u.deg, atol=5e-3 * u.deg)
    assert_quantity_allclose(sun_L0[1], 237.83 * u.deg, atol=5e-3 * u.deg)
Пример #10
0
def test_L0_sunspice():
    # Validate against values from SunSPICE (including calling CSPICE functions)

    # With the aberration correction for observer motion (specify 'LT+S')
    #
    # IDL> load_sunspice_gen
    # IDL> cspice_str2et, '2013-01-01', et
    # IDL> cspice_subpnt, 'Intercept/Ellipsoid', 'Sun', et, 'IAU_Sun', 'LT+S', 'Earth', spoint1, trgepc1, srfvec1
    # IDL> cspice_reclat, spoint1, spcrad1, spclon1, spclat1
    # IDL> print, spclon1 * cspice_dpr()
    #       -33.025998
    values1 = {
        '2013-01-01': -33.025998,
        '2013-02-01': -81.226108,
        '2013-03-01': -89.943817,
        '2013-04-01': -138.57536,
        '2013-05-01': -174.70941,
        '2013-06-01': +135.28726,
        '2013-07-01': +98.205970,
        '2013-08-01': +48.020071,
        '2013-09-01': -1.7260099,
        '2013-10-01': -37.789945,
        '2013-11-01': -86.700744,
        '2013-12-01': -122.17899
    }
    sun_L0 = sun.L0(Time(list(values1.keys()), scale='utc'),
                    light_travel_time_correction=True,
                    aberration_correction=True,
                    nearest_point=True)
    assert_longitude_allclose(sun_L0,
                              list(values1.values()) * u.deg,
                              atol=0.3 * u.arcsec)

    # Without the aberration correction for observer motion (specify 'LT')
    #
    # IDL> cspice_subpnt, 'Intercept/Ellipsoid', 'Sun', et, 'IAU_Sun', 'LT', 'Earth', spoint2, trgepc2, srfvec2
    # IDL> cspice_reclat, spoint2, spcrad2, spclon2, spclat2
    # IDL> print, spclon2 * cspice_dpr()
    #       -33.020271
    values2 = {
        '2013-01-01': -33.020271,
        '2013-02-01': -81.220344,
        '2013-03-01': -89.938057,
        '2013-04-01': -138.56966,
        '2013-05-01': -174.70380,
        # '2013-06-01':  135.29281,  # skipping due to low precision in comparison
        '2013-07-01': +98.211514,
        '2013-08-01': +48.025667,
        '2013-09-01': -1.7203500,
        '2013-10-01': -37.784252,
        '2013-11-01': -86.695047,
        '2013-12-01': -122.17329
    }
    sun_L0 = sun.L0(Time(list(values2.keys()), scale='utc'),
                    light_travel_time_correction=True,
                    aberration_correction=False,
                    nearest_point=True)
    assert_longitude_allclose(sun_L0,
                              list(values2.values()) * u.deg,
                              atol=0.01 * u.arcsec)

    # Without any corrections (do a straight conversion from 'HEQ' to 'Carrington')
    #
    # IDL> coord = [1.d, 0.d, 10.d]
    # IDL> convert_sunspice_lonlat, '2013-01-01', coord, 'HEQ', 'Carrington', /au, /degrees
    # IDL> print, coord
    #        1.0000000       326.89956       10.000000
    values3 = {
        '2013-01-01': 326.89956,
        '2013-02-01': 278.69932,
        '2013-03-01': 269.98115,
        '2013-04-01': 221.34886,
        '2013-05-01': 185.21404,
        '2013-06-01': 135.21012,
        '2013-07-01': 98.128607,
        '2013-08-01': 47.942897,
        '2013-09-01': 358.19735,
        '2013-10-01': 322.13410,
        '2013-11-01': 273.22402,
        '2013-12-01': 237.74631
    }
    sun_L0 = sun.L0(Time(list(values3.keys()), scale='utc'),
                    light_travel_time_correction=False,
                    aberration_correction=False,
                    nearest_point=True)
    assert_longitude_allclose(sun_L0,
                              list(values3.values()) * u.deg,
                              atol=0.02 * u.arcsec)
Пример #11
0
def prepData(files, base_dir, prefix, custom_keywords={}, plot=False):
    diffs = {'center_x': [], 'center_y': [], 'radius': [], 'scale': []}
    os.makedirs(os.path.join(base_dir, 'level1'), exist_ok=True)
    os.makedirs(os.path.join(base_dir, 'level1_5'), exist_ok=True)

    with warnings.catch_warnings():
        warnings.simplefilter("ignore")
        for file in tqdm(files):
            try:
                # load existing file
                hdul = fits.open(file)
                hdu = hdul[0]
                hdu.verify('fix')
                d, h = hdu.data, hdu.header

                # set custom keywords
                h.update(custom_keywords)

                # evaluate center and radius
                imsave("demo.jpg", d)
                myCmd = os.popen(
                    '/home/rja/PythonProjects/SpringProject/spring/limbcenter/sunlimb demo.jpg'
                ).read()
                center_x, center_y, radius, d_radius = map(
                    float, myCmd.splitlines())

                if "EXPTIME" in h:
                    h['EXP_TIME'] = h['EXPTIME']
                    del h['EXPTIME']
                if 'TIME-OBS' in h:
                    obs_date = datetime.strptime(
                        h['DATE-OBS'] + 'T' + h['TIME-OBS'],
                        "%m/%d/1%yT%H:%M:%S")
                    h['DATE-OBS'] = obs_date.isoformat()
                    del h["TIME-OBS"]
                if 'TIME' in h:
                    obs_date = datetime.strptime(
                        h['DATE-OBS'] + 'T' + h['TIME'], "%d/%m/%YT%H:%M:%S")
                    h['DATE-OBS'] = obs_date.isoformat()
                    del h["TIME"]

                obs_time = parse(h["DATE-OBS"])
                rsun = angular_radius(obs_time)
                b0_angle = sun.B0(obs_time)
                l0 = sun.L0(obs_time)
                p_angle = sun.P(obs_time)
                filename = "%s_%s_fi_%s.fits" % (
                    prefix, h["OBS_TYPE"].lower(),
                    obs_time.strftime("%Y%m%d_%H%M%S"))

                # prepare existing header information
                if "ANGLE" not in h:
                    h["ANGLE"] = p_angle.value

                scale = rsun / (radius * u.pix)
                coord = SkyCoord(0 * u.arcsec,
                                 0 * u.arcsec,
                                 obstime=obs_time,
                                 observer='earth',
                                 frame=frames.Helioprojective)

                # create WCS header info
                header = header_helper.make_fitswcs_header(
                    d,
                    coord,
                    rotation_angle=h["ANGLE"] * u.deg,
                    reference_pixel=u.Quantity([center_x, center_y] * u.pixel),
                    scale=u.Quantity([scale, scale]),
                    instrument=h["INSTRUME"],
                    telescope=h["TELESCOP"],
                    observatory=h["OBSVTRY"],
                    exposure=h["EXP_TIME"] * u.ms,
                    wavelength=h["WAVELNTH"] * u.angstrom)

                header["KEYCOMMENTS"] = {
                    "EXPTIME": "[s] exposure time in seconds",
                    "DATE": "file creation date (YYYY-MM-DDThh:mm:ss UT)",
                    "DATE-OBS": "date of observation",
                    "WAVELNTH": "[Angstrom] wavelength",
                    "BANDPASS": "******",
                    "WAVEMIN": "[Angstrom] minimum wavelength",
                    "WAVEMAX": "[Angstrom] maximum wavelength",
                    "BZERO": "offset data range to that of unsigned short",
                    "CDELT1": "[arcsec/pix]",
                    "CDELT2": "[arcsec/pix]",
                    "SOLAR_R": "[pix]",
                    "DSUN_OBS": "[m]",
                    "RSUN_REF": "[m]",
                    "RSUN_ARC": "[%s]" % rsun.unit,
                    "ANGLE": "[deg]",
                    "SOLAR_P": "[%s]" % p_angle.unit,
                    "SOLAR_L0": "[%s]" % l0.unit,
                    "SOLAR_B0": "[%s]" % b0_angle.unit,
                    'SIMPLE': 'file does conform to FITS standard',
                    'BITPIX': 'number of bits per data pixel',
                    'CUNIT1': '[arcsec]',
                    'CUNIT2': '[arcsec]',
                    'CRVAL1': 'coordinate system value at reference pixel',
                    'CRVAL2': 'coordinate system value at reference pixel',
                    'CTYPE1': 'name of the coordinate axis',
                    'CTYPE2': 'name of the coordinate axis',
                    'INSTRUME': 'name of instrument',
                    'TELESCOP': 'name of telescope',
                    'OBSVTRY': 'name of observatory',
                }

                # set constants and default values
                header["FILENAME"] = filename
                header["DATE"] = datetime.now().strftime("%Y-%m-%dT%H:%M:%S")

                header["SOLAR_R"] = radius
                header["RSUN_ARC"] = rsun.value
                header["SOLAR_P"] = p_angle.value
                header["SOLAR_L0"] = l0.value
                header["SOLAR_B0"] = b0_angle.value

                header["DATAMIN"] = np.min(d)
                header["DATAMEAN"] = np.mean(d)
                header["DATAMAX"] = np.max(d)

                # copy existing keys
                for key, value in h.items():
                    if key not in header:
                        header[key] = value

                # copy comments
                for key, value in zip(list(h.keys()), list(h.comments)):
                    if key not in header["KEYCOMMENTS"]:
                        header["KEYCOMMENTS"][key] = value

                # LEVEL 1
                s_map = Map(d.astype(np.float32), header)
                level1_path = os.path.join(base_dir, 'level1', filename)

                h.add_history("unified FITS header")
                s_map.meta["HISTORY"] = h["HISTORY"]
                s_map.meta["LVL_NUM"] = "1.0"
                s_map = Map(s_map.data.astype(np.float32), s_map.meta)
                s_map.save(level1_path, overwrite=True)

                # LEVEL 1.5
                scale = s_map.scale[0].value
                s_map = padScale(s_map)

                s_map = s_map.rotate(
                    recenter=True,
                    scale=scale,
                    missing=s_map.min(),
                )
                center = np.floor(s_map.meta['crpix1'])
                range_side = (center + np.array([-1, 1]) * 2048 / 2) * u.pix
                s_map = s_map.submap(
                    u.Quantity([range_side[0], range_side[0]]),
                    u.Quantity([range_side[1], range_side[1]]))
                level1_5_path = os.path.join(base_dir, 'level1_5', filename)

                h.add_history("recentered and derotated")
                s_map.meta["HISTORY"] = h["HISTORY"]
                s_map.meta["LVL_NUM"] = "1.5"
                s_map = Map(s_map.data.astype(np.float32), s_map.meta)
                s_map.save(level1_5_path, overwrite=True)

                if plot:
                    s_map.plot()
                    s_map.draw_grid()
                    plt.savefig(level1_5_path.replace(".fits", ".jpg"))
                    plt.close()

                # check header
                hdul = fits.open(level1_5_path)
                hdu = hdul[0]
                hdu.verify('exception')

                # evaluate difference
                if 'center_x' in h and not isinstance(h["center_x"], str):
                    diffs['center_x'].append(
                        np.abs(h['center_x'] - header['crpix1']))
                if 'center_y' in h and not isinstance(h["center_y"], str):
                    diffs['center_y'].append(
                        np.abs(h['center_y'] - header['crpix2']))
                if 'SOLAR_R' in h and not isinstance(h["SOLAR_R"], str):
                    diffs['radius'].append(
                        np.abs(h['SOLAR_R'] - header['SOLAR_R']))
                if 'cdelt1' in h and not isinstance(h["cdelt1"], str):
                    diffs['scale'].append(
                        np.abs(h['cdelt1'] - header['cdelt1']))
            except Exception as ex:
                print("INVALID FILE", file)
                print("ERROR:", ex)
        return diffs