はじめに
以前の記事では、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だったのかを眺めてみます。
こちらがその結果です。
上4行が Chandra HETG、下3行が Chandra HRC です。
各panelには、
- ObsID
- precession phase $\phi_{\rm prec}$
- orbital phase $\phi_{\rm orb}$
を表示しています。
黄色がcompanion、黒がcompact object、緑がdiskです。
青と赤はそれぞれ LOS-approaching、LOS-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ではどんな配置だったのか
を少しイメージしやすくなった気がします。
こういう複数の周期運動が重なった天体では、とりあえず全部同じ形式で絵にして並べてみるのも案外便利かもしれません。
参考文献
-
Gies et al. (2002), The Spectral Components of SS 433
https://ui.adsabs.harvard.edu/abs/2002ApJ...566.1069G/abstract -
Goranskij (2011), Photometric Mass Estimate for the Compact Component of SS 433
https://ui.adsabs.harvard.edu/abs/2011PZ.....31....5G/abstract -
Sakai et al. (2025), Arcsecond-scale X-ray imaging and spectroscopy of SS 433 with the Chandra High-Energy Transmission Grating
https://doi.org/10.1093/pasj/psaf088 -
Shidatsu et al. (2025), XRISM high-resolution spectroscopy of SS 433
https://doi.org/10.1093/pasj/psaf110 -
Takagi et al. (2026), XRISM observation of the neutral iron and nickel emission lines in the microquasar SS 433
https://doi.org/10.1093/pasj/psaf142 -
Sakai et al. (2026), Spectral and photometric variability of SS 433 observed with XRISM and simultaneous optical and near-infrared telescopes
https://doi.org/10.1093/pasj/psaf152
関連記事
コード
最後に、今回の図を作成したコードを載せておきます。
コードはこちら
"""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()
