示例#1
0
def trace(map_file, psp_coord, pfss_input, retrace=False):
    # Load field line
    fline_file = map_file.with_suffix('.fline')
    if fline_file.exists() and not retrace:
        fline = load_fline(fline_file)
    else:
        print('Tracing field line')
        # Calculate field line

        output = pfsspy.pfss(pfss_input)
        tracer = pfsspy.tracing.PythonTracer()
        fline = tracer.trace(psp_coord, output)[0].coords
        if not retrace:
            fline_xyz = np.array([fline.x / u.m, fline.y / u.m, fline.z / u.m])
            np.savetxt(fline_file, fline_xyz)

    fline.representation_type = 'spherical'
    lon = fline.lon.to_value(u.deg)
    lat = fline.lat.to_value(u.deg)
    r = fline.radius.to_value(u.m)
    lon, lat, r = insert_nans(lon, lat, r)

    fline = astropy.coordinates.SkyCoord(lon * u.deg,
                                         lat * u.deg,
                                         r * u.m,
                                         frame='heliographic_carrington',
                                         obstime=fline.obstime)

    return fline
示例#2
0
 def __init__(self, nrho, rss, gong_map=sunpy.map.Map(get_gong_map())):
     self._nrho = nrho
     self._rss = rss
     self.gong_map = gong_map
     self.input = pfsspy.Input(self.gong_map, self.nrho, self.rss)
     self._output = pfsspy.pfss(self.input)
     self.tracer = tracing.PythonTracer()
示例#3
0
def dipole_result(dipole_map):
    nr = 10
    rss = 2.5

    input = pfsspy.Input(dipole_map, nr, rss)
    output = pfsspy.pfss(input)
    return input, output
示例#4
0
文件: test_pfss.py 项目: PyDL/pfsspy
def test_shape(zero_map):
    # Test output map shapes
    input, out = zero_map
    nr = input.grid.nr
    nphi = input.grid.nphi
    ns = input.grid.ns

    out = pfsspy.pfss(input)
    alr, als, alp = out.al
    for comp in (alr, als, alp):
        assert np.all(comp == 0)

    assert alr.shape == (nphi + 1, ns + 1, nr)
    assert als.shape == (nphi + 1, ns, nr + 1)
    assert alp.shape == (nphi, ns + 1, nr + 1)

    br, bs, bp = out.bc
    for comp in (br, bs, bp):
        assert np.all(comp == 0)

    assert br.shape == (nphi + 2, ns + 2, nr + 1)
    assert bs.shape == (nphi + 2, ns + 1, nr + 2)
    assert bp.shape == (nphi + 1, ns + 2, nr + 2)

    br, bs, bp = out.bg
    for comp in (br, bs, bp):
        assert np.all(comp == 0)

    assert br.shape == (nphi + 1, ns + 1, nr + 1)
    assert bs.shape == (nphi + 1, ns + 1, nr + 1)
    assert bp.shape == (nphi + 1, ns + 1, nr + 1)
示例#5
0
def test_shape(zero_map):
    # Test output map shapes
    input, out = zero_map
    nr = input.grid.nr
    nphi = input.grid.nphi
    ns = input.grid.ns

    out = pfsspy.pfss(input)
    alr, als, alp = out._al
    for comp in (alr, als, alp):
        assert np.all(comp == 0)

    assert alr.shape == (nphi + 1, ns + 1, nr)
    assert als.shape == (nphi + 1, ns, nr + 1)
    assert alp.shape == (nphi, ns + 1, nr + 1)

    br, bs, bp = out.bc
    for comp in (br, bs, bp):
        assert np.all(comp == 0)

    assert br.shape == (nphi, ns, nr + 1)
    assert bs.shape == (nphi, ns + 1, nr)
    assert bp.shape == (nphi + 1, ns, nr)

    bg = out.bg
    assert np.all(bg == 0)
    assert bg.shape == (nphi + 1, ns + 1, nr + 1, 3)
    assert (bg[0, ...] == bg[-1, ...]).all()
示例#6
0
def trace_to_surface(seeds, synoptic_map, rss=rss, nrho=60):
    """
    seeds : astropy.coordinates.SkyCoord
        Seed coordinates on the source surface.
    synoptic_map : sunpy.map.GenericMap
        Input synoptic magnetogram.
    rss : scalar
        Source surface radius.
    nrho : int
        Number of grid points in the radial direciton
        of the PFSS model.
    
    Returns
    -------
    flines : pfsspy.flines.field_lines
        Traced field lines.
    pfss_input : pfsspy.Input
        PFSS input.
    pfss_output : pfsspy.Output
        PFSS output.
    """
    pfss_input = pfsspy.Input(synoptic_map, nrho, rss)
    print('Computing PFSS...')
    pfss_output = pfsspy.pfss(pfss_input)

    tracer = pfsspy.tracing.FortranTracer(max_steps=2000)
    print('Tracing field lines...')
    flines = tracer.trace(seeds, pfss_output)
    return flines, pfss_input, pfss_output
示例#7
0
def adapt2pfsspy(dt,
                 rss=2.5,
                 nr=60,
                 adapt_source="GONG",
                 realization="mean",
                 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}'
    A = {"GONG": 3, "HMI": 4}.get(adapt_source)
    filepath = sorted(glob.glob(f"{data_dir}/adapt40{A}*{YYYYMMDD}*.fts"))[0]
    stdout.write(f"Read in {filepath}\r")
    adapt_map = fits.open(filepath)
    if realization == "mean": br_adapt_ = np.mean(adapt_map[0].data, axis=0)
    elif isinstance(realization, int):
        br_adapt_ = adapt_map[0].data[realization, :, :]
    else:
        raise ValueError("realization should either be 'mean' or type int ")
    # Interpolate to Strumfric Grid (const lat spacing -> const cos(lat) spacing)
    lat_dr = np.linspace(-90, 90, br_adapt_.shape[0])
    lon_dr = np.linspace(0, 360, br_adapt_.shape[1])
    clat_dr = np.sin(np.radians(lat_dr))
    clat_dr_interp = np.linspace(clat_dr[0], clat_dr[-1], len(clat_dr))
    br_adapt = np.zeros(br_adapt_.shape)
    for ind, _ in enumerate(lon_dr):
        interper = interp1d(clat_dr, br_adapt_[:, ind])
        br_adapt[:, ind] = interper(clat_dr_interp)

    br_adapt -= np.mean(br_adapt)
    br_adapt *= 1e5  # G -> nT
    if ret_magnetogram: return br_adapt
    peri_input = pfsspy.Input(br_adapt, nr, rss, dtime=dt)
    peri_output = pfsspy.pfss(peri_input)

    return peri_output
示例#8
0
def compute_pfss(gong_fname, dtime):
    gong_map = sunpy.map.Map(gong_fname)
    br = gong_map.data
    header = gong_map.meta

    br = br - np.mean(br)
    br = np.roll(br, header['CRVAL1'] + 180, axis=1)
    header['CRVAL1'] = 180
    header['DATE_ORI'] = header['DATE']
    header['date-obs'] = Time(dtime).isot

    gong_map = sunpy.map.Map(br, header)
    nrho = 60
    rss = 2.5

    input = pfsspy.Input(gong_map, nrho, rss)
    ssfile = gong_fname.with_suffix('.ssmap')

    if ssfile.exists():
        ssmap = np.loadtxt(ssfile)
        ssmap = sunpy.map.Map(ssmap, header)
    else:
        print('Calculating PFSS solution')
        # Compute PFSS solution and source surface map
        output = pfsspy.pfss(input)
        ssdata = output.source_surface_br.data
        np.savetxt(ssfile, ssdata)
        ssmap = output.source_surface_br

    return input, ssmap
示例#9
0
文件: test_pfss.py 项目: PyDL/pfsspy
def zero_map():
    # Test a completely zero input
    ns = 30
    nphi = 20
    nr = 10
    rss = 2.5
    br = np.zeros((ns, nphi))

    input = pfsspy.Input(br, nr, rss)
    output = pfsspy.pfss(input)
    return input, output
示例#10
0
def zero_map():
    # Test a completely zero input
    ns = 30
    nphi = 20
    nr = 10
    rss = 2.5
    br = np.zeros((nphi, ns))
    header = pfsspy.utils.carr_cea_wcs_header(Time('1992-12-21'), br.shape)
    input_map = Map((br.T, header))

    input = pfsspy.Input(input_map, nr, rss)
    output = pfsspy.pfss(input)
    return input, output
示例#11
0
def test_bunit(gong_map):
    # Regression test to check that the output of pfss doesn't change
    m = sunpy.map.Map(gong_map)
    pfss_in = pfsspy.Input(m, 2, 2)
    pfss_out = pfsspy.pfss(pfss_in)
    assert pfss_out.bunit == u.G

    pfss_out.input_map.meta['bunit'] = 'notaunit'
    with pytest.warns(UserWarning, match='Could not parse unit string "notaunit"'):
        assert pfss_out.bunit is None

    pfss_out.input_map.meta.pop('bunit')
    assert pfss_out.bunit is None
示例#12
0
def test_pfss(gong_map):
    # Regression test to check that the output of pfss doesn't change
    m = sunpy.map.Map(gong_map)
    # Resample to lower res for easier comparisons
    m = m.resample([30, 15] * u.pix)
    m = sunpy.map.Map(m.data - np.mean(m.data), m.meta)
    expected = np.loadtxt(test_data / 'br_in.txt')
    np.testing.assert_equal(m.data, expected)

    pfss_in = pfsspy.Input(m, 50, 2)
    pfss_out = pfsspy.pfss(pfss_in)

    br = pfss_out.source_surface_br.data
    expected = np.loadtxt(test_data / 'br_out.txt')
    # atol is emperically set for tests to pass on CI
    np.testing.assert_allclose(br, expected, atol=1e-13, rtol=0)
示例#13
0
    def __init__(self,
                 gongMap,
                 SSradius: float = 2.5,
                 nrho: int = 25,
                 tracer=tracing.FortranTracer()):
        """
        PFSS solution to solar magnetic field is calculated on a 3D grid (phi, s, rho).
        rho = ln(r), and r is the standard spherical radial coordinate.
        """
        self.gongMap = gongMap
        self.SSradius = SSradius
        self.SSradiusRsun = SSradius * const.R_sun
        self.nrho = nrho

        self.input = pfsspy.Input(gongMap, nrho, SSradius)
        self.output = pfsspy.pfss(self.input)
        self.tracer = tracer
示例#14
0
文件: test_pfss.py 项目: PyDL/pfsspy
def dipole_map():
    # Test a completely zero input
    ntheta = 30
    nphi = 20
    nr = 10
    rss = 2.5

    phi = np.linspace(0, 2 * np.pi, nphi)
    theta = np.linspace(-np.pi / 2, np.pi / 2, ntheta)
    theta, phi = np.meshgrid(theta, phi)

    def dipole_Br(r, theta):
        return 2 * np.sin(theta) / r**3

    br = dipole_Br(1, theta).T
    input = pfsspy.Input(br, nr, rss)
    output = pfsspy.pfss(input)
    return input, output
示例#15
0
def gong2pfsspy(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}'
    gongpath = f'mrzqs{YYYYMMDD}/'
    filepath = sorted(glob.glob(f'{data_dir}/mrzqs{YYYYMMDD[2:]}*.fits'))[0]
    stdout.write(f"Read in {filepath}\r")
    # Sunpy 1.03 error : need to fix header of gong maps to include units
    am = fits.open(filepath)[0]
    am.header.append(('CUNIT1', 'degree'))
    am.header.append(('CUNIT2', 'degree'))
    gong_map = sunpy.map.Map(am.data, am.header)
    br_gong = extract_br(gong_map)
    if ret_magnetogram: return br_gong
    peri_input = pfsspy.Input(br_gong, nr, rss, dtime=dt)
    peri_output = pfsspy.pfss(peri_input)

    return peri_output
示例#16
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
示例#17
0
def derosa2pfsspy(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}'
    dr_times = ['_000400.h5', '_060432.h5', '_120400.h5', '_180328.h5']
    dr_time = dr_times[np.argmin(np.abs(dt.hour - np.array([0, 6, 12, 18])))]
    filepath = f'{data_dir}/Bfield_{YYYYMMDD}{dr_time}'
    f = h5py.File(filepath, 'r')
    stdout.write(f"Read in {filepath}\r")
    fdata = f['ssw_pfss_extrapolation']
    br_dr = fdata['BR'][0, :, :, :] * 1e5
    nr_dr = fdata['NR']
    nlat_dr = fdata['NLAT']
    nlon_dr = fdata['NLON']
    r_dr = fdata['RIX'][0]
    lat_dr = fdata['LAT'][0]
    c_dr = np.cos(np.radians(90 - lat_dr))
    lon_dr = fdata['LON'][0]
    date = fdata['MODEL_DATE']
    magnetogram = br_dr[0, :, :]

    # Interpolate to Strumfric Grid (const lat spacing -> const cos(lat) spacing)
    clat_dr = np.sin(np.radians(lat_dr))
    clat_dr_interp = np.linspace(clat_dr[0], clat_dr[-1], len(clat_dr))
    br_dr_interp = np.zeros(magnetogram.shape)
    for ind, _ in enumerate(lon_dr):
        interper = interp1d(clat_dr, magnetogram[:, ind])
        br_dr_interp[:, ind] = interper(clat_dr_interp)
    br_dr_interp -= np.mean(
        br_dr_interp)  # Remove Mean offest for pfsspy FFT based PFSS extrap
    if ret_magnetogram: return (magnetogram, br_dr_interp)
    peri_input = pfsspy.Input(br_dr_interp, nr, rss, dtime=dt)
    peri_output = pfsspy.pfss(peri_input)
    return peri_output
示例#18
0
rss = 2.5

phi = np.linspace(0, 2 * np.pi, nphi)
theta = np.linspace(-np.pi / 2, np.pi / 2, ntheta)
theta, phi = np.meshgrid(theta, phi)


def dipole_Br(r, theta):
    return 2 * np.sin(theta) / r**3


br = dipole_Br(1, theta)
br = sunpy.map.Map(br.T,
                   pfsspy.utils.carr_cea_wcs_header('2010-01-01', br.shape))
pfss_input = pfsspy.Input(br, nr, rss)
pfss_output = pfsspy.pfss(pfss_input)
print('Computed PFSS solution')

###############################################################################
# Trace some field lines
seed0 = np.atleast_2d(np.array([1, 1, 0]))
tracers = [pfsspy.tracing.PythonTracer(), pfsspy.tracing.FortranTracer()]
nseeds = 2**np.arange(14)
times = [[], []]

for nseed in nseeds:
    print(nseed)
    seeds = np.repeat(seed0, nseed, axis=0)
    r, lat, lon = pfsspy.coords.cart2sph(seeds[:, 0], seeds[:, 1], seeds[:, 2])
    r = r * astropy.constants.R_sun
    lat = (lat - np.pi / 2) * u.rad
示例#19
0
    ax.set_ylim(0, 180)


###############################################################################
# Using the Input object, plot the input field
m = input.map
fig = plt.figure()
ax = plt.subplot(projection=m)
m.plot()
plt.colorbar()
ax.set_title('Input field')
set_axes_lims(ax)

###############################################################################
# Now calculate the PFSS solution
output = pfsspy.pfss(input)

###############################################################################
# Using the Output object we can plot the source surface field, and the
# polarity inversion line.
ss_br = output.source_surface_br
# Create the figure and axes
fig = plt.figure()
ax = plt.subplot(projection=ss_br)

# Plot the source surface map
ss_br.plot()
# Plot the polarity inversion line
ax.plot_coord(output.source_surface_pils[0])
# Plot formatting
plt.colorbar()