Source code for tcv.geom

# pylint: disable=invalid-name, no-member
"""
TCV geometry and vessel properties
"""

import numpy as np

import matplotlib.pyplot as plt
from matplotlib.path import Path
from matplotlib.patches import PathPatch
from matplotlib.ticker import MaxNLocator

import tcv


[docs]class StaticParameters(object): """ TCV static parameters """ def __init__(self, coordinates): self._coordinates = coordinates
[docs] def get_coordinates(self, part, coord_names=None): """ Get the coordinates of a certain vessel part. """ if coord_names is None: return self._coordinates[part] names = coord_names.split(',') names = [str.strip(x) for x in names] ret = [self._coordinates[part][key] for key in names] if len(ret) == 1: ret = ret[0] else: ret = tuple(ret) return ret
@classmethod
[docs] def from_tree(cls, shotnum): """ Read the vessel's parameters from the static MDS nodes """ vessel = {} with tcv.shot(shotnum) as conn: for key, query in cls._vessel_nodes().items(): vessel[key] = conn.tdi(query).values tiles = {} tiles['R'] = np.array([ 1.1360, 1.1360, 1.1120, 1.0880, 1.0640, 1.0399, 1.0159, 0.9919, 0.9679, 0.6707, 0.6240, 0.6240, 0.6240, 0.6724, 0.9679, 1.1360, 1.1360 ]) tiles['Z'] = np.array([ 0, 0.5494, 0.5781, 0.6067, 0.6354, 0.6640, 0.6927, 0.7213, 0.7500, 0.7500, 0.7033, 0, -0.7033, -0.7500, -0.7500, -0.5494, 0.0000 ]) return cls({'vessel': vessel, 'tiles': tiles})
@staticmethod def _vessel_nodes(): """ Return the static MDS nodes containing the vessel parameters """ nodes = { 'R_in': 'static("r_v:in")', 'R_out': 'static("r_v:out")', 'Z_in': 'static("z_v:in")', 'Z_out': 'static("z_v:out")'} return nodes
[docs]class VesselDrawer(object): def __init__(self, coordinates): """ Input ----- coordinates : dict Dictionary with the following structure 'vessel': dict with keys 'R_in', 'Z_in', 'R_out', 'Z_out' 'tiles': dict with keys 'R', 'Z' """ self.coordinates = coordinates self._tiles_shown = False @classmethod
[docs] def from_static(cls, shotnum=0): static = StaticParameters.from_tree(shotnum) coords = {'vessel': static.get_coordinates('vessel'), 'tiles': static.get_coordinates('tiles')} return cls(coords)
[docs] def render(self, ax=None, tiles=True): ax = ax or plt.gca() ax.add_patch(self._get_vessel_patch()) if tiles and self.has_tiles_coordinates(): ax.add_patch(self._get_tiles_patch()) self._tiles_shown = True
[docs] def get_coordinates(self, key): return self.coordinates.get(key)
[docs] def has_tiles_coordinates(self): return 'tiles' in self.coordinates
[docs] def get_patches(self): patches = [self._get_vessel_patch()] if self.get_coordinates('tiles') is not None: patches.append(self._get_tiles_patch()) return patches
def _inside(self): coords = self.get_coordinates('vessel') vertices = [r for r in zip(coords['R_in'], coords['Z_in'])] vertices.append(vertices[0]) codes = [Path.MOVETO] + (len(vertices) - 1) * [Path.LINETO] return vertices, codes def _outside(self): coords = self.get_coordinates('vessel') vertices = [r for r in zip(coords['R_out'], coords['Z_out'])][::-1] vertices.append(vertices[0]) codes = [Path.MOVETO] + (len(vertices) - 1) * [Path.LINETO] return vertices, codes def _tiles(self): coords = self.get_coordinates('tiles') vertices = [r for r in zip(coords['R'], coords['Z'])][::-1] vertices.append(vertices[0]) codes = [Path.MOVETO] + (len(vertices) - 1) * [Path.LINETO] return vertices, codes def _get_vessel_patch(self): vertices_in, codes_in = self._inside() vertices_out, codes_out = self._outside() vessel_path = Path(vertices_in + vertices_out, codes_in + codes_out) vessel_patch = PathPatch(vessel_path, facecolor=(0.6, 0.6, 0.6), edgecolor='black') return vessel_patch def _get_tiles_patch(self): vertices_in, codes_in = self._tiles() vertices_out, codes_out = self._inside() tiles_path = Path(vertices_in + vertices_out, codes_in + codes_out) tiles_patch = PathPatch(tiles_path, facecolor=(0.75, 0.75, 0.75), edgecolor='black') return tiles_patch def _transparent_inside_patch(self): if self._tiles_shown: vertices, codes = self._tiles() else: vertices, codes = self._inside() path = Path(vertices, codes) return PathPatch(path, alpha=0)
[docs] def clip_collections_inside(self, ax): vessel_in = self._transparent_inside_patch() ax.add_patch(vessel_in) for c in ax.collections: c.set_clip_path(vessel_in)
[docs]def tcvview(shotnum, time, vessel=True, ports=False, tiles=True): """ Popular way to display TCV. Parameters ---------- shotnum : int, or MDSConnection Shot number or an open MDS connection instance. time : float Time of the equilibrium. vessel : bool, optional Draw vessel. ports : bool, optional Draw ports tiles : bool, optional Draw tiles. Example ------- >>> import tcv >>> tcv.tcvview(42660, 1) """ ax = plt.gca() from . equilibrium import LiuqeEquilibrium eq = LiuqeEquilibrium.fromshot(shotnum, time) if ports: PortsDrawer().render() if vessel: vd = VesselDrawer.from_static(shotnum) vd.render(ax, tiles) r, z, psi = eq.get_psi_contours() r0, z0 = eq.magnetic_axis levels_core = np.linspace(0, 10, 101) levels_sol = np.linspace(-10, 0, 101) ax.contour(r, z, psi.T, levels=levels_core, colors='r') ax.contour(r, z, psi.T, levels=levels_sol, colors='r', linestyles=':') ax.plot([r0], [z0], 'r+') ax.set_aspect('equal') if vessel: vd.clip_collections_inside(ax) _add_shot_time(eq.shot, eq.time, ax) ax.xaxis.set_major_locator(MaxNLocator(4)) if plt.isinteractive(): ax.figure.canvas.draw()
def _add_shot_time(shot, time, ax): text = r'$\#%d\ %1.3f\ \mathrm{s}$' % (shot, time) ax.text(1.0, 0, text, rotation=270, transform=ax.transAxes, va='bottom', ha='left', size='small') def _add_plasma_parameters(connection, time, ax): text = r'$I_\mathrm{p}=999\ \mathrm{kA}$' ax.text(0.5, 1.0, text, transform=ax.transAxes, va='bottom', ha='center', size='small')
[docs]class PortsDrawer(object):
[docs] def get_ports_coordinates(self): Hportx = np.array([ 0.04, 0, 0, 0.022, 0.046, 0.245, 0.245, 0.27, 0.27, 0.04 ]) Hporty = np.array([ 0.06, 0.06, 0.115, 0.115, 0.08, 0.08, 0.126, 0.126, 0.064, 0.064 ]) pm1y = 0.455 pt1y = pm1y + Hporty pb1y = pm1y - Hporty p1x = 1.16 + Hportx pm2y = -0.0025 pt2y = pm2y + Hporty pb2y = pm2y - Hporty p2x = 1.16 + Hportx pm3y = -0.46 pt3y = pm3y + Hporty pb3y = pm3y - Hporty p3x = 1.16 + Hportx Vportx = np.array([ 0.035, 0.035, 0.068, 0.068, 0.054, 0.054, 0.075, 0.075, 0.04, 0.04 ]) Vporty = np.array([ 0.045, 0, 0, 0.045, 0.059, 0.069, 0.069, 0.09, 0.09, 0.045 ]) Vporty1 = np.array([ 0.045, -0.059157, -0.086867, 0.045, 0.059, 0.069, 0.069, 0.09, 0.09, 0.045 ]) pm4x = 0.715 pl4x = pm4x - Vportx pr4x = pm4x + Vportx p4y = 0.77 + Vporty pm5x = 0.715 pl5x = pm5x - Vportx pr5x = pm5x + Vportx p5y = -0.77 - Vporty pm6x = 0.88 pl6x = pm6x - Vportx pr6x = pm6x + Vportx pl6y = -0.77 - Vporty # pm6y = -0.77 - Vporty pr6y = -0.77 - Vporty # pm7x = 0.88 pl7x = pm6x - Vportx pr7x = pm6x + Vportx pl7y = 0.77 + Vporty # pm7y = 0.77 + Vporty pr7y = 0.77 + Vporty pm8x = 1.045 pl8x = pm8x - Vportx pr8x = pm8x + Vportx pl8y = -0.77 - Vporty # pm8y = -0.77 - Vporty pr8y = -0.77 - Vporty1 pm9x = 1.045 pl9x = pm9x - Vportx pr9x = pm9x + Vportx pl9y = 0.77 + Vporty # pm9y = 0.77 + Vporty pr9y = 0.77 + Vporty1 p1 = self._vertices_codes(p1x, pt1y, p1x, pb1y) p2 = self._vertices_codes(p2x, pt2y, p2x, pb2y) p3 = self._vertices_codes(p3x, pt3y, p3x, pb3y) p4 = self._vertices_codes(pl4x, p4y, pr4x, p4y) p5 = self._vertices_codes(pl5x, p5y, pr5x, p5y) p6 = self._vertices_codes(pl6x, pl6y, pr6x, pr6y) p7 = self._vertices_codes(pl7x, pl7y, pr7x, pr7y) p8 = self._vertices_codes(pl8x, pl8y, pr8x, pr8y) p9 = self._vertices_codes(pl9x, pl9y, pr9x, pr9y) return [p1, p2, p3, p4, p5, p6, p7, p8, p9]
def _vertices_codes(self, x1, y1, x2, y2): vertices1 = [r for r in zip(x1, y1)] vertices1.append(vertices1[0]) codes1 = [Path.MOVETO] + (len(vertices1) - 1) * [Path.LINETO] vertices2 = [r for r in zip(x2, y2)] vertices2.append(vertices2[0]) codes2 = [Path.MOVETO] + (len(vertices2) - 1) * [Path.LINETO] vertices = vertices1 + vertices2 codes = codes1 + codes2 return vertices, codes
[docs] def get_patch(self): codes, vertices = [], [] for p in self.get_ports_coordinates(): v, c = p codes += c vertices += v path = Path(vertices, codes) return PathPatch(path, facecolor=(0.6, 0.6, 0.6), edgecolor='black')
[docs] def render(self, ax=None): ax = ax or plt.gca() ax.add_patch(self.get_patch())