0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

以前の記事では、SS 433の公転・歳差・nutation・ballistic jetをまとめて3次元的に可視化してみました。

SS 433の全体的な動きはこれでかなりイメージしやすくなったのですが、実際の観測と対応させて考えると少しややこしいところがあります。

SS 433には約162日のprecessionと約13日のbinary orbital motionがあり、それぞれ異なる周期で進んでいます。そのため、precession phaseだけを見ても、そのときのbinaryの配置までは決まりません。

観測時のgeometryを眺めるには、

(\phi_{\rm orb},\,\phi_{\rm prec})

という2つのphaseの組み合わせで見てみるのが分かりやすそうです。

今回は、ChandraによるSS 433観測について、この2つのphaseから簡単なポンチ絵を作って並べてみました。

Chandra観測をgeometryとして眺める

実際のChandra HETG zeroth-order / HRCの観測画像については、以前こちらの記事で一覧にしています。

今回は画像そのものではなく、それぞれの観測時にSS 433がどのようなgeometryだったのかを眺めてみます。

こちらがその結果です。

chandra_hetg_hrc_geometry_6x7.png

上4行が Chandra HETG、下3行が Chandra HRC です。

各panelには、

  • ObsID
  • precession phase $\phi_{\rm prec}$
  • orbital phase $\phi_{\rm orb}$

を表示しています。

黄色がcompanion、黒がcompact object、緑がdiskです。

青と赤はそれぞれ LOS-approachingLOS-receding を示しています。ここでは固定されたjet branchの名称というより、そのphaseでのline-of-sight方向の状態を表すものとして使っています。

SS 433には、このほかにChandra ACIS-S no-gratingによる観測も過去に3回あります。今回はHETG zeroth-orderとHRCを眺めることを目的としているため、これらは省略しています。

phaseのephemerisについて

今回表示しているphaseについては、

  • orbital phase:Goranskij (2011)
  • precession phase:Gies et al. (2002)

のephemerisをもとにしています。

図を作る際には、各観測について求めた $\phi_{\rm orb}$ と $\phi_{\rm prec}$ を入力し、その組み合わせに対応するgeometryを描いています。

例えば、同じようなprecession phaseでもorbital phaseが違えば、companionとcompact objectの配置は変わります。

逆にorbital phaseが似ていても、precession phaseが違えばdisk / jet axisの向きが変わります。

40観測あると、phaseの数字を見ながら毎回頭の中でgeometryを組み立てるより、全部同じ視点・同じscaleで並べてしまった方が雰囲気をつかみやすい気がします。

実際の観測と見比べる

例えば、Sakai et al. (2025)で詳しく解析した2014年のHETG観測 ObsID 15781 は、

\phi_{\rm orb}\simeq 0.01,\qquad
\phi_{\rm prec}\simeq 0.43

付近です。

図で見ると、orbital phaseとしてはeclipse付近で、同時にprecessionによってjet axisがline of sightに対してかなり横向きになる時期であることが分かります。

Sakai et al. (2025)では、このHETG zeroth-order imageから東西方向のarcsecond-scale構造を調べています。また、なぜそのような構造が見えるのかについても論文中で検討しているので、そのあたりの物理的な議論はそちらに譲ります。

今回の図はあくまでポンチ絵

今回の図は精密なbinary simulationというより、観測時のgeometryをイメージするための模式図です。

orbitやcompanion、diskなどには単純化がありますが、

  • binary scale
  • Roche-lobe scale
  • precession cone
  • inclination
  • position angle
  • observer projection

などは、以前作成したSS 433のkinematic visualizationと同じ考え方をベースにしています。

そのため、

science解析にそのまま使うmodelというより、geometryを把握するためにある程度scaleやorientationを合わせたポンチ絵

くらいに見てもらうのがよいかと思います。

さらに細かく見るとnutationもある

今回は、

(\phi_{\rm orb},\,\phi_{\rm prec})

の2つだけを使っています。

ただし、SS 433にはさらに約6日のnutation(章動運動、nodding motion)もあります。

もう少し細かく観測時の状態を考えるなら、

(\phi_{\rm orb},\,\phi_{\rm prec},\,\phi_{\rm nut})

という3つ目のphaseも入ってきます。

今回は見通しをよくするためnutationは入れていませんが、最近のXRISMによるSS 433観測では、Resolveの高分解能分光によってjet emission lineのDoppler shiftを精密に追えるようになり、短時間変動やnutationとの関係についても検討されています(Shidatsu et al. 2025; Sakai et al. 2026)。

まとめ

SS 433のChandra HETG 24観測とHRC 16観測について、

(\phi_{\rm orb},\,\phi_{\rm prec})

の組み合わせからbinary / disk / jetのgeometryを簡単なポンチ絵にして並べてみました。

phase tableだけを眺めるより、

このObsIDではどんな配置だったのか

を少しイメージしやすくなった気がします。

こういう複数の周期運動が重なった天体では、とりあえず全部同じ形式で絵にして並べてみるのも案外便利かもしれません。

参考文献

関連記事

コード

最後に、今回の図を作成したコードを載せておきます。

コードはこちら
"""SS 433 Chandra HETG/HRC phase-geometry overview.

Orbital and precession phases are supplied directly for each observation.
The figure is a qualitative observer-side geometry schematic.

Outputs
-------
chandra_hetg_hrc_geometry_6x7.pdf
chandra_hetg_hrc_geometry_6x7.png
"""

from dataclasses import dataclass

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.lines import Line2D
from matplotlib.patches import Circle, Patch, Polygon


# =============================================================================
# Physical parameters
# =============================================================================

P_ORB = 13.08211  # d; used for the binary separation / orbital velocity
M_COMPACT = 6.0  # solar masses; representative
M_COMPANION = 12.0  # solar masses; representative
ORBIT_SENSE = +1

PREC_CONE_DEG = 20.92
INCLINATION_DEG = 78.05
POSITION_ANGLE_DEG = 98.2
PREC_SENSE = -1  # retrograde relative to +L_orb
BETA = 0.2647

DISK_RADIUS_RSUN = 8.0

G_SI = 6.67430e-11
M_SUN_KG = 1.98847e30
R_SUN_M = 6.957e8
AU_M = 1.495978707e11
DAY_S = 86400.0
C_M_S = 299792458.0
C_AU_DAY = C_M_S * DAY_S / AU_M

PREC_CONE_RAD = np.deg2rad(PREC_CONE_DEG)
INCLINATION_RAD = np.deg2rad(INCLINATION_DEG)
POSITION_ANGLE_RAD = np.deg2rad(POSITION_ANGLE_DEG)

M_TOTAL = M_COMPACT + M_COMPANION
P_ORB_S = P_ORB * DAY_S
A_REL_M = (
    G_SI * M_TOTAL * M_SUN_KG * (P_ORB_S / (2.0 * np.pi)) ** 2
) ** (1.0 / 3.0)
A_REL_AU = A_REL_M / AU_M
Q_DONOR_OVER_COMPACT = M_COMPANION / M_COMPACT


def eggleton_roche_fraction(q_donor_over_compact: float) -> float:
    """Donor volume-equivalent Roche radius divided by separation."""
    q23 = q_donor_over_compact ** (2.0 / 3.0)
    return 0.49 * q23 / (
        0.6 * q23 + np.log(1.0 + q_donor_over_compact ** (1.0 / 3.0))
    )


COMPANION_RADIUS_AU = A_REL_AU * eggleton_roche_fraction(
    Q_DONOR_OVER_COMPACT
)
DISK_RADIUS_AU = DISK_RADIUS_RSUN * R_SUN_M / AU_M
COMPACT_ORBIT_RADIUS_AU = A_REL_AU * M_COMPANION / M_TOTAL
COMPANION_ORBIT_RADIUS_AU = A_REL_AU * M_COMPACT / M_TOTAL
V_JET_AU_DAY = BETA * C_AU_DAY

# Binary frame -> observer frame: (LOS toward Earth, North, East).
R_BIN_TO_OBS = np.array(
    [
        [np.sin(INCLINATION_RAD), 0.0, np.cos(INCLINATION_RAD)],
        [
            -np.cos(INCLINATION_RAD) * np.cos(POSITION_ANGLE_RAD),
            np.sin(POSITION_ANGLE_RAD),
            np.sin(INCLINATION_RAD) * np.cos(POSITION_ANGLE_RAD),
        ],
        [
            -np.cos(INCLINATION_RAD) * np.sin(POSITION_ANGLE_RAD),
            -np.cos(POSITION_ANGLE_RAD),
            np.sin(INCLINATION_RAD) * np.sin(POSITION_ANGLE_RAD),
        ],
    ]
)


# =============================================================================
# Visualization parameters
# =============================================================================

BLUE = "#1479d1"
RED = "#d4483b"
STAR_COLOR = "#f2b134"
STAR_EDGE = "#8a5a00"
DISK_COLOR = "#159a70"
DISK_DARK = "#086f51"
COMPACT_COLOR = "#171717"
ORBIT_COLOR = "#6b7280"

LOS_APPROACHING_LABEL = "LOS-approaching"
LOS_RECEDING_LABEL = "LOS-receding"

DISK_OPACITY = 1.0
JET_GUIDE_LENGTH_AU = 0.22
COMPACT_MARKER_RADIUS_AU = 0.009  # symbolic, not the black-hole radius
OBSERVER_LIMIT_AU = 0.36


# =============================================================================
# Chandra observations
# =============================================================================

@dataclass(frozen=True)
class ChandraObservation:
    instrument: str
    obsid: int
    phi_orb: float
    phi_prec: float


# Tuple order: (ObsID, phi_orb, phi_prec)
# Listed order = left-to-right, top-to-bottom panel order.
HETG_OBSERVATIONS = tuple(
    ChandraObservation("HETG", obsid, phi_orb, phi_prec)
    for obsid, phi_orb, phi_prec in (
        (106,   0.64, 0.92),
        (1020,  0.67, 0.58),
        (1019,  0.95, 0.25),
        (1940,  0.97, 0.58),
        (1941,  0.12, 0.59),
        (1942,  0.27, 0.60),
        (5512,  0.52, 0.14),
        (5513,  0.97, 0.18),
        (5514,  0.21, 0.20),
        (6360,  0.40, 0.21),
        (15781, 0.01, 0.43),
        (20132, 0.77, 0.45),
        (20131, 0.01, 0.47),
        (24702, 0.22, 0.70),
        (25047, 0.34, 0.71),
        (25048, 0.41, 0.71),
        (24703, 0.67, 0.97),
        (25081, 0.73, 0.98),
        (24704, 0.18, 0.26),
        (25690, 0.28, 0.27),
        (27356, 0.35, 0.00),
        (29311, 0.64, 0.02),
        (27357, 0.21, 0.47),
        (27358, 0.04, 0.94),
    )
)

HRC_OBSERVATIONS = tuple(
    ChandraObservation("HRC", obsid, phi_orb, phi_prec)
    for obsid, phi_orb, phi_prec in (
        (6597,  0.61, 0.36),
        (6598,  0.75, 0.37),
        (6599,  0.99, 0.39),
        (6600,  0.21, 0.41),
        (26568, 0.34, 0.48),
        (26569, 0.92, 0.53),
        (26570, 0.35, 0.56),
        (26571, 0.02, 0.62),
        (26572, 0.53, 0.66),
        (26573, 0.84, 0.69),
        (26574, 0.24, 0.72),
        (26575, 0.99, 0.78),
        (26576, 0.38, 0.81),
        (26577, 0.17, 0.87),
        (26578, 0.54, 0.90),
        (26579, 0.14, 0.95),
    )
)


# =============================================================================
# Direct phase -> geometry
# =============================================================================

def _as_xyz(x, y, z):
    return np.stack([x, y, z], axis=-1)


def transform_to_observer(vectors):
    """Binary (Xb, Yb, Zb) -> (LOS toward Earth, North, East)."""
    vectors = np.asarray(vectors, dtype=float)
    return vectors @ R_BIN_TO_OBS.T


def binary_state_from_orbital_phase(phi_orb):
    """Barycentric positions and velocities at direct orbital-phase input."""
    phi_orb = np.asarray(phi_orb, dtype=float)
    phase = ORBIT_SENSE * 2.0 * np.pi * phi_orb + np.pi
    omega = ORBIT_SENSE * 2.0 * np.pi / P_ORB

    radial = _as_xyz(
        np.cos(phase), np.sin(phase), np.zeros_like(phase)
    )
    tangent = omega * _as_xyz(
        -np.sin(phase), np.cos(phase), np.zeros_like(phase)
    )

    r_compact = COMPACT_ORBIT_RADIUS_AU * radial
    r_companion = -COMPANION_ORBIT_RADIUS_AU * radial
    v_compact = COMPACT_ORBIT_RADIUS_AU * tangent
    v_companion = -COMPANION_ORBIT_RADIUS_AU * tangent
    return r_companion, r_compact, v_companion, v_compact


def jet_direction_from_precession_phase(phi_prec):
    """Unit plus-jet direction using the retrograde precession convention."""
    phi_prec = np.asarray(phi_prec, dtype=float)
    phi_angle = PREC_SENSE * 2.0 * np.pi * phi_prec

    return _as_xyz(
        np.sin(PREC_CONE_RAD) * np.cos(phi_angle),
        np.sin(PREC_CONE_RAD) * np.sin(phi_angle),
        np.cos(PREC_CONE_RAD) * np.ones_like(phi_angle),
    )


def relativistic_velocity_addition(source_velocity, velocity_source_frame):
    """Lorentz-add the compact object's orbital motion to a jet velocity."""
    u = np.asarray(source_velocity, dtype=float)
    vp = np.asarray(velocity_source_frame, dtype=float)
    u, vp = np.broadcast_arrays(u, vp)

    umag = np.linalg.norm(u, axis=-1)
    uhat = u / umag[..., None]

    vpar_scalar = np.sum(vp * uhat, axis=-1)
    vpar = vpar_scalar[..., None] * uhat
    vperp = vp - vpar

    gamma_u = 1.0 / np.sqrt(1.0 - (umag / C_AU_DAY) ** 2)
    denominator = 1.0 + np.sum(u * vp, axis=-1) / C_AU_DAY**2

    return (
        ((vpar_scalar + umag) / denominator)[..., None] * uhat
        + vperp / (gamma_u * denominator)[..., None]
    )


def instantaneous_los_branches(phi_orb, phi_prec):
    """Return directions classified by instantaneous barycentric LOS velocity."""
    n_plus = jet_direction_from_precession_phase(phi_prec)
    _, _, _, v_source = binary_state_from_orbital_phase(phi_orb)

    v_plus = relativistic_velocity_addition(
        v_source, V_JET_AU_DAY * n_plus
    )
    v_minus = relativistic_velocity_addition(
        v_source, -V_JET_AU_DAY * n_plus
    )

    plus_los = transform_to_observer(v_plus)[0]
    minus_los = transform_to_observer(v_minus)[0]

    if plus_los >= minus_los:
        return n_plus, -n_plus
    return -n_plus, n_plus


def orthonormal_disk_basis(normal):
    normal = np.asarray(normal, dtype=float)
    normal = normal / np.linalg.norm(normal)

    reference = np.array([0.0, 0.0, 1.0])
    if abs(np.dot(normal, reference)) > 0.90:
        reference = np.array([1.0, 0.0, 0.0])

    u = np.cross(normal, reference)
    u /= np.linalg.norm(u)
    v = np.cross(normal, u)
    return u, v


def disk_circle(center, normal, radius=DISK_RADIUS_AU, n=160):
    u, v = orthonormal_disk_basis(normal)
    angle = np.linspace(0.0, 2.0 * np.pi, n)

    return (
        np.asarray(center)
        + radius * np.cos(angle)[:, None] * u
        + radius * np.sin(angle)[:, None] * v
    )


def observer_binary_geometry_from_phases(phi_orb, phi_prec):
    """Return projected central geometry and LOS depth-ordering state."""
    r_star, r_compact, _, _ = binary_state_from_orbital_phase(phi_orb)
    normal = jet_direction_from_precession_phase(phi_prec)

    star_obs = transform_to_observer(r_star)
    compact_obs = transform_to_observer(r_compact)
    normal_obs = transform_to_observer(normal)

    delta = compact_obs - star_obs
    projected_separation = np.hypot(delta[1], delta[2])
    compact_in_front = bool(delta[0] > 0.0)

    return {
        "star_obs": star_obs,
        "compact_obs": compact_obs,
        "normal": normal,
        "normal_obs": normal_obs,
        "compact_in_front": compact_in_front,
        "compact_center_eclipsed": bool(
            (not compact_in_front)
            and projected_separation < COMPANION_RADIUS_AU
        ),
    }


def orbit_curves_from_phase(n=400):
    phases = np.linspace(0.0, 1.0, n)
    r_star, r_compact, _, _ = binary_state_from_orbital_phase(phases)
    return r_star, r_compact


def masked_curve(points_xy, mask):
    points_xy = np.asarray(points_xy, dtype=float)
    mask = np.asarray(mask, dtype=bool)

    out = points_xy.copy()
    out[~mask] = np.nan
    return out


# =============================================================================
# Drawing
# =============================================================================

def draw_observer_binary_phase(ax, phi_orb: float, phi_prec: float):
    """Draw one observer-side SS 433 schematic from direct phase inputs."""
    r_star_orbit, r_compact_orbit = orbit_curves_from_phase()
    star_orbit_obs = transform_to_observer(r_star_orbit)
    compact_orbit_obs = transform_to_observer(r_compact_orbit)

    ax.plot(
        star_orbit_obs[:, 2], star_orbit_obs[:, 1],
        color=STAR_COLOR, lw=0.90, alpha=0.48, zorder=1,
    )
    ax.plot(
        compact_orbit_obs[:, 2], compact_orbit_obs[:, 1],
        color=ORBIT_COLOR, lw=0.90, alpha=0.62, zorder=1,
    )
    ax.scatter(
        0.0, 0.0, marker="+", s=16,
        color="black", linewidths=0.75, zorder=1,
    )

    view = observer_binary_geometry_from_phases(phi_orb, phi_prec)
    star_obs = view["star_obs"]
    compact_obs = view["compact_obs"]
    star_xy = np.array([star_obs[2], star_obs[1]])
    compact_xy = np.array([compact_obs[2], compact_obs[1]])

    ax.plot(
        [star_xy[0], compact_xy[0]],
        [star_xy[1], compact_xy[1]],
        color=ORBIT_COLOR, lw=0.65, alpha=0.50, zorder=1,
    )

    normal = view["normal"]
    disk = disk_circle(
        binary_state_from_orbital_phase(phi_orb)[1], normal
    )
    disk_obs = transform_to_observer(disk)
    disk_xy = np.c_[disk_obs[:, 2], disk_obs[:, 1]]

    near_mask = disk_obs[:, 0] >= compact_obs[0]
    near_xy = masked_curve(disk_xy, near_mask)
    far_xy = masked_curve(disk_xy, ~near_mask)

    n_app, n_rec = instantaneous_los_branches(phi_orb, phi_prec)
    n_app_obs = transform_to_observer(n_app)
    n_rec_obs = transform_to_observer(n_rec)

    app_end_obs = compact_obs + JET_GUIDE_LENGTH_AU * n_app_obs
    rec_end_obs = compact_obs + JET_GUIDE_LENGTH_AU * n_rec_obs

    star_patch = Circle(
        star_xy,
        COMPANION_RADIUS_AU,
        facecolor=STAR_COLOR,
        edgecolor=STAR_EDGE,
        linewidth=0.85,
        alpha=1.0,
    )
    compact_patch = Circle(
        compact_xy,
        COMPACT_MARKER_RADIUS_AU,
        facecolor=COMPACT_COLOR,
        edgecolor="white",
        linewidth=0.55,
    )
    disk_patch = Polygon(
        disk_xy,
        closed=True,
        facecolor=DISK_COLOR,
        edgecolor=DISK_DARK,
        linewidth=0.75,
        alpha=DISK_OPACITY,
    )

    ax.add_patch(star_patch)

    rec_line, = ax.plot(
        [compact_obs[2], rec_end_obs[2]],
        [compact_obs[1], rec_end_obs[1]],
        color=RED,
        lw=1.65,
        solid_capstyle="round",
    )

    ax.add_patch(disk_patch)

    far_line, = ax.plot(
        far_xy[:, 0], far_xy[:, 1],
        color=DISK_DARK, lw=0.8, ls="--",
    )
    near_line, = ax.plot(
        near_xy[:, 0], near_xy[:, 1],
        color="#33d19a", lw=1.55,
    )

    app_line, = ax.plot(
        [compact_obs[2], app_end_obs[2]],
        [compact_obs[1], app_end_obs[1]],
        color=BLUE,
        lw=1.65,
        solid_capstyle="round",
    )

    ax.add_patch(compact_patch)

    if view["compact_in_front"]:
        star_patch.set_zorder(3)
        rec_line.set_zorder(4)
        disk_patch.set_zorder(5)
        far_line.set_zorder(5)
        near_line.set_zorder(6)
        app_line.set_zorder(7)
        compact_patch.set_zorder(8)
    else:
        rec_line.set_zorder(2)
        disk_patch.set_zorder(3)
        far_line.set_zorder(3)
        near_line.set_zorder(4)
        app_line.set_zorder(4)
        compact_patch.set_zorder(4)
        star_patch.set_zorder(9)

    ax.set_xlim(OBSERVER_LIMIT_AU, -OBSERVER_LIMIT_AU)  # east is left
    ax.set_ylim(-OBSERVER_LIMIT_AU, OBSERVER_LIMIT_AU)
    ax.set_aspect("equal", adjustable="box")
    ax.set_facecolor("white")
    ax.set_xticks([])
    ax.set_yticks([])

    for spine in ax.spines.values():
        spine.set_color("#d1d5db")
        spine.set_linewidth(0.55)


def legend_handles():
    return [
        Patch(
            facecolor=STAR_COLOR,
            edgecolor=STAR_EDGE,
            label="Companion",
        ),
        Line2D(
            [0], [0],
            marker="o",
            color="none",
            markerfacecolor=COMPACT_COLOR,
            markeredgecolor="white",
            label="Compact object (symbolic marker)",
        ),
        Patch(
            facecolor=DISK_COLOR,
            edgecolor=DISK_DARK,
            label="Opaque disk",
        ),
        Line2D(
            [0], [0],
            color=BLUE,
            lw=2,
            label=LOS_APPROACHING_LABEL,
        ),
        Line2D(
            [0], [0],
            color=RED,
            lw=2,
            label=LOS_RECEDING_LABEL,
        ),
    ]


def make_chandra_overview():
    observations = HETG_OBSERVATIONS + HRC_OBSERVATIONS

    fig, axes = plt.subplots(7, 6, figsize=(15.6, 17.3))
    flat_axes = list(axes.flat)

    for ax, observation in zip(flat_axes, observations):
        draw_observer_binary_phase(
            ax,
            observation.phi_orb,
            observation.phi_prec,
        )

        ax.text(
            0.025, 0.975, f"{observation.obsid}",
            transform=ax.transAxes,
            ha="left", va="top",
            fontsize=7.2,
            weight="bold",
            bbox={
                "facecolor": "white",
                "alpha": 0.88,
                "edgecolor": "none",
                "pad": 1.3,
            },
            zorder=20,
        )

        ax.text(
            0.025, 0.912,
            rf"$\phi_{{\rm prec}}$ = {observation.phi_prec:.2f}" "\n"
            rf"$\phi_{{\rm orb}}$  = {observation.phi_orb:.2f}",
            transform=ax.transAxes,
            ha="left", va="top",
            fontsize=5.8,
            linespacing=1.10,
            bbox={
                "facecolor": "white",
                "alpha": 0.88,
                "edgecolor": "none",
                "pad": 1.1,
            },
            zorder=20,
        )

    # 6 x 7 = 42 cells; the final two are intentionally blank.
    for ax in flat_axes[len(observations):]:
        ax.axis("off")

    fig.suptitle(
        "SS 433 Chandra phase geometry - HETG and HRC",
        fontsize=16,
        y=0.992,
    )

    fig.legend(
        handles=legend_handles(),
        loc="lower center",
        ncol=5,
        fontsize=8.2,
        bbox_to_anchor=(0.5, 0.023),
        frameon=False,
    )

    fig.subplots_adjust(
        left=0.040,
        right=0.995,
        top=0.970,
        bottom=0.057,
        wspace=0.035,
        hspace=0.075,
    )

    block_ranges = (
        (0, 3, "Chandra HETG"),
        (4, 6, "Chandra HRC"),
    )

    for first_row, last_row, text in block_ranges:
        top = axes[first_row, 0].get_position().y1
        bottom = axes[last_row, 0].get_position().y0

        fig.text(
            0.011,
            0.5 * (top + bottom),
            text,
            rotation=90,
            ha="center",
            va="center",
            fontsize=11,
            weight="bold",
        )

    separator_y = 0.5 * (
        axes[3, 0].get_position().y0
        + axes[4, 0].get_position().y1
    )

    fig.add_artist(
        Line2D(
            [0.031, 0.995],
            [separator_y, separator_y],
            transform=fig.transFigure,
            color="#9ca3af",
            lw=0.8,
        )
    )

    fig.text(
        0.50,
        0.011,
        "Every panel: fixed +/-0.36 AU field; east is left; "
        "colors show instantaneous LOS state",
        ha="center",
        va="bottom",
        fontsize=8.5,
        color="#4b5563",
    )

    fig.savefig(
        "chandra_hetg_hrc_geometry_6x7.pdf",
        format="pdf",
        metadata={
            "Title": "SS 433 Chandra HETG and HRC phase geometry"
        },
    )
    fig.savefig(
        "chandra_hetg_hrc_geometry_6x7.png",
        dpi=200,
        facecolor="white",
    )
    plt.close(fig)


if __name__ == "__main__":
    plt.rcParams.update(
        {
            "font.family": "DejaVu Sans",
            "pdf.fonttype": 42,
            "ps.fonttype": 42,
            "axes.linewidth": 0.7,
            "savefig.facecolor": "white",
        }
    )

    make_chandra_overview()
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?