diff --git a/.gitignore b/.gitignore index 0b588c856..a94e3bed3 100644 --- a/.gitignore +++ b/.gitignore @@ -5,9 +5,15 @@ *.o *.so *.c +*.cpp *.nfs* + +# annotated files tofu/geom/*.html +# No images +#*.png + # Mac stuff *.AppleDouble .DS_Store @@ -34,24 +40,33 @@ dist/ tofu.egg-info/ build/ -#Notes_Upgrades/ - # Tex files *.aux *.log -# .gitignore -1 -Introduction -computing -Details +# coverage output .coverage # Include travis !.travis.yml +# no precommit configurations +.pre-commit-config.yaml + # installation dir usr/ -# tests of LOS on west and ITER -tofu/tests/tests01_geom/laura_tmp/ +# no PyCharm config files +.idea/ + +# do not commit sphinx built files +doc/build/html/ + +# do not commit built compiled files on windows +*.pyd + +# do not commit sphinx-gallery files +doc/source/auto_examples/ + +# do not commit nose tests files +*.noseids diff --git a/.travis.yml b/.travis.yml index b780c961b..460d5e775 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,7 @@ language: python python: -- '2.7' - '3.6' -#- '3.7-dev' +- '3.7-dev' git: depth: 200 @@ -14,9 +13,9 @@ before_install: - gcc --version - export START=$(pwd) install: -- if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then wget https://repo.continuum.io/miniconda/Miniconda2-latest-Linux-x86_64.sh - -O miniconda.sh; export VADD="py27"; else wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh - -O miniconda.sh; export VADD="py36"; fi +- if [[ "$TRAVIS_PYTHON_VERSION" == "3.7-dev" ]]; then export VADD="py37"; else export VADD="py36"; fi +- wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh + -O miniconda.sh - bash miniconda.sh -b -p $HOME/miniconda - export PATH="$HOME/miniconda/bin:$PATH" - hash -r diff --git a/Debug_JINTRACMesh.pdf b/Debug_JINTRACMesh.pdf new file mode 100644 index 000000000..e69de29bb diff --git a/Debug_JINTRACMesh.png b/Debug_JINTRACMesh.png new file mode 100644 index 000000000..0e536fb53 Binary files /dev/null and b/Debug_JINTRACMesh.png differ diff --git a/Debug_JINTRACMesh.svg b/Debug_JINTRACMesh.svg new file mode 100644 index 000000000..725e03413 --- /dev/null +++ b/Debug_JINTRACMesh.svg @@ -0,0 +1,21 @@ + + + + + + + + + + + + + diff --git a/Debug_JINTRACMesh2.png b/Debug_JINTRACMesh2.png new file mode 100644 index 000000000..5dbb05bc9 Binary files /dev/null and b/Debug_JINTRACMesh2.png differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/2019_LM_Euroscipy.bib b/Notes_Upgrades/Communications/Euroscipy2019/2019_LM_Euroscipy.bib new file mode 100644 index 000000000..b98edc6a2 --- /dev/null +++ b/Notes_Upgrades/Communications/Euroscipy2019/2019_LM_Euroscipy.bib @@ -0,0 +1,10 @@ +@article{didier2016, + title={Non-monotonic growth rates of sawtooth precursors evidenced with a new method on ASDEX Upgrade}, + author={Vezinet, D and Igochine, V and Weiland, M and Yu, Q and Gude, A and Meshcheriakov, D and Sertoli, M and EUROfusion MST1 Team and others}, + journal={Nuclear Fusion}, + volume={56}, + number={8}, + pages={086001}, + year={2016}, + publisher={IOP Publishing} +} \ No newline at end of file diff --git a/Notes_Upgrades/Communications/Euroscipy2019/2019_LM_Euroscipy.pdf b/Notes_Upgrades/Communications/Euroscipy2019/2019_LM_Euroscipy.pdf new file mode 100644 index 000000000..443e84fe1 Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/2019_LM_Euroscipy.pdf differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/2019_LM_Euroscipy.tex b/Notes_Upgrades/Communications/Euroscipy2019/2019_LM_Euroscipy.tex new file mode 100644 index 000000000..e58e1518b --- /dev/null +++ b/Notes_Upgrades/Communications/Euroscipy2019/2019_LM_Euroscipy.tex @@ -0,0 +1,1026 @@ +\documentclass[10pt]{beamer} + +\usepackage{appendixnumberbeamer} +% +%\usepackage{lmodern} +%\usepackage{wrapfig} +\usepackage{tikz} +%\usetikzlibrary{positioning} +\usetikzlibrary{arrows,shapes} +\usepackage{amsmath,esint,esvect} % arrow for vector, maths and more +%\usepackage{datetime} +\usepackage{gensymb}%for degree symbol +%\usepackage{beamerthemesplit} +%\usepackage{graphicx} %trimed images +%\usepackage{pifont} %for dings +% +%\usepackage{import} +%\usepackage{cases} +\usepackage{booktabs} %beautiful tables +\usepackage{pgfplots} +\usepgfplotslibrary{dateplot} +% +\usepackage{siunitx} % SI notations +\sisetup{table-number-alignment=center, exponent-product=\cdot} + + + + +% Bibliography includes +\usepackage[backend=bibtex, citestyle=verbose-trad2,bibstyle=authortitle-icomp,sortcites=true,block=space,firstinits=true]{biblatex} +\addbibresource{2019_LM_Euroscipy.bib} +\usepackage{hyperref} + +\usetheme[progressbar=frametitle]{metropolis} + + + + \setbeamertemplate{itemize subitem}{\color{orange}$\blacktriangleright$} + +% --------------Math mode------------------ +\renewcommand\mathfamilydefault{\rmdefault} +% ----------------------------------------- + +% ------ Images path ------------------ +\newcommand{\figurespath}{./figures} + +%% ---------- Editing the footer ------------ +%\makeatother +%\setbeamertemplate{footline} +%{ +% \leavevmode% +% \hbox{% +% \begin{beamercolorbox}[wd=.6\paperwidth,ht=2.25ex,dp=1ex,center]{institute in head/foot}% +% \usebeamerfont{institute in head/foot}\insertshortinstitute +% \end{beamercolorbox}% +% \begin{beamercolorbox}[wd=.4\paperwidth,ht=2.25ex,dp=1ex,center]{date in head/foot}% +% \usebeamerfont{date in head/foot}\insertshortdate\hspace*{2em} +% \insertframenumber{} \hspace*{2ex} +% \end{beamercolorbox}}% +% \vskip0pt% +%} +%\makeatletter +%\setbeamertemplate{navigation symbols}{} +%% ----------------------------------------- + +% ------ Date definition ------------------ +% \newdate{date}{04}{09}{2019} +% ----------------------------------------- + +% ----------New color---------------------- +\definecolor{myblue}{RGB}{51,51,179} +\definecolor{beaubleu2}{cmyk}{1,0,0,0.71} +\definecolor{SchoolColor}{rgb}{0.6471, 0.1098, 0.1882} % Crimson +\definecolor{beaurouge}{HTML}{405684} +\definecolor{beaubleu}{HTML}{CC382C} +\definecolor{myyellow}{rgb}{0.99, 0.82, 0.35} +% ----------------------------------------- + +%% ---------Redifining foot cites----------- +\newrobustcmd*{\footlessfullcite}{\AtNextCite{\renewbibmacro{title}{}\renewbibmacro{in:}{}}\footfullcite} + +%\renewbibmacro{in:}{\hspace{-5pt}} +\AtEveryCitekey{\clearfield{pages}\clearfield{volume}\clearfield{url} +\clearfield{doi}\clearfield{issn}} +%% ----------------------------------------- + +% ---------First page variables------------ +\title{ToFu} +\subtitle{An open-source python/cython library for synthetic tomography diagnostics on tokamaks} +\author[Laura S. Mendoza] % (optional, for multiple authors) +{\textbf{Laura~S.~Mendoza}\inst{1}, \and Didier~Vezinet\inst{2}} +\institute[] % (optional) +{ + \inst{1}% + INRIA Grand-Est, + TONUS Team, Strasbourg, France\\ + + \inst{2}% + CEA, + Cadarache, France +} +\date[\displaydate{date}] % (optional) +{\alert{Euroscipy 2019, Bilbao, Espa\~na}} +\subject{} + + +% ----------------------------------------- + +%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{document} + +\newcommand{\gradx}{\nablax} +\newcommand{\vpar}{v_\parallel} +\newcommand{\xvec}{\mathbf{x}} +\newcommand{\nablax}{\nabla_{\!\xvec}} + + +% ================================= +%\usebackgroundtemplate{\includegraphics[height=\paperheight,width=\paperwidth]{figures/background.png}}% +\begin{frame} + \titlepage +\end{frame} +% ================================= + +% ================================= +\begin{frame}{Table of contents} + \setbeamertemplate{section in toc}[sections numbered] + \tableofcontents[hideallsubsections] +\end{frame} +% ================================= + +\section{Context} + +% ================================= +\begin{frame} +\frametitle{Context: energy needs vs resources and climate change} + + \begin{center} + \includegraphics[height=1.8cm]{figures/oil-power.jpg}% + \includegraphics[height=1.8cm]{figures/solar-power.jpg}% + \includegraphics[height=1.8cm]{figures/nuclear-power.jpg}% + \includegraphics[height=1.8cm]{figures/wind-power.jpg} + \end{center} + +Worldwide growing energy needs (population, standards of living...)\\ +$\quad \Rightarrow$ high pressure on environment (degrading, changing, exhausting...)\\ + +$\quad \Rightarrow$ need to decrease consumption + alternative production means\\ + +$\quad \Rightarrow$ a relatively clean, safe, mass-production means with large resources would be welcome in the mix\\ + +%\begin{itemize}%[leftmargin=1em] +%\setbeamertemplate{itemize item}{$\Rightarrow$} +% \item \alert{Fusion}: cleaner, more reliable, more powerful energy source? +%\end{itemize} + +\end{frame} +% ================================= + + + +% ================================= +\begin{frame} +\frametitle{Context: Controlled fusion and magnetic confinement} + +\begin{columns} + \begin{column}{0.65\textwidth} + \begin{center} + \textbf{D-T Fusion reaction\;\;\;}\vspace{0.3cm} + %\includegraphics[width=3.5cm]{figures/DT_reaction3.png} + \resizebox{0.5\textwidth}{!}{\input{figures/reaction.tex}} + \end{center} + \vspace{-0.5cm} + \begin{itemize}%[leftmargin=1em] + \item Gas $>$ 100 Million\degree K composed of positive ions and negative electrons: plasma + \item Confinement using electromagnetic fields + \item break-even not obtained yet + \end{itemize} + + \end{column} + + \begin{column}{0.35\textwidth} + \includegraphics[width=1.\textwidth]{figures/ITER.pdf} + \end{column} + +\end{columns} + +%\begin{itemize}%[leftmargin=1em] +\begin{center} +In a nutshell: toroidal vacuum vessel, filled with H plasma +\end{center}%\end{itemize} +\vspace{-0.2cm} +%%\begin{itemize}%[leftmargin=1em] +%%\setbeamertemplate{itemize item}{$\Rightarrow$} +%% \item \alert{Fusion codes:} complexity due to the number of parameters, geometry, model, etc. +%%\end{itemize} +\end{frame} +% ================================= + + +\section{Tomography diagnostics} + + +% ================================= +\begin{frame} +\frametitle{Tokamak diagnostics to measure plasma quantities} + + \metroset{block=fill} +\begin{alertblock}{Diagnostics} +Set of instruments to measure plasma quantities, for understanding, control, optimization. +\end{alertblock} + +e.g: magnetic field, neutrons, \textbf{emitted light}, temperature, density...\\[1cm] + + +$\quad \Rightarrow$ cameras (1D or 2D) for measuring light in various wavelengths + + +% +%\begin{itemize} +%\item \textbf{Magnetic} diagnostics: currents, plasma stored energy, plasma shape and position; +% +%\item \textbf{Neutron} diagnostics (ie. cameras, spectrometers, etc.): fusion power; +% +%\item Optical systems (\textbf{interferometers}): temperature and density profiles; +% +%\item Bolometric systems (\textbf{tomography}): spatial distribution of radiated power; +% +%\item \textbf{Spectroscopic}: X-ray wavelength range, impurity species and density, input particle flux, ion temperature, helium density, fueling ratio, plasma rotation, and current density. + +%\item Microwave diagnostics probe the main plasma and the plasma in the divertor region in order to measure plasma position. + +%\end{itemize} + +\end{frame} +% ================================= + + +% ================================= +\begin{frame} +\frametitle{A tokamak as a poloidal + horizontal projections} + +\begin{columns} + + \begin{column}{0.25\textwidth} + \includegraphics[width=1.\textwidth]{figures/ITER.pdf} + \end{column} + + \begin{column}{0.75\textwidth} + \begin{center} + \textbf{tofu.geom.Config class} + \end{center} + \includegraphics[width=1.\textwidth]{figures/Config01.pdf} + \end{column} + +\end{columns} + + +\end{frame} +% ================================= + +% ================================= +\begin{frame} +\frametitle{Tomography diagnostics - numerical context} + \vspace{-0.75cm} + + $$M_i(t) = \iiint\limits_{V_i} \vv{\varepsilon(x,t)}\cdot\vv{n} \,\Omega_i \;{d}V$$ + \vspace{-0.75cm} +\begin{columns} + \begin{column}{0.325\textwidth} + + %\def\svgwidth{\linewidth} + %\import{figures/}{detectors.pdf_tex} + \includegraphics[width=\linewidth,trim={0 0 1cm 0}]{figures/Tomography.pdf} + + \end{column} + + \begin{column}{0.675\textwidth} + \begin{center} + + %DIRECT PROBLEM + \begin{block}{} + \begin{itemize} + \item \textcolor{myblue}{\textbf{Direct problem} (synthetic diagnostic):\\ + } + \end{itemize} + \end{block} + %\textbf{Direct problem} (synthetic diagnostic):\\ +Simulated emissivity $\longrightarrow$ integrated measurements\\ + + %INVERSE PROBLEM + \begin{block}{} + \begin{itemize} + \item \textcolor{myblue}{\textbf{Inverse problem} (tomography):\\ + } + \end{itemize} + \end{block} + %\textbf{Direct problem} (synthetic diagnostic):\\ +Integrated measurements $\longrightarrow$ Reconstructed emissivity \\ + + \end{center} + + \end{column} +% +\end{columns} + + +\end{frame} +% ================================= + + + + +% ================================= +\begin{frame} +\frametitle{Tomography diagnostics - numerical context} + + $$M_i(t) = \iiint\limits_{V_i} \vv{\varepsilon(x,t)}\cdot\vv{n} \,\Omega_i \;{d}V$$ + \vspace{-1cm} +\begin{columns} + \begin{column}{0.325\textwidth} + + %\def\svgwidth{\linewidth} + %\import{figures/}{detectors.pdf_tex} + \includegraphics[width=\linewidth,trim={0 0 1cm 0}]{figures/Tomography.pdf} + + \end{column} + + \begin{column}{0.675\textwidth} + \begin{center} + + %DIRECT PROBLEM + \begin{block}{} + \begin{itemize} + \item \textcolor{myblue}{\textbf{Direct problem} (synthetic diagnostic):\\ + } + \end{itemize} + \end{block} + %\textbf{Direct problem} (synthetic diagnostic):\\ +Simulated emissivity $\longrightarrow$ measurements\\ + \alert{Spatial integration} + \vspace{-0.5cm} + + %INVERSE PROBLEM + \begin{block}{} + \begin{itemize} + \item \textcolor{myblue}{\textbf{Inverse problem} (tomography):\\ + } + \end{itemize} + \end{block} + %\textbf{Direct problem} (synthetic diagnostic):\\ +Integrated measurements $\longrightarrow$ Reconstructed emissivity \\ + \alert{Mesh and basis functions construction, spatial integration, data filtering, inversion routines, etc.} + + \end{center} + + \end{column} +% +\end{columns} + +\pause +\vspace{-0.5cm} +\begin{block}{} +\begin{center} +Tomography is \textbf{ill-posed}, very sensitive to errors, noise and bias\\ +$\longrightarrow$ \alert{Reputation for low reproducibility / reliability } +\end{center} + \end{block} +\end{frame} +% ================================= + + + +\section{The ToFu package} + + +% ================================= +\begin{frame} +\frametitle{Motivation: ``current" state} + + In the fusion community, codes for tomography diagnostic are often: + \begin{itemize} + \item developed by physicists (with little programming experience) + \item in Matlab (or IDL) + \item written from scratch, re-done by new students + \item not distributed (few users), rarely documented + \end{itemize} + +... which means +\begin{itemize} + \item waste of resources: time, man-power + \item low traceability, reproducibility + \item low standardization, unclear assumptions / methods + \end{itemize} + +\end{frame} +% ================================= + + +% ================================= +\begin{frame} +\frametitle{A code for Tomography for Fusion} +\textbf{Develop a common tool:} +\begin{columns} +\begin{column}{0.65\textwidth} + \begin{itemize} + \item Generic (geometry independent) + \item Portable (Python) + \item Optimized / parallelized + \item Documented online + \item Continuous integration + \end{itemize} +\end{column} +\begin{column}{0.35\textwidth} +\vspace{-1cm} +\begin{center} + \includegraphics[width=0.8\linewidth]{figures/ci.pdf} +\end{center} +\end{column} +\end{columns} +\vspace{-0.9cm} + +\begin{block}{} + \begin{center} + \alert{\textbf{ToFu}\footnote{repository: \url{https://github.com/ToFuProject/tofu}}\footnote{documentation: \url{https://tofuproject.github.io/tofu/index.html} }\footcite{didier2016}} = \alert{\textbf{To}mography for \textbf{Fu}sion} + \end{center} +\vspace{-5mm} +\end{block} + +\end{frame} +% ================================= + +% ================================= +\begin{frame} +\frametitle{More about Tofu} + +\begin{columns} +\begin{column}{0.65\textwidth} +\begin{itemize} + \item Created in 2014 + \item Open Source:\textbf{ MIT license} + \item Python 2.7 and \textbf{Python} 3 + \textbf{Cython} + \item Continuous integration: \textbf{Travis} CI + \item \textbf{conda}, \textbf{pip} + \item Two (main) developers: + \begin{itemize} + \item Didier Vezinet (creator, Physics) + \item Laura S. Mendoza (since 06.2018, Applied Maths) + \end{itemize} + \item Contributors: + \begin{itemize} + \item Jorge Morales + \item Florian Le Bourdais + \item Arpan Khandelwal + \end{itemize} +\end{itemize} +\end{column} +\begin{column}{0.35\textwidth} +\begin{center} + \includegraphics[width=\textwidth]{figures/qr-code.png} +\end{center} +\end{column} +\end{columns} +\begin{center} + \includegraphics[width=\textwidth]{figures/badges.png} +\end{center} + +\end{frame} +% ================================= + +% ================================= +\begin{frame} +\frametitle{Tofu's structure} + +\begin{center} + \includegraphics[width=0.8\linewidth]{figures/tofu.pdf} +\end{center} + +\end{frame} +% ================================= + + +%% ================================= +%\begin{frame} +%\frametitle{What ToFu can do: modeling of simplified geometry} +% \begin{center} +% \includegraphics[width=\textwidth,trim={0 0 4cm 0}]{figures/geom_B3.png} +% \end{center} +%\end{frame} +%% ================================= +% +%% ================================= +%\begin{frame} +%\frametitle{What ToFu can do: 3D modeling of a 1D camera} +% \begin{center} +% \includegraphics[width=\textwidth]{figures/cam1d.png} +% \end{center} +%\end{frame} +%% ================================= +% +%% ================================= +%\begin{frame} +%\frametitle{What ToFu can do: 3D modeling of a 2D camera} +% \begin{center} +% \includegraphics[width=\textwidth]{figures/cam2d.png} +% \end{center} +%\end{frame} +%% ================================= + + +% ================================= +\begin{frame} +\frametitle{tofu.geom: modeling of simplified geometry} +\begin{columns} +% \begin{column}{0.33\textwidth} +% \begin{center} +% \textbf{Geometry configuration} +% \includegraphics[width=\textwidth,trim={0 0 6cm 0}]{figures/geom_B3.png} +% \end{center} +% \pause +% \end{column} + \begin{column}{0.5\textwidth} + \begin{center} + \textbf{1D Camera\\(tofu.geom.CamLOS1D)} + \includegraphics[width=\textwidth]{figures/cam1d_bis.pdf} + \end{center} + \end{column} + \pause + \begin{column}{0.5\textwidth} + \begin{center} + \textbf{2D Camera\\(tofu.geom.CamLOS2D)} + \includegraphics[width=\textwidth]{figures/cam2d_bis.pdf} + \end{center} + \end{column} + \end{columns} +\end{frame} +% ================================= + +% ================================= +\begin{frame} +\frametitle{tofu.geom: handle basic reflexions} +\begin{columns} +% \begin{column}{0.33\textwidth} +% \begin{center} +% \textbf{Geometry configuration} +% \includegraphics[width=\textwidth,trim={0 0 6cm 0}]{figures/geom_B3.png} +% \end{center} +% \pause +% \end{column} + \begin{column}{0.5\textwidth} + \begin{center} + \textbf{1D Camera with reflexions\\(tofu.geom.CamLOS1D)} + \includegraphics[width=\textwidth]{figures/cam1d_bis_ref.pdf} + \end{center} + \end{column} + \begin{column}{0.5\textwidth} + \begin{center} + \textbf{2D Camera with reflexions\\(tofu.geom.CamLOS2D)} + \includegraphics[width=\textwidth]{figures/cam2d_bis_ref.pdf} + \end{center} + \end{column} + \end{columns} +\end{frame} +% ================================= + +%% ================================= +%\begin{frame} +%\frametitle{What ToFu can do: computing synthetic signals} +% +%\end{frame} +% ================================= + +% ================================= +\begin{frame} +\frametitle{What ToFu can do} +\begin{itemize} + \item Model simplified 3D geometry + \item 3D modeling of a 1D and 2D LOS camera + \item Handle basic reflections + \item Computing synthetic signals + \item native support for IMAS interfacing + \item data easy interactive visualization and basic treatment + \pause + \item ...and soon (being re-written / developed): + \begin{itemize} + \item Finite beam width (VOS, in 1.4.2, late 2019) + \item meshing and basis functions (mid 2020) + \item tomographic inversion (late 2020 - 2021) + \item dust particle trajectory tracking (new, Arpan) + \item faster Matplotlib + PyQtGraph visualization + \item magnetic field line tracing (new) + \item statistical data analysis (pandas) integrated + \end{itemize} +\end{itemize} +\end{frame} +% ================================= +\section{Demo} + +% ================================= +{\setbeamercolor{palette primary}{fg=black, bg=yellow} +\begin{frame}[standout] + Demo +\end{frame} +} +% ================================= + +\section{Code Optimization} + + +% ================================= +\begin{frame} +\frametitle{Geometry reconstruction: ray-tracing techniques} + + To reconstruct emissivity we need to take account: + \begin{itemize} + \item Up to hundreds of structural elements in vessel + \item Scale of the vessel: + $10^4$ bigger than smaller structural detail + \setbeamertemplate{itemize item}{$\Rightarrow$} + + \item Geometry defined with minimal data polygon $(R,Z)$\\ extruded along $\varphi$ + \item Symmetry of vessel along $\varphi$ + + \end{itemize} + + \vspace{0.5cm} + \begin{center} + \includegraphics[height=2.3cm]{figures/confB3_wp_view2.png}% + ~ + \includegraphics[height=2.3cm]{figures/confB3_wp_view1.png}% + ~ + \includegraphics[height=2.3cm]{figures/confB3_wp_view3.png}% + \end{center} + +\end{frame} +% ================================= + + + +% ================================= +\begin{frame} +\frametitle{Optimization of ray-tracing algorithm} + +\begin{columns} +\begin{column}{0.65\textwidth} + \begin{itemize} + \item Description of geometry: + \begin{itemize} + \item Vessel and structures: set of 2D polygon $\mathcal{P}_j = \cup_{i=1}^n \overline{{\rm A}_i{\rm B}_i}$ + \item Extruded along $[\varphi_{min}, \varphi_{max}]$ + \item Detectors defined as set of rays (of origin $D$ and direction $u$) + \item[{$\Rightarrow$}] Light memory-wise + \end{itemize} + \item[{$\Rightarrow$}] Equivalent to: set of truncated cones (frustums) of generatrix $A_iB_i$ + + \end{itemize} +\end{column} +\begin{column}{0.35\textwidth} +\begin{center} + \includegraphics[width=\linewidth]{figures/tore_cones1.pdf} +\end{center} +\end{column} +\end{columns} + +\vspace{0.3cm} +\begin{alertblock}{Ray-tracing algorithm on fusion device $\longrightarrow$ Computation of cone-Ray intersection} +\end{alertblock} + +$$ +\hspace{-3cm} +\exists (q,k) \in [0;1]\times [0;\infty[, \; +\left\{\begin{array}{ll} +R-R_A = q(R_B-R_A)\\ +Z-Z_A = q(Z_B-Z_A)\\ +DM = k u +\end{array}\right. +$$ + +\end{frame} +% ================================= + + +% ================================= +\begin{frame} +\frametitle{Optimization of ray-tracing algorithm} + + +Cone-Ray intersection algorithm: + \begin{itemize} + \item Main steps: + \begin{itemize} + \item Test intersection \textbf{bounding-box} + \item \textbf{special cases} (ray direction, segment, etc.) + \item General case: solution of a\textbf{ quadratic equation} + \end{itemize} + \item Pre-computation of variables + \item Core functions in \textbf{Cython} + \item Parallelization (\textbf{prange} loops) + \end{itemize} +\pause +\begin{table}[h] % just use this specifier if really needed. + \centering + \label{tab:LOS_init_sirrah} + \sisetup{round-mode=places} + \begin{tabular}{@{}l*{4}{S[table-format=1.2e-1,scientific-notation=true]}@{}} + \toprule + \textbf{Nb LOS} & {$10^3$} & {$10^4$} & {$10^5$} & {$10^6$}\\ + \midrule + original & 32.569 & 310.23 & 3202.38 & 31723.827 $(~8$h$48)$\\ + optimized & 0.0258 & 0.2720 & 2.73581 & 26.589564 $(<30$s$)$\\ + 32 threads & 0.0136 & 0.0466 & 0.3640 & 2.9188 \\ + \bottomrule + \end{tabular} +\end{table} + + +\end{frame} +% ================================= + + +% ================================= +\begin{frame} +\frametitle{Tofu's structure} + +\begin{center} + \includegraphics[width=0.8\linewidth]{figures/tofu.pdf} +\end{center} + +\end{frame} +% ================================= + + + +% ================================= +\begin{frame} +\frametitle{Optimization of spatial integration routines} + +Integration of \textbf{user-defined function} along a LOS: + \begin{itemize} + \item Integration of a python function \textbf{func} defined by user by: + \begin{itemize} + \item \textbf{numpy}.sum (quad: \textbf{midpoint}) + \item Cython based sum (quad: \textbf{midpoint}) + \item \textbf{Scipy}.integrate.simps + \item \textbf{Scipy}.integrate.romb + \end{itemize} + \item Optional optimizations: + \begin{itemize} + \item calls to \textbf{func}: avoid Cython-Python conversion, user-defined + \item memory: fine resolutions, high number of LOS + \item hybrid: compromise + \end{itemize} + \end{itemize} + +\end{frame} +% ================================= + + +%% ================================= +%\begin{frame} +%\frametitle{Optimization of spatial integration routines} +% \begin{figure} +% \begin{tikzpicture} +% \begin{axis}[ +% mbarplot, +% xlabel={Number of Lines of Sight}, +% ylabel={Execution time}, +% width=0.9\textwidth, +% height=6cm, +% xticklabels={$0$,,$10$,,$10^2$, ,$10^3$,,$10^4$}] +% ] +% +% \addplot plot coordinates {(1, 0.46) (2, 2.24) (3, 18.1) }; +% \addplot plot coordinates {(1, 18) (2, 24) (3, 23.5) (4, 13.2)}; +% \addplot plot coordinates {(1, 0.2) (2, 0.53) (3, 4.32) (4, 40)}; +% \addplot plot coordinates {(1, 0.08) (2, 0.44) (3, 4.4) (4, 40)}; +% +% \legend{ref, mem, calls, hybd} +% +% \end{axis} +% \end{tikzpicture} +% \end{figure} +% \vspace{-0.2cm} +% \begin{itemize} +% \item Space resolution: $10^{-3}$ +% \item Number of time steps: $10^3$ +% \item Integration method: \textbf{sum} (Cython or numpy) on midpoint +% \end{itemize} +% \end{frame} +% +% +%% ================================= + + + +% ================================= +\begin{frame} +\frametitle{Optimization of spatial integration routines} + +\begin{table}[h] % just use this specifier if really needed. + \centering + \label{tab:LOS_init_sirrah} + \sisetup{round-mode=places} + \begin{tabular}{@{}lllll@{}} + \toprule + \textbf{LOS} & {$10$} & {$10^2$} & {$10^3$} & {$10^4$} \\% & {$10^5$}\\ + \midrule + original & 0.46 & 2.24 & 18.1 & x \\%& x \\ + memory & 0.9 & 8.9 & 96 & 945 (6Gb)\\ + calls & 0.207 & 0.53 & 4.32 & x \\ + hybrid & 0.08 & 0.44 & 4.2 & 40.3 (32Gb) \\%& 612 (32Gb)\\ + \bottomrule + \end{tabular} +\end{table} + + \vspace{-0.2cm} + \begin{itemize} + \item Space resolution: $10^{-3}$ + \item Number of time steps: $10^3$ + \item Integration method: \textbf{sum} (Cython or numpy) on midpoint + \end{itemize} + \end{frame} +% ================================= + + +\section{What's next} + + +% ================================= +\begin{frame} +\frametitle{Tofu's structure} + +\begin{center} + \includegraphics[width=0.8\linewidth]{figures/tofu.pdf} +\end{center} + +\end{frame} +% ================================= + +% +%% ================================= +%\begin{frame} +%\frametitle{Optimization of ray-tracing algorithm} +% +% +%$$ +%\hspace{-3cm} +%\exists (q,k) \in [0;1]\times [0;\infty[, \; +%\left\{\begin{array}{ll} +%R-R_A = q(R_B-R_A)\\ +%Z-Z_A = q(Z_B-Z_A)\\ +%DM = k u +%\end{array}\right. +%$$ +%\vspace{-0.5cm} +%\begin{columns} +%\begin{column}{0.65\textwidth} +% \begin{itemize} +% \item Vessel and structures defined as polygons +% \item Algorithm based on \textbf{cone-ray intersection} +% \item Core functions written in \textbf{cython} +% \item Parallelization using \textbf{OpenMP} +% \end{itemize} +%\end{column} +%\begin{column}{0.35\textwidth} +%\vspace{-1cm} +%\begin{center} +% \includegraphics[width=\linewidth]{figures/tore_cones1.pdf} +%\end{center} +%\end{column} +%\end{columns} +% +%\begin{table}[h] % just use this specifier if really needed. +% \centering +% \label{tab:LOS_init_sirrah} +% % Visionner le code LaTeX du paragraphe 0 +% \sisetup{round-mode=places} +% \begin{tabular}{@{}l*{4}{S[table-format=1.2e-1,scientific-notation=true]}@{}} +% \toprule +% \textbf{Nb LOS} & {$10^3$} & {$10^4$} & {$10^5$} & {$10^6$}\\ +% \midrule +% original & 32.569 & 310.23 & 3202.38 & 31723.827 $(~8$h$48)$\\ +% optimized & 0.0258 & 0.2720 & 2.73581 & 26.589564 $(<30$s$)$\\ +% 32 threads & 0.0136 & 0.0466 & 0.3640 & 2.9188 \\ +% \bottomrule +% \end{tabular} +%\end{table} +% +% +%\end{frame} +%% ================================= + + + + + + +% ================================= +\begin{frame} +\frametitle{Tofu's main algorithms} + + +\begin{columns} +\begin{column}{0.6\textwidth} +\textbf{Geometry}: + \begin{itemize} + \item Finite beam width (LOS $\Rightarrow$ VOS) + \item More advanced reflections + \item Thermal heat load computation + \end{itemize} +\end{column} +\begin{column}{0.4\textwidth} + +\begin{center} + \hspace{-0.5cm}\includegraphics[width=\linewidth]{figures/cones.png} +\end{center} +\end{column} +\end{columns} + +\vspace{0.2cm} +\textbf{Meshing and Inversions}: +\begin{itemize} + \item Meshing and Basis functions (local and global) with visualization + \item Geometry matrix (fast) computation and introspection plots + \item Multiple Inversion-Regularization (linear and non-linear) and visualization + \item post-inversion analysis tools +\end{itemize} + +\vspace{0.2cm} +\textbf{On the side}: +\begin{itemize} + \item Statistical data analysis (tofu / pandas interface) + \item Basic magnetic field line and particle trajectory tracing + \item continued IMAS support +\end{itemize} + +%\begin{center} +% \includegraphics[width=0.6\linewidth]{figures/meshes.png} +%\end{center} +\end{frame} +% ================================= + + + +% ================================= +\begin{frame} +\frametitle{On geometry discretization: meshing} + + +\begin{columns} +\begin{column}{0.6\textwidth} +Several options for poloidal cut meshing: + +\begin{itemize} + \item Cartesian mesh + \item Polar mesh + \item Adaptive polar mesh + \item Hexagonal mesh + \item Triangular mesh +\end{itemize} + +\end{column} +\begin{column}{0.4\textwidth} + +For basis functions: + +\begin{itemize} + \item B-splines + \item NURBS + \item Box-splines +\end{itemize} +\end{column} +\end{columns} + + + +\begin{center} + \includegraphics[width=0.85\linewidth]{figures/meshes.png} +\end{center} +\vspace{-0.5cm} +\end{frame} +% ================================= + + + + +% ================================= +\begin{frame} +\centering +\Huge{Thank you for your attention!} +%\includegraphics[width=\linewidth]{figures/cones.png} +\end{frame} +% ================================= + + +% ================================= +\subsection*{Splines interpolation} +\begin{frame} + \frametitle{B(asis)-Splines basis*} + + B-Splines of degree $d$ are defined by the \textbf{recursion} formula: + + \begin{equation} + B_j^{d+1}(x)= \dfrac{x - x_j}{x_{j+d}-x_j} B_j^d(x)+ \dfrac{x_{j+1} - x}{x_{j+d+1} - x_{j+1}} B_{j+1}^d (x) + \end{equation} + + Some important properties about B-splines: + + \begin{itemize} + \item Piece-wise polynomials of degree $d \quad \Rightarrow$ \textbf{smoothness} + \item Compact support $\Rightarrow$ \textbf{sparse matrix system} + \item Partition of unity $\sum_j Bj (x) = 1$, $\forall x \quad \Rightarrow$ \textbf{conservation laws} + \end{itemize} + + \begin{center} + \includegraphics[width = 0.3\textwidth]{\figurespath/bsplines1.png} + \includegraphics[width = 0.3\textwidth]{\figurespath/bsplines3.png} + \includegraphics[width = 0.3\textwidth]{\figurespath/bsplines5.png} + \end{center} + +\end{frame} +% ================================= + + +\end{document} + diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/Config01.pdf b/Notes_Upgrades/Communications/Euroscipy2019/figures/Config01.pdf new file mode 100644 index 000000000..022a22133 Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/Config01.pdf differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/ITER.pdf b/Notes_Upgrades/Communications/Euroscipy2019/figures/ITER.pdf new file mode 100644 index 000000000..1e95a16f4 Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/ITER.pdf differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/Tomography.pdf b/Notes_Upgrades/Communications/Euroscipy2019/figures/Tomography.pdf new file mode 100644 index 000000000..d602866cd Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/Tomography.pdf differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/background.png b/Notes_Upgrades/Communications/Euroscipy2019/figures/background.png new file mode 100644 index 000000000..b01cc16ed Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/background.png differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/badges.png b/Notes_Upgrades/Communications/Euroscipy2019/figures/badges.png new file mode 100644 index 000000000..93f256d05 Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/badges.png differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/bsplines1.png b/Notes_Upgrades/Communications/Euroscipy2019/figures/bsplines1.png new file mode 100644 index 000000000..e9ab358a1 Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/bsplines1.png differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/bsplines3.png b/Notes_Upgrades/Communications/Euroscipy2019/figures/bsplines3.png new file mode 100644 index 000000000..2c365306e Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/bsplines3.png differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/bsplines5.png b/Notes_Upgrades/Communications/Euroscipy2019/figures/bsplines5.png new file mode 100644 index 000000000..391f9bdb1 Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/bsplines5.png differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/cam1d.png b/Notes_Upgrades/Communications/Euroscipy2019/figures/cam1d.png new file mode 100644 index 000000000..dd2084ef7 Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/cam1d.png differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/cam1d_bis.pdf b/Notes_Upgrades/Communications/Euroscipy2019/figures/cam1d_bis.pdf new file mode 100644 index 000000000..bad7dfe86 Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/cam1d_bis.pdf differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/cam1d_bis_ref.pdf b/Notes_Upgrades/Communications/Euroscipy2019/figures/cam1d_bis_ref.pdf new file mode 100644 index 000000000..69c154ebe Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/cam1d_bis_ref.pdf differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/cam1d_ref.png b/Notes_Upgrades/Communications/Euroscipy2019/figures/cam1d_ref.png new file mode 100644 index 000000000..2a6d28f1b Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/cam1d_ref.png differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/cam2d.png b/Notes_Upgrades/Communications/Euroscipy2019/figures/cam2d.png new file mode 100644 index 000000000..cac3efc5b Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/cam2d.png differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/cam2d_bis.pdf b/Notes_Upgrades/Communications/Euroscipy2019/figures/cam2d_bis.pdf new file mode 100644 index 000000000..b393d2507 Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/cam2d_bis.pdf differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/cam2d_bis_ref.pdf b/Notes_Upgrades/Communications/Euroscipy2019/figures/cam2d_bis_ref.pdf new file mode 100644 index 000000000..d913accf9 Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/cam2d_bis_ref.pdf differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/cam2d_ref.png b/Notes_Upgrades/Communications/Euroscipy2019/figures/cam2d_ref.png new file mode 100644 index 000000000..5cb76a83c Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/cam2d_ref.png differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/ci.pdf b/Notes_Upgrades/Communications/Euroscipy2019/figures/ci.pdf new file mode 100644 index 000000000..5e2f27828 Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/ci.pdf differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/cones.png b/Notes_Upgrades/Communications/Euroscipy2019/figures/cones.png new file mode 100644 index 000000000..2f1076faa Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/cones.png differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/confB3_wp_view1.png b/Notes_Upgrades/Communications/Euroscipy2019/figures/confB3_wp_view1.png new file mode 100644 index 000000000..a9627d92d Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/confB3_wp_view1.png differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/confB3_wp_view2.png b/Notes_Upgrades/Communications/Euroscipy2019/figures/confB3_wp_view2.png new file mode 100644 index 000000000..806e3c881 Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/confB3_wp_view2.png differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/confB3_wp_view3.png b/Notes_Upgrades/Communications/Euroscipy2019/figures/confB3_wp_view3.png new file mode 100644 index 000000000..bd57b9ef8 Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/confB3_wp_view3.png differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/detectors2.png b/Notes_Upgrades/Communications/Euroscipy2019/figures/detectors2.png new file mode 100644 index 000000000..b81669b0e Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/detectors2.png differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/geom_B2.png b/Notes_Upgrades/Communications/Euroscipy2019/figures/geom_B2.png new file mode 100644 index 000000000..2b28a0f81 Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/geom_B2.png differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/geom_B3.png b/Notes_Upgrades/Communications/Euroscipy2019/figures/geom_B3.png new file mode 100644 index 000000000..53a6098fc Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/geom_B3.png differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/meshes.png b/Notes_Upgrades/Communications/Euroscipy2019/figures/meshes.png new file mode 100644 index 000000000..a5bb8c6d6 Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/meshes.png differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/newiter.png b/Notes_Upgrades/Communications/Euroscipy2019/figures/newiter.png new file mode 100644 index 000000000..d1eab858b Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/newiter.png differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/nuclear-power.jpg b/Notes_Upgrades/Communications/Euroscipy2019/figures/nuclear-power.jpg new file mode 100644 index 000000000..e2a3e622b Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/nuclear-power.jpg differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/oil-power.jpg b/Notes_Upgrades/Communications/Euroscipy2019/figures/oil-power.jpg new file mode 100644 index 000000000..0951184ff Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/oil-power.jpg differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/qr-code.png b/Notes_Upgrades/Communications/Euroscipy2019/figures/qr-code.png new file mode 100644 index 000000000..cc3ce60ce Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/qr-code.png differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/reaction.tex b/Notes_Upgrades/Communications/Euroscipy2019/figures/reaction.tex new file mode 100644 index 000000000..a991b29a2 --- /dev/null +++ b/Notes_Upgrades/Communications/Euroscipy2019/figures/reaction.tex @@ -0,0 +1,79 @@ +% !TEX root = ../LM_defense.tex +% \begin{center} + + +\pgfdeclareradialshading{sphere}{\pgfpoint{0cm}{0cm}}% +{rgb(0cm)=(1,1,1); +rgb(0.7cm)=(0.7,0.1,0); rgb(1cm)=(0.5,0.05,0); rgb(1.05cm)=(1,1,1)} + + \begin{tikzpicture}[->,>=stealth',shorten >=10pt,auto,node distance=3cm, + very thick, color=black] + + \pgfdeclareradialshading{redsphere}{\pgfpoint{-0.2cm}{0.5cm}}% +{rgb(0cm)=(1,1,1); +color(0.7cm)=(beaurouge); color(1cm)=(beaurouge); rgb(1.05cm)=(1,1,1)} + + \pgfdeclareradialshading{greysphere}{\pgfpoint{-0.2cm}{0.5cm}}% +{rgb(0cm)=(1,1,1); +color(0.7cm)=(beaubleu); color(1cm)=(SchoolColor); rgb(1.05cm)=(1,1,1)} + + + \tikzset{plus/.style = {shape = circle, + ball color = SchoolColor, + text = black, + inner sep = 0pt, + outer sep = 0pt, + minimum size = 16 pt, + shading = redsphere}} + + \tikzset{neutron/.style = {shape = circle, + text = black, + inner sep = 0pt, + outer sep = 0pt, + minimum size = 16 pt, + shading = greysphere}} + + \tikzset{boom/.style = {shape = star, + star points = 10, + fill = myyellow, + text = black, + inner sep = 0pt, + outer sep = 0pt, + minimum size = 80 pt}} + + \node[plus] (Dplus) {}; + \node[neutron] (Dneutron) [below left of=Dplus,xshift=1.7cm,yshift=2.1cm]{n}; + + \node[boom] (star)[right of=Dplus,yshift = -1.2cm] {}; + + \node[plus] (Tplus2) [below of=Dplus,yshift=0.2cm,xshift=-8pt]{}; + \node[neutron] (Tneutron) [below right of=Tplus2,xshift=-1.65cm,yshift=2.1cm]{n}; + \node[neutron] (Tneutronbis) [below left of=Tplus2,xshift=1.65 cm,yshift=2.1cm]{n}; + + \node[plus] (Rplus1) [right of=Dplus,yshift = -1.2cm,xshift=0.3cm] {}; + \node[neutron] (Rneutron1) [below left of=Rplus1,xshift=1.8cm,yshift=2.1cm]{}; + \node[plus] (Rplus2) [below left of=Rneutron1,xshift=1.8cm,yshift=2.1cm]{}; + \node[neutron] (Rneutron2) [below right of=Rplus2,xshift=-2cm,yshift=1.9cm]{}; + \node[neutron] (Rneutron3) [right of=Rneutron2,xshift=-2.6 cm,yshift=0cm]{}; + + + \node[neutron] (Neutron) [right of=Rplus1,yshift=1.2cm]{n}; + + \node[plus] (HePlus) [right of=Rplus1,yshift=-1.2cm]{}; + \node[neutron] (Heneu2) [below right of=HePlus,yshift=1.9cm,xshift=-1.8cm]{n}; + \node[plus] (HePlus2) [below of=HePlus,yshift=2.5cm]{}; + \node[neutron] (Heneu3) [below left of=HePlus,yshift=1.9cm,xshift=1.8cm]{n}; + + \draw[->] (Dplus) to (Rplus2); + \draw[->] (Tneutron) to (Rplus2); + \draw[->] (Rplus1) to (Neutron); + \draw[->] (Rneutron3) to (Heneu3); + \node (texte1) [above of=Dplus,black,yshift=-2.3cm,xshift=-0.2cm] {Deuterium}; + \node(texte2)[below of=Tplus2,black,xshift=0cm,yshift=2.3cm] {Tritium}; + \node(texte3)[below of=HePlus,black,xshift=0cm,yshift=2cm] {Helium}; + +\end{tikzpicture} + + + + diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/solar-power.jpg b/Notes_Upgrades/Communications/Euroscipy2019/figures/solar-power.jpg new file mode 100644 index 000000000..3573cec05 Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/solar-power.jpg differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/tofu.pdf b/Notes_Upgrades/Communications/Euroscipy2019/figures/tofu.pdf new file mode 100644 index 000000000..c026388fa Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/tofu.pdf differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/tore_cones1.pdf b/Notes_Upgrades/Communications/Euroscipy2019/figures/tore_cones1.pdf new file mode 100644 index 000000000..f8e76942c Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/tore_cones1.pdf differ diff --git a/Notes_Upgrades/Communications/Euroscipy2019/figures/wind-power.jpg b/Notes_Upgrades/Communications/Euroscipy2019/figures/wind-power.jpg new file mode 100644 index 000000000..92be901af Binary files /dev/null and b/Notes_Upgrades/Communications/Euroscipy2019/figures/wind-power.jpg differ diff --git a/Notes_Upgrades/Communications/PyconFR2019/2019_LM_PyconFR.bib b/Notes_Upgrades/Communications/PyconFR2019/2019_LM_PyconFR.bib new file mode 100644 index 000000000..b98edc6a2 --- /dev/null +++ b/Notes_Upgrades/Communications/PyconFR2019/2019_LM_PyconFR.bib @@ -0,0 +1,10 @@ +@article{didier2016, + title={Non-monotonic growth rates of sawtooth precursors evidenced with a new method on ASDEX Upgrade}, + author={Vezinet, D and Igochine, V and Weiland, M and Yu, Q and Gude, A and Meshcheriakov, D and Sertoli, M and EUROfusion MST1 Team and others}, + journal={Nuclear Fusion}, + volume={56}, + number={8}, + pages={086001}, + year={2016}, + publisher={IOP Publishing} +} \ No newline at end of file diff --git a/Notes_Upgrades/Communications/PyconFR2019/2019_LM_PyconFR.pdf b/Notes_Upgrades/Communications/PyconFR2019/2019_LM_PyconFR.pdf new file mode 100644 index 000000000..6911a5803 Binary files /dev/null and b/Notes_Upgrades/Communications/PyconFR2019/2019_LM_PyconFR.pdf differ diff --git a/Notes_Upgrades/Communications/PyconFR2019/2019_LM_PyconFR.tex b/Notes_Upgrades/Communications/PyconFR2019/2019_LM_PyconFR.tex new file mode 100644 index 000000000..df05ec538 --- /dev/null +++ b/Notes_Upgrades/Communications/PyconFR2019/2019_LM_PyconFR.tex @@ -0,0 +1,1074 @@ +\documentclass[10pt]{beamer} + +\usepackage{appendixnumberbeamer} +% +%\usepackage{lmodern} +%\usepackage{wrapfig} +\usepackage{tikz} +%\usetikzlibrary{positioning} +\usetikzlibrary{arrows,shapes} +\usepackage{amsmath,esint,esvect} % arrow for vector, maths and more +%\usepackage{datetime} +\usepackage{gensymb}%for degree symbol +%\usepackage{beamerthemesplit} +%\usepackage{graphicx} %trimed images +%\usepackage{pifont} %for dings +% +%\usepackage{import} +%\usepackage{cases} +\usepackage{booktabs} %beautiful tables +\usepackage{pgfplots} +\usepgfplotslibrary{dateplot} +% +\usepackage{siunitx} % SI notations +\sisetup{table-number-alignment=center, exponent-product=\cdot} + + + + +% Bibliography includes +\usepackage[backend=bibtex, citestyle=verbose-trad2,bibstyle=authortitle-icomp,sortcites=true,block=space,firstinits=true]{biblatex} +\addbibresource{2019_LM_PyconFR.bib} +\usepackage{hyperref} + +\usetheme[progressbar=frametitle]{metropolis} + + + + \setbeamertemplate{itemize subitem}{\color{orange}$\blacktriangleright$} + +% --------------Math mode------------------ +\renewcommand\mathfamilydefault{\rmdefault} +% ----------------------------------------- + +% ------ Images path ------------------ +\newcommand{\figurespath}{./figures} + +%% ---------- Editing the footer ------------ +%\makeatother +%\setbeamertemplate{footline} +%{ +% \leavevmode% +% \hbox{% +% \begin{beamercolorbox}[wd=.6\paperwidth,ht=2.25ex,dp=1ex,center]{institute in head/foot}% +% \usebeamerfont{institute in head/foot}\insertshortinstitute +% \end{beamercolorbox}% +% \begin{beamercolorbox}[wd=.4\paperwidth,ht=2.25ex,dp=1ex,center]{date in head/foot}% +% \usebeamerfont{date in head/foot}\insertshortdate\hspace*{2em} +% \insertframenumber{} \hspace*{2ex} +% \end{beamercolorbox}}% +% \vskip0pt% +%} +%\makeatletter +%\setbeamertemplate{navigation symbols}{} +%% ----------------------------------------- + +% ------ Date definition ------------------ +% \newdate{date}{04}{09}{2019} +% ----------------------------------------- + +% ----------New color---------------------- +\definecolor{myblue}{RGB}{51,51,179} +\definecolor{beaubleu2}{cmyk}{1,0,0,0.71} +\definecolor{SchoolColor}{rgb}{0.6471, 0.1098, 0.1882} % Crimson +\definecolor{beaurouge}{HTML}{405684} +\definecolor{beaubleu}{HTML}{CC382C} +\definecolor{myyellow}{rgb}{0.99, 0.82, 0.35} +% ----------------------------------------- + +%% ---------Redifining foot cites----------- +\newrobustcmd*{\footlessfullcite}{\AtNextCite{\renewbibmacro{title}{}\renewbibmacro{in:}{}}\footfullcite} + +%\renewbibmacro{in:}{\hspace{-5pt}} +\AtEveryCitekey{\clearfield{pages}\clearfield{volume}\clearfield{url} +\clearfield{doi}\clearfield{issn}} +%% ----------------------------------------- + +% ---------First page variables------------ +\title{ToFu} +\subtitle{An open-source python/cython library for synthetic tomography diagnostics on tokamaks} +\author[Laura S. Mendoza] % (optional, for multiple authors) +{\textbf{Laura~S.~Mendoza}\inst{1}, \and Didier~Vezinet\inst{2}} +\institute[] % (optional) +{ + \inst{1}% + INRIA Grand-Est, + TONUS Team, Strasbourg, France\\ + + \inst{2}% + CEA, + Cadarache, France +} +\date[\displaydate{date}] % (optional) +{\alert{PyConFr 2019, Bordeaux, France}} +\subject{} + + +% ----------------------------------------- + +%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\begin{document} + +\newcommand{\gradx}{\nablax} +\newcommand{\vpar}{v_\parallel} +\newcommand{\xvec}{\mathbf{x}} +\newcommand{\nablax}{\nabla_{\!\xvec}} + + +% ================================= +%\usebackgroundtemplate{\includegraphics[height=\paperheight,width=\paperwidth]{figures/background.png}}% +\begin{frame} + \titlepage +\end{frame} +% ================================= + +% ================================= +\begin{frame}{Table of contents} + \setbeamertemplate{section in toc}[sections numbered] + \tableofcontents[hideallsubsections] +\end{frame} +% ================================= + +\section{Context} + +% ================================= +\begin{frame} +\frametitle{Context: energy needs vs resources and climate change} + + \begin{center} + \includegraphics[height=1.8cm]{figures/oil-power.jpg}% + \includegraphics[height=1.8cm]{figures/solar-power.jpg}% + \includegraphics[height=1.8cm]{figures/nuclear-power.jpg}% + \includegraphics[height=1.8cm]{figures/wind-power.jpg} + \end{center} + +Worldwide growing energy needs (population, standards of living...)\\ +$\quad \Rightarrow$ Production of $CO_2$, limited resources, radioactive waste, not efficient enough, harmful to surrounding environment\\ + +$\quad \Rightarrow$ need to decrease consumption + alternative production means\\ + +$\quad \Rightarrow$ Need for cleaner, more reliable, more powerful energy source\\ + +%\begin{itemize}%[leftmargin=1em] +%\setbeamertemplate{itemize item}{$\Rightarrow$} +% \item \alert{Fusion}: cleaner, more reliable, more powerful energy source? +%\end{itemize} + +\end{frame} +% ================================= + + + +% ================================= +\begin{frame} +\frametitle{Context: Controlled fusion and magnetic confinement} + +\begin{columns} + \begin{column}{0.65\textwidth} + \begin{center} + \textbf{D-T Fusion reaction\;\;\;}\vspace{0.3cm} + %\includegraphics[width=3.5cm]{figures/DT_reaction3.png} + \resizebox{0.5\textwidth}{!}{\input{figures/reaction.tex}} + \end{center} + \vspace{-0.5cm} + \begin{itemize}%[leftmargin=1em] + \item Gas $>$ 100 Million\degree K composed of positive ions and negative electrons: plasma + \item Confinement using electromagnetic fields + \item break-even not obtained yet + \end{itemize} + + \end{column} + + \begin{column}{0.35\textwidth} + \includegraphics[width=1.\textwidth]{figures/ITER.pdf} + \end{column} + +\end{columns} + +%\begin{itemize}%[leftmargin=1em] +\begin{center} +In a nutshell: toroidal vacuum vessel, filled with H plasma +\end{center}%\end{itemize} +\vspace{-0.2cm} +%%\begin{itemize}%[leftmargin=1em] +%%\setbeamertemplate{itemize item}{$\Rightarrow$} +%% \item \alert{Fusion codes:} complexity due to the number of parameters, geometry, model, etc. +%%\end{itemize} +\end{frame} +% ================================= + + +\section{Tomography diagnostics} + + +% ================================= +\begin{frame} +\frametitle{Tokamak diagnostics to measure plasma quantities} + + \metroset{block=fill} +\begin{alertblock}{Diagnostics} +Set of instruments to measure plasma quantities, for understanding, control, optimization. +\end{alertblock} + +e.g: magnetic field, neutrons, \textbf{emitted light}, temperature, density...\\[1cm] + + +$\quad \Rightarrow$ cameras (1D or 2D) for measuring light in various wavelengths + + +% +%\begin{itemize} +%\item \textbf{Magnetic} diagnostics: currents, plasma stored energy, plasma shape and position; +% +%\item \textbf{Neutron} diagnostics (ie. cameras, spectrometers, etc.): fusion power; +% +%\item Optical systems (\textbf{interferometers}): temperature and density profiles; +% +%\item Bolometric systems (\textbf{tomography}): spatial distribution of radiated power; +% +%\item \textbf{Spectroscopic}: X-ray wavelength range, impurity species and density, input particle flux, ion temperature, helium density, fueling ratio, plasma rotation, and current density. + +%\item Microwave diagnostics probe the main plasma and the plasma in the divertor region in order to measure plasma position. + +%\end{itemize} + +\end{frame} +% ================================= + + +%% ================================= +%\begin{frame} +%\frametitle{A tokamak as a poloidal + horizontal projections} +% +%\begin{columns} +% +% \begin{column}{0.25\textwidth} +% \includegraphics[width=1.\textwidth]{figures/ITER.pdf} +% \end{column} +% +% \begin{column}{0.75\textwidth} +% \begin{center} +% \textbf{tofu.geom.Config class} +% \end{center} +% \includegraphics[width=1.\textwidth]{figures/Config01.pdf} +% \end{column} +% +%\end{columns} +% +% +%\end{frame} +%% ================================= + + +% ================================= +\begin{frame} +\frametitle{Tomography diagnostics - numerical context} + \vspace{-0.75cm} + + $$M_i(t) = \iiint\limits_{V_i} \vv{\varepsilon(x,t)}\cdot\vv{n} \,\Omega_i \;{d}V$$ + \vspace{-0.75cm} +\begin{columns} + \begin{column}{0.325\textwidth} + + %\def\svgwidth{\linewidth} + %\import{figures/}{detectors.pdf_tex} + \includegraphics[width=\linewidth,trim={0 0 1cm 0}]{figures/Tomography.pdf} + + \end{column} + + \begin{column}{0.675\textwidth} + \begin{center} + + %DIRECT PROBLEM + \begin{block}{} + \begin{itemize} + \item \textcolor{myblue}{\textbf{Direct problem} (synthetic diagnostic):\\ + } + \end{itemize} + \end{block} + %\textbf{Direct problem} (synthetic diagnostic):\\ +Simulated emissivity $\longrightarrow$ integrated measurements\\ + + %INVERSE PROBLEM + \begin{block}{} + \begin{itemize} + \item \textcolor{myblue}{\textbf{Inverse problem} (tomography):\\ + } + \end{itemize} + \end{block} + %\textbf{Direct problem} (synthetic diagnostic):\\ +Integrated measurements $\longrightarrow$ Reconstructed emissivity \\ + + \end{center} + + \end{column} +% +\end{columns} + + +\end{frame} +% ================================= + + + + +% ================================= +\begin{frame} +\frametitle{Tomography diagnostics - numerical context} + + $$M_i(t) = \iiint\limits_{V_i} \vv{\varepsilon(x,t)}\cdot\vv{n} \,\Omega_i \;{d}V$$ + \vspace{-1cm} +\begin{columns} + \begin{column}{0.325\textwidth} + + %\def\svgwidth{\linewidth} + %\import{figures/}{detectors.pdf_tex} + \includegraphics[width=\linewidth,trim={0 0 1cm 0}]{figures/Tomography.pdf} + + \end{column} + + \begin{column}{0.675\textwidth} + \begin{center} + + %DIRECT PROBLEM + \begin{block}{} + \begin{itemize} + \item \textcolor{myblue}{\textbf{Direct problem} (synthetic diagnostic):\\ + } + \end{itemize} + \end{block} + %\textbf{Direct problem} (synthetic diagnostic):\\ +Simulated emissivity $\longrightarrow$ measurements\\ + \alert{Spatial integration} + \vspace{-0.5cm} + + %INVERSE PROBLEM + \begin{block}{} + \begin{itemize} + \item \textcolor{myblue}{\textbf{Inverse problem} (tomography):\\ + } + \end{itemize} + \end{block} + %\textbf{Direct problem} (synthetic diagnostic):\\ +Integrated measurements $\longrightarrow$ Reconstructed emissivity \\ + \alert{Mesh and basis functions construction, spatial integration, data filtering, inversion routines, etc.} + + \end{center} + + \end{column} +% +\end{columns} + +\pause +\vspace{-0.5cm} +\begin{block}{} +\begin{center} +Tomography is \textbf{ill-posed}, very sensitive to errors, noise and bias\\ +$\longrightarrow$ \alert{Reputation for low reproducibility / reliability } +\end{center} + \end{block} +\end{frame} +% ================================= + + + +\section{The ToFu package} + + +% ================================= +\begin{frame} +\frametitle{Motivation: ``current" state} + + In the fusion community, codes for tomography diagnostic are often: + \begin{itemize} + \item developed by physicists (with little programming experience) + \item in Matlab (or IDL) + \item written from scratch, re-done by new students + \item not distributed (few users), rarely documented + \end{itemize} + +... which means +\begin{itemize} + \item waste of resources: time, man-power + \item low traceability, reproducibility + \item low standardization, unclear assumptions / methods + \end{itemize} + +\end{frame} +% ================================= + + +% ================================= +\begin{frame} +\frametitle{A code for Tomography for Fusion} +\textbf{Develop a common tool:} +\begin{columns} +\begin{column}{0.65\textwidth} + \begin{itemize} + \item Generic (geometry independent) + \item Portable (Python) + \item Optimized / parallelized + \item Documented online + \item Continuous integration + \end{itemize} +\end{column} +\begin{column}{0.35\textwidth} +\vspace{-1cm} +\begin{center} + \includegraphics[width=0.8\linewidth]{figures/ci.pdf} +\end{center} +\end{column} +\end{columns} +\vspace{-0.9cm} + +\begin{block}{} + \begin{center} + \alert{\textbf{ToFu}\footnote{repository: \url{https://github.com/ToFuProject/tofu}}\footnote{documentation: \url{https://tofuproject.github.io/tofu/index.html} }\footcite{didier2016}} = \alert{\textbf{To}mography for \textbf{Fu}sion} + \end{center} +\vspace{-5mm} +\end{block} + +\end{frame} +% ================================= + +% ================================= +\begin{frame} +\frametitle{More about Tofu} + +\begin{columns} +\begin{column}{0.65\textwidth} +\begin{itemize} + \item Created in 2014 + \item Open Source:\textbf{ MIT license} + \item Python 2.7 and \textbf{Python} 3 + \textbf{Cython} + \item Continuous integration: \textbf{Travis} CI + \item \textbf{conda}, \textbf{pip} + \item Two (main) developers: + \begin{itemize} + \item Didier Vezinet (creator, Physics) + \item Laura S. Mendoza (since 06.2018, Applied Maths) + \end{itemize} + \item Contributors: + \begin{itemize} + \item Jorge Morales + \item Florian Le Bourdais + \item Arpan Khandelwal + \item Koyo Munechika + \end{itemize} +\end{itemize} +\end{column} +\begin{column}{0.35\textwidth} +\begin{center} + \includegraphics[width=\textwidth]{figures/qr-code.png} +\end{center} +\end{column} +\end{columns} +\begin{center} + \includegraphics[width=\textwidth]{figures/badges.png} +\end{center} + +\end{frame} +% ================================= + +% ================================= +\begin{frame} +\frametitle{Tofu's structure} + +\begin{center} + \includegraphics[width=0.8\linewidth]{figures/tofu.pdf} +\end{center} + +\end{frame} +% ================================= + + +% ================================= +\begin{frame} +\frametitle{Tofu's geometry representation} + +\begin{center} + \includegraphics[width=0.6\linewidth]{figures/ITER.pdf} +\end{center} + +\end{frame} +% ================================= + +% ================================= +\begin{frame} +\frametitle{Tofu's geometry representation} + +\begin{center} + \includegraphics[width=\linewidth]{figures/newiter.png} +\end{center} + +\end{frame} +% ================================= + + +%% ================================= +%\begin{frame} +%\frametitle{What ToFu can do: modeling of simplified geometry} +% \begin{center} +% \includegraphics[width=\textwidth,trim={0 0 4cm 0}]{figures/geom_B3.png} +% \end{center} +%\end{frame} +%% ================================= +% +%% ================================= +%\begin{frame} +%\frametitle{What ToFu can do: 3D modeling of a 1D camera} +% \begin{center} +% \includegraphics[width=\textwidth]{figures/cam1d.png} +% \end{center} +%\end{frame} +%% ================================= +% +%% ================================= +%\begin{frame} +%\frametitle{What ToFu can do: 3D modeling of a 2D camera} +% \begin{center} +% \includegraphics[width=\textwidth]{figures/cam2d.png} +% \end{center} +%\end{frame} +%% ================================= + + +% ================================= +\begin{frame} +\frametitle{tofu.geom: modeling of simplified geometry} +\begin{columns} +% \begin{column}{0.33\textwidth} +% \begin{center} +% \textbf{Geometry configuration} +% \includegraphics[width=\textwidth,trim={0 0 6cm 0}]{figures/geom_B3.png} +% \end{center} +% \pause +% \end{column} + \begin{column}{0.5\textwidth} + \begin{center} + \textbf{1D Camera\\(tofu.geom.CamLOS1D)} + \includegraphics[width=\textwidth]{figures/cam1d_bis.pdf} + \end{center} + \end{column} + \pause + \begin{column}{0.5\textwidth} + \begin{center} + \textbf{2D Camera\\(tofu.geom.CamLOS2D)} + \includegraphics[width=\textwidth]{figures/cam2d_bis.pdf} + \end{center} + \end{column} + \end{columns} +\end{frame} +% ================================= + +% ================================= +\begin{frame} +\frametitle{tofu.geom: handle basic reflexions} +\begin{columns} +% \begin{column}{0.33\textwidth} +% \begin{center} +% \textbf{Geometry configuration} +% \includegraphics[width=\textwidth,trim={0 0 6cm 0}]{figures/geom_B3.png} +% \end{center} +% \pause +% \end{column} + \begin{column}{0.5\textwidth} + \begin{center} + \textbf{1D Camera with reflexions\\(tofu.geom.CamLOS1D)} + \includegraphics[width=\textwidth]{figures/cam1d_bis_ref.pdf} + \end{center} + \end{column} + \begin{column}{0.5\textwidth} + \begin{center} + \textbf{2D Camera with reflexions\\(tofu.geom.CamLOS2D)} + \includegraphics[width=\textwidth]{figures/cam2d_bis_ref.pdf} + \end{center} + \end{column} + \end{columns} +\end{frame} +% ================================= + +%% ================================= +%\begin{frame} +%\frametitle{What ToFu can do: computing synthetic signals} +% +%\end{frame} +% ================================= + +% ================================= +\begin{frame} +\frametitle{What ToFu can do} +\begin{itemize} + \item Model simplified 3D geometry + \item 3D modeling of a 1D and 2D LOS camera + \item Handle basic reflections + \item Computing synthetic signals + \item Native support for IMAS interfacing + \item Data easy interactive visualization and basic treatment + \pause + \item ...and soon (being re-written / developed): + \begin{itemize} + \item finite beam width (VOS, in 1.4.2, late 2019) + \item meshing and basis functions (mid 2020) + \item tomographic inversion (late 2020 - 2021) + \item dust particle trajectory tracking (new, Arpan) + \item faster Matplotlib + PyQtGraph visualization + \item magnetic field line tracing (new) + \item statistical data analysis (pandas) integrated + \end{itemize} +\end{itemize} +\end{frame} + + +\section{Code Optimization} + + +% ================================= +\begin{frame} +\frametitle{Geometry reconstruction: ray-tracing techniques} + + To reconstruct emissivity we need to take account: + \begin{itemize} + \item Up to hundreds of structural elements in vessel + \item Scale of the vessel: + $10^4$ bigger than smaller structural detail + \setbeamertemplate{itemize item}{$\Rightarrow$} + + \item Geometry defined with minimal data polygon $(R,Z)$\\ extruded along $\varphi$ + \item Symmetry of vessel along $\varphi$ + + \end{itemize} + + \vspace{0.5cm} + \begin{center} + \includegraphics[height=2.3cm]{figures/confB3_wp_view2.png}% + ~ + \includegraphics[height=2.3cm]{figures/confB3_wp_view1.png}% + ~ + \includegraphics[height=2.3cm]{figures/confB3_wp_view3.png}% + \end{center} + +\end{frame} +% ================================= + + + +% ================================= +\begin{frame} +\frametitle{Optimization of ray-tracing algorithm} + +\begin{columns} +\begin{column}{0.65\textwidth} + \begin{itemize} + \item Description of geometry: + \begin{itemize} + \item Vessel and structures: set of 2D polygon $\mathcal{P}_j = \cup_{i=1}^n \overline{{\rm A}_i{\rm B}_i}$ + \item Extruded along $[\varphi_{min}, \varphi_{max}]$ + \item Detectors defined as set of rays (of origin $D$ and direction $u$) + \item[{$\Rightarrow$}] Light memory-wise + \end{itemize} + \item[{$\Rightarrow$}] Equivalent to: set of truncated cones (frustums) of generatrix $A_iB_i$ + + \end{itemize} +\end{column} +\begin{column}{0.35\textwidth} +\begin{center} + \includegraphics[width=\linewidth]{figures/tore_cones1.pdf} +\end{center} +\end{column} +\end{columns} + +\vspace{0.3cm} +\begin{alertblock}{Ray-tracing algorithm on fusion device $\longrightarrow$ Computation of cone-Ray intersection} +\end{alertblock} + +$$ +\hspace{-3cm} +\exists (q,k) \in [0;1]\times [0;\infty[, \; +\left\{\begin{array}{ll} +R-R_A = q(R_B-R_A)\\ +Z-Z_A = q(Z_B-Z_A)\\ +DM = k u +\end{array}\right. +$$ + +\end{frame} +% ================================= + + +% ================================= +\begin{frame} +\frametitle{Optimization of ray-tracing algorithm} + + + \begin{itemize} + \item Algorithmic optimizations: + \begin{itemize} + \item Test intersection \textbf{bounding-box} + \item \textbf{special cases} (ray direction, segment, etc.) + \item Cone-Ray intersection algorithm: solution of a\textbf{ quadratic equation} + \end{itemize} + \item Pre-computation of variables + \item Core functions in \textbf{Cython} + \item OpenMP parallelization (Cython \textbf{prange} loops) + \end{itemize} +\pause +\begin{table}[h] % just use this specifier if really needed. + \centering + \label{tab:LOS_init_sirrah} + \sisetup{round-mode=places} + \begin{tabular}{@{}l*{4}{S[table-format=1.2e-1,scientific-notation=true]}@{}} + \toprule + \textbf{Nb LOS} & {$10^3$} & {$10^4$} & {$10^5$} & {$10^6$}\\ + \midrule + original & 32.569 & 310.23 & 3202.38 & 31723.827 $(~8$h$48)$\\ + optimized & 0.0258 & 0.2720 & 2.73581 & 26.589564 $(<30$s$)$\\ + 32 threads & 0.0136 & 0.0466 & 0.3640 & 2.9188 \\ + \bottomrule + \end{tabular} +\end{table} +\end{frame} +% ================================= + + +% ================================= +\begin{frame} +\frametitle{Tofu's structure} + +\begin{center} + \includegraphics[width=0.8\linewidth]{figures/tofu.pdf} +\end{center} + +\end{frame} +% ================================= + + + +% ================================= +\begin{frame} +\frametitle{Optimization of spatial integration routines} + +Integration of \textbf{user-defined function} along a LOS: + \begin{itemize} + \item Integration of a python function \textbf{func} defined by user by: + \begin{itemize} + \item \textbf{numpy}.sum (quad: \textbf{midpoint}) + \item Cython based sum (quad: \textbf{midpoint}) + \item \textbf{Scipy}.integrate.simps + \item \textbf{Scipy}.integrate.romb + \end{itemize} + \item Optional optimizations: + \begin{itemize} + \item calls to \textbf{func}: avoid Cython-Python conversion, user-defined + \item memory: fine resolutions, high number of LOS + \item hybrid: compromise + \end{itemize} + \end{itemize} + +\end{frame} +% ================================= + + +%% ================================= +%\begin{frame} +%\frametitle{Optimization of spatial integration routines} +% \begin{figure} +% \begin{tikzpicture} +% \begin{axis}[ +% mbarplot, +% xlabel={Number of Lines of Sight}, +% ylabel={Execution time}, +% width=0.9\textwidth, +% height=6cm, +% xticklabels={$0$,,$10$,,$10^2$, ,$10^3$,,$10^4$}] +% ] +% +% \addplot plot coordinates {(1, 0.46) (2, 2.24) (3, 18.1) }; +% \addplot plot coordinates {(1, 18) (2, 24) (3, 23.5) (4, 13.2)}; +% \addplot plot coordinates {(1, 0.2) (2, 0.53) (3, 4.32) (4, 40)}; +% \addplot plot coordinates {(1, 0.08) (2, 0.44) (3, 4.4) (4, 40)}; +% +% \legend{ref, mem, calls, hybd} +% +% \end{axis} +% \end{tikzpicture} +% \end{figure} +% \vspace{-0.2cm} +% \begin{itemize} +% \item Space resolution: $10^{-3}$ +% \item Number of time steps: $10^3$ +% \item Integration method: \textbf{sum} (Cython or numpy) on midpoint +% \end{itemize} +% \end{frame} +% +% +%% ================================= + + + +% ================================= +\begin{frame} +\frametitle{Optimization of spatial integration routines} + +\begin{table}[h] % just use this specifier if really needed. + \centering + \label{tab:LOS_init_sirrah} + \sisetup{round-mode=places} + \begin{tabular}{@{}lllll@{}} + \toprule + \textbf{LOS} & {$10$} & {$10^2$} & {$10^3$} & {$10^4$} \\% & {$10^5$}\\ + \midrule + original & 0.46 & 2.24 & 18.1 & x \\%& x \\ + memory & 0.9 & 8.9 & 96 & 945 (6Gb)\\ + calls & 0.207 & 0.53 & 4.32 & x \\ + hybrid & 0.08 & 0.44 & 4.2 & 40.3 (32Gb) \\%& 612 (32Gb)\\ + \bottomrule + \end{tabular} +\end{table} + + \vspace{-0.2cm} + \begin{itemize} + \item Space resolution: $10^{-3}$ + \item Number of time steps: $10^3$ + \item Integration method: \textbf{sum} (Cython or numpy) on midpoint + \end{itemize} + \end{frame} +% ================================= + + +% ================================= +\begin{frame} +\frametitle{What we've learned on code optimization} + +Importance of \textbf{cross disciplinary} expert collaborations: + + \begin{itemize} + \item Understand and define the problem (physics) + \item Create optimal algorithm (mathematics) + \item Write efficient code (computer science) + \end{itemize} + +...and from there: + + \begin{itemize} + \item \textbf{Profile} your code + \item Core functions: \textbf{Cython} (or Numba or Transonic or ...) + \item Cython specific: + \begin{itemize} + \item \textbf{cython --annotate} + \item \textbf{type} your variables and \textbf{inline} your functions! + \item use cython decorators: \textbf{@cython.boundscheck(False)}, \textbf{@cython.wraparound(False)} + \item release the gil (when possible)! + \item see more: \href{https://github.com/ToFuProject/tofu/blob/master/Notebooks/Cython_speedup_notes.ipynb}{\textcolor{blue}{my notes}}, \href{https://github.com/jeremiedbb/tutorial-euroscipy-2019}{\textcolor{blue}{Jeremie du Boisberranger's tutorial}} + + \end{itemize} + \end{itemize} + +\end{frame} +% ================================= + + +\section{What's next} + + +% ================================= +\begin{frame} +\frametitle{Tofu's structure} + +\begin{center} + \includegraphics[width=0.8\linewidth]{figures/tofu.pdf} +\end{center} + +\end{frame} +% ================================= + +% +%% ================================= +%\begin{frame} +%\frametitle{Optimization of ray-tracing algorithm} +% +% +%$$ +%\hspace{-3cm} +%\exists (q,k) \in [0;1]\times [0;\infty[, \; +%\left\{\begin{array}{ll} +%R-R_A = q(R_B-R_A)\\ +%Z-Z_A = q(Z_B-Z_A)\\ +%DM = k u +%\end{array}\right. +%$$ +%\vspace{-0.5cm} +%\begin{columns} +%\begin{column}{0.65\textwidth} +% \begin{itemize} +% \item Vessel and structures defined as polygons +% \item Algorithm based on \textbf{cone-ray intersection} +% \item Core functions written in \textbf{cython} +% \item Parallelization using \textbf{OpenMP} +% \end{itemize} +%\end{column} +%\begin{column}{0.35\textwidth} +%\vspace{-1cm} +%\begin{center} +% \includegraphics[width=\linewidth]{figures/tore_cones1.pdf} +%\end{center} +%\end{column} +%\end{columns} +% +%\begin{table}[h] % just use this specifier if really needed. +% \centering +% \label{tab:LOS_init_sirrah} +% % Visionner le code LaTeX du paragraphe 0 +% \sisetup{round-mode=places} +% \begin{tabular}{@{}l*{4}{S[table-format=1.2e-1,scientific-notation=true]}@{}} +% \toprule +% \textbf{Nb LOS} & {$10^3$} & {$10^4$} & {$10^5$} & {$10^6$}\\ +% \midrule +% original & 32.569 & 310.23 & 3202.38 & 31723.827 $(~8$h$48)$\\ +% optimized & 0.0258 & 0.2720 & 2.73581 & 26.589564 $(<30$s$)$\\ +% 32 threads & 0.0136 & 0.0466 & 0.3640 & 2.9188 \\ +% \bottomrule +% \end{tabular} +%\end{table} +% +% +%\end{frame} +%% ================================= + + + + + + +% ================================= +\begin{frame} +\frametitle{Tofu's main algorithms} + + +\begin{columns} +\begin{column}{0.6\textwidth} +\textbf{Geometry}: + \begin{itemize} + \item Finite beam width (LOS $\Rightarrow$ VOS) + \item More advanced reflections + \item Thermal heat load computation + \end{itemize} +\end{column} +\begin{column}{0.4\textwidth} + +\begin{center} + \hspace{-0.5cm}\includegraphics[width=\linewidth]{figures/cones.png} +\end{center} +\end{column} +\end{columns} + +\vspace{0.2cm} +\textbf{Meshing and Inversions}: +\begin{itemize} + \item Meshing and Basis functions (local and global) with visualization + \item Geometry matrix (fast) computation and introspection plots + \item Multiple Inversion-Regularization (linear and non-linear) and visualization + \item post-inversion analysis tools +\end{itemize} + +\vspace{0.2cm} +\textbf{On the side}: +\begin{itemize} + \item Statistical data analysis (tofu / pandas interface) + \item Basic magnetic field line and particle trajectory tracing + \item continued IMAS support +\end{itemize} + +%\begin{center} +% \includegraphics[width=0.6\linewidth]{figures/meshes.png} +%\end{center} +\end{frame} +% ================================= + + + +% ================================= +\begin{frame} +\frametitle{On geometry discretization: meshing} + + +\begin{columns} +\begin{column}{0.6\textwidth} +Several options for poloidal cut meshing: + +\begin{itemize} + \item Cartesian mesh + \item Polar mesh + \item Adaptive polar mesh + \item Hexagonal mesh + \item Triangular mesh +\end{itemize} + +\end{column} +\begin{column}{0.4\textwidth} + +For basis functions: + +\begin{itemize} + \item B-splines + \item NURBS + \item Box-splines +\end{itemize} +\end{column} +\end{columns} + + + +\begin{center} + \includegraphics[width=0.85\linewidth]{figures/meshes.png} +\end{center} +\vspace{-0.5cm} +\end{frame} +% ================================= + + + + +% ================================= +\begin{frame} +\frametitle{} +{\centering +{\Huge Thank you for your attention!}} +\vspace{3cm} + +{\footnotesize \emph{ This work has been carried out within the framework of the EUROfusion Consortium and has received funding from the Euratom research and training programme 2014-2018 and 2019-2020 under grant agreement No 633053. The views and opinions expressed herein do not necessarily reflect those of the European Commission.}} +\end{frame} +% ================================= + + +% ================================= +\subsection*{Splines interpolation} +\begin{frame} + \frametitle{B(asis)-Splines basis*} + + B-Splines of degree $d$ are defined by the \textbf{recursion} formula: + + \begin{equation} + B_j^{d+1}(x)= \dfrac{x - x_j}{x_{j+d}-x_j} B_j^d(x)+ \dfrac{x_{j+1} - x}{x_{j+d+1} - x_{j+1}} B_{j+1}^d (x) + \end{equation} + + Some important properties about B-splines: + + \begin{itemize} + \item Piece-wise polynomials of degree $d \quad \Rightarrow$ \textbf{smoothness} + \item Compact support $\Rightarrow$ \textbf{sparse matrix system} + \item Partition of unity $\sum_j Bj (x) = 1$, $\forall x \quad \Rightarrow$ \textbf{conservation laws} + \end{itemize} + + \begin{center} + \includegraphics[width = 0.3\textwidth]{\figurespath/bsplines1.png} + \includegraphics[width = 0.3\textwidth]{\figurespath/bsplines3.png} + \includegraphics[width = 0.3\textwidth]{\figurespath/bsplines5.png} + \end{center} + +\end{frame} +% ================================= + + +\end{document} + diff --git a/Notes_Upgrades/Communications/PyconFR2019/figures b/Notes_Upgrades/Communications/PyconFR2019/figures new file mode 120000 index 000000000..b8d0ba1c6 --- /dev/null +++ b/Notes_Upgrades/Communications/PyconFR2019/figures @@ -0,0 +1 @@ +../Euroscipy2019/figures \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 000000000..b560cd262 --- /dev/null +++ b/README.md @@ -0,0 +1,167 @@ +[![Travis-CI](https://travis-ci.org/ToFuProject/tofu.svg?branch=master)](https://travis-ci.org/ToFuProject/tofu) +[![Conda]( https://anaconda.org/tofuproject/tofu/badges/version.svg)](https://anaconda.org/tofuproject/tofu/badges/) +[![](https://anaconda.org/tofuproject/tofu/badges/downloads.svg)](https://anaconda.org/tofuproject/tofu/badges/) +[![](https://anaconda.org/tofuproject/tofu/badges/latest_release_date.svg)](https://anaconda.org/tofuproject/tofu/badges/) +[![](https://anaconda.org/tofuproject/tofu/badges/platforms.svg)](https://anaconda.org/tofuproject/tofu/badges/) +[![](https://anaconda.org/tofuproject/tofu/badges/license.svg)](https://anaconda.org/tofuproject/tofu/badges/) +[![](https://anaconda.org/tofuproject/tofu/badges/installer/conda.svg)](https://anaconda.org/tofuproject/tofu/badges/) +[![](https://codecov.io/gh/ToFuProject/tofu/branch/master/graph/badge.svg)](https://codecov.io/gh/ToFuProject/tofu) +[![](https://badge.fury.io/py/tofu.svg)](https://badge.fury.io/py/tofu) + + +tofu +==== + + +**tofu** stands for **To**mography for **Fu**sion, it is an IMAS-compatible open-source machine-independent python library +with non-open source plugins containing all machine-dependent routines. + +It aims at providing the **fusion** and **plasma** community with an object-oriented, transparent and documented tool for designing **tomography diagnostics**, computing **synthetic signal** (direct problem) as well as **tomographic inversions** (inverse problem). It gives access to a full 3D description of the diagnostic geometry, thus reducing the impact of geometrical approximations on the direct and, most importantly, on the inverse problem. + +**tofu** is relevant for all diagnostics integrating, in a finitie field of view or along a set of lines of sight, a quantity (scalar or vector) for which the plasma can be considered transparent (e.g.: light in the visible, UV, soft and hard X-ray ranges, or electron density for interferometers). + +**tofu** is **command-line oriented**, for maximum flexibility and scriptability. +The absence of a GUI is compensated by built-in one-liners for interactive plots. + + +A sphinx-generated [documentation](https://tofuproject.github.io/tofu/index.html) (to be updated soon), and the code itself is hosted on [GitHub](https://github.com/ToFuProject/tofu). + + + + +## Examples Gallery + + +Here are some examples of what **tofu** can do + +#### Built-in one-liners for interactive camera geometry visualization +

+Built-in one-liners for interactive camera geometry visualization +

+ +#### ...both for 1D and 2D cameras, including the basics for multiple reflections handling +

+...both for 1D and 2D cameras, including the basics for multiple reflections handling +

+ +#### Built-in plotting of sinograms + +

+Built-in plotting of sinograms +

+ +#### Basic magnetic field line tracing + +

+Basic magnetic field line tracing +

+ + +#### Multiple 1d profiles interactive plotting +

+Multiple 1d profiles interactive plotting +

+ +#### Built-in basic data treatment and interactive plotting: svd and spectrograms +

+Built-in basic data treatment and interactive plotting: svd and spectrograms +

+ + + +**tofu** provides the user with a series of python classes for creating, handling and visualizing a diagnostic geometry, meshes and basis functions, +geometry matrices, pre-treating experimental data and computing tomographic inversions. + +Each one of these main tasks is accomplished by a dedicated module in the larger tofu package. + +In its current version, only the geometry and data-handling modules are released. +The others, while operational, are not user-friendly and documented yet, they will be available in future releases. + +The geometry module is sufficient for diagnostic designing and for a synthetic diagnostic approach (i.e.: computing the integrated signal from a simulated 2D or 3D emissivity). +This geometry module allows in particular: + +* To handle linear and toroidal vaccum vessels +* To define apertures and detectors as planar polygons of arbitrary shapes, or to define a spherical converging lens and a circular detector in its focal plane. +* To assign an arbitrary number of apertures to each detector (and the apertures do not have to stand in parallel planes) +* To automatically compute the full Volume of Sight (VOS) in 3D of each {detector+aperture(s)} set +* To discretise the VOS for a numerical 3D integration of a simulated emissivity in order to compute the associated signal + +It is in this geometrical sense that tofu enables a synthetic diagnostic approach, it does not provide the tools for simulating the emissivity (that should be an input, provided by another code). + + +## IMAS-compatibility + + +IMAS is a standardized data structure, it comes as an extra layer on the database of any Tokamak to provide a machine-independent way of accessing scientific data. +tofu has built-in advanced classes for handling the interface with IMAS, hold in the imas2tofu sub-package. +It pre-supposes, of course, that IMAS is installed and operational next to your python install, but tofu does not require IMAS to run in general. +If IMAS is not available, tofu will simply display a warning stating that the imas2tofu sub-package is not usable. + +tofu can thus easily load and handle multiple IDSs (IMAS data structure units) and provide command-line tools for exporting IMAS data to other general tofu classes (e.g.: Cameras, Plasma2D...) and for interactive plotting. +All tofu objects have methods to facailitate in-python-console introspection, the ``__repr__`` method is overloaded to display relevant information, an dthis is widely used to explore the data loaded from IMAS. + +Do you want to use **tofu** on IMAS and don't know where to start? [See our wiki.](https://github.com/ToFuProject/tofu/wiki/Using-tofu-on-IMAS-server) + +---- + + +## Installing tofu + + +### For Windows + + +- [Follow this link to know how to configure your Windows to code on ToFu !](https://github.com/ToFuProject/tofu/wiki/Installing-tofu-on-windows) + +### For Ubuntu / Mac + +#### Standard mode + + ``` conda install -c tofuproject tofu ``` + +#### Developer mode + +Install dependencies + + + python (>= 3.6) + numpy + scipy + matplotlib + cython >= 0.26 + nose + pygments + pandas + + +Checkout the tofu git repository and from the top directory + + + python setup.py build_ext --inplace + python setup.py install + + +## Getting Started + +See our wiki's page: [Getting started](https://github.com/ToFuProject/tofu/wiki/Getting-started) + +----- + + +**Licensing** + +It is distributed under the MIT license and aims at providing the fusion community with +a transparent and modular tool for creating / designing diagnostics and using them for +synthetic diagnostic (direct problem) and tomography (inverse problem). + +**History** + +It was first created at the Max-Planck Institute for Plasma Physics (IPP) in Garching, Germany, +by Didier Vezinet, and is now maintained / debugged / updated by a team of contributors. + + +----- + +**Warning** +This Pypi package focuses on tomography for fusion research. +It uses the same name as a previous package dedicated to a testing framework coupling fixtures and tests loosely, now renamed **reahl-tofu** and developped by Iwan Vosloo since 2006. If you ended up here looking for a web-oriented library, you should probably redirect to the more recent [**reahl-tofu**](https://pypi.python.org/pypi/reahl-tofu) page. diff --git a/README.rst b/README.rst deleted file mode 100644 index 2555f366a..000000000 --- a/README.rst +++ /dev/null @@ -1,109 +0,0 @@ -.. image:: https://img.shields.io/travis/ToFuProject/tofu.svg?label=Travis-CI - :target: https://travis-ci.org/ToFuProject/tofu - -.. image:: https://anaconda.org/tofuproject/tofu/badges/version.svg - :target: https://anaconda.org/tofuproject/tofu/badges/ - -.. image:: https://anaconda.org/tofuproject/tofu/badges/downloads.svg - :target: https://anaconda.org/tofuproject/tofu/badges/ - -.. image:: https://anaconda.org/tofuproject/tofu/badges/latest_release_date.svg - :target: https://anaconda.org/tofuproject/tofu/badges/ - -.. image:: https://anaconda.org/tofuproject/tofu/badges/platforms.svg - :target: https://anaconda.org/tofuproject/tofu/badges/ - -.. image:: https://anaconda.org/tofuproject/tofu/badges/license.svg - :target: https://anaconda.org/tofuproject/tofu/badges/ - -.. image:: https://anaconda.org/tofuproject/tofu/badges/installer/conda.svg - :target: https://anaconda.org/tofuproject/tofu/badges/ - -.. image:: https://codecov.io/gh/ToFuProject/tofu/branch/master/graph/badge.svg - :target: https://codecov.io/gh/ToFuProject/tofu - -.. image:: https://badge.fury.io/py/tofu.svg - :target: https://badge.fury.io/py/tofu - - -tofu -==== - - -tofu stands for Tomography for Fusion, it is an open-source machine-independent python library -with non-open source plugins containing all machine-dependent routines. - -It is distributed under the MIT license and aims at providing the fusion community with -a transparent and modular tool for creating / designing diagnostics and using them for -synthtic diagnostic (direct problem) and tomography (inverse problem). - -It was first created at the Max-Planck Institute for Plasma Physics (IPP) in Garching, Germany, -by Didier Vezinet, and is now maintained / debugged / updated by him and other contributors. - -A sphinx-generated documentation can be found at [the tofu documentation page](https://ToFuProject.github.io/tofu/index.html), -and the code itself is hosted on [GitHub](https://github.com/ToFuProject/tofu). - - ----- - -tofu provides the user with a series of python classes for creating, handling and visualizing a diagnostic geometry, meshes and basis functions, -geometry matrices, pre-treating experimental data and computing tomographic inversions. - -Each one of these main tasks is accomplished by a dedicated module in the larger tofu package. - -In its current version, only the geometry and data-handling modules are released. -The others, while operational, are not user-friendly and documented yet, they will be available in future releases. - - -The geometry module is sufficient for diagnostic designing and for a synthetic diagnostic approach (i.e.: computing the integrated signal from a simulated 2D or 3D emissivity). -This geometry module allows in particular: - -* To handle linear and toroidal vaccum vessels -* To define apertures and detectors as planar polygons of arbitrary shapes, or to define a spherical converging lens and a circular detector in its focal plane. -* To assign an arbitrary number of apertures to each detector (and the apertures do not have to stand in parallel planes) -* To automatically compute the full Volume of Sight (VOS) in 3D of each {detector+aperture(s)} set -* To discretise the VOS for a numerical 3D integration of a simulated emissivity in order to compute the associated signal - -It is in this geometrical sense that tofu enables a synthetic diagnostic approach, it does not provide the tools for simulating the emissivity (that should be an input, provided by another code). - ----- - - -Installing tofu -*************** - -- **Standard mode**:: - - conda install -c tofuproject tofu - -- **Developer mode** - -Install dependencies.:: - - python (2.7 or 3) - numpy - scipy - matplotlib - cython - nose - pygments - pandas - polygon3 (or polygon2 if you are using python 2.7) - -Checkout the tofu git repository and from the top directory:: - - python setup.py build_ext --inplace - python setup.py install - - ------ - -**Warning** -This Pypi package focuses on tomography for fusion research. -It uses the same name as a previous package dedicated to a testing framework coupling fixtures and tests loosely, now renamed **reahl-tofu** and developped by Iwan Vosloo since 2006. If you ended up here looking for a web-oriented library, you should probably redirect to the more recent [**reahl-tofu**](https://pypi.python.org/pypi/reahl-tofu) page. - - - - - - diff --git a/README_figures/54300_1dTe_svd.pdf b/README_figures/54300_1dTe_svd.pdf new file mode 100644 index 000000000..2aad61585 Binary files /dev/null and b/README_figures/54300_1dTe_svd.pdf differ diff --git a/README_figures/54300_1dTe_svd.png b/README_figures/54300_1dTe_svd.png new file mode 100644 index 000000000..fdabd8918 Binary files /dev/null and b/README_figures/54300_1dTe_svd.png differ diff --git a/README_figures/CamLOS1D_sino.pdf b/README_figures/CamLOS1D_sino.pdf new file mode 100644 index 000000000..d1951cc9c Binary files /dev/null and b/README_figures/CamLOS1D_sino.pdf differ diff --git a/README_figures/CamLOS1D_sino.png b/README_figures/CamLOS1D_sino.png new file mode 100644 index 000000000..692cafedc Binary files /dev/null and b/README_figures/CamLOS1D_sino.png differ diff --git a/README_figures/CamLOS1D_touch.pdf b/README_figures/CamLOS1D_touch.pdf new file mode 100644 index 000000000..7e1fd3d53 Binary files /dev/null and b/README_figures/CamLOS1D_touch.pdf differ diff --git a/README_figures/CamLOS1D_touch.png b/README_figures/CamLOS1D_touch.png new file mode 100644 index 000000000..aa5594738 Binary files /dev/null and b/README_figures/CamLOS1D_touch.png differ diff --git a/README_figures/CamLOS2D_touch_refelect.pdf b/README_figures/CamLOS2D_touch_refelect.pdf new file mode 100644 index 000000000..74a089d22 Binary files /dev/null and b/README_figures/CamLOS2D_touch_refelect.pdf differ diff --git a/README_figures/CamLOS2D_touch_refelect.png b/README_figures/CamLOS2D_touch_refelect.png new file mode 100644 index 000000000..cd73f241f Binary files /dev/null and b/README_figures/CamLOS2D_touch_refelect.png differ diff --git a/README_figures/MagfieldLines.pdf b/README_figures/MagfieldLines.pdf new file mode 100644 index 000000000..a7afbb6db Binary files /dev/null and b/README_figures/MagfieldLines.pdf differ diff --git a/README_figures/MagfieldLines.png b/README_figures/MagfieldLines.png new file mode 100644 index 000000000..6edcacc41 Binary files /dev/null and b/README_figures/MagfieldLines.png differ diff --git a/README_figures/Plasma2D_1dneTe.pdf b/README_figures/Plasma2D_1dneTe.pdf new file mode 100644 index 000000000..f0f0b4bf1 Binary files /dev/null and b/README_figures/Plasma2D_1dneTe.pdf differ diff --git a/README_figures/Plasma2D_1dneTe.png b/README_figures/Plasma2D_1dneTe.png new file mode 100644 index 000000000..36b6e02c1 Binary files /dev/null and b/README_figures/Plasma2D_1dneTe.png differ diff --git a/README_figures/cam2d.PNG b/README_figures/cam2d.PNG new file mode 100644 index 000000000..4eb36e744 Binary files /dev/null and b/README_figures/cam2d.PNG differ diff --git a/README_figures/configB2.PNG b/README_figures/configB2.PNG new file mode 100644 index 000000000..54983210e Binary files /dev/null and b/README_figures/configB2.PNG differ diff --git a/README_figures/starting_ipython.PNG b/README_figures/starting_ipython.PNG new file mode 100644 index 000000000..669a9891f Binary files /dev/null and b/README_figures/starting_ipython.PNG differ diff --git a/TODO_EndOfVisit_20181212.txt b/TODO_EndOfVisit_20181212.txt index d295de1d9..a2e89a891 100644 --- a/TODO_EndOfVisit_20181212.txt +++ b/TODO_EndOfVisit_20181212.txt @@ -110,6 +110,7 @@ x 2/ Calculer, pour N polygones, et lorsque les lignes de visée ne les - Les réflexions sur un cristal à simple ou double courbure (pour les spectromètres) + 8/ S'attaquer aux maillages (an 2) J'arrive ;-) diff --git a/_updateversion.py b/_updateversion.py index cdcb1f415..b14f878f2 100644 --- a/_updateversion.py +++ b/_updateversion.py @@ -23,9 +23,10 @@ def updateversion(path=_HERE): version_git = fh.read().strip().split("=")[-1].replace("'",'') version_git = version_git.lower().replace('v','') - version_msg = "# Do not edit this file, pipeline versioning is governed by git tags !" + version_msg = "# Do not edit, pipeline versioning governed by git tags!" with open(version_py,"w") as fh: - fh.write((version_msg + os.linesep + '__version__=').replace('',"") + "'%s'" % version_git) + msg = "{0}__version__ = '{1}'{0}".format(os.linesep, version_git) + fh.write(version_msg + msg) return version_git diff --git a/benchmarks/__init__.py b/benchmarks/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/benchmarks/calc_signal_benchmark.py b/benchmarks/calc_signal_benchmark.py new file mode 100644 index 000000000..a0dcf9df0 --- /dev/null +++ b/benchmarks/calc_signal_benchmark.py @@ -0,0 +1,417 @@ +#!/usr/bin/env python + +# Built-in +import os +import sys +import argparse + +# Common +import datetime as dtm +import numpy as np +import matplotlib.pyplot as plt +from mpl_toolkits.mplot3d import Axes3D +import socket +import getpass + +# tofu +# test if in a tofu git repo +_HERE = os.path.abspath(os.path.dirname(__file__)) +istofugit = False +heresplit = _HERE.split(os.path.sep) +if 'benchmarks' in heresplit: + ind = heresplit[::-1].index('benchmarks') + pp = os.path.sep + os.path.join(*heresplit[:-ind-1]) + lf = os.listdir(pp) + if '.git' in lf and 'tofu' in lf: + istofugit = True + +if istofugit: + # Make sure we load the corresponding tofu + sys.path.insert(1,pp) + import tofu as tf + _ = sys.path.pop(1) +else: + import tofu as tf +tforigin = tf.__file__ +tfversion = tf.__version__ + +np.set_printoptions(linewidth=200) + + +################### +# Defining defaults +################### + +_LRES = [-3, -3, 0] +_LLOS = [5, 5, 0] +_LT = [3, 3, 0] +_NREP = 2 + +_DRES = abs(_LRES[1] - _LRES[0]) +_DLOS = abs(_LLOS[1] - _LLOS[0]) +_DT = abs(_LT[1] - _LT[0]) +_RES = np.logspace(_LRES[0], _LRES[1], _LRES[2]*_DRES + _DRES + 1 , + base=10) +_NLOS = np.round(np.logspace(_LLOS[0], _LLOS[1], _LLOS[2]*_DLOS + _DLOS + 1, + base=10)) +_NT = np.round(np.logspace(_LT[0], _LT[1], _LT[2]*_DT + _DT + 1, base=10)) +_SHOT = 54178 +_IDS = ['core_profiles', 'equilibrium', 'core_sources'] +_QUANT = 'core_profiles.1dne' +_REF1D = 'core_profiles.1drhotn' +_REF2D = 'equilibrium.2drhotn' +_DALGO = {'ref-sum':{'newcalc':False}, + 'calls-sum': {'newcalc':True, 'minimize':'calls', 'method':'sum'}, + # 'calls-simps': {'newcalc':True, 'minimize':'calls', 'method':'simps'}, + # 'calls-romb': {'newcalc':True, 'minimize':'calls', 'method':'romb'}, + 'hybrid-sum': {'newcalc':True, 'minimize':'hybrid', 'method':'sum'}, + # 'hybrid-simps': {'newcalc':True, 'minimize':'hybrid', 'method':'simps'}, + # 'hybrid-romb': {'newcalc':True, 'minimize':'hybrid', 'method':'romb'}, + 'memory-sum': {'newcalc':True, 'minimize':'memory', 'method':'sum'}, + # 'memory-simps': {'newcalc':True, 'minimize':'memory', 'method':'simps'}, + # 'memory-romb': {'newcalc':True, 'minimize':'memory', 'method':'romb'}, + } +_DCAM = {'P':[3.4,0.,0.], 'F':0.1, 'D12':0.1, + 'angs':[1.05*np.pi, np.pi/4, np.pi/4]} + +_PATH = _HERE +_FUNC = True +_TXTFILE = None +_SAVE = True +_PLOT = False + +_FS = (14,10) +_DMARGIN = {'left':0.05, 'right':0.95, + 'bottom':0.05, 'top':0.95, + 'wspace':0.1, 'hspace':0.1} + + + +################### +# Emissivity +################### + +def emiss(pts, t=None, vect=None): + r, z = np.hypot(pts[0,:],pts[1,:]), pts[2,:] + e = np.exp(-(r-2.4)**2/0.2**2 - z**2/0.2**2) + if t is not None: + e = np.cos(np.atleast_1d(t))[:,None] * e[None,:] + return e + +################### +# Main function +################### + + +def benchmark(config=None, func=_FUNC, plasma=None, shot=None, ids=None, + quant=None, ref1d=None, ref2d=None, + res=None, nlos=None, nt=None, t=None, + dalgo=None, nrep=None, txtfile=None, + path=None, name=None, nameappend=None, + plot=_PLOT, save=_SAVE): + + # -------------- + # Prepare inputs + + # res and los + if res is None: + res = _RES + nres = len(res) + if nlos is None: + nlos = _NLOS + nlos = np.array(nlos, dtype=int) + nnlos = len(nlos) + + # dalgo + if dalgo is None: + dalgo = _DALGO + lalgo = list(dalgo.keys()) + nalgo = len(dalgo) + + # nrep + if nrep is None: + nrep = _NREP + + if t is None: + if nt is None: + nt = _NT + lt = [np.linspace(0,100,ntt) for ntt in nt] + else: + lt = [np.atleast_1d(t).ravel()] + nnt = len(lt) + + if path is None: + path = _PATH + if name is None: + lvar = [('nalgo',nalgo), ('nnlos',nnlos), + ('nres',nres), ('nnt',nnt), + ('Host',socket.gethostname()), ('USR',getpass.getuser())] + name = 'benchmark_LOScalcsignal_' + name += '_'.join(['%s%s'%(nn,vv) + for nn,vv in lvar]) + if nameappend is not None: + name += '_'+nameappend + + # printing file + stdout = False + if txtfile is None: + txtfile = sys.stdout + stdout = True + elif type(txtfile) is str: + txtfile = open(os.path.join(path,txtfile), 'w') + elif txtfile is True: + txtfile = open(os.path.join(path,name+'.txt'), 'w') + msg_loc = "\ntofu %s loaded from:\n %s\n"%(tfversion,tforigin) + print(msg_loc, file=txtfile) + + + # config + if config is None: + config = 'B2' + if type(config) is str: + config = tf.geom.utils.create_config(config) + + # func vs plasma + if func == True: + func = emiss + elif func is None: + if plasma is None: + if ids is None: + ids = _IDS + if shot is None: + shot = _SHOT + didd = tf.imas2tofu.MultiIDSLoader(shot=shot, ids=ids) + plasma = didd.to_Plasma2D() + + # quant, ref1d, ref2d + if quant is None: + quant = _QUANT + ref1d = _REF1D + ref2d = _REF2D + + #--------------- + # Prepare output + + # data + t_av = np.full((nalgo, nnlos, nres, nnt), np.nan) + t_std = np.full((nalgo, nnlos, nres, nnt), np.nan) + memerr = np.zeros((nalgo, nnlos, nres, nnt), dtype=bool) + win = np.zeros((nnlos, nres, nnt), dtype=int) + + #--------------- + # Prepare saving params + if save: + pfe = os.path.join(path,name+'.npz') + lk = ['tforigin', 'tfversion', 't_std', 'nnt', 'lt', 'nalgo', 'nres', + 'name', 'path', 'save', 'plot', 'nrep', 'dalgo', 't', 'nt', + 'res', 'ref2d', 'ref1d', 'quant', 'ids', 'shot', + 'win', 't_av', 'nnlos', 'nlos', 'ncase', 'lalgo'] + + #------------ + # Start loop + + names = np.array([['%s los = %s'%(lalgo[ii],int(nlos[jj])) + for jj in range(nnlos)] + for ii in range(nalgo)]) + lennames = np.max(np.char.str_len(names)) + msg = "\n###################################"*2 + msg += "\nBenchmark about to be run with:" + msg += "\n-------------------------------\n\n" + msg += "lalgo = %s\n"%str(lalgo) + msg += "nlos = %s\n"%str(nlos) + msg += "res = %s\n"%str(res) + msg += "nt = %s\n"%str(nt) + msg += "rep = %s\n\n"%str(nrep) + msg += " algo:".ljust(lennames) + ' times:' + print(msg, file=txtfile) + + err0 = None + for ii in range(nalgo): + print('', file=txtfile, flush=True) + for jj in range(nnlos): + cam = tf.geom.utils.create_CamLOS1D(N12=nlos[jj], + config=config, + Name=str(names[ii,jj]), Exp='dummy', + Diag='Dummy', + **_DCAM) + msg = " %s"%(names[ii,jj].ljust(lennames)) + print(msg, file=txtfile, flush=True) + + for ll in range(nres): + msg = " res %s/%s"%(ll+1, nres) + for tt in range(nnt): + dt = np.zeros((nrep,)) + for rr in range(nrep): + if stdout: + msgi = "\r" + msg + " nt %s/%s rep %s/%s"%(tt+1,nnt,rr+1,nrep) + print(msgi, end='', file=txtfile, flush=True) + + try: + if func is None: + t0 = dtm.datetime.now() + _ = cam.calc_signal_from_Plasma2D(plasma, + quant=quant, + ref1d=ref1d, + ref2d=ref2d, + res=res[ll], + resMode='abs', + plot=False, + t = lt[tt], + **dalgo[lalgo[ii]]) + dt[rr] = (dtm.datetime.now()-t0).total_seconds() + else: + t0 = dtm.datetime.now() + _ = cam.calc_signal(func, res=res[ll], + resMode='abs', plot=False, + t = lt[tt], + **dalgo[lalgo[ii]]) + dt[rr] = (dtm.datetime.now()-t0).total_seconds() + except MemoryError as err: + dt[rr] = -1 + memerr[ii,jj,ll,tt] = True + except Exception as err: + if err0 is None: + err0 = err + + t_av[ii,jj,ll,tt] = np.mean(dt) + t_std[ii,jj,ll,tt] = np.std(dt) + + msgi = msg + ': %s'%str(t_av[ii,jj,ll,:]) + if stdout: + msgi = '\r'+msgi + print(msgi, file=txtfile, flush=True) + if save: + out = {kk:vv for kk,vv in locals().items() if kk in lk} + np.savez(pfe, **out) + print(" (saved)", file=txtfile) + + + + t_av[memerr] = np.nan + win = np.nanargmin(t_av, axis=0) + ncase = win.size + + # Print synthesis + ln = np.max([len(aa) for aa in lalgo]) + msg = "\n --------------------\n --- Synthesis ---" + msg += "\n\n Speed score:\n " + msg += "\n ".join(["%s : %s"%(lalgo[ii].ljust(ln), + 100.*np.sum(win==ii)/ncase) +' %' + for ii in range(nalgo)]) + + winname = np.char.rjust(np.asarray(lalgo)[win], ln) + lsblocks = ['nlos = %s'%str(nlos[jj]) + "\n " + + "\n ".join([('res %s/%s '%(ll,nres) + + str(winname[jj,ll,:])) + for ll in range(nres)]) + for jj in range(nnlos)] + msg += "\n" + "\n " + "\n ".join(lsblocks) + + + msg += "\n\n Memory score:\n " + msg += "\n ".join(["%s : %s"%(lalgo[ii].ljust(ln), + 100.*np.sum(t_av[ii,...]>=0)/ncase) + ' %' + for ii in range(nalgo)]) + print(msg, file=txtfile) + + + if err0 is not None: + raise err0 + + #------------- + # Plot / save + + + if save: + out = {kk:vv for kk,vv in locals().items() if kk in lk} + np.savez(pfe, **out) + print('Saved in:\n %s'%pfe, file=txtfile) + + if plot: + try: + plot_benchmark(**out) + except Exception: + pass + if txtfile != sys.stdout: + txtfile.close() + return out + + + +################### +# Plotting +################### + + +def plot_benchmark(fname=None, fs=None, dmargin=None, **kwdargs): + + if fname is not None: + assert type(fname) is str + out = dict(np.load(fname)) + else: + out = kwdargs + + # Prepare inputs + # -------------- + if fs is None: + fs = _FS + if dmargin is None: + dmargin = _DMARGIN + + indok = out['t_av'] >= 0. + vmin, vmax = np.nanmin(out['t_av'][indok]), np.nanmax(out['t_av'][indok]) + + + # Plotting + # -------------- + fig = plt.figure(figsize=fs) + # axarr = GridSpec(1,4, **dmargin) + # ax0 = fig.add_subplot(axarr[0,0]) + # ax1 = + # ax2 = + # ax3 = + ax0 = fig.add_axes([0.1,0.1,0.8,0.8]) + + ax0.scatter(out['nlos'], out['res'], out['nt'], + c=out['t_av'][0,...], s=8, marker='o') + + return + + + +################### +# Bash interface +################### + +if __name__ == '__main__': + + # Parse input arguments + msg = \ + """ Launch benchmark for _GG.LOS_calc_signal + + This is a bash wrapper around the function benchmark() + """ + parser = argparse.ArgumentParser(description=msg) + + parser.add_argument('-f', '--func', type=bool, + help='emissivity function', required=False, default=_FUNC) + parser.add_argument('-tf', '--txtfile', type=bool, + help='write to txt file ?', required=False, + default=_TXTFILE) + parser.add_argument('-na', '--nameappend', type=str, + help='str to be appended to the name', required=False, + default=None) + parser.add_argument('-s', '--save', type=bool, + help='save results ?', required=False, + default=_SAVE) + parser.add_argument('-p', '--plot', type=bool, + help='plot results ?', required=False, + default=_PLOT) + parser.add_argument('-pa', '--path', type=str, + help='path where to save results', required=False, + default=_PATH) + + args = parser.parse_args() + + # Call wrapper function + benchmark(**dict(args._get_kwargs())) diff --git a/conda_recipe/meta.yaml b/conda_recipe/meta.yaml index a61f8ca17..77064c52a 100644 --- a/conda_recipe/meta.yaml +++ b/conda_recipe/meta.yaml @@ -26,13 +26,9 @@ requirements: - numpy - scipy - matplotlib - - cython + - cython >=0.26 - nose - pygments - - pandas - - polygon2 # [py27] - - polygon3 # [not py27] - - funcsigs # [py27] # for running the library @@ -43,19 +39,13 @@ requirements: - numpy - scipy - matplotlib - - cython + - cython >=0.26 - nose - pygments - - pandas - - polygon2 # [py27] - - polygon3 # [not py27] - - funcsigs # [py27] test: requires: - nose - - polygon2 # [py2k] - - polygon3 # [not py27] imports: - tofu.geom diff --git a/doc/Makefile b/doc/Makefile index d4d543162..2327611a5 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -5,7 +5,7 @@ SPHINXOPTS = SPHINXBUILD = sphinx-build PAPER = -BUILDDIR = build +BUILDDIR = ../../test_doc/tofu # Internal variables. PAPEROPT_a4 = -D latex_paper_size=a4 @@ -39,12 +39,12 @@ help: @echo " doctest to run all doctests embedded in the documentation (if enabled)" clean: - -rm -rf $(BUILDDIR)/* - + rm -rf $(BUILDDIR)/* + rm -rf source/auto_examples/ html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR) @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." + @echo "Build finished. The HTML pages are in $(BUILDDIR)." dirhtml: $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml diff --git a/doc/build/doctrees/Auto_tofu.geom.doctree b/doc/build/doctrees/Auto_tofu.geom.doctree deleted file mode 100644 index aa5539e79..000000000 Binary files a/doc/build/doctrees/Auto_tofu.geom.doctree and /dev/null differ diff --git a/doc/build/doctrees/Auto_tofu.pathfile.doctree b/doc/build/doctrees/Auto_tofu.pathfile.doctree deleted file mode 100644 index cca6ef76c..000000000 Binary files a/doc/build/doctrees/Auto_tofu.pathfile.doctree and /dev/null differ diff --git a/doc/build/doctrees/Auto_tofu.plugins.AUG.SXR.geom.doctree b/doc/build/doctrees/Auto_tofu.plugins.AUG.SXR.geom.doctree deleted file mode 100644 index 1709abd24..000000000 Binary files a/doc/build/doctrees/Auto_tofu.plugins.AUG.SXR.geom.doctree and /dev/null differ diff --git a/doc/build/doctrees/Auto_tofu.plugins.AUG.doctree b/doc/build/doctrees/Auto_tofu.plugins.AUG.doctree deleted file mode 100644 index 91f793ee6..000000000 Binary files a/doc/build/doctrees/Auto_tofu.plugins.AUG.doctree and /dev/null differ diff --git a/doc/build/doctrees/Auto_tofu.plugins.ITER.Bolo.geom.doctree b/doc/build/doctrees/Auto_tofu.plugins.ITER.Bolo.geom.doctree deleted file mode 100644 index 33b0e57dd..000000000 Binary files a/doc/build/doctrees/Auto_tofu.plugins.ITER.Bolo.geom.doctree and /dev/null differ diff --git a/doc/build/doctrees/Auto_tofu.plugins.ITER.doctree b/doc/build/doctrees/Auto_tofu.plugins.ITER.doctree deleted file mode 100644 index d2ac2ce44..000000000 Binary files a/doc/build/doctrees/Auto_tofu.plugins.ITER.doctree and /dev/null differ diff --git a/doc/build/doctrees/Auto_tofu.plugins.doctree b/doc/build/doctrees/Auto_tofu.plugins.doctree deleted file mode 100644 index ea041eb32..000000000 Binary files a/doc/build/doctrees/Auto_tofu.plugins.doctree and /dev/null differ diff --git a/doc/build/doctrees/Auto_tofu.treat.doctree b/doc/build/doctrees/Auto_tofu.treat.doctree deleted file mode 100644 index 528bc7034..000000000 Binary files a/doc/build/doctrees/Auto_tofu.treat.doctree and /dev/null differ diff --git a/doc/build/doctrees/Autodoc.doctree b/doc/build/doctrees/Autodoc.doctree deleted file mode 100644 index 6f8a56e1c..000000000 Binary files a/doc/build/doctrees/Autodoc.doctree and /dev/null differ diff --git a/doc/build/doctrees/Citation.doctree b/doc/build/doctrees/Citation.doctree deleted file mode 100644 index bb6e3631f..000000000 Binary files a/doc/build/doctrees/Citation.doctree and /dev/null differ diff --git a/doc/build/doctrees/Dependencies.doctree b/doc/build/doctrees/Dependencies.doctree deleted file mode 100644 index 3e27b5a0e..000000000 Binary files a/doc/build/doctrees/Dependencies.doctree and /dev/null differ diff --git a/doc/build/doctrees/Todos.doctree b/doc/build/doctrees/Todos.doctree deleted file mode 100644 index f13fd4218..000000000 Binary files a/doc/build/doctrees/Todos.doctree and /dev/null differ diff --git a/doc/build/doctrees/Tutorial_AUG.doctree b/doc/build/doctrees/Tutorial_AUG.doctree deleted file mode 100644 index 02dc53b68..000000000 Binary files a/doc/build/doctrees/Tutorial_AUG.doctree and /dev/null differ diff --git a/doc/build/doctrees/Tutorial_Geom_Advanced.doctree b/doc/build/doctrees/Tutorial_Geom_Advanced.doctree deleted file mode 100644 index 4c9d52a18..000000000 Binary files a/doc/build/doctrees/Tutorial_Geom_Advanced.doctree and /dev/null differ diff --git a/doc/build/doctrees/Tutorial_Geom_HowToCreateGeometry.doctree b/doc/build/doctrees/Tutorial_Geom_HowToCreateGeometry.doctree deleted file mode 100644 index 7232743ba..000000000 Binary files a/doc/build/doctrees/Tutorial_Geom_HowToCreateGeometry.doctree and /dev/null differ diff --git a/doc/build/doctrees/Tutorial_Geom_SynthDiag_Basic.doctree b/doc/build/doctrees/Tutorial_Geom_SynthDiag_Basic.doctree deleted file mode 100644 index f40561388..000000000 Binary files a/doc/build/doctrees/Tutorial_Geom_SynthDiag_Basic.doctree and /dev/null differ diff --git a/doc/build/doctrees/Tutorial_ITER.doctree b/doc/build/doctrees/Tutorial_ITER.doctree deleted file mode 100644 index 8bbac8225..000000000 Binary files a/doc/build/doctrees/Tutorial_ITER.doctree and /dev/null differ diff --git a/doc/build/doctrees/Versions.doctree b/doc/build/doctrees/Versions.doctree deleted file mode 100644 index ac5da06dd..000000000 Binary files a/doc/build/doctrees/Versions.doctree and /dev/null differ diff --git a/doc/build/doctrees/environment.pickle b/doc/build/doctrees/environment.pickle deleted file mode 100644 index c9d12b6bd..000000000 Binary files a/doc/build/doctrees/environment.pickle and /dev/null differ diff --git a/doc/build/doctrees/index.doctree b/doc/build/doctrees/index.doctree deleted file mode 100644 index 48a13497d..000000000 Binary files a/doc/build/doctrees/index.doctree and /dev/null differ diff --git a/doc/build/doctrees/overview.doctree b/doc/build/doctrees/overview.doctree deleted file mode 100644 index 7d67588d5..000000000 Binary files a/doc/build/doctrees/overview.doctree and /dev/null differ diff --git a/doc/build/html/.buildinfo b/doc/build/html/.buildinfo deleted file mode 100644 index e1601ba93..000000000 --- a/doc/build/html/.buildinfo +++ /dev/null @@ -1,4 +0,0 @@ -# Sphinx build info version 1 -# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. -config: 396f35bc9ac97e5f2534e73d7a02feec -tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/doc/build/html/Auto_tofu.geom.html b/doc/build/html/Auto_tofu.geom.html deleted file mode 100644 index 45f56c2ed..000000000 --- a/doc/build/html/Auto_tofu.geom.html +++ /dev/null @@ -1,2229 +0,0 @@ - - - - - - - - 1. tofu.geom — tofu v1.1 - - - - - - - - - - - - - - - - -
-
-
-
- -
-

1. tofu.geom¶

-

Load all core packages and modules which are all machine-independent, diagnostic-independent and code-independent

-
-
-class tofu.geom.Ves(Id, Poly, Type='Tor', DLong=None, Sino_RefPt=None, Sino_NP=50, Clock=False, arrayorder='C', Exp=None, shot=None, dtime=None, dtimeIn=False, SavePath=None)[source]¶
-

A class defining a Linear or Toroidal vaccum vessel (i.e. a 2D polygon representing a cross-section and assumed to be linearly or toroidally invariant)

-

A Ves object is mostly defined by a close 2D polygon, which can be understood as a poloidal cross-section in (R,Z) cylindrical coordinates if Type=’Tor’ (toroidal shape) or as a straight cross-section through a cylinder in (Y,Z) cartesian coordinates if Type=’Lin’ (linear shape). -Attributes such as the surface, the angular volume (if Type=’Tor’) or the center of mass are automatically computed. -The instance is identified thanks to an attribute Id (which is itself a tofu.ID class object) which contains informations on the specific instance (name, Type...).

- --- - - - - - -
Parameters:
    -
  • Id (str / tfpf.ID) – A name string or a pre-built tfpf.ID class to be used to identify this particular instance, if a string is provided, it is fed to tfpf.ID()
  • -
  • Poly (np.ndarray) – An array (2,N) or (N,2) defining the contour of the vacuum vessel in a cross-section, if not closed, will be closed automatically
  • -
  • Type (str) – Flag indicating whether the vessel will be a torus (‘Tor’) or a linear device (‘Lin’)
  • -
  • DLong (list / np.ndarray) – Array or list of len=2 indicating the limits of the linear device volume on the x axis
  • -
  • Sino_RefPt (None / np.ndarray) – Array specifying a reference point for computing the sinogram (i.e. impact parameter), if None automatically set to the (surfacic) center of mass of the cross-section
  • -
  • Sino_NP (int) – Number of points in [0,2*pi] to be used to plot the vessel sinogram envelop
  • -
  • Clock (bool) – Flag indicating whether the input polygon should be made clockwise (True) or counter-clockwise (False)
  • -
  • arrayorder (str) – Flag indicating whether the attributes of type=np.ndarray (e.g.: Poly) should be made C-contiguous (‘C’) or Fortran-contiguous (‘F’)
  • -
  • Exp (None / str) – Flag indicating which experiment the object corresponds to, allowed values are in [None,’AUG’,’MISTRAL’,’JET’,’ITER’,’TCV’,’TS’,’Misc’]
  • -
  • shot (None / int) – Shot number from which this Ves is usable (in case of change of geometry)
  • -
  • SavePath (None / str) – If provided, forces the default saving path of the object to the provided value
  • -
  • dtime (None / dtm.datetime) – A time reference to be used to identify this particular instance (used for debugging mostly)
  • -
  • dtimeIn (bool) – Flag indicating whether dtime should be included in the SaveName (used for debugging mostly)
  • -
-
Returns:

Ves (Ves object) – The created Ves object, with all necessary computed attributes and methods

-
-
-
-BaryS¶
-

Return the (surfacic) center of mass of the polygon defining the vessel cross-section

-
- -
-
-BaryV¶
-

Return the (volumic) center of mass of the polygon defining the vessel cross-section

-
- -
-
-Id¶
-

Return the tfpf.ID object of the vessel

-
- -
-
-Poly¶
-

Return the polygon defining the vessel cross-section

-
- -
-
-Sino_NP¶
-

Return the number of points used used for plotting the Ves polygon in projection space

-
- -
-
-Sino_RefPt¶
-

Return the 2D coordinates of the points used as a reference for computing the Ves polygon in projection space (where sinograms are plotted)

-
- -
-
-Surf¶
-

Return the area of the polygon defining the vessel cross-section

-
- -
-
-Type¶
-

Return the type of vessel

-
- -
-
-Vect¶
-

Return the polygon elementary vectors

-
- -
-
-Vin¶
-

Return the normalized vectors pointing inwards for each segment of the polygon

-
- -
-
-VolLin¶
-

Return the angular volume of the polygon defining the vessel cross-section of Tor type

-
- -
-
-arrayorder¶
-

Return the flag indicating which order is used for multi-dimensional array attributes

-
- -
-
-get_InsideConvexPoly(RelOff=0.05, ZLim='Def', Spline=True, Splprms=[100.0, 2.0, 3], NP=100, Plot=False, Test=True)[source]¶
-

Return a polygon that is a smaller and smoothed approximation of Ves.Poly, useful for excluding the divertor region in a Tokamak

-

For some uses, it can be practical to approximate the polygon defining the Ves object (which can be non-convex, like with a divertor), by a simpler, sligthly smaller and convex polygon. -This method provides a fast solution for computing such a proxy.

- --- - - - - - -
Parameters:
    -
  • RelOff (float) – Fraction by which an homothetic polygon should be reduced (1.-RelOff)*(Poly-BaryS)
  • -
  • ZLim (None / str / tuple) – Flag indicating what limits shall be put to the height of the polygon (used for excluding divertor)
  • -
  • Spline (bool) – Flag indiating whether the reduced and truncated polygon shall be smoothed by 2D b-spline curves
  • -
  • Splprms (list) – List of 3 parameters to be used for the smoothing [weights,smoothness,b-spline order], fed to scipy.interpolate.splprep()
  • -
  • NP (int) – Number of points to be used to define the smoothed polygon
  • -
  • Plot (bool) – Flag indicating whether the result shall be plotted for visual inspection
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

Poly (np.ndarray) – (2,N) polygon resulting from homothetic transform, truncating and optional smoothing

-
-
- -
-
-get_MeshCrossSection(CrossMesh=[0.01, 0.01], CrossMeshMode='abs', Test=True)[source]¶
-

Return a (2,N) array of 2D points coordinates meshing the Ves cross-section using the spacing specified by CrossMesh for each direction (taken as absolute distance or relative to the total size)

-

Method used for fast automatic meshing of the cross-section using a rectangular mesh uniform in each direction. -Returns the flattened points coordinates array, as well as the two increasing vectors and number of points.

- --- - - - - - -
Parameters:
    -
  • CrossMesh (iterable) – Iterable of len()==2 specifying the distance to be used between points in each direction (R or Y and Z), in absolute value or relative to the total size of the Ves in each direction
  • -
  • CrossMeshMode (str) – Flag specifying whether the distances provided in CrossMesh are absolute (‘abs’) or relative (‘rel’)
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

    -
  • Pts (np.ndarray) – Array of shape (2,N), comtaining the 2D coordinates of the N points consituting the mesh, only points lying inside the cross-section are returned
  • -
  • X1 (np.ndarray) – Flat array of the unique first coordinates of the mesh points (R or Y)
  • -
  • X2 (np.ndarray) – Flat array of the unique second coordinates of the mesh points (Z)
  • -
  • NumX1 (int) – Number of unique values in X1 (=X1.size)
  • -
  • NumX2 (int) – Number of unique values in X2 (=X2.size)
  • -
-

-
-
- -
-
-isInside(Pts, In='(X, Y, Z)')[source]¶
-

Return an array of booleans indicating whether each point lies inside the Ves volume

-

Tests for each point whether it lies inside the Ves object. -The points coordinates can be provided in 2D or 3D, just specify which coordinate system is provided using the ‘In’ parameter. -An array of boolean flags is returned.

- --- - - - - - -
Parameters:
    -
  • Pts (np.ndarray) – (2,N) or (3,N) array with the coordinates of the points to be tested
  • -
  • In (str) – Flag indicating the coordinate system in which the points are provided, in [‘(X,Y,Z)’,’(R,Z)’,’‘]
  • -
-
Returns:

ind (np.ndarray) – Array of booleans of shape (N,), True if a point is inside the Ves volume

-
-
- -
-
-plot(Lax=None, Proj='All', Elt='PIBsBvV', Pdict=None, Idict={'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, Bsdict={'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, Bvdict={'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, Vdict={'color': 'r', 'scale': 10}, IdictHor={'c': 'k', 'ls': 'dashed'}, BsdictHor={'c': 'b', 'ls': 'dashed'}, BvdictHor={'c': 'g', 'ls': 'dashed'}, Lim=[1.5707963267948966, 6.283185307179586], Nstep=50, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, draw=True, a4=False, Test=True)[source]¶
-

Plot the polygon defining the vessel, with a cross-section view, a longitudinal view or both, and optionally its reference point for plotting it in projection space

-

Generic method for plotting the Ves object, the projections to be plotted, the elements to plot, and the dictionaries or properties to be used for plotting each elements can all be specified using keyword arguments. -If an ax is not provided a default one is created.

- --- - - - - - -
Parameters:
    -
  • Lax (list or plt.Axes) – The axes to be used for plotting (provide a list of 2 axes if Proj=’All’), if None a new figure with axes is created
  • -
  • Proj (str) – Flag specifying the kind of projection used for the plot (‘Cross’ for a cross-section, ‘Hor’ for a horizontal plane, or ‘All’ for the two plots)
  • -
  • Elt (str) –
    -
    Flag specifying which elements to plot, each capital letter corresponds to an element
    -
      -
    • ‘P’: polygon
    • -
    • ‘I’: point used as a reference for computing impact parameters
    • -
    • ‘Bs’: (surfacic) center of mass
    • -
    • ‘Bv’: (volumic) center of mass for Tor type
    • -
    • ‘V’: vector pointing inward perpendicular to each segment defining the polygon
    • -
    -
    -
    -
  • -
  • Pdict (dict or None) – Dictionary of properties used for plotting the polygon, fed to plt.Axes.plot() or plt.plot_surface() if Proj=‘3d’, set to ToFu_Defauts.py if None
  • -
  • Idict (dict) – Dictionary of properties used for plotting point ‘I’ in Cross-section projection, fed to plt.Axes.plot()
  • -
  • IdictHor (dict) – Dictionary of properties used for plotting point ‘I’ in horizontal projection, fed to plt.Axes.plot()
  • -
  • Bsdict (dict) – Dictionary of properties used for plotting point ‘Bs’ in Cross-section projection, fed to plt.Axes.plot()
  • -
  • BsdictHor (dict) – Dictionry of properties used for plotting point ‘Bs’ in horizontal projection, fed to plt.Axes.plot()
  • -
  • Bvdict (dict) – Dictionary of properties used for plotting point ‘Bv’ in Cross-section projection, fed to plt.Axes.plot()
  • -
  • BvdictHor (dict) – Dictionary of properties used for plotting point ‘Bv’ in horizontal projection, fed to plt.Axes.plot()
  • -
  • Vdict (dict) – Dictionary of properties used for plotting point ‘V’ in cross-section projection, fed to plt.Axes.quiver()
  • -
  • LegDict (dict or None) – Dictionary of properties used for plotting the legend, fed to plt.legend(), the legend is not plotted if None
  • -
  • Lim (list or tuple) – Array of a lower and upper limit of angle (rad.) or length for plotting the ‘3d’ Proj
  • -
  • Nstep (int) – Number of points for sampling in ignorable coordinate (toroidal angle or length)
  • -
  • draw (bool) – Flag indicating whether the fig.canvas.draw() shall be called automatically
  • -
  • a4 (bool) – Flag indicating whether the figure should be plotted in a4 dimensions for printing
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

La list or plt.Axes Handles of the axes used for plotting (list if several axes where used)

-
-
- -
-
-plot_Sinogram(Proj='Cross', ax=None, Ang='theta', AngUnit='rad', Sketch=True, Pdict=None, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, draw=True, a4=False, Test=True)[source]¶
-

Plot the sinogram of the vessel polygon, by computing its envelopp in a cross-section, can also plot a 3D version of it

-

The envelop of the polygon is computed using self.Sino_RefPt as a reference point in projection space, and plotted using the provided dictionary of properties. -Optionaly a smal sketch can be included illustrating how the angle and the impact parameters are defined (if the axes is not provided).

- --- - - - - - -
Parameters:
    -
  • Proj (str) – Flag indicating whether to plot a classic sinogram (‘Cross’) from the vessel cross-section (assuming 2D), or an extended 3D version ‘3d’ of it with additional angle
  • -
  • ax (None or plt.Axes) – The axes on which the plot should be done, if None a new figure and axes is created
  • -
  • Ang (str) – Flag indicating which angle to use for the impact parameter, the angle of the line itself (xi) or of its impact parameter (theta)
  • -
  • AngUnit (str) – Flag for the angle units to be displayed, ‘rad’ for radians or ‘deg’ for degrees
  • -
  • Sketch (bool) – Flag indicating whether a small skecth showing the definitions of angles ‘theta’ and ‘xi’ should be included or not
  • -
  • Pdict (dict) – Dictionary of properties used for plotting the polygon envelopp, fed to plt.plot() if Proj=’Cross’ and to plt.plot_surface() if Proj=‘3d’
  • -
  • LegDict (None or dict) – Dictionary of properties used for plotting the legend, fed to plt.legend(), the legend is not plotted if None
  • -
  • draw (bool) – Flag indicating whether the fig.canvas.draw() shall be called automatically
  • -
  • a4 (bool) – Flag indicating whether the figure should be plotted in a4 dimensions for printing
  • -
  • Test (bool) – Flag indicating whether the inputs shall be tested for conformity
  • -
-
Returns:

ax (plt.Axes) – The axes used to plot

-
-
- -
-
-save(SaveName=None, Path=None, Mode='npz', compressed=False)[source]¶
-

Save the object in folder Name, under file name SaveName, using specified mode

-

Most tofu objects can be saved automatically as numpy arrays (.npz, recommended) at the default location (recommended) by simply calling self.save()

- --- - - - -
Parameters:
    -
  • SaveName (None / str) – The name to be used for the saved file, if None (recommended) uses self.Id.SaveName
  • -
  • Path (None / str) – Path specifying where to save the file, if None (recommended) uses self.Id.SavePath
  • -
  • Mode (str) – Flag specifying whether to save the object as a numpy array file (‘.npz’, recommended) or an object using cPickle (not recommended, heavier and may cause retro-compatibility issues)
  • -
  • compressed (bool) – Flag, used when Mode=’npz’, indicating whether to use np.savez or np.savez_compressed (slower saving and loading but smaller files)
  • -
-
-
- -
- -
-
-class tofu.geom.Struct(Id, Poly, Type='Tor', DLong=None, Ves=None, Clock=False, arrayorder='C', Exp=None, shot=None, dtime=None, dtimeIn=False, SavePath=None)[source]¶
-

A class defining a Linear or Toroidal structural element (i.e. a 2D polygon representing a cross-section and assumed to be linearly or toroidally invariant), like a Ves but with less properties.

-

A Struct object is mostly defined by a close 2D polygon, which can be understood as a poloidal cross-section in (R,Z) cylindrical coordinates if Type=’Tor’ (toroidal shape) or as a straight cross-section through a cylinder in (Y,Z) cartesian coordinates if Type=’Lin’ (linear shape). -Attributes such as the surface, the angular volume (if Type=’Tor’) or the center of mass are automatically computed. -The instance is identified thanks to an attribute Id (which is itself a tofu.ID class object) which contains informations on the specific instance (name, Type...).

- --- - - - - - -
Parameters:
    -
  • Id (str / tfpf.ID) – A name string or a pre-built tfpf.ID class to be used to identify this particular instance, if a string is provided, it is fed to tfpf.ID()
  • -
  • Poly (np.ndarray) – An array (2,N) or (N,2) defining the contour of the vacuum vessel in a cross-section, if not closed, will be closed automatically
  • -
  • Type (str) – Flag indicating whether the vessel will be a torus (‘Tor’) or a linear device (‘Lin’)
  • -
  • DLong (list / np.ndarray) – Array or list of len=2 indicating the limits of the linear device volume on the x axis
  • -
  • Ves (None or Ves) – An optional associated vessel
  • -
  • Clock (bool) – Flag indicating whether the input polygon should be made clockwise (True) or counter-clockwise (False)
  • -
  • arrayorder (str) – Flag indicating whether the attributes of type=np.ndarray (e.g.: Poly) should be made C-contiguous (‘C’) or Fortran-contiguous (‘F’)
  • -
  • Exp (None / str) – Flag indicating which experiment the object corresponds to, allowed values are in [None,’AUG’,’MISTRAL’,’JET’,’ITER’,’TCV’,’TS’,’Misc’]
  • -
  • shot (None / int) – Shot number from which this Ves is usable (in case of change of geometry)
  • -
  • SavePath (None / str) – If provided, forces the default saving path of the object to the provided value
  • -
  • dtime (None / dtm.datetime) – A time reference to be used to identify this particular instance (used for debugging mostly)
  • -
  • dtimeIn (bool) – Flag indicating whether dtime should be included in the SaveName (used for debugging mostly)
  • -
-
Returns:

struct (Struct object) – The created Struct object, with all necessary computed attributes and methods

-
-
-
-BaryS¶
-

Return the (surfacic) center of mass of the polygon defining the vessel cross-section

-
- -
-
-BaryV¶
-

Return the (volumic) center of mass of the polygon defining the vessel cross-section

-
- -
-
-DLong¶
-

Return the length spanned by the object in the ignorable coordinate

-
- -
-
-Id¶
-

Return the tfpf.ID object of the structure

-
- -
-
-Poly¶
-

Return the polygon defining the vessel cross-section

-
- -
-
-Surf¶
-

Return the area of the polygon defining the vessel cross-section

-
- -
-
-Type¶
-

Return the type of structure

-
- -
-
-Vect¶
-

Return the polygon elementary vectors

-
- -
-
-Ves¶
-

Return the associated Ves object, if any

-
- -
-
-Vin¶
-

Return the normalized vectors pointing inwards for each segment of the polygon

-
- -
-
-VolLin¶
-

Return the angular volume of the polygon defining the vessel cross-section of Tor type

-
- -
-
-arrayorder¶
-

Return the flag indicating which order is used for multi-dimensional array attributes

-
- -
-
-isInside(Pts, In='(X, Y, Z)')[source]¶
-

Return an array of booleans indicating whether each point lies inside the Ves volume

-

Tests for each point whether it lies inside the Ves object. -The points coordinates can be provided in 2D or 3D, just specify which coordinate system is provided using the ‘In’ parameter. -An array of boolean flags is returned.

- --- - - - - - -
Parameters:
    -
  • Pts (np.ndarray) – (2,N) or (3,N) array with the coordinates of the points to be tested
  • -
  • In (str) – Flag indicating the coordinate system in which the points are provided, in [‘(X,Y,Z)’,’(R,Z)’,’‘]
  • -
-
Returns:

ind (np.ndarray) – Array of booleans of shape (N,), True if a point is inside the Ves volume

-
-
- -
-
-plot(Lax=None, Proj='All', Elt='P', Pdict=None, Bsdict={'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, Bvdict={'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, Vdict={'color': 'r', 'scale': 10}, BsdictHor={'c': 'b', 'ls': 'dashed'}, BvdictHor={'c': 'g', 'ls': 'dashed'}, Lim=[1.5707963267948966, 6.283185307179586], Nstep=50, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, draw=True, a4=False, Test=True)[source]¶
-

Plot the polygon defining the vessel, with a cross-section view, a longitudinal view or both, and optionally its reference point for plotting it in projection space

-

Generic method for plotting the Ves object, the projections to be plotted, the elements to plot, and the dictionaries or properties to be used for plotting each elements can all be specified using keyword arguments. -If an ax is not provided a default one is created.

- --- - - - - - -
Parameters:
    -
  • Lax (list or plt.Axes) – The axes to be used for plotting (provide a list of 2 axes if Proj=’All’), if None a new figure with axes is created
  • -
  • Proj (str) – Flag specifying the kind of projection used for the plot (‘Cross’ for a cross-section, ‘Hor’ for a horizontal plane, or ‘All’ for the two plots)
  • -
  • Elt (str) –
    -
    Flag specifying which elements to plot, each capital letter corresponds to an element
    -
      -
    • ‘P’: polygon
    • -
    • ‘Bs’: (surfacic) center of mass
    • -
    • ‘Bv’: (volumic) center of mass for Tor type
    • -
    • ‘V’: vector pointing inward perpendicular to each segment defining the polygon
    • -
    -
    -
    -
  • -
  • Pdict (dict or None) – Dictionary of properties used for plotting the polygon, fed to plt.Axes.plot() or plt.plot_surface() if Proj=‘3d’, set to ToFu_Defauts.py if None
  • -
  • Bsdict (dict) – Dictionary of properties used for plotting point ‘Bs’ in Cross-section projection, fed to plt.Axes.plot()
  • -
  • BsdictHor (dict) – Dictionry of properties used for plotting point ‘Bs’ in horizontal projection, fed to plt.Axes.plot()
  • -
  • Bvdict (dict) – Dictionary of properties used for plotting point ‘Bv’ in Cross-section projection, fed to plt.Axes.plot()
  • -
  • BvdictHor (dict) – Dictionary of properties used for plotting point ‘Bv’ in horizontal projection, fed to plt.Axes.plot()
  • -
  • Vdict (dict) – Dictionary of properties used for plotting point ‘V’ in cross-section projection, fed to plt.Axes.quiver()
  • -
  • LegDict (dict or None) – Dictionary of properties used for plotting the legend, fed to plt.legend(), the legend is not plotted if None
  • -
  • Lim (list or tuple) – Array of a lower and upper limit of angle (rad.) or length for plotting the ‘3d’ Proj
  • -
  • Nstep (int) – Number of points for sampling in ignorable coordinate (toroidal angle or length)
  • -
  • draw (bool) – Flag indicating whether the fig.canvas.draw() shall be called automatically
  • -
  • a4 (bool) – Flag indicating whether the figure should be plotted in a4 dimensions for printing
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

La list or plt.Axes Handles of the axes used for plotting (list if several axes where used)

-
-
- -
-
-save(SaveName=None, Path=None, Mode='npz', compressed=False)[source]¶
-

Save the object in folder Name, under file name SaveName, using specified mode

-

Most tofu objects can be saved automatically as numpy arrays (.npz, recommended) at the default location (recommended) by simply calling self.save()

- --- - - - -
Parameters:
    -
  • SaveName (None / str) – The name to be used for the saved file, if None (recommended) uses self.Id.SaveName
  • -
  • Path (None / str) – Path specifying where to save the file, if None (recommended) uses self.Id.SavePath
  • -
  • Mode (str) – Flag specifying whether to save the object as a numpy array file (‘.npz’, recommended) or an object using cPickle (not recommended, heavier and may cause retro-compatibility issues)
  • -
  • compressed (bool) – Flag, used when Mode=’npz’, indicating whether to use np.savez or np.savez_compressed (slower saving and loading but smaller files)
  • -
-
-
- -
- -
-
-class tofu.geom.LOS(Id, Du, Ves=None, Sino_RefPt=None, arrayorder='C', Clock=False, Type=None, Exp=None, Diag=None, shot=None, dtime=None, dtimeIn=False, SavePath=None)[source]¶
-

A Line-Of-Sight object (semi-line with signed direction) with all useful geometrical parameters, associated Ves object and built-in methods for plotting, defined in (X,Y,Z) cartesian coordinates

-

A Line of Sight (LOS) is a semi-line. It is a useful approximate representation of a (more accurate) Volume of Sight (VOS) when the latter is narrow and elongated. -It is usually associated to a detector placed behind apertures. -When associated to a Ves object, special points are automatically computed (entry point, exit point, closest point to the center of the Ves object...) as well as a projection in a cross-section. -While tofu provides the possibility of creating LOS objects for academic and simplification pueposes, it is generally not recommended to use them for doing physics, consider using a Detect object instead (which will provide you with a proper and automatically-computed VOS as well as with a LOS if you want).

- --- - - - -
Parameters:
    -
  • Id (str / tfpf.ID) – A name string or a pre-built tfpf.ID class to be used to identify this particular instance, if a string is provided, it is fed to tfpf.ID()
  • -
  • Du (list / tuple) – List of 2 arrays of len=3, the (X,Y,Z) coordinates of respectively the starting point D of the LOS and its directing vector u (will be automatically normalized)
  • -
  • Ves (Ves) – A Ves instance to be associated to the created LOS
  • -
  • Sino_RefPt (None or np.ndarray) – If provided, array of size=2 containing the (R,Z) (for ‘Tor’ Type) or (Y,Z) (for ‘Lin’ Type) coordinates of the reference point for the sinogram
  • -
  • arrayorder (str) – Flag indicating whether the attributes of type=np.ndarray (e.g.: Poly) should be made C-contiguous (‘C’) or Fortran-contiguous (‘F’)
  • -
  • Type (None) – (not used in the current version)
  • -
  • Exp (None / str) – Experiment to which the Lens belongs, should be identical to Ves.Id.Exp if Ves is provided, if None and Ves is provided, Ves.Id.Exp is used
  • -
  • Diag (None / str) – Diagnostic to which the Lens belongs
  • -
  • shot (None / int) – Shot number from which this Lens is usable (in case its position was changed from a previous configuration)
  • -
  • SavePath (None / str) – If provided, forces the default saving path of the object to the provided value
  • -
  • dtime (None / dtm.datetime) – A time reference to be used to identify this particular instance (used for debugging mostly)
  • -
  • dtimeIn (bool) – Flag indicating whether dtime should be included in the SaveName (used for debugging mostly)
  • -
-
-
-
-plot(Lax=None, Proj='All', Lplot='Tot', Elt='LDIORP', EltVes='', Leg='', Ldict={'lw': 2, 'c': 'k'}, MdictD={'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, MdictI={'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, MdictO={'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, MdictR={'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, MdictP={'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, Vesdict={'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'BsdictHor': {'c': 'b', 'ls': 'dashed'}, 'Bvdict': {'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, 'Lim': [1.5707963267948966, 6.283185307179586], 'Test': True, 'Proj': 'All', 'IdictHor': {'c': 'k', 'ls': 'dashed'}, 'Elt': 'PIBsBvV', 'Pdict': None, 'Vdict': {'color': 'r', 'scale': 10}, 'Idict': {'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, 'Bsdict': {'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, 'Lax': None, 'BvdictHor': {'c': 'g', 'ls': 'dashed'}, 'Nstep': 50}, draw=True, a4=False, Test=True)[source]¶
-

Plot the LOS, in a cross-section projection, a horizontal projection or both, and optionally the Ves object associated to it.

-

Plot the desired projections of the LOS object. -The plot can include the special points, the directing vector, and the properties of the plotted objects are specified by dictionaries.

- --- - - - - - -
Parameters:
    -
  • Lax (list / plt.Axes) – The axes to be used for plotting (provide a list of 2 axes if Proj=’All’), if None a new figure with axes is created
  • -
  • Proj (str) – Flag specifying the kind of projection used for the plot (‘Cross’ for a cross-section, ‘Hor’ for a horizontal plane, ‘All’ both and ‘3d’ for 3d)
  • -
  • Elt (str) –
    -
    Flag specifying which elements to plot, each capital letter corresponds to an element
    -
      -
    • ‘L’: LOS
    • -
    • ‘D’: Starting point of the LOS
    • -
    • ‘I’: Input point (i.e.: where the LOS enters the Vessel)
    • -
    • ‘O’: Output point (i.e.: where the LOS exits the Vessel)
    • -
    • ‘R’: Point of minimal major radius R (only for Vessel of Type=’Tor’)
    • -
    • ‘P’: Point of used for impact parameter (i.e.: minimal distance to reference point Sino_RefPt)
    • -
    -
    -
    -
  • -
  • Lplot (str) – Flag specifying whether to plot the full LOS (‘Tot’: from starting point output point) or only the fraction inside the vessel (‘In’: from input to output point)
  • -
  • EltVes (str) – Flag specifying the elements of the Vessel to be plotted, fed to plot()
  • -
  • Leg (str) – Legend to be used to identify this LOS, if Leg=’’ the LOS name is used
  • -
  • Ldict (dict / None) – Dictionary of properties used for plotting the polygon, fed to plt.Axes.plot() or plt.plot_surface() if Proj=‘3d’, set to ToFu_Defauts.py if None
  • -
  • MdictD (dict) – Dictionary of properties used for plotting point ‘D’, fed to plt.Axes.plot()
  • -
  • MdictI (dict) – Dictionary of properties used for plotting point ‘I’, fed to plt.Axes.plot()
  • -
  • MdictO (dict) – Dictionary of properties used for plotting point ‘O’, fed to plt.Axes.plot()
  • -
  • MdictR (dict) – Dictionary of properties used for plotting point ‘R’, fed to plt.Axes.plot()
  • -
  • MdictP (dict) – Dictionary of properties used for plotting point ‘P’, fed to plt.Axes.plot()
  • -
  • LegDict (dict or None) – Dictionary of properties used for plotting the legend, fed to plt.legend(), the legend is not plotted if None
  • -
  • Vesdict (dict) – Dictionary of kwdargs to fed to plot(), and ‘EltVes’ is used instead of ‘Elt’
  • -
  • draw (bool) – Flag indicating whether the fig.canvas.draw() shall be called automatically
  • -
  • a4 (bool) – Flag indicating whether the figure should be plotted in a4 dimensions for printing
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

La (list / plt.Axes) – Handles of the axes used for plotting (list if several axes where used)

-
-
- -
-
-plot_Sinogram(Proj='Cross', ax=None, Elt='LV', Sketch=True, Ang='theta', AngUnit='rad', Ldict={'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, Vdict={'edgecolor': (0.8, 0.8, 0.8, 1.0), 'linewidth': 1, 'linestyle': 'solid', 'facecolor': (0.8, 0.8, 0.8, 1.0)}, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, draw=True, a4=False, Test=True)[source]¶
-

Plot the sinogram of the vessel polygon, by computing its envelopp in a cross-section, can also plot a 3D version of it

-

Plot the LOS in projection space (where sinograms are plotted) as a point. -You can plot the conventional projection-space (in 2D in a cross-section), or a 3D extrapolation of it, where the third coordinate is provided by the angle that the LOS makes with the cross-section plane (useful in case of multiple LOS with a partially tangential view).

- --- - - - - - -
Parameters:
    -
  • Proj (str) – Flag indicating whether to plot a classic sinogram (‘Cross’) from the vessel cross-section (assuming 2D), or an extended 3D version (‘3d’) of it with additional angle
  • -
  • ax (None or plt.Axes) – The axes on which the plot should be done, if None a new figure and axes is created
  • -
  • Elt (str) –
    -
    Flag indicating which elements to plot, each capital letter stands for one element
    -
      -
    • ‘L’: LOS
    • -
    • ‘V’: Vessel
    • -
    -
    -
    -
  • -
  • Ang (str) – Flag indicating which angle to use for the impact parameter, the angle of the line itself (xi) or of its impact parameter (theta)
  • -
  • AngUnit (str) – Flag for the angle units to be displayed, ‘rad’ for radians or ‘deg’ for degrees
  • -
  • Sketch (bool) – Flag indicating whether a small skecth showing the definitions of angles ‘theta’ and ‘xi’ should be included or not
  • -
  • Ldict (dict) – Dictionary of properties used for plotting the LOS point, fed to plt.plot() if Proj=’Cross’ and to plt.plot_surface() if Proj=‘3d’
  • -
  • Vdict (dict) – Dictionary of properties used for plotting the polygon envelopp, fed to plt.plot() if Proj=’Cross’ and to plt.plot_surface() if Proj=‘3d’
  • -
  • LegDict (None or dict) – Dictionary of properties used for plotting the legend, fed to plt.legend(), the legend is not plotted if None
  • -
  • draw (bool) – Flag indicating whether to draw the figure
  • -
  • a4 (bool) – Flag indicating whether the figure should be plotted in a4 dimensions for printing
  • -
  • Test (bool) – Flag indicating whether the inputs shall be tested for conformity
  • -
-
Returns:

ax (plt.Axes) – The axes used to plot

-
-
- -
-
-save(SaveName=None, Path=None, Mode='npz', compressed=False)[source]¶
-

Save the object in folder Name, under file name SaveName, using specified mode

-

Most tofu objects can be saved automatically as numpy arrays (.npz, recommended) at the default location (recommended) by simply calling self.save()

- --- - - - -
Parameters:
    -
  • SaveName (None / str) – The name to be used for the saved file, if None (recommended) uses self.Id.SaveName
  • -
  • Path (None / str) – Path specifying where to save the file, if None (recommended) uses self.Id.SavePath
  • -
  • Mode (str) – Flag specifying whether to save the object as a numpy array file (‘.npz’, recommended) or an object using cPickle (not recommended, heavier and may cause retro-compatibility issues)
  • -
  • compressed (bool) – Flag, used when Mode=’npz’, indicating whether to use np.savez or np.savez_compressed (slower saving and loading but smaller files)
  • -
-
-
- -
- -
-
-class tofu.geom.GLOS(Id, LLOS, Ves=None, Sino_RefPt=None, Type=None, Exp=None, Diag=None, shot=None, arrayorder='C', Clock=False, dtime=None, dtimeIn=False, SavePath=None)[source]¶
-

An object regrouping a group of LOS objects with some common features (e.g.: all belong to the same camera) and the same Ves object, provides methods for common computing and plotting

-

Usually LOS correspond to detectors which are naturally grouped in ‘cameras’ (sets of detectors located in the same place or sharing an aperture or a data acquisition system). -The GLOS object provided by tofu provides the object-oriented equivalent. -The GLOS objects provides the same methods as the LOS objects, plus extra methods for fast handling or selecting of the whole set. -Note that you must first create each LOS independently and then provide them as a list argument to a GLOS object.

- --- - - - -
Parameters:
    -
  • Id (str / tfpf.ID) – A name string or a pre-built tfpf.ID class to be used to identify this particular instance, if a string is provided, it is fed to tfpf.ID()
  • -
  • LLOS (list / :class:'LOS') – List of LOS instances with the same Ves instance
  • -
  • Type (None) – (not used in the current version)
  • -
  • Exp (None / str) – Experiment to which the Lens belongs, should be identical to Ves.Id.Exp if Ves is provided, if None and Ves is provided, Ves.Id.Exp is used
  • -
  • Diag (None / str) – Diagnostic to which the Lens belongs
  • -
  • shot (None / int) – Shot number from which this Lens is usable (in case its position was changed from a previous configuration)
  • -
  • Sino_RefPt (None / iterable) – If provided, array of size=2 containing the (R,Z) (for ‘Tor’ Type) or (Y,Z) (for ‘Lin’ Type) coordinates of the reference point for the sinogram
  • -
  • arrayorder (str) – Flag indicating whether the attributes of type=np.ndarray (e.g.: Poly) should be made C-contiguous (‘C’) or Fortran-contiguous (‘F’)
  • -
  • SavePath (None / str) – If provided, forces the default saving path of the object to the provided value
  • -
  • None / dtm.datetime (dtime) – A time reference to be used to identify this particular instance (used for debugging mostly)
  • -
  • bool (dtimeIn) – Flag indicating whether dtime should be included in the SaveName (used for debugging mostly)
  • -
-
-
-
-plot(Lax=None, Proj='All', Lplot='Tot', Elt='LDIORP', EltVes='', Leg='', Ldict={'lw': 2, 'c': 'k'}, MdictD={'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, MdictI={'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, MdictO={'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, MdictR={'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, MdictP={'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, ind=None, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In', Vesdict={'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'BsdictHor': {'c': 'b', 'ls': 'dashed'}, 'Bvdict': {'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, 'Lim': [1.5707963267948966, 6.283185307179586], 'Test': True, 'Proj': 'All', 'IdictHor': {'c': 'k', 'ls': 'dashed'}, 'Elt': 'PIBsBvV', 'Pdict': None, 'Vdict': {'color': 'r', 'scale': 10}, 'Idict': {'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, 'Bsdict': {'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, 'Lax': None, 'BvdictHor': {'c': 'g', 'ls': 'dashed'}, 'Nstep': 50}, draw=True, a4=False, Test=True)[source]¶
-

Plot the GLOS, with a cross-section view, a horizontal view or both, and optionally the Ves object associated to it.

-

Plot all the LOS of the GLOS, or only a selection of them (using the same parameters as self.select()).

- --- - - - - - -
Parameters:
    -
  • Lax (list or plt.Axes) – The axes to be used for plotting (provide a list of 2 axes if Proj=’All’), if None a new figure with axes is created
  • -
  • Proj (str) – Flag specifying the kind of projection used for the plot (‘Cross’ for a cross-section, ‘Hor’ for a horizontal plane, ‘All’ both and ‘3d’ for 3d)
  • -
  • Elt (str) –
    -
    Flag specifying which elements to plot, each capital letter corresponds to an element
    -
      -
    • ‘L’: LOS
    • -
    • ‘D’: Starting point of the LOS
    • -
    • ‘I’: Input point (i.e.: where the LOS enters the Vessel)
    • -
    • ‘O’: Output point (i.e.: where the LOS exits the Vessel)
    • -
    • ‘R’: Point of minimal major radius R (only for Vessel of Type=’Tor’)
    • -
    • ‘P’: Point of used for impact parameter (i.e.: minimal distance to reference point ImpRZ)
    • -
    -
    -
    -
  • -
  • Lplot (str) – Flag specifying whether to plot the full LOS (‘Tot’: from starting point output point) or only the fraction inside the vessel (‘In’: from input to output point)
  • -
  • EltVes (str) – Flag specifying the elements of the Vessel to be plotted, fed to plot()
  • -
  • Leg (str) – Legend to be used to identify this LOS, if Leg=’’ the LOS name is used
  • -
  • Ldict (dict or None) – Dictionary of properties used for plotting the polygon, fed to plt.Axes.plot() or plt.plot_surface() if Proj=‘3d’, set to ToFu_Defauts.py if None
  • -
  • MdictD (dict) – Dictionary of properties used for plotting point ‘D’, fed to plt.Axes.plot()
  • -
  • MdictI (dict) – Dictionary of properties used for plotting point ‘I’, fed to plt.Axes.plot()
  • -
  • MdictO (dict) – Dictionary of properties used for plotting point ‘O’, fed to plt.Axes.plot()
  • -
  • MdictR (dict) – Dictionary of properties used for plotting point ‘R’, fed to plt.Axes.plot()
  • -
  • MdictP (dict) – Dictionary of properties used for plotting point ‘P’, fed to plt.Axes.plot()
  • -
  • LegDict (dict or None) – Dictionary of properties used for plotting the legend, fed to plt.legend(), the legend is not plotted if None
  • -
  • Vesdict (dict) – Dictionary of kwdargs to fed to plot(), and ‘EltVes’ is used instead of ‘Elt’
  • -
  • Lim (list or tuple) – Array of a lower and upper limit of angle (rad.) or length for plotting the ‘3d’ Proj
  • -
  • draw (bool) – Flag indicating whether the fig.canvas.draw() shall be called automatically
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
  • None or np.ndarray (ind) – Array of indices (int or bool) of the LOS to be plotted if only some of them are to be plotted
  • -
  • kwdargs – kwdargs to be fed to GLOS.select() if ind=None and only a fraction of the LOS are to be plotted
  • -
-
Returns:

La (list or plt.Axes) – Handles of the axes used for plotting (list if several axes where used)

-
-
- -
-
-plot_Sinogram(Proj='Cross', ax=None, Elt='LV', Sketch=True, Ang='theta', AngUnit='rad', Ldict={'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, Vdict={'edgecolor': (0.8, 0.8, 0.8, 1.0), 'linewidth': 1, 'linestyle': 'solid', 'facecolor': (0.8, 0.8, 0.8, 1.0)}, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, draw=True, a4=False, Test=True, ind=None, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In')[source]¶
-

Plot the sinogram of the vessel polygon, by computing its envelopp in a cross-section, can also plot a 3D version of it

-

Plot all the LOS of the GLOS, or only a selection of them in projection space

- --- - - - - - -
Parameters:
    -
  • Proj (str) – Flag indicating whether to plot a classic sinogram (‘Cross’) from the vessel cross-section (assuming 2D), or an extended 3D version ‘3d’ of it with additional angle, default: ‘Cross’
  • -
  • ax (None or plt.Axes) – The axes on which the plot should be done, if None a new figure and axes is created, default: None
  • -
  • Elt (str) –
    -
    Flag indicating which elements to plot, each capital letter stands for one element, default: ‘LV’
    -
      -
    • ‘L’: LOS
    • -
    • ‘V’: Vessel
    • -
    -
    -
    -
  • -
  • Ang (str) – Flag indicating which angle to use for the impact parameter, the angle of the line itself (xi) or of its impact parameter (theta), default: ‘theta’
  • -
  • AngUnit (str) – Flag for the angle units to be displayed, ‘rad’ for radians or ‘deg’ for degrees, default: ‘rad’
  • -
  • Sketch (bool) – Flag indicating whether a small skecth showing the definitions of angles ‘theta’ and ‘xi’ should be included or not
  • -
  • Ldict (dict) – Dictionary of properties used for plotting the LOS point, fed to plt.plot() if Proj=’Cross’ and to plt.plot_surface() if Proj=‘3d’, default: see ToFu_Defaults.py
  • -
  • Vdict (dict) – Dictionary of properties used for plotting the polygon envelopp, fed to plt.plot() if Proj=’Cross’ and to plt.plot_surface() if Proj=‘3d’, default: see ToFu_Defaults.py
  • -
  • LegDict (None or dict) – Dictionary of properties used for plotting the legend, fed to plt.legend(), the legend is not plotted if None, default: see ToFu_Defaults.py
  • -
  • draw (bool) – Flag indicating whether to draw the figure, default: True
  • -
  • Test (bool) – Flag indicating whether the inputs shall be tested for conformity, default: True
  • -
-
Returns:

ax (plt.Axes) – The axes used to plot

-
-
- -
-
-save(SaveName=None, Path=None, Mode='npz', compressed=False)[source]¶
-

Save the object in folder Name, under file name SaveName, using specified mode

-

Most tofu objects can be saved automatically as numpy arrays (.npz, recommended) at the default location (recommended) by simply calling self.save()

- --- - - - -
Parameters:
    -
  • SaveName (None / str) – The name to be used for the saved file, if None (recommended) uses self.Id.SaveName
  • -
  • Path (None / str) – Path specifying where to save the file, if None (recommended) uses self.Id.SavePath
  • -
  • Mode (str) – Flag specifying whether to save the object as a numpy array file (‘.npz’, recommended) or an object using cPickle (not recommended, heavier and may cause retro-compatibility issues)
  • -
  • compressed (bool) – Flag, used when Mode=’npz’, indicating whether to use np.savez or np.savez_compressed (slower saving and loading but smaller files)
  • -
-
-
- -
-
-select(Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In', Out=<type 'bool'>)[source]¶
-

Return the indices or instances of all instances matching the specified criterion.

-

The selection can be done according to 2 different mechanism (1) and (2).

-

For mechanism (1): the user provides the value (Val) that the specified criterion (Crit) should take for a LOS to be selected. -The criteria are typically attributes of the self.Id attribute (i.e.: name of the instance, or user-defined attributes like the camera head...)

-

For mechanism (2), used if Val=None: the user provides a str expression (or a list of such) to be fed to eval(), used to check on quantitative criteria, placed before the criterion value (e.g.: ‘not ‘ or ‘<=’). -Another str or list of str expressions can be provided that will be placed after the criterion value.

-

Other parameters are used to specify logical operators for the selection (match any or all the criterion...) and the type of output.

- --- - - - - - -
Parameters:
    -
  • Crit (str) – Flag indicating which criterion to use for discrimination -Can be set to any attribute of the tofu.pathfile.ID class (e.g.: ‘Name’,’SaveName’,’SavePath’...) or any key of ID.USRdict (e.g.: ‘Exp’...)
  • -
  • Val (list, str or None) – The value to match for the chosen criterion, can be a list of different values -Used for selection mechanism (1)
  • -
  • PreExp (list, str or None) – A str of list of str expressions to be fed to eval(), used to check on quantitative criteria, placed before the criterion value (e.g.: ‘not ‘) -Used for selection mechanism (2)
  • -
  • PostExp (list, str or None) – A str of list of str expressions to be fed to eval(), used to check on quantitative criteria, placed after the criterion value (e.g.: ‘>=5.’) -Used for selection mechanism (2)
  • -
  • Log (str) – Flag indicating whether the criterion shall match all provided values or one of them (‘any’ or ‘all’)
  • -
  • InOut (str) – Flag indicating whether the returned indices are the ones matching the criterion (‘In’) or the ones not matching it (‘Out’)
  • -
  • Out (type / str) – Flag indicating in which form shall the result be returned, as an array of integer indices (int), an array of booleans (bool), a list of names (‘Names’) or a list of instances (‘LOS’)
  • -
-
Returns:

ind (list / np.ndarray) – The computed output (array of index, list of names or instances depending on parameter ‘Out’)

-
-

Examples

-
>>> import tofu.geom as tfg
->>> ves = tfg.Ves('ves', [[0.,1.,1.,0.],[0.,0.,1.,1.]], DLong=[-1.,1.], Type='Lin', Exp='Misc', shot=0)
->>> los1 = tfg.LOS('los1', ([0.,-0.1,-0.1],[0.,1.,1.]), Ves=ves, Exp='Misc', Diag='D', shot=0)
->>> los2 = tfg.LOS('los2', ([0.,-0.1,-0.1],[0.,0.5,1.]), Ves=ves, Exp='Misc', Diag='D', shot=1)
->>> los3 = tfg.LOS('los3', ([0.,-0.1,-0.1],[0.,1.,0.5]), Ves=ves, Exp='Misc', Diag='D', shot=1)
->>> glos = tfg.GLOS('glos', [los1,los2,los3])
->>> ind = glos.select(Val=['los1','los3'], Log='any', Out='LOS')
->>> print [ii.Id.Name for ii in ind]
-['los1', 'los3']
->>> ind = glos.select(Val=['los1','los3'], Log='any', InOut='Out', Out=int)
-array([1])
-
-
-
- -
- -
-
-class tofu.geom.Lens(Id, O, nIn, Rad, F1, F2=inf, R1=None, R2=None, dd=None, Ves=None, Type='Sph', Exp=None, Diag=None, shot=None, arrayorder='C', Clock=False, SavePath=None, dtime=None, dtimeIn=False)[source]¶
-

A Lens class with all geometrical data and built-in methods, defined as a planar polygon in 3D cartesian coordinates, with optional Ves object

-

A Lens object is useful for implementing one of the two possible optical arrangements available in tofu. -A Lens (implicitly convergent) is used for focusing incoming light on a detector of reduced size (i.e.g: like the end of an optic fiber cable). -In this case, anmd in its current version, tofu only handles spherical lenses and assumes that the detector has a circular active surface, centered on the same axis as the lens and located in its focal plane.

- --- - - - -
Parameters:
    -
  • Id (str or tfpf.ID) – A name string or a pre-built tfpf.ID class to be used to identify this particular instance, if a string is provided, it is fed to tfpf.ID()
  • -
  • O (iterable) – Array of 3D cartesian coordinates of the center of the Lens
  • -
  • nIn (iterable) – Array of 3D cartesian coordiantes of the vector defining the axis of the Lens
  • -
  • Rad (float) – Radius of the Lens
  • -
  • F1 (float) – Focal length of the Lens, on the detector side
  • -
  • F2 (float) – Focal length of the Lens, on the plasma side (only np.inf supported so far)
  • -
  • Type (str) – Flag indicating the type of Lens (only ‘Sph’ - for spherical lens - supported so far)
  • -
  • R1 (None or float) – Radius of the first face of the Lens, for full description only
  • -
  • R2 (None or float) – Radius of the second face of the Lens, for full description only
  • -
  • dd (None or float) – Width of the Lens along its axis, for full description only
  • -
  • Ves (Ves) – Ves object to which the aperture is assigned
  • -
  • Exp (None or str) – Experiment to which the Lens belongs, should be identical to Ves.Id.Exp if Ves is provided, if None and Ves is provided, Ves.Id.Exp is used
  • -
  • Diag (None or str) – Diagnostic to which the Lens belongs
  • -
  • shot (None or int) – Shot number from which this Lens is usable (in case its position was changed from a previous configuration)
  • -
  • SavePath (None / str) – If provided, forces the default saving path of the object to the provided value
  • -
  • Clock (bool) – Flag indicating whether the input polygon should be made clockwise (True) or counter-clockwise (False), default: False
  • -
  • arrayorder (str) – Flag indicating whether the attributes of type=np.ndarray (e.g.: Poly) should be made C-contiguous (‘C’) or Fortran-contiguous (‘F’), default: ‘C’
  • -
  • dtime (None or dtm.datetime) – A time reference to be used to identify this particular instance (used for debugging mostly), default: None
  • -
  • dtimeIn (bool) – Flag indicating whether dtime should be included in the SaveName (used for debugging mostly), default: False
  • -
-
-
-
-Poly¶
-

Return a simple representation of the Lens as a 3D circle (if Lens.Type=’Sph’)

-
- -
-
-plot(Lax=None, Proj='All', Elt='PV', EltVes='', Leg=None, LVIn=0.1, Pdict={'lw': 2, 'c': 'k', 'ls': 'solid'}, Vdict={'color': 'r', 'lw': 2, 'ls': 'solid'}, Vesdict={'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'BsdictHor': {'c': 'b', 'ls': 'dashed'}, 'Bvdict': {'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, 'Lim': [1.5707963267948966, 6.283185307179586], 'Test': True, 'Proj': 'All', 'IdictHor': {'c': 'k', 'ls': 'dashed'}, 'Elt': 'PIBsBvV', 'Pdict': None, 'Vdict': {'color': 'r', 'scale': 10}, 'Idict': {'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, 'Bsdict': {'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, 'Lax': None, 'BvdictHor': {'c': 'g', 'ls': 'dashed'}, 'Nstep': 50}, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, draw=True, a4=False, Test=True)[source]¶
-

Plot the Lens object, optionally with the associated Ves object

-

Plot the chosen projections of the Lens polygon.

- --- - - - - - -
Parameters:
    -
  • Lax (list or plt.Axes) – The axes to be used for plotting (provide a list of 2 axes if Proj=’All’), if None a new figure with axes is created
  • -
  • Proj (str) – Flag specifying the kind of projection used for the plot (‘Cross’ for a cross-section, ‘Hor’ for a horizontal plane, ‘All’ both and ‘3d’ for 3d)
  • -
  • Elt (str) –
    -
    Flag specifying which elements to plot, each capital letter corresponds to an element
    -
      -
    • ‘P’: polygon
    • -
    • ‘V’: vector perpendicular to the polygon, oriented towards the interior of the Vessel
    • -
    -
    -
    -
  • -
  • EltVes (str) – Flag specifying the elements of the Vessel to be plotted, fed to plot()
  • -
  • Leg (str) – Legend to be used to identify this LOS, if Leg=’’ the LOS name is used
  • -
  • LVIn (float) – Length (in data coordinates, meters) of the vector ‘V’
  • -
  • Pdict (dict) – Dictionary of properties used for plotting the polygon, fed to plt.Axes.plot() or plt.plot_surface() if Proj=‘3d’, set to ToFu_Defauts.py if None (default: None)
  • -
  • Vdict (dict) – Dictionary of properties used for plotting vector ‘V’, fed to plt.Axes.plot()
  • -
  • Vesdict (dict) – Dictionary of kwdargs to fed to plot(), and ‘EltVes’ is used instead of ‘Elt’
  • -
  • LegDict (dict or None) – Dictionary of properties used for plotting the legend, fed to plt.legend(), the legend is not plotted if None
  • -
  • draw (bool) – Flag indicating whether the fig.canvas.draw() shall be called automatically
  • -
  • a4 (bool) – Flag indicating whether the figure should be a4 size (for printing or saving as pdf for example)
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

Lax (list or plt.Axes) – Handles of the axes used for plotting (list if several axes where used)

-
-
- -
-
-plot_alone(ax=None, V='red', nin=1.5, nout=1.0, Lmax='F', V_NP=50, src=None, draw=True, a4=False, Test=True)[source]¶
-

Plot a 2D representation of the Lens object, optionally with 2D viewing cone and rays of several sources in the plane, either with reduced of full representation

-

Plot a sketch of the Lens, optionally with ray-traced incoming light beams. -This plotting routine does not consider any syurrounding and plots everything assuming the origine of the coordinate system is on the Lens

- --- - - - - - -
Parameters:
    -
  • ax (None or plt.Axes) – Axes to be used for plotting, if None a new figure with axes is created (default: None)
  • -
  • V (str) – Flag indicating whether the Lens should be considered in its reduced geometry model (‘red’) or its full version (‘full’), default: ‘red’
  • -
  • nin (float) – Value of the optical index to be used inside the Lens (useful when V=’full’ only)
  • -
  • nout (float) – Value of the optical index to be used outside the Lens (useful when V=’full’ only)
  • -
  • Lmax (float) – Maximum length on which the source beams should be plotted after going through the Lens, if ‘F’ all beams are plotted up to the focal plane
  • -
  • V_NP (int) – Number of points to be used to plot each circle fraction of the full version of the Lens geometry (useful when V=’full’ only)
  • -
  • src (None or dict) –
    -
    Dictionary of parameters for the source of ray beams:
    -
      -
    • ‘Pt’: iterable of len()=2 with the 2D cartesian coordinates of the point where the source should be located with reference to the Lens center (0,0) and axis (1,0)
    • -
    • ‘Type’: Flag indicating whether the source should a point (‘Pt’) or an array of parallel beams perpendicular to a plane passing through Pt
    • -
    • ‘nn’: iterable of len()=2 with the 2D cartesian coordinates of a vector directing the array of parallel beams
    • -
    • ‘NP’: int, number of beams to be plotted from the source
    • -
    -
    -
    -
  • -
  • draw (bool) – Flag indicating whether the fig.canvas.draw() shall be called automatically, default: True
  • -
  • a4 (bool) – Flag indicating whether the figure should be a4 size (for printing or saving as pdf for example)
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity, default: True
  • -
-
Returns:

ax (plt.Axes) – Handle of the axes used for plotting

-
-
- -
-
-save(SaveName=None, Path=None, Mode='npz', compressed=False)[source]¶
-

Save the object in folder Name, under file name SaveName, using specified mode

-

Most tofu objects can be saved automatically as numpy arrays (.npz, recommended) at the default location (recommended) by simply calling self.save()

- --- - - - -
Parameters:
    -
  • SaveName (None / str) – The name to be used for the saved file, if None (recommended) uses self.Id.SaveName
  • -
  • Path (None / str) – Path specifying where to save the file, if None (recommended) uses self.Id.SavePath
  • -
  • Mode (str) – Flag specifying whether to save the object as a numpy array file (‘.npz’, recommended) or an object using cPickle (not recommended, heavier and may cause retro-compatibility issues)
  • -
  • compressed (bool) – Flag, used when Mode=’npz’, indicating whether to use np.savez or np.savez_compressed (slower saving and loading but smaller files)
  • -
-
-
- -
- -
-
-class tofu.geom.Apert(Id, Poly, Type=None, Ves=None, Exp=None, Diag=None, shot=None, arrayorder='C', Clock=False, SavePath=None, dtime=None, dtimeIn=False)[source]¶
-

An Aperture class with all geometrical data and built-in methods, defined as a planar polygon in 3D cartesian coordinates, with optional Ves object

-

An Apert object is useful for implementing one of the two possible optical arrangements available in tofu. -An aperture is modelled as a planar polygon (of any non self-intersecting shape) through which light can pass (fully transparent) and around which light cannot pass (fully non-transparent). -One of the added-values of tofu is that it allows to create several non-coplanar aperture and assign them to a single detector. It then computes automatically the volume of sight by assuming that a detectable photon should go through all apertures.

- --- - - - -
Parameters:
    -
  • Id (str or tfpf.ID) – A name string or a pre-built tfpf.ID class to be used to identify this particular instance, if a string is provided, it is fed to tfpf.ID()
  • -
  • Poly (np.ndarray) – An array (2,N) or (N,2) defining the contour of the aperture in 3D (X,Y,Z) cartesian coordinates, if not closed, will be closed automatically
  • -
  • Ves (Ves) – Ves object to which the aperture is assigned
  • -
  • Type (None or str) – Flag specifying the type of Apert
  • -
  • Exp (None or str) – Experiment to which the Lens belongs, should be identical to Ves.Id.Exp if Ves is provided, if None and Ves is provided, Ves.Id.Exp is used
  • -
  • Diag (None or str) – Diagnostic to which the Lens belongs
  • -
  • shot (None or int) – Shot number from which this Lens is usable (in case its position was changed from a previous configuration)
  • -
  • SavePath (None / str) – If provided, forces the default saving path of the object to the provided value
  • -
  • Clock (bool) – Flag indicating whether the input polygon should be made clockwise (True) or counter-clockwise (False)
  • -
  • dtime (None or dtm.datetime) – A time reference to be used to identify this particular instance (mostly used for debugging)
  • -
  • dtimeIn (bool) – Flag indicating whether dtime should be included in the SaveName (mostly used for debugging)
  • -
-
-
-
-BaryS¶
-

Return the (surfacic) center of mass of the polygon (in 3D cartesian coordinates)

-
- -
-
-Id¶
-

Return the associated tfpf.ID object

-
- -
-
-NP¶
-

Return the number of points defining the polygon

-
- -
-
-Poly¶
-

Return the planar polygon defining the aperture (in 3D cartesian coordinates)

-
- -
-
-Surf¶
-

Return the area of the polygon

-
- -
-
-Ves¶
-

Return the associated Ves object

-
- -
-
-nIn¶
-

Return the normalized vector perpendicular to the polygon surface and oriented towards the interior of the associated vessel (in 3D cartesian coordinates)

-
- -
-
-plot(Lax=None, Proj='All', Elt='PV', EltVes='', Leg=None, LVIn=0.1, Pdict={'lw': 2, 'c': 'k', 'ls': 'solid'}, Vdict={'color': 'r', 'lw': 2, 'ls': 'solid'}, Vesdict={'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'BsdictHor': {'c': 'b', 'ls': 'dashed'}, 'Bvdict': {'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, 'Lim': [1.5707963267948966, 6.283185307179586], 'Test': True, 'Proj': 'All', 'IdictHor': {'c': 'k', 'ls': 'dashed'}, 'Elt': 'PIBsBvV', 'Pdict': None, 'Vdict': {'color': 'r', 'scale': 10}, 'Idict': {'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, 'Bsdict': {'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, 'Lax': None, 'BvdictHor': {'c': 'g', 'ls': 'dashed'}, 'Nstep': 50}, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, draw=True, a4=False, Test=True)[source]¶
-

Plot the Apert, with a cross-section view, a horizontal view or both, or a 3d view, and optionally the Ves object associated to it.

-

Plot the desired projections of the polygon defining the aperture.

- --- - - - - - -
Parameters:
    -
  • list or plt.Axes (Lax) – The axes to be used for plotting (provide a list of 2 axes if Proj=’All’), if None a new figure with axes is created
  • -
  • str (Leg) – Flag specifying the kind of projection used for the plot (‘Cross’ for a cross-section, ‘Hor’ for a horizontal plane, ‘All’ both and ‘3d’ for 3d)
  • -
  • str
    -
    Flag specifying which elements to plot, each capital letter corresponds to an element
    -
      -
    • ‘P’: polygon
    • -
    • ‘V’: vector perpendicular to the polygon, oriented towards the interior of the Vessel
    • -
    -
    -
    -
  • -
  • str – Flag specifying the elements of the Vessel to be plotted, fed to plot()
  • -
  • str – Legend to be used to identify this LOS, if Leg=’’ the LOS name is used
  • -
  • float (LVIn) – Length (in data coordinates, meters) of the vector ‘V’
  • -
  • dict (Vesdict) – Dictionary of properties used for plotting the polygon, fed to plt.Axes.plot() or plt.plot_surface() if Proj=‘3d’, set to ToFu_Defauts.py if None
  • -
  • dict – Dictionary of properties used for plotting vector ‘V’, fed to plt.Axes.plot()
  • -
  • dict – Dictionary of kwdargs to fed to plot(), and ‘EltVes’ is used instead of ‘Elt’
  • -
  • dict or None (LegDict) – Dictionary of properties used for plotting the legend, fed to plt.legend(), the legend is not plotted if None
  • -
  • bool (Test) – Flag indicating whether the fig.canvas.draw() shall be called automatically
  • -
  • bool – Flag indicating whether the figure should be a4 size (for printing or saving as pdf for example)
  • -
  • bool – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

La list or plt.Axes – Handles of the axes used for plotting (list if several axes where used)

-
-
- -
-
-save(SaveName=None, Path=None, Mode='npz', compressed=False)[source]¶
-

Save the object in folder Name, under file name SaveName, using specified mode

-

Most tofu objects can be saved automatically as numpy arrays (.npz, recommended) at the default location (recommended) by simply calling self.save()

- --- - - - -
Parameters:
    -
  • SaveName (None / str) – The name to be used for the saved file, if None (recommended) uses self.Id.SaveName
  • -
  • Path (None / str) – Path specifying where to save the file, if None (recommended) uses self.Id.SavePath
  • -
  • Mode (str) – Flag specifying whether to save the object as a numpy array file (‘.npz’, recommended) or an object using cPickle (not recommended, heavier and may cause retro-compatibility issues)
  • -
  • compressed (bool) – Flag, used when Mode=’npz’, indicating whether to use np.savez or np.savez_compressed (slower saving and loading but smaller files)
  • -
-
-
- -
- -
-
-class tofu.geom.Detect(Id, Poly, Optics=None, Ves=None, Sino_RefPt=None, CalcEtend=True, CalcSpanImp=True, CalcCone=True, CalcPreComp=True, Calc=True, Verb=True, Etend_Method='quad', Etend_RelErr=0.001, Etend_dX12=[0.01, 0.01], Etend_dX12Mode='rel', Etend_Ratio=0.02, Colis=True, LOSRef='Cart', Cone_DRY=0.0025, Cone_DXTheta=None, Cone_DZ=0.0025, Cone_NPsi=20, Cone_Nk=60, arrayorder='C', Clock=False, Type=None, Exp=None, Diag=None, shot=None, dtime=None, dtimeIn=False, SavePath=None)[source]¶
-

A Detector class with all geometrical data and built-in methods, defined as a planar polygon in 3D cartesian coordinates, with optional aperture objects

-

A Detect object is at the core of tofu’s added value and is mostly defined by a 3D planar polygon of any non self-intersecting shape representing the active surface of a detector. -It can then be associated to optics (a Lens or a list of Apert objects) and to a Ves to automatically compute a natural :class:’LOS’ (with its etendue) and, most importantly, a proper VOS (that can be discretized for 3D numerical integration). -It can be 2 different types: either ‘Circ’ if it is associated to a Lens (in which case it is simply defined by radius and is assumed to be circular and placed at the focal plane of the Lens object), or None in the more general case in which it is associated to a set of apertures. -Most of the commonly used quantities are automatically calculated (etendue of the LOS, VOS...) and it comes with built-in methods for plotting and computing synthetic data.

-

To compute the VOS, tofu tests all points inside a 3D grid to see if each point is visible from the detector through the apertures or not. -The meshed space is determined by the volume spanned by a LOS sampling of the VOS. -Then, a contour function is used to find the polygons limiting the cross-section and horizontal projections of the VOS. -Once computed, the viewing cones are assigned to attributes of the Detect instance.

-

In the particular case (1) when the LOS of the detector lies entirely inside one cross-section (e.g.: tomography diagnostics), tofu also computes the integral in the direction of the ignorable coordinate of the solid angle on a regular mesh (for faster computation of the geometry assuming toroidaly invariant basis functions). -This regular mesh is defined in 2D, by the distance between a mesh point and the detector (k) and by the poloidal angle between the LOS and the line going from the detector to the mesh point (psi)

- --- - - - -
Parameters:
    -
  • Id (str or tfpf.ID) – A name string or a pre-built tfpf.ID class to be used to identify this particular instance, if a string is provided, it is fed to tfpf.ID()
  • -
  • Poly (dict or np.ndarray) –
    -
    Contains the information regarding the geometry of the Detect object
    -
      -
    • np.ndarray: (2,N) or (N,2) defining the contour of the detector active surface in 3D (X,Y,Z) cartesian coordinates, if not closed, will be closed automatically, if Type=None
    • -
    • dict: dictionary of properties for a circular detector placed in the focal plane of a Lens on its axis, contains field ‘Rad’=float (radius), if Optics is Lens and Type=’Circ’
    • -
    -
    -
    -
  • -
  • Optics (list or Lens) – The optics to be associated to the detector, either a spherical Lens or a list of apertures Apert
  • -
  • Ves (Ves or None) – Ves object to which the detector is assigned
  • -
  • Sino_RefPt (np.ndarray or None) – Array of size=2 containing the (R,Z) (for ‘Tor’ Type) or (Y,Z) (for ‘Lin’ Type) coordinates of the reference point for the sinogram
  • -
  • CalcEtend (bool) – Flag indicating whether to compute the etendue
  • -
  • CalcSpanImp (bool) – Flag indicating whether to compute the maximal span of the viewing volume
  • -
  • CalcCone (bool) – Flag indicating whether to compute the viewing volume or viewing cone and its two projections
  • -
  • CalcPreComp (bool) – Flag indicating whether to pre-compute a set of pre-defined points inside the viewing volume for faster computation of signal from 3D emissivity
  • -
  • Calc (bool) – Flag indicating whether to compute all the above
  • -
  • Verb (bool) – Flag indicating whether the creation of the object should be verbose (comments for each step)
  • -
  • Etend_Method (str) – Flag indicating which numerical integration to use for the computation of the etendue (picked from scipy.integrate : ‘quad’, ‘simps’, ‘trapz’)
  • -
  • Etend_RelErr (float) – If Etend_Method=’quad’, specifies the maximum relative error to be tolerated on the value of the integral (i.e.: etendue)
  • -
  • Etend_dX12 (list) – If Etend_Method in [‘simps’,’trapz’], which implies a discretization of the plane perpendicular to the LOS, specifies the resolution of the discretization
  • -
  • Etend_dX12Mode (str) – If Etend_Method in [‘simps’,’trapz’], specifies whether Etend_dX12 should be iunderstood as an absolute distance (‘abs’) or a fraction of the maximum width (‘rel’)
  • -
  • Etend_Ratio (float) – The numerical integration is performed on an automatically-deterimned interval, this ratio (fraction of unity) is a safety margin to increase a bit the interval and make sure all non-zero values are included
  • -
  • Colis (bool) – Flag indicating whether the collision detection mechanism should be considered when computing the VOS
  • -
  • LOSRef (str) – Key indicating which of the LOS in the LOS dictionary should be considered as the reference LOS
  • -
  • Cone_DRY (float) – Resolution of the grid in the R (for ‘Tor’ vessel types) or Y (for ‘Lin’ vessel types) direction, in meters
  • -
  • Cone_DXTheta (float) – Resolution of the grid in the toroidal (for ‘Tor’ vessel types, in radians) or X (for ‘Lin’ vessel types, in meters) direction
  • -
  • Cone_DZ (float) – Resolution of the grid in the Z direction, in meters
  • -
  • Cone_NPsi (int) – Number of points of the regular mesh in psi direction (angle), in case (1)
  • -
  • Cone_Nk (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
  • Type (None / str) – If the detector is associated to a Lens, it should be of type ‘Circ’ (only circular shaped detectors are handled by tofu behind spherical lenses)
  • -
  • Exp (None or str) – Experiment to which the Lens belongs, should be identical to Ves.Id.Exp if Ves is provided, if None and Ves is provided, Ves.Id.Exp is used
  • -
  • Diag (None or str) – Diagnostic to which the Lens belongs
  • -
  • shot (None or int) – Shot number from which this Lens is usable (in case its position was changed from a previous configuration)
  • -
  • SavePath (None / str) – If provided, forces the default saving path of the object to the provided value
  • -
  • Clock (bool) – Flag indicating whether the input polygon should be made clockwise (True) or counter-clockwise (False), default: False
  • -
  • arrayorder (str) – Flag indicating whether the attributes of type=np.ndarray (e.g.: Poly) should be made C-contiguous (‘C’) or Fortran-contiguous (‘F’), default: ‘C’
  • -
  • dtime (None or dtm.datetime) – A time reference to be used to identify this particular instance (used for debugging mostly)
  • -
  • dtimeIn (bool) – Flag indicating whether dtime should be included in the SaveName (used for debugging mostly)
  • -
-
-
-
-BaryS¶
-

Return the (surfacic) center of mass of the polygon (in 3D cartesian coordinates)

-
- -
-
-Cone_PolyCross¶
-

Return the polygon that is the projection in a cross-section of the viewing cone

-
- -
-
-Cone_PolyHor¶
-

Return the polygon that is the projection in a horizontal plane of the viewing cone

-
- -
-
-Id¶
-

Return the associated tfpf.ID object

-
- -
-
-LOS¶
-

Return the dictionary of associated LOS objects

-
- -
-
-NP¶
-

Return the number of points defining the polygon

-
- -
-
-Optics¶
-

Return the list of associated Optics objects (Lens or list of Apert)

-
- -
-
-OpticsNb¶
-

Return the number of associated Optics

-
- -
-
-OpticsType¶
-

Return the type of associated Optics objects

-
- -
-
-Poly¶
-

Return the planar polygon defining the aperture (in 3D cartesian coordinates)

-
- -
-
-Rad¶
-

Return the radius of the polygon (if Type=’Circ’, else None)

-
- -
-
-SAngCross_Int¶
-

Return the integral of the solid angle at pre-computed points of the VOS in a cross-section projection

-
- -
-
-SAngCross_Points¶
-

Return the pre-computed points of the VOS in a cross-section projection

-
- -
-
-SAngHor_Int¶
-

Return the integral of the solid angle at pre-computed points of the VOS in a horizontal projection

-
- -
-
-SAngHor_Points¶
-

Return the pre-computed points of the VOS in a horizontal projection

-
- -
-
-Sino_RefPt¶
-

Return the coordinates (R,Z) or (Y,Z) for Ves of Type ‘Tor’ or (Y,Z) for Ves of Type ‘Lin’ of the reference point used to compute the sinogram

-
- -
-
-Surf¶
-

Return the area of the polygon

-
- -
-
-Ves¶
-

Return the associated Ves object

-
- -
-
-calc_Etendue_AlongLOS(Length='', NP=20, Modes=['trapz', 'quad'], RelErr=0.001, dX12=[0.005, 0.005], dX12Mode='abs', Ratio=0.02, Colis=True, LOSRef=None, Test=True)[source]¶
-

Return the etendue computed at different points along the LOS, with various numerical methods, with or without collision detection

-

Computing the etendue along the LOS of a Detect object can be useful for checking whether the etendue is constant (as it should be if the LOS approximation is to be used). -Cases with non-constant etendue include in particular partially obstructed VOS in the divertor region of Tokamaks. -Also useful for debugging: if the etendue is not constant but the VOS is not obstructed, something might be wrong with the computation of the etendue or with the model (e.g.: for Lens optics). -Indeed, the model implemented for a Lens is ideal, but a close look at the etendue shows that the model is not perfect (but sufficiently accurate for most uses though).

- --- - - - - - -
Parameters:
    -
  • Length (str) – Flag indicating whether to use the full length of the VOS (including partially obstructed parts: ‘’), or just the length of the LOS unil its exit point (‘LOS’).
  • -
  • NP (int) – Number of points (uniformly distributed along the LOS) where the etendue should be computed
  • -
  • Modes (list or str) – Flag or list of flags indicating which numerical integration methods shoud be used in [‘quad’,’simps’,’trapz’]
  • -
  • RelErr (float) – For ‘quad’, a positive float defining the relative tolerance allowed
  • -
  • dX12 (list) – For ‘simps’ or ‘trapz’, a list of 2 floats defining the resolution of the sampling in X1 and X2
  • -
  • dX12Mode (str) – For ‘simps’ or’trapz’, ‘rel’ or ‘abs’, if ‘rel’ the resolution dX12 is in dimensionless units in [0;1] (hence a value of 0.1 means 10 discretisation points between the extremes), if ‘abs’ dX12 is in meters
  • -
  • Ratio (float) – A float specifying the relative margin to be taken for integration boundaries
  • -
  • Colis (bool) – Flag indicating whether collision detection should be used
  • -
  • LOSRef (None or str) – Flag indicating which LOS should be used
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

    -
  • Etend (np.ndarray) – Computed etendues
  • -
  • Pts (np.ndarray) – (3,NP) array specifying the 3D (X,Y,Z) coordinates of the points along the LOS where the etendue was computed
  • -
  • kPts (np.ndarray) – (NP,) array of the distance-coordinate k along the LOS
  • -
  • LOSRef (str) – The LOS that was used
  • -
-

-
-
- -
-
-calc_SAngNb(Pts=None, Proj='Cross', Slice='Int', DRY=None, DXTheta=None, DZ=None, Colis=True)[source]¶
-

Compute the solid angle subtended by the Detect+Optics system as seen for desired points, in a slice or integrated manner

-

Mostly useful in the GDetect object when there are several detectors. -Computes, for each point in the desired projection, the total solid angle subtended by all the detectors (or its integral) and the number of detectors that ‘see’ each point.

- --- - - - - - -
Parameters:
    -
  • Pts (None / np.ndarray) – (3,N) array of cartesian (X,Y,Z) coordinates of the provided N points, if None a default set of points is computed according to DRY, DXTheta and DZ
  • -
  • Proj (str) – Flag indicating to which projection of the VOS the method should be applied
  • -
  • Slice (str) – Flag indicating whether to compute the solid angle (‘Slice’), the maximum solid angle along the ignorable coordinate (‘Max’), or the integral over the ignorable coordinate (‘Int’)
  • -
  • DRY (None / float) – Resolution (in horizontal direction of the cross-section) of the mesh to be constructed if the points are not provided
  • -
  • DXTheta (None / float) – Resolution (in ignorable coordinate direction) of the mesh to be constructed if the points are not provided
  • -
  • DZ (None / float) – Resolution (in vertical direction) of the mesh to be constructed if the points are not provided
  • -
  • Colis (bool) – Flag indicating whether collision detection should be used
  • -
-
Returns:

    -
  • SA (np.ndarray) – Array of (ND,NP) solid angle values, where ND is the number of detectors and NP the number of points
  • -
  • Nb (np.ndarray) – Array of (ND,NP) booleans, True if a point is seen by a detector
  • -
  • Pts (np.ndarray) – The computed points (in case they were not provided)
  • -
-

-
-
- -
-
-calc_SAngVect(Pts, In='(X, Y, Z)', Colis=True, Test=True)[source]¶
-

Return the Solid Angle of the Detect-Apert system as seen from the specified points, including collisions detection or not

-

Compute the solid angle and the directing vector subtended by the Detect-Optics system as seen from the desired points (provided in the specified coordinates). -This can be useful for visualizing the solid angle distribution or for computing synthetic signal from simulated emissivity in a 3D numerical integration manner. -The automtic detection of collisions with the edges of the Ves object can be switched off (not recommended).

- --- - - - - - -
Parameters:
    -
  • Pts (np.ndarray) – (2,N) or (3,N) array of coordinates of the provided N points
  • -
  • In (str) – Flag indicating in which coordinate system the Pts are provided, must be in [‘(R,Z)’,’(X,Y,Z)’,’(R,phi,Z)’]
  • -
  • Colis (bool) – Flag indicating whether collision detection should be activated
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

SAng (np.ndarray) – (N,) array of floats, the computed solid angles

-
-
- -
-
-calc_Sig(ff, extargs={}, Method='Vol', Mode='simps', PreComp=True, epsrel=0.0001, dX12=[0.005, 0.005], dX12Mode='abs', ds=0.005, dsMode='abs', MarginS=0.001, Colis=True, Test=True)[source]¶
-

Return the signal computed from an input emissivity function, using a 3D or LOS method

-

The synthetic signal resulting from a simulated emissivity can be computed automatically in several ways. -The user can choose between a VOS and a LOS approach (volume integration or line integration with etendue). -In each case the user can choose between the numerical integration method (from scipy.integrate + np.sum()). -It is possible to specify that, for a VOS approach, you want to use the pre-conputed mesh for faster computation (see set_SigPrecomp()). -For a VOS approach, the user can specify how fine the discretization should be. -The collision detection with the edges of the Ves object can be switched off (not recommended).

- --- - - - - - -
Parameters:
    -
  • ff (function) –
    -
    Input emissiviy function, should take one input as follows:
    -
      -
    • ff(Pts), where Points is a np.ndarray of shape=(3,N), with the (X,Y,Z) coordinates of any N number of points
    • -
    -
    -
    -
  • -
  • Method (str) – Flag indicating whether the spatial integration should be done with a volume (‘Vol’) or a LOS (‘LOS’) approach
  • -
  • Mode (str) – Flag indicating the numerical integration method in [‘quad’,’simps’,’trapz’,’nptrapz’,’sum’]
  • -
  • PreComp (bool) – Flag indicating whether the pre-computed grid should be used
  • -
  • epsrel (float) – Float specifying the tolerated relative error on the numerical integration, used for ‘quad’
  • -
  • dX12 (list) – Array of the 2 resolutions to be used to define the grid in a plane perpendicular to the LOS
  • -
  • dX12Mode (str) – Flag specifying whether the values in dX12 are absolute distances or relative values (i.e. fraction of the total width [0;1])
  • -
  • ds (float) – Float indicating the resolution in the longitudinal direction
  • -
  • dsMode (str) – Flag specifying whether ds is an absolute distance or relative (i.e. fraction of the total length [0;1])
  • -
  • Colis (bool) – Flag indicating whether collision detection should be used
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

Sig (float) – The computed signal

-
-
- -
-
-isInside(Points, In='(X, Y, Z)', Test=True)[source]¶
-

Return an array of indices indicating whether each point lies both in the cross-section and horizontal porojections of the viewing cone

-

Like for the Ves object, points can be provided in 2D or 3D coordinates (specified by ‘In’), and an array of booleans is returned.

- --- - - - - - -
Parameters:
    -
  • Points (np.ndarray) – (2,N) or (3,N) array of coordinates of the N points to be tested
  • -
  • In (str) –
    -
    Flag indicating in which coordinate system the Points are provided, must be in [‘(R,Z)’,’(Y,Z)’,’(X,Y)’,’(X,Y,Z)’,’(R,phi,Z)’]
    -
      -
    • ‘(R,Z)’: All points are assumed to lie in the horizontal projection, for ‘Tor’ vessel type only
    • -
    • ‘(Y,Z)’: All points are assumed to lie in the horizontal projection, for ‘Lin’ vessel type only
    • -
    • ‘(X,Y)’: All points are assumed to lie in the cross-section projection
    • -
    -
    -
    -
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

ind (np.ndarray) – (N,) array of booleans with True if a point lies inside both projections of the viewing cone

-
-
- -
-
-nIn¶
-

Return the normalized vector perpendicular to the polygon surface and oriented towards the interior of the associated vessel (in 3D cartesian coordinates)

-
- -
-
-plot(Lax=None, Proj='All', Elt='PVC', EltLOS='LDIORP', EltOptics='P', EltVes='', Leg=None, LOSRef=None, Pdict={'lw': 2, 'c': 'k', 'ls': 'solid'}, Vdict={'color': 'r', 'lw': 2, 'ls': 'solid'}, Cdict={'edgecolors': 'k', 'antialiaseds': False, 'linestyles': '-', 'linewidths': 0.0, 'alpha': 0.2, 'facecolors': (0.8, 0.8, 0.8, 0.2)}, LVIn=0.1, LOSdict={'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'EltVes': '', 'Proj': 'All', 'Test': True, 'Elt': 'LDIORP', 'MdictP': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, 'MdictR': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, 'Leg': '', 'Lplot': 'Tot', 'Lax': None, 'Vesdict': {'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'BsdictHor': {'c': 'b', 'ls': 'dashed'}, 'Bvdict': {'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, 'Lim': [1.5707963267948966, 6.283185307179586], 'Test': True, 'Proj': 'All', 'IdictHor': {'c': 'k', 'ls': 'dashed'}, 'Elt': 'PIBsBvV', 'Pdict': None, 'Vdict': {'color': 'r', 'scale': 10}, 'Idict': {'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, 'Bsdict': {'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, 'Lax': None, 'BvdictHor': {'c': 'g', 'ls': 'dashed'}, 'Nstep': 50}, 'MdictI': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, 'Ldict': {'lw': 2, 'c': 'k'}, 'MdictO': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, 'MdictD': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}}, Opticsdict={'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'Pdict': {'lw': 2, 'c': 'k', 'ls': 'solid'}, 'Vdict': {'color': 'r', 'lw': 2, 'ls': 'solid'}, 'EltVes': '', 'Leg': '', 'Lax': None, 'Vesdict': {'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'BsdictHor': {'c': 'b', 'ls': 'dashed'}, 'Bvdict': {'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, 'Lim': [1.5707963267948966, 6.283185307179586], 'Test': True, 'Proj': 'All', 'IdictHor': {'c': 'k', 'ls': 'dashed'}, 'Elt': 'PIBsBvV', 'Pdict': None, 'Vdict': {'color': 'r', 'scale': 10}, 'Idict': {'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, 'Bsdict': {'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, 'Lax': None, 'BvdictHor': {'c': 'g', 'ls': 'dashed'}, 'Nstep': 50}, 'LVIn': 0.1, 'Test': True, 'Elt': 'PV', 'Proj': 'All'}, Vesdict={'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'BsdictHor': {'c': 'b', 'ls': 'dashed'}, 'Bvdict': {'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, 'Lim': [1.5707963267948966, 6.283185307179586], 'Test': True, 'Proj': 'All', 'IdictHor': {'c': 'k', 'ls': 'dashed'}, 'Elt': 'PIBsBvV', 'Pdict': None, 'Vdict': {'color': 'r', 'scale': 10}, 'Idict': {'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, 'Bsdict': {'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, 'Lax': None, 'BvdictHor': {'c': 'g', 'ls': 'dashed'}, 'Nstep': 50}, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, draw=True, a4=False, Test=True)[source]¶
-

Plot the Detect instance in a projection or in 3D, its polygon, perpendicular vector, projected viewing cones and optionally its LOS, Apert, and Ves objects

-

The Detect instance can be plotted in a cross-section or horizontal projection, or in 3D. -Several of its attributes can be plotted too using the usual ‘Elt’ keyword argument. -Dedicated ‘Elt’ keyword arguments are also usable to specify the elements to be plotted for sub-classes like LOS, Apert, and Ves. -Dedicated dictionary help specify how each element sshould be plotted.

- --- - - - - - -
Parameters:
    -
  • Lax (None, plt.Axes or list) – Axes or list of axes to be used for plotting, if None a new figure and appropriate axes are created
  • -
  • Proj (str) – Flag indicating whether to plot the cross-section (‘Cross’), the horizontal projection (‘Hor’), both (‘All’) or a 3D representation (‘3D’)
  • -
  • Elt (str) –
    -
    Flag indicating which elements of the Detect instance to plot, each capital letter stands for an element
    -
      -
    • ‘P’: polygon
    • -
    • ‘V’: perpendicular vector
    • -
    • ‘C’: viewing cone
    • -
    -
    -
    -
  • -
  • EltLOS (None or str) – Flag indicating which elements of the LOS to plot, will be fed to LOS.plot(), if None uses the ‘Elt’ arg of LOSdict instead
  • -
  • EltOptics (None or str) – Flag indicating which elements of the Aperts to plot, will be fed to Apert.plot(), if None uses the ‘Elt’ arg of Apertdict instead
  • -
  • EltVes (None or str) – Flag indicating which elements of the Ves to plot, will be fed to plot(), if None uses the ‘Elt’ arg of Vesdict instead
  • -
  • Leg (str) – Legend to be used for the detector, if ‘’ the Detect.iD.Name is used
  • -
  • LOSRef (None or str) – Flag indicating which LOS should be represented, if None Detect._LOSRef is used
  • -
  • Pdict (dict) – Dictionary of properties for the Polygon
  • -
  • Vdict (dict) – Dictionary of properties for the Vector
  • -
  • Cdict (dict) – Dictionary of properties for the Cone
  • -
  • LVIn (float) – Length of the Vector
  • -
  • LOSdict (dict) – Dictionary of properties for the LOS if EltLOS is not ‘’, fed to LOS.plot()
  • -
  • Apertdict (dict) – Dictionary of properties for the Apert if EltOptics is not ‘’, fed to Apert.plot()
  • -
  • Vesdict (dict) – Dictionary of properties for the Ves if EltVes is not ‘’, fed to plot()
  • -
  • LegDict (dict) – Dictionary of properties for the legend, fed to plt.legend()
  • -
  • draw (bool) – Flag indicating whether to draw the figure
  • -
  • a4 (bool) – Flag indicating whether the default figure should be of size a4 paper
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

Lax plt.Axes or list – Axes or list of axes used for plotting

-
-
- -
-
-plot_Etend_AlongLOS(ax=None, NP=20, kMode='rel', Modes=['trapz'], Length='', RelErr=0.001, dX12=[0.005, 0.005], dX12Mode='abs', Ratio=0.02, LOSRef=None, LOSPts=True, Ldict={'lw': 2, 'c': 'k', 'ls': 'solid'}, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, Colis=True, draw=True, a4=True, Test=True)[source]¶
-

Plot the etendue of the selected LOS along it, with or without collision detection

-

The number of points along the LOS where the etendue is computed can be specified via arguments, as well as the numerical integration method. -Arguments Length, NP, Modes, RelErr, dX12, dX12Mode, Ratio, Colis, LOSRef are fed to calc_Etendue_AlongLOS()

- --- - - - - - -
Parameters:
    -
  • ax (None or plt.Axes) – Axes to be used for plotting, if None a new figure and appropriate axes are created
  • -
  • kMode (str) – Flag indicating whether the distance on the line should be plotted as abolute distance (‘abs’) or relative to the total length (‘rel’)
  • -
  • Ldict (dict) – Dictionary of properties for plotting the result
  • -
  • LegDict (None / dict) – If None, no legend is plotted, else LegDict is fed to :meth:’~matplotlib.pyplot.Axes.legend’
  • -
  • draw (bool) – Flag indicating whether to draw the figure
  • -
  • a4 (bool) – Flag indicating whether the created figure should have a4 dimensions (useful for printing)
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

ax (plt.Axes) – The axes used for plotting

-
-
- -
-
-plot_SAngNb(Lax=None, Proj='Cross', Slice='Int', Pts=None, plotfunc='scatter', DRY=None, DXTheta=None, DZ=None, Elt='P', EltVes='P', EltLOS='', EltOptics='P', Pdict={'lw': 2, 'c': 'k', 'ls': 'solid'}, Vdict={'color': 'r', 'lw': 2, 'ls': 'solid'}, Cdict={'edgecolors': 'k', 'antialiaseds': False, 'linestyles': '-', 'linewidths': 0.0, 'alpha': 0.2, 'facecolors': (0.8, 0.8, 0.8, 0.2)}, LVIn=0.1, LOSdict={'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'EltVes': '', 'Proj': 'All', 'Test': True, 'Elt': 'LDIORP', 'MdictP': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, 'MdictR': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, 'Leg': '', 'Lplot': 'Tot', 'Lax': None, 'Vesdict': {'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'BsdictHor': {'c': 'b', 'ls': 'dashed'}, 'Bvdict': {'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, 'Lim': [1.5707963267948966, 6.283185307179586], 'Test': True, 'Proj': 'All', 'IdictHor': {'c': 'k', 'ls': 'dashed'}, 'Elt': 'PIBsBvV', 'Pdict': None, 'Vdict': {'color': 'r', 'scale': 10}, 'Idict': {'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, 'Bsdict': {'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, 'Lax': None, 'BvdictHor': {'c': 'g', 'ls': 'dashed'}, 'Nstep': 50}, 'MdictI': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, 'Ldict': {'lw': 2, 'c': 'k'}, 'MdictO': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, 'MdictD': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}}, Opticsdict={'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'Pdict': {'lw': 2, 'c': 'k', 'ls': 'solid'}, 'Vdict': {'color': 'r', 'lw': 2, 'ls': 'solid'}, 'EltVes': '', 'Leg': '', 'Lax': None, 'Vesdict': {'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'BsdictHor': {'c': 'b', 'ls': 'dashed'}, 'Bvdict': {'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, 'Lim': [1.5707963267948966, 6.283185307179586], 'Test': True, 'Proj': 'All', 'IdictHor': {'c': 'k', 'ls': 'dashed'}, 'Elt': 'PIBsBvV', 'Pdict': None, 'Vdict': {'color': 'r', 'scale': 10}, 'Idict': {'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, 'Bsdict': {'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, 'Lax': None, 'BvdictHor': {'c': 'g', 'ls': 'dashed'}, 'Nstep': 50}, 'LVIn': 0.1, 'Test': True, 'Elt': 'PV', 'Proj': 'All'}, Vesdict={'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'BsdictHor': {'c': 'b', 'ls': 'dashed'}, 'Bvdict': {'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, 'Lim': [1.5707963267948966, 6.283185307179586], 'Test': True, 'Proj': 'All', 'IdictHor': {'c': 'k', 'ls': 'dashed'}, 'Elt': 'PIBsBvV', 'Pdict': None, 'Vdict': {'color': 'r', 'scale': 10}, 'Idict': {'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, 'Bsdict': {'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, 'Lax': None, 'BvdictHor': {'c': 'g', 'ls': 'dashed'}, 'Nstep': 50}, CDictSA=None, CDictNb=None, Colis=True, a4=False, draw=True, Test=True)[source]¶
-

Plot the solid angle projections (integrated ‘Int’ or maximum ‘Max’) as well as the number of detectors visible from each point in the plasma

-

Mostly useful with the GDetect object, used to visualize the goemetrical coverage in terms of total solid angle and number of detectors ‘seeing’ each point for a set of detectors (see calc_SAngNb() method for details).

- --- - - - - - -
Parameters:
    -
  • Lax (None or list or plt.Axes) – Axes or list of Axes to be used for plotting, if None a new figure and appropriate axes are created
  • -
  • Proj (str) – Flag indicating whether to plot the cross-section (‘Cross’) or the horizontal projection (‘Hor’)
  • -
  • Mode (str, None or float) –
    -
    Flag indicating whether to plot:
    -
      -
    • ‘Int’: the integrated value along the projected coordinates
    • -
    • ‘Max’: the maximum value along the projected coordinates
    • -
    • float: the projected coordinate at which to plot the slice (Theta or X if Proj=’Cross’, Z if Proj=’Hor’)
    • -
    • None: the slice is done in the middle of the viewing volume
    • -
    -
    -
    -
  • -
  • plotfunc (str) – Flag indicating which plotting method to use (‘scatter’, ‘contour’, ‘contourf’ or ‘imshow’)
  • -
  • DCross (float) – Resolution along the 1st cross-section coordinate (R for Type=’Tor’, Y for Type=’Lin’)
  • -
  • DXTheta (float) – Resolution along the ignorable coordinate (Theta for Type=’Tor’, X for Type=’Lin’)
  • -
  • DZ (float) – Vertical resolution (for both Types)
  • -
  • CDictSA (dict) – Properties of the solid angle plot, to be fed to the function chosen by plotfunc
  • -
  • CDictNb (dict) – Properties of the Nb plot, to be fed to the chsoen plotting routine
  • -
  • Colis (bool) – Flag indicating whether collision detection should be used
  • -
  • a4 (bool) – Flag indicating whether to use a4 dimensions to create a new figure if Lax=None
  • -
  • draw (bool) – Flag indicating whether to draw the figure
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

Lax (plt.Axes or list) – List of the axes used for plotting

-
-
- -
-
-plot_Sinogram(ax=None, Proj='Cross', Elt='DLV', Ang='theta', AngUnit='rad', Sketch=True, Ddict={'lw': 1, 'c': 'k', 'ls': 'solid'}, Ldict={'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, Vdict={'edgecolor': (0.8, 0.8, 0.8, 1.0), 'linewidth': 1, 'linestyle': 'solid', 'facecolor': (0.8, 0.8, 0.8, 1.0)}, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, LOSRef=None, draw=True, a4=False, Test=True)[source]¶
-

Plot the the Detect VOS in projection space, optionally also the associated Ves object and reference LOS

-

In projection space, a VOS is a patch (as opposed to a LOS which is a point). -The patch is estimated by plotting a large number of LOS sampling the VOS and taking the convex hull of the resulting points on projection space. -Notice that this method results in irrelevant patches for VOS lying at the edges of the projection space. -See plot_Sinogram() for details.

- --- - - - - - -
Parameters:
    -
  • ax (None / plt.Axes) – Axes on which to plot the Etendue, if None a default axes is created
  • -
  • Proj (str) – Flag indicating whether to plot the traditional sinogram in a cross-section (‘Cross’) or a 3D sinogram (‘3d’), cannot be ‘3d’ if ‘D’ in Elt.
  • -
  • Elt (str) – Flags indicating whether to plot the VOS of the Detect (‘D’ in Elt => only Proj=’Cross’), the LOS (‘L’ in Elt) and the Ves (‘V’ in Elt)
  • -
  • Ang (str) – Flag indicating which angle to use for the plot, with respect to the considered line () or to the impact parameter line ()
  • -
  • AngUnit (str) – Flag indicating whether the angle should be measured in ‘rad’ or ‘deg’
  • -
  • Sketch (bool) – Flag indicating whether a small sketch illustrating the definitions of angles and impact parameter should be included
  • -
  • Ddict (dict) – Plotting properties of the VOS of the Detect, fed to plt.plot()
  • -
  • Ldict (dict) – Plotting properties of the LOS, fed to plt.plot()
  • -
  • Vdict (dict) – Plotting properties of the Ves, fed to plt.plot()
  • -
  • LegDict (None / dict) – Plotting properties of the legend, if None no legend is plotted
  • -
  • LOSRef (None / str) – Flag indicating which LOS to plot, if None self._LOSRef is used
  • -
  • draw (bool) – Flag indicating whether to draw the figure
  • -
  • a4 (bool) – Flag indicating whether the created figure should have a4 dimensions (useful for printing)
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

ax (plt.Axes) – The axes used for plotting

-
-
- -
-
-refine_ConePoly(dMax=0.02, Proj='Cross', indPoly=0, Verb=True, Test=True)[source]¶
-

Reduce the number of points of the selected Cone_Poly projection using the provided maximum distance and checking for convexity

-

Provide a built-in method to simplify the 2 projections of the viewing cone (VOS). -In its raw form, the projection of the VOS is a polygon with potentially a high number of points (computed using matplotlib._cntr() function). -A re-sampled version of this polygon is computed by taking its convex hull and checking, for each edge, how far it is from the original edge. -Each edge (2 points) of the convex hull is then compared to the set of original edges it encloses. -If the maximum distance between this convex hull-derived edge and the original set of edges is smaller than dMax, then the convex hull-derived egde is used, otherwise the original edges are preserved. -The method does not return a value, instead it assigns the new polygon to a dedicated attribute of the object, thus ensuring that both the original and the re-sampled projections of the VOS are available.

- --- - - - -
Parameters:
    -
  • dMax (float) – Threshold absolute distance that limits the acceptable discrepancy between the original polygon and its convex hull (checked for each edge of the convex hull)
  • -
  • Proj (str) – Flag indicating to which projection of the VOS the method should be applied
  • -
  • indPoly (int) – Index of the polygon to be treated (i.e.: in case one projection of the VOS results in a list of several polygons instead of just one polygon as is usually the case)
  • -
  • Verb (bool) – Flag indicating whether a one-line comment should be printed at the end of the calculation giving the number of points of the new polygon vs the number of points of the original polygon
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
-
- -
-
-save(SaveName=None, Path=None, Mode='npz', compressed=False, SynthDiag=False)[source]¶
-

Save the object in folder Name, under file name SaveName, using specified mode

-

Most tofu objects can be saved automatically as numpy arrays (.npz, recommended) at the default location (recommended) by simply calling self.save() -In the case of Detect and GDetect instances, there is an additional keyword argument ‘SynthDiag’ which allows to not save the pre-computed 3D mesh of the VOS for synthetic diagnostic. -Indeed, this pre-computed data is often large and results in big files. Not saving it results in significantly smaller files, and it can be re-computed when loading the instance.

- --- - - - -
Parameters:
    -
  • SaveName (None / str) – The name to be used for the saved file, if None (recommended) uses self.Id.SaveName
  • -
  • Path (None / str) – Path specifying where to save the file, if None (recommended) uses self.Id.SavePath
  • -
  • Mode (str) – Flag specifying whether to save the object as a numpy array file (‘.npz’, recommended) or an object using cPickle (not recommended, heavier and may cause retro-compatibility issues)
  • -
  • compressed (bool) – Flag, used when Mode=’npz’, indicating whether to use np.savez or np.savez_compressed (slower saving and loading but smaller files)
  • -
  • SynthDiag (bool) – Flag indicating whether the pre-computed mesh for synthetic diagnostics calculations shall be saved too (can be heavy, if False, it will be re-computed when opening the saved object)
  • -
-
-
- -
-
-set_SigPrecomp(CalcPreComp=True, dX12=None, dX12Mode=None, ds=None, dsMode=None, MarginS=None, Colis=None)[source]¶
-

Precompute a 3D grid for fast integration of a 3D emissivity for a synthetic diagnostic approach

-

In order to accelerate the computation of synthetic signal from simulated emissivity, it is possible to pre-compute a discretisation of the VOS (mesh points + solid angle) and store it as an attribute of the Detect object. -While such pre-computation does speed-up significantly the numerical integration, it also burdens the object with heavy attributes that can make it too big to save. -Hence, the saving method has a special argument that allows to specify that these pre-computed attributes should not be saved but should instead be re-computed automatically when loading the file. -The parameters dX12, dX12Mode, ds and dsMode give the user control over how fine the discretization of the VOS should be, which affects both the accuracy of the numerical integration and the size of the resulting mesh.

- --- - - - -
Parameters:
    -
  • CalcPreComp (bool) – Flag indicating whether the pre-computation should be run
  • -
  • dX12 (list) – Array of the 2 resolutions to be used to define the grid in a plane perpendicular to the LOS
  • -
  • dX12Mode (str) – Flag specifying whether the values in dX12 are absolute distances or relative values (i.e. fraction of the total width [0;1])
  • -
  • ds (float) – Float indicating the resolution in the longitudinal direction
  • -
  • dsMode (str) – Flag specifying whether ds is an absolute distance or relative (i.e. fraction of the total length [0;1])
  • -
  • MarginS (float) – Float specifying
  • -
  • Colis (bool) – Flag indicating whether collision detection should be used
  • -
-
-
- -
- -
-
-class tofu.geom.GDetect(Id, LDetect, Type=None, Exp=None, Diag=None, shot=None, Sino_RefPt=None, LOSRef=None, arrayorder='C', Clock=False, dtime=None, dtimeIn=False, SavePath=None)[source]¶
-

An object grouping a list of Detect objects with some common features (e.g.: all belong to the same camera) and the same Ves object, provides methods for common computing and plotting

-

A GDetect object is a convenient tool for managing groups of detectors, applying common treatment, plotting... -It is typically suited for a camera (e.g.: a group of detectors sharing a common aperture)

- --- - - - -
Parameters:
    -
  • Id (str or tfpf.ID) – A name string or a pre-built tfpf.ID class to be used to identify this particular instance, if a string is provided, it is fed to ID
  • -
  • LDetect (list or Detect) – List of Detect instances with the same Ves instance
  • -
  • Type (None) – Not used in the current verion of tofu
  • -
  • Exp (None or str) – Experiment to which the Lens belongs, should be identical to Ves.Id.Exp if Ves is provided, if None and Ves is provided, Ves.Id.Exp is used
  • -
  • Diag (None or str) – Diagnostic to which the Lens belongs
  • -
  • shot (None or int) – Shot number from which this Lens is usable (in case its position was changed from a previous configuration)
  • -
  • SavePath (None / str) – If provided, forces the default saving path of the object to the provided value
  • -
  • Sino_RefPt (None or iterable) – If provided, forces the common Sino_RefPt to the provided value for all Detect instances
  • -
  • arrayorder (str) – Flag indicating whether the attributes of type=np.ndarray (e.g.: Poly) should be made C-contiguous (‘C’) or Fortran-contiguous (‘F’)
  • -
  • dtime (None or dtm.datetime) – A time reference to be used to identify this particular instance (used for debugging mostly)
  • -
  • dtimeIn (bool) – Flag indicating whether dtime should be included in the SaveName (used for debugging mostly)
  • -
-
-
-
-Id¶
-

the associated tfpf.ID object

-
- -
-
-LDetect¶
-

Return the list of Detect instances the GDetect object comprises

-
- -
-
-Optics¶
-

Return the list of optics the GDetect object comprises (either Lens or Apert)

-
- -
-
-Sino_RefPt¶
-

Return the coordinates (R,Z) or (Y,Z) for Ves of Type ‘Tor’ or (Y,Z) for Ves of Type ‘Lin’ of the reference point used to compute the sinogram

-
- -
-
-Ves¶
-

Return the Ves instance associated to the GDetect object

-
- -
-
-calc_SAngVect(Pts, In='(X, Y, Z)', Colis=True, Test=True)[source]¶
-

Applies calc_SAngVect() to all Detect instances

-

Return the result as two 2D arrays where the first dimension is the number of Detect instances -see calc_SAngVect() for details

-
- -
-
-calc_Sig(ff, extargs={}, Method='Vol', Mode='simps', PreComp=True, epsrel=0.0001, dX12=[0.005, 0.005], dX12Mode='abs', ds=0.005, dsMode='abs', MarginS=0.001, Colis=True, Test=True, ind=None, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In')[source]¶
-

Applies calc_Sig() to all Detect instances

-

See calc_Sig() for details -Arguments ind, Val, Crit, PreExp, PostExp, Log and InOut are fed to select()

-
- -
-
-get_GLOS(Name=None, LOSRef=None)[source]¶
-

Return the GLOS instance that can be built by grouping the LOS of each Detect instance

-

Can be useful for handling a GLOS instead of a GDetect (heavier) instance

- --- - - - - - -
Parameters:
    -
  • Name (None / str) – Name to be given to the GLOS instance, if None a name is built from the name of the GDetect object by appending ‘_GLOS’
  • -
  • LOSRef (None / str) – Key indicating which LOS to be used, if None the default LOSRef is used
  • -
-
Returns:

glos (GLOS) – The constructed GLOS instance

-
-
- -
-
-isInside(Points, In='(X, Y, Z)', Test=True)[source]¶
-

Return an array of indices indicating whether each point lies both in the cross-section and horizontal porojections of the viewing cone of each Detect

-

see isInside() for details

- --- - - - - - -
Parameters:
    -
  • Points (np.ndarray) – (2,N) or (3,N) array of coordinates of the N points to be tested
  • -
  • In (str) –
    -
    Flag indicating in which coordinate system the Points are provided, must be in [‘(R,Z)’,’(Y,Z)’,’(X,Y)’,’(X,Y,Z)’,’(R,phi,Z)’]
    -
      -
    • ‘(R,Z)’: All points are assumed to lie in the horizontal projection, for ‘Tor’ vessel type only
    • -
    • ‘(Y,Z)’: All points are assumed to lie in the horizontal projection, for ‘Lin’ vessel type only
    • -
    • ‘(X,Y)’: All points are assumed to lie in the cross-section projection
    • -
    -
    -
    -
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

ind (np.ndarray) – (ND,N) array of booleans with True if a point lies inside both projections of the viewing cone, where ND is the number of Detect instances

-
-
- -
-
-nDetect¶
-

Return the number of Detect instances the GDetect object comprises

-
- -
-
-plot(Lax=None, Proj='All', Elt='PVC', EltLOS='LDIORP', EltOptics='P', EltVes='', Leg=None, LOSRef=None, Pdict={'lw': 2, 'c': 'k', 'ls': 'solid'}, Vdict={'color': 'r', 'lw': 2, 'ls': 'solid'}, Cdict={'edgecolors': 'k', 'antialiaseds': False, 'linestyles': '-', 'linewidths': 0.0, 'alpha': 0.2, 'facecolors': (0.8, 0.8, 0.8, 0.2)}, LVIn=0.1, LOSdict={'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'EltVes': '', 'Proj': 'All', 'Test': True, 'Elt': 'LDIORP', 'MdictP': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, 'MdictR': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, 'Leg': '', 'Lplot': 'Tot', 'Lax': None, 'Vesdict': {'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'BsdictHor': {'c': 'b', 'ls': 'dashed'}, 'Bvdict': {'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, 'Lim': [1.5707963267948966, 6.283185307179586], 'Test': True, 'Proj': 'All', 'IdictHor': {'c': 'k', 'ls': 'dashed'}, 'Elt': 'PIBsBvV', 'Pdict': None, 'Vdict': {'color': 'r', 'scale': 10}, 'Idict': {'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, 'Bsdict': {'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, 'Lax': None, 'BvdictHor': {'c': 'g', 'ls': 'dashed'}, 'Nstep': 50}, 'MdictI': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, 'Ldict': {'lw': 2, 'c': 'k'}, 'MdictO': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, 'MdictD': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}}, Opticsdict={'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'Pdict': {'lw': 2, 'c': 'k', 'ls': 'solid'}, 'Vdict': {'color': 'r', 'lw': 2, 'ls': 'solid'}, 'EltVes': '', 'Leg': '', 'Lax': None, 'Vesdict': {'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'BsdictHor': {'c': 'b', 'ls': 'dashed'}, 'Bvdict': {'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, 'Lim': [1.5707963267948966, 6.283185307179586], 'Test': True, 'Proj': 'All', 'IdictHor': {'c': 'k', 'ls': 'dashed'}, 'Elt': 'PIBsBvV', 'Pdict': None, 'Vdict': {'color': 'r', 'scale': 10}, 'Idict': {'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, 'Bsdict': {'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, 'Lax': None, 'BvdictHor': {'c': 'g', 'ls': 'dashed'}, 'Nstep': 50}, 'LVIn': 0.1, 'Test': True, 'Elt': 'PV', 'Proj': 'All'}, Vesdict={'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'BsdictHor': {'c': 'b', 'ls': 'dashed'}, 'Bvdict': {'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, 'Lim': [1.5707963267948966, 6.283185307179586], 'Test': True, 'Proj': 'All', 'IdictHor': {'c': 'k', 'ls': 'dashed'}, 'Elt': 'PIBsBvV', 'Pdict': None, 'Vdict': {'color': 'r', 'scale': 10}, 'Idict': {'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, 'Bsdict': {'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, 'Lax': None, 'BvdictHor': {'c': 'g', 'ls': 'dashed'}, 'Nstep': 50}, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, draw=True, a4=False, Test=True, ind=None, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In')[source]¶
-

Plot all or a subset of the Detect instances in a projection or in 3D

-

See plot() for details -Arguments ind, Val, Crit, PreExp, PostExp, Log and InOut are fed to select()

- --- - - - - - -
Parameters:
    -
  • Lax (None, plt.Axes or list) – Axes or list of axes to be used for plotting, if None a new figure and appropriate axes are created
  • -
  • Proj (str) – Flag indicating whether to plot the cross-section (‘Cross’), the horizontal projection (‘Hor’), both (‘All’) or a 3D representation (‘3D’)
  • -
  • Elt (str) –
    -
    Flag indicating which elements of the Detect instance to plot, each capital letter stands for an element
    -
      -
    • ‘P’: polygon
    • -
    • ‘V’: perpendicular vector
    • -
    • ‘C’: viewing cone
    • -
    -
    -
    -
  • -
  • EltLOS (None or str) – Flag indicating which elements of the LOS to plot, will be fed to LOS.plot(), if None uses the ‘Elt’ arg of LOSdict instead
  • -
  • EltOptics (None or str) – Flag indicating which elements of the Aperts to plot, will be fed to Apert.plot(), if None uses the ‘Elt’ arg of Apertdict instead
  • -
  • EltVes (None or str) – Flag indicating which elements of the Ves to plot, will be fed to plot(), if None uses the ‘Elt’ arg of Vesdict instead
  • -
  • Leg (str) – Legend to be used for the detector, if ‘’ the Detect.iD.Name is used
  • -
  • LOSRef (None or str) – Flag indicating which LOS should be represented, if None Detect._LOSRef is used
  • -
  • Pdict (dict) – Dictionary of properties for the Polygon
  • -
  • Vdict (dict) – Dictionary of properties for the Vector
  • -
  • Cdict (dict) – Dictionary of properties for the Cone
  • -
  • LVIn (float) – Length of the Vector
  • -
  • LOSdict (dict) – Dictionary of properties for the LOS if EltLOS is not ‘’, fed to LOS.plot()
  • -
  • Apertdict (dict) – Dictionary of properties for the Apert if EltOptics is not ‘’, fed to Apert.plot()
  • -
  • Vesdict (dict) – Dictionary of properties for the Ves if EltVes is not ‘’, fed to plot()
  • -
  • LegDict (dict) – Dictionary of properties for the legend, fed to plt.legend()
  • -
  • draw (bool) – Flag indicating whether to draw the figure
  • -
  • a4 (bool) – Flag indicating whether the default figure should be of size a4 paper
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

Lax plt.Axes or list – Axes or list of axes used for plotting

-
-
- -
-
-plot_Etend_AlongLOS(ax=None, NP=20, kMode='rel', Modes=['trapz'], RelErr=None, dX12=None, dX12Mode=None, Ratio=None, LOSRef=None, LOSPts=True, Ldict={'lw': 2, 'c': 'k', 'ls': 'solid'}, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, Colis=True, draw=True, a4=True, Test=True, ind=None, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In')[source]¶
-

Plot the etendue of the selected LOS along it, with or without collision detection

-

The number of points along the LOS where the etendue is computed can be specified via arguments, as well as the numerical integration method. -See plot_Etendue_AlongLOS() for details -Arguments Length, NP, Modes, RelErr, dX12, dX12Mode, Ratio, Colis, LOSRef are fed to calc_Etendue_AlongLOS() -Arguments ind, Val, Crit, PreExp, PostExp, Log and InOut are fed to select()

- --- - - - - - -
Parameters:
    -
  • ax (None or plt.Axes) – Axes to be used for plotting, if None a new figure and appropriate axes are created
  • -
  • NP (int) – Number of points along the LOS at which the Etendue should be computed
  • -
  • kMode (str) – Flag indicating whether the distance on the line should be plotted as abolute distance (‘abs’) or relative to the total length (‘rel’)
  • -
  • Modes (str or list) – Flag or list of flags indicating which integration method should be used
  • -
  • Colis (bool) – Flag indicating whether collision detection should be used
  • -
  • LOSRef (None or str) – Flag indicating which LOS should be used
  • -
  • Ldict (dict) – Dictionary of properties for plotting the result
  • -
  • LegDict (None / dict) – If None, no legend is plotted, else LegDict is fed to :meth:’~matplotlib.pyplot.Axes.legend’
  • -
  • draw (bool) – Flag indicating whether to draw the figure
  • -
  • a4 (bool) – Flag indicating whether the created figure should have a4 dimensions (useful for printing)
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

ax (plt.Axes) – The axes used for plotting

-
-
- -
-
-plot_Etendues(Mode='Etend', Elt='', ax=None, Adict={'marker': '+', 'lw': 2, 'c': 'k', 'ls': 'None'}, Rdict={'marker': 'x', 'lw': 2, 'c': 'b', 'ls': 'None'}, Edict={'marker': 'o', 'lw': 2, 'c': 'g', 'ls': 'None'}, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, draw=True, a4=False, Test=True, ind=None, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In')[source]¶
-

Plot the etendues of all or a subset of the Detect instances for the chosen LOS

-

A given Detect+Optics system has a VOS, under proper conditions, this VOS can be approximated by a LOS, but the choice of the LOS is not unique, there is an infinite number of possible LOS in a single VOS. -The LOS automatically computed by tofu os the ‘natural’ option : goes from the midlle of the Detect area throught the middle of the optics. -Then tofu automatically computes the associated etendue. -This methods plots all the etendues of all the chosen Detect instances for the chosen LOS, which is by default the ‘natural’ LOS computed by tofu

- --- - - - - - -
Parameters:
    -
  • Mode (str) – Flasg indicating whether to plot the etendue (‘Etend’) or a geometrical calibration factor (‘Calib’) computed as the 4pi/etendue
  • -
  • Elt (str) – Flag indicating whether to plot, in addition to the etendue, also the direct (‘A’) and reverse (‘R’) 0-order approximation of the etendue
  • -
  • ax (None or plt.Axes) – Axes to be used for plotting, if None a new figure and appropriate axes are created
  • -
  • Adict (dict) – Dictionary of properties for plotting the direct 0-order approximation of the etendue (if ‘A’ in Elt), fed to plot()
  • -
  • Rdict (dict) – Dictionary of properties for plotting the reverse 0-order approximation of the etendue (if ‘R’ in Elt), fed to plot()
  • -
  • Edict (dict) – Dictionary of properties for plotting the etendue, fed to plot()
  • -
  • LegDict (dict) – If None, no legend is plotted, else LegDict is fed to :meth:’~matplotlib.pyplot.Axes.legend’
  • -
  • draw (bool) – Flag indicating whether to draw the figure
  • -
  • a4 (bool) – Flag indicating whether the created figure should have a4 dimensions (useful for printing)
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

ax (plt.Axes) – The axes used for plotting

-
-
- -
-
-plot_SAngNb(Lax=None, Proj='Cross', Slice='Int', Pts=None, plotfunc='scatter', DRY=None, DXTheta=None, DZ=None, Elt='P', EltVes='P', EltLOS='', EltOptics='P', Pdict={'lw': 2, 'c': 'k', 'ls': 'solid'}, Vdict={'color': 'r', 'lw': 2, 'ls': 'solid'}, Cdict={'edgecolors': 'k', 'antialiaseds': False, 'linestyles': '-', 'linewidths': 0.0, 'alpha': 0.2, 'facecolors': (0.8, 0.8, 0.8, 0.2)}, LVIn=0.1, LOSdict={'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'EltVes': '', 'Proj': 'All', 'Test': True, 'Elt': 'LDIORP', 'MdictP': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, 'MdictR': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, 'Leg': '', 'Lplot': 'Tot', 'Lax': None, 'Vesdict': {'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'BsdictHor': {'c': 'b', 'ls': 'dashed'}, 'Bvdict': {'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, 'Lim': [1.5707963267948966, 6.283185307179586], 'Test': True, 'Proj': 'All', 'IdictHor': {'c': 'k', 'ls': 'dashed'}, 'Elt': 'PIBsBvV', 'Pdict': None, 'Vdict': {'color': 'r', 'scale': 10}, 'Idict': {'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, 'Bsdict': {'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, 'Lax': None, 'BvdictHor': {'c': 'g', 'ls': 'dashed'}, 'Nstep': 50}, 'MdictI': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, 'Ldict': {'lw': 2, 'c': 'k'}, 'MdictO': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, 'MdictD': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}}, Opticsdict={'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'Pdict': {'lw': 2, 'c': 'k', 'ls': 'solid'}, 'Vdict': {'color': 'r', 'lw': 2, 'ls': 'solid'}, 'EltVes': '', 'Leg': '', 'Lax': None, 'Vesdict': {'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'BsdictHor': {'c': 'b', 'ls': 'dashed'}, 'Bvdict': {'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, 'Lim': [1.5707963267948966, 6.283185307179586], 'Test': True, 'Proj': 'All', 'IdictHor': {'c': 'k', 'ls': 'dashed'}, 'Elt': 'PIBsBvV', 'Pdict': None, 'Vdict': {'color': 'r', 'scale': 10}, 'Idict': {'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, 'Bsdict': {'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, 'Lax': None, 'BvdictHor': {'c': 'g', 'ls': 'dashed'}, 'Nstep': 50}, 'LVIn': 0.1, 'Test': True, 'Elt': 'PV', 'Proj': 'All'}, Vesdict={'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'BsdictHor': {'c': 'b', 'ls': 'dashed'}, 'Bvdict': {'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, 'Lim': [1.5707963267948966, 6.283185307179586], 'Test': True, 'Proj': 'All', 'IdictHor': {'c': 'k', 'ls': 'dashed'}, 'Elt': 'PIBsBvV', 'Pdict': None, 'Vdict': {'color': 'r', 'scale': 10}, 'Idict': {'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, 'Bsdict': {'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, 'Lax': None, 'BvdictHor': {'c': 'g', 'ls': 'dashed'}, 'Nstep': 50}, CDictSA=None, CDictNb=None, Colis=True, a4=False, draw=True, Test=True, ind=None, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In')[source]¶
-

Plot the solid angle projections (integrated ‘Int’ or maximum ‘Max’) as well as the number of detectors visible from each point in the plasma

-

See plot_SAngNb() for details -Arguments ind, Val, Crit, PreExp, PostExp, Log and InOut are fed to select()

- --- - - - - - -
Parameters:
    -
  • Lax (None or list or plt.Axes) – Axes or list of Axes to be used for plotting, if None a new figure and appropriate axes are created
  • -
  • Proj (str) – Flag indicating whether to plot the cross-section (‘Cross’) or the horizontal projection (‘Hor’)
  • -
  • Mode (str, None or float) –
    -
    Flag indicating whether to plot:
    -
      -
    • ‘Int’: the integrated value along the projected coordinates
    • -
    • ‘Max’: the maximum value along the projected coordinates
    • -
    • float: the projected coordinate at which to plot the slice (Theta or X if Proj=’Cross’, Z if Proj=’Hor’)
    • -
    • None: the slice is done in the middle of the viewing volume
    • -
    -
    -
    -
  • -
  • plotfunc (str) – Flag indicating which plotting method to use (‘scatter’, ‘contour’, ‘contourf’ or ‘imshow’)
  • -
  • DCross (float) – Resolution along the 1st cross-section coordinate (R for Type=’Tor’, Y for Type=’Lin’)
  • -
  • DXTheta (float) – Resolution along the ignorable coordinate (Theta for Type=’Tor’, X for Type=’Lin’)
  • -
  • DZ (float) – Vertical resolution (for both Types)
  • -
  • CDictSA (dict) – Properties of the solid angle plot, to be fed to the function chosen by plotfunc
  • -
  • CDictNb (dict) – Properties of the Nb plot, to be fed to ...
  • -
  • Colis (bool) – Flag indicating whether collision detection should be used
  • -
  • a4 (bool) – Flag indicating whether to use a4 dimensions to create a new figure if Lax=None
  • -
  • draw (bool) – Flag indicating whether to draw the figure
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

Lax plt.Axes or list List of the axes used for plotting

-
-
- -
-
-plot_Sig(ffSig, extargs={}, Method='Vol', Mode='simps', ax=None, Leg='', Sdict={'marker': '+', 'lw': 2, 'c': 'k', 'ls': 'solid'}, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, draw=True, a4=False, Test=True, PreComp=True, epsrel=0.0001, dX12=[0.005, 0.005], dX12Mode='abs', ds=0.005, dsMode='abs', MarginS=0.001, Colis=True, ind=None, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In')[source]¶
-

Plot the ignal computed for each or a subset of the Detect instances

-

If the signal is not directly provided as an array, it is computed from a function. -If ffSig is a callable function, arguments ffSig, extargs, Method, Mode, PreComp, epsrel, dX12, dX12Mode, ds, dsMode, MarginS, Colis and Test are fed to calc_Sig() -Arguments ind, Val, Crit, PreExp, PostExp, Log and InOut are fed to select()

- --- - - - - - -
Parameters:
    -
  • np.ndarray or callable (ffSig) – Either a np.ndarray containing the signal to be plotted (of shape (ND,) or (N,ND) where ND is the number of detectors to be plotted) or a callable to be fed to for computing the signal
  • -
  • ax (None or plt.Axes) – Axes to be used for plotting, if None a new figure and appropriate axes are created
  • -
  • Sdict (dict) – Dictionary of properties for plotting the signal, fed to plot()
  • -
  • Leg (str) – Label to be used for the plot
  • -
  • LegDict (dict) – If None, no legend is plotted, else LegDict is fed to :meth:’~matplotlib.pyplot.Axes.legend’
  • -
  • draw (bool) – Flag indicating whether to draw the figure
  • -
  • a4 (bool) – Flag indicating whether the created figure should have a4 dimensions (useful for printing)
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

ax (plt.Axes) – The axes used for plotting

-
-
- -
-
-plot_Sinogram(ax=None, Proj='Cross', Elt='DLV', Ang='theta', AngUnit='rad', Sketch=True, Ddict={'lw': 1, 'c': 'k', 'ls': 'solid'}, Ldict={'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, Vdict={'edgecolor': (0.8, 0.8, 0.8, 1.0), 'linewidth': 1, 'linestyle': 'solid', 'facecolor': (0.8, 0.8, 0.8, 1.0)}, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, LOSRef=None, draw=True, a4=False, Test=True, ind=None, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In')[source]¶
-

Plot the VOS of all or of a subset of the Detect instances in projection space, optionally also the associated Ves object and reference LOS

-

See plot_Sinogram() for details -Arguments ind, Val, Crit, PreExp, PostExp, Log and InOut are fed to select()

-
- -
-
-save(SaveName=None, Path=None, Mode='npz', compressed=False, SynthDiag=False)[source]¶
-

Save the object in folder Name, under file name SaveName, using specified mode

-

Most tofu objects can be saved automatically as numpy arrays (.npz, recommended) at the default location (recommended) by simply calling self.save() -In the case of Detect and GDetect instances, there is an additional keyword argument ‘SynthDiag’ which allows to not save the pre-computed 3D mesh of the VOS for synthetic diagnostic. -Indeed, this pre-computed data is often large and results in big files. Not saving it results in significantly smaller files, and it can be re-computed when loading the instance.

- --- - - - -
Parameters:
    -
  • SaveName (None / str) – The name to be used for the saved file, if None (recommended) uses self.Id.SaveName
  • -
  • Path (None / str) – Path specifying where to save the file, if None (recommended) uses self.Id.SavePath
  • -
  • Mode (str) – Flag specifying whether to save the object as a numpy array file (‘.npz’, recommended) or an object using cPickle (not recommended, heavier and may cause retro-compatibility issues)
  • -
  • compressed (bool) – Flag, used when Mode=’npz’, indicating whether to use np.savez or np.savez_compressed (slower saving and loading but smaller files)
  • -
  • SynthDiag (bool) – Flag indicating whether the pre-computed mesh for synthetic diagnostics calculations shall be saved too (can be heavy, if False, it will be re-computed when opening the saved object)
  • -
-
-
- -
-
-select(Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In', Out=<type 'bool'>)[source]¶
-

Return the indices or instances of all instances matching the specified criterion.

-

The selection can be done according to 2 different mechanism (1) and (2).

-

For mechanism (1): the user provides the value (Val) that the specified criterion (Crit) should take for a tofu.geom.Detect to be selected. -The criteria are typically attributes of the self.Id attribute (i.e.: name of the instance, or user-defined attributes like the camera head...)

-

For mechanism (2), used if Val=None: the user provides a str expression (or a list of such) to be fed to eval(), used to check on quantitative criteria, placed before the criterion value (e.g.: ‘not ‘ or ‘<=’). -Another str or list of str expressions can be provided that will be placed after the criterion value.

-

Other parameters are used to specify logical operators for the selection (match any or all the criterion...) and the type of output. -See select() for examples

- --- - - - - - -
Parameters:
    -
  • Crit (str) – Flag indicating which criterion to use for discrimination -Can be set to any attribute of the tofu.pathfile.ID class (e.g.: ‘Name’,’SaveName’,’SavePath’...) or any key of ID.USRdict (e.g.: ‘Exp’...)
  • -
  • Val (list, str or None) – The value to match for the chosen criterion, can be a list of different values -Used for selection mechanism (1)
  • -
  • PreExp (list, str or None) – A str of list of str expressions to be fed to eval(), used to check on quantitative criteria, placed before the criterion value (e.g.: ‘not ‘) -Used for selection mechanism (2)
  • -
  • PostExp (list, str or None) – A str of list of str expressions to be fed to eval(), used to check on quantitative criteria, placed after the criterion value (e.g.: ‘>=5.’) -Used for selection mechanism (2)
  • -
  • Log (str) – Flag indicating whether the criterion shall match all provided values or one of them (‘any’ or ‘all’)
  • -
  • InOut (str) – Flag indicating whether the returned indices are the ones matching the criterion (‘In’) or the ones not matching it (‘Out’)
  • -
  • Out (type / str) – Flag indicating in which form shall the result be returned, as an array of integer indices (int), an array of booleans (bool), a list of names (‘Names’) or a list of instances (‘Detect’)
  • -
-
Returns:

ind (list / np.ndarray) – The computed output (array of index, list of names or instances depending on parameter ‘Out’)

-
-
- -
-
-set_SigPrecomp(CalcPreComp=True, dX12=[0.005, 0.005], dX12Mode='abs', ds=0.005, dsMode='abs', MarginS=0.001, Colis=True)[source]¶
-

Applies set_SigPrecomp() to all Detect instances

-
- -
- -
-

1.1. Indices and tables¶

- -
-
- - -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/build/html/Auto_tofu.pathfile.html b/doc/build/html/Auto_tofu.pathfile.html deleted file mode 100644 index 5d5bf47a8..000000000 --- a/doc/build/html/Auto_tofu.pathfile.html +++ /dev/null @@ -1,456 +0,0 @@ - - - - - - - - 3. tofu.pathfile — tofu v1.1 - - - - - - - - - - - - - - - - -
-
-
-
- -
-

3. tofu.pathfile¶

-

Created on Wed Jul 30 14:37:31 2014

-

@author: didiervezinet

-
-
-tofu.pathfile.Find_Rootpath(Path='/afs/ipp-garching.mpg.de/home/d/didiv/Python/tofu/doc', substr='/tofu')[source]¶
-

Return the absolute path of the root directory of ToFu, searching for a pattern in the provided input path

- --- - - - - - -
Parameters:
    -
  • Path (str) – An absolute path in which a pattern is to be looked for
  • -
  • substr (str) – The pattern to look for
  • -
-
Returns:

root (str) – The absolute path containing the pattern

-
-
- -
-
-tofu.pathfile.get_DefaultPaths(RootPath=None, Plugin=None, lSubs=[], PathInp=None, PathObj=None, PathOut=None)[source]¶
-

Return the default paths for input loading, object and output saving depending on the root path used

-
- -
-
-tofu.pathfile.get_Default_dtimeFmt(dtime=None, dtFormat='D%Y%m%d_T%H%M%S')[source]¶
-

Return the default datetime value and format

-
- -
-
-tofu.pathfile.convert_units(P, In='cm', Out='m')[source]¶
-

Quickly convert distance units between meters, centimeters and millimeters

-
- -
-
-tofu.pathfile.get_PolyFromPolyFileObj(PolyFileObj, SavePathInp=None, units='m', comments='#', skiprows=0, shape0=2)[source]¶
-

Return a polygon as a np.ndarray, extracted from a txt file or from a ToFu object, with appropriate units

-

Useful for tofu.plugins.AUG.Ves._create()

- --- - - - - - -
Parameters:
    -
  • PolyFileObj (str / tofu.geom object / np.ndarray) –
    -
    The source where the polygon is to be found, either:
    -
      -
    • str: the name of a file containing the coorindates of a polygon to be loaded with numpy.loadtxt()
    • -
    • A tofu.geom object: with attribute ‘Poly’
    • -
    • np.ndarray: an 2-dimensional array containing the 2D cartesian coordinates of a polygon
    • -
    -
    -
    -
  • -
  • SavePathInp (str / None) – The absolute path where the input file is stored
  • -
  • units (str) – Flag indicating in which units the polygon coordinates is expressed in the input file / object / array (will be converted to meters)
  • -
  • comments (str) – Parameter to be fed to numpy.loadtxt() if PolyFileObj is a file name
  • -
  • skiprows (int) – Parameter to be fed to numpy.loadtxt() if PolyFileObj is a file name
  • -
  • shape0 (int) – Specifies whether the loaded array is a (2,N) or (3,N) array (transposed it if necessary)
  • -
-
Returns:

    -
  • Poly (np.ndarray) – (2,N) np.ndarray containing the 2D cartesian coordinates of the polygon, where N is the number of points
  • -
  • addInfo (dict) – Dictionaryb containing information on the origin of the polygon, for the record (e.g.: the name and absolute path of the file from which it was extracted)
  • -
-

-
-
- -
-
-class tofu.pathfile.ID(Cls, Name, Type=None, Deg=None, Exp=None, Diag=None, shot=None, SaveName=None, SavePath=None, USRdict=None, LObj=None, dtime=None, dtFormat='D%Y%m%d_T%H%M%S', dtimeIn=False)[source]¶
-

A class used by all ToFu objects as an attribute, storing all relevant data for the identification of created instances and providing default path and names for saving objects

-

Each detector created in ToFu should be identifiable thanks to user-friendly criteria, like its name, the diagnostic and experiment it is attached to, the shot number from from it was physically installed on the experiement... -Users can also freely add some information they consider relevant, such as some characteristics of the detector (size, manufacturer, date of last calibration...)

- --- - - - - - -
Parameters:
    -
  • Cls (str) –
    -
    Flag indicating which class is the object fro which the ID instance is being created, available class flags are:
    -
      -
    • From tofu.geom: ‘Ves’, ‘Struct’, ‘LOS’, ‘GLOS’, ‘Apert’, ‘Lens’, ‘Detect’ and ‘GDetect’
    • -
    • From tofu.mesh: ‘Mesh1D’, ‘Mesh2D’, ‘LBF1D’ and ‘LBF2D’ (to be finished)
    • -
    • From tofu.: (to be completed)
    • -
    -
    -
    -
  • -
  • Name (str) – Name to be assigned to the created instance, should be a str without ‘ ‘ or ‘_’ (spaces and underscores will be automatically removed if present)
  • -
  • Type (None / str) – If provided (necessary for some objects, but not for all), specifies the Type of object (i.e.: ‘Tor’ or ‘Lin’ for a Ves instance)
  • -
  • Deg (None / int) – If provided (necessary only for objects of class ‘LBF1D’ and ‘LBF2D’), specifies the degree of the b-splines constituting the tofu.mesh object
  • -
  • Exp (None / str) – A short 3-4 letters max flag specifying the experiment to which the created instance belongs (e.g.: ‘AUG’, ‘ITER’, ‘TCV’, ‘JET’...)
  • -
  • Diag (None / str) – A short flag indicating which diagnostic the the created instance belongs to (e.g.: ‘SXR’, ‘HXR’, ‘Bolo’...)
  • -
  • shot (None / int) – A shot number from which the created instance can be considered valid (useful for tracking geometry changes in the case of Ves and Detect objects)
  • -
  • SaveName (None / str) – If provided, overrides the automatically generated name for saving the created instance (not recommended)
  • -
  • SavePath (None / str) – If provided, overrides the automatically generated path for saving the created instance
  • -
  • USRdict (None / dict) – If provided, a user-defined dictionary containing information about the instance considered relevant (e.g.: thickness of the diode, date of installation...)
  • -
  • LObj (None / dict / list) –
    -
    If provided, either
    -
      -
    • list: list of other ID instances of objects on which the created object depends (this list will then be sorted by class and formatted into a dictionary storign key attributes)
    • -
    • dict: a ready-made such dictionary
    • -
    -
    -
    -
  • -
  • dtime (None / dtm.datetime) – If provided, a time reference to be used to identify this particular instance (used for debugging mostly)
  • -
  • dtFormat (None / str) – If provided, the format in which dtime should be written in the automatically generated saving name for the created instance
  • -
  • dtimeIn (bool) – Flag indicating whether the dtm.datetime should be included in the automatically generated saving name for the created instance
  • -
-
Returns:

Id ID instance – The created ID instance, with all necessary computed attributes and methods

-
-
-
-set_LObj(LObj=None)[source]¶
-

Set the LObj attribute to store the list of ID of other objects the created instance depends on

-

A Detect object depends on a vessel and some optics (e.g.: a list of apertures). -It is necessary that the link between the created Detect object and the already-existing Ves and Apert objects be stored somewhere, so that even after saving and closing the session, this correspondence can be retrieved and the Detect object can be re-loaded with links to the proper Ves and Apert objects, themselves beoing possibly saved elsewhere (so their respective SavePath must also be stored). -The LObj parameter does this: it stores all information necessary about each of the other objects the created instance depends on, mostly by storing their ID attributes as dictionaries.

- --- - - - -
Parameters:LObj (None / dict / list) –
-
If provided, either
-
    -
  • list: list of other ID instances of objects on which the created object depends (this list will then be sorted by class and formatted into a dictionary storign key attributes)
  • -
  • dict: a ready-made such dictionary
  • -
-
-
-
-
- -
-
-set_Name(Name, SaveName=None, dtimeIn=None)[source]¶
-

Set the Name of the created instance, automatically updating the SaveName

-

When the name is changed (reminding it should not include space (‘ ‘) or underscore (‘_’) characters), the name used for saving the object is automatically changed

- --- - - - -
Parameters:
    -
  • Name (str) – Name to be assigned to the created instance, should be a str without ‘ ‘ or ‘_’ (spaces and underscores will be automatically removed if present)
  • -
  • SaveName (None / str) – If provided, overrides the automatically generated name for saving the created instance (not recommended)
  • -
  • dtimeIn (None / bool) – If provided, modifies the value of dtimeIn provided upon creation of the ID object
  • -
-
-
- -
-
-set_SaveName(SaveName=None, dtimeIn=None)[source]¶
-

Enables either to automatically compute a ToFu-consistent saving name for the created instance, or to override that default saving name with the user-provided SaveName

-

When creating an object of any class, an ID object is assigned to it that automatically computes a saving name in case the user wants to save the object. -This automatically generated saving name includes not only the name given to the instance but also useful classifying info such as the class of the object, its Type, experiment, diagnostic... -It is not recommended to override this automatically generated saving name (because some routines rely on it for fast identification of saved files), but it is made possible for flexibility.

- --- - - - -
Parameters:
    -
  • SaveName (None / str) – If provided, a str that overrides the automatically generated saving name
  • -
  • dtimeIn (None / bool) – If provided, modifies the value of dtimeIn provided upon creation of the ID object
  • -
-
-
- -
-
-set_SavePath(SavePath=None)[source]¶
-

Enables to automatically generate a saving path for the created object, or to override that default path with the user-provided SavePath

-

Similarily to SaveName, ToFu automatically generates a saving path for any created object. -This saving path can be overriden if desired. -This is less crucial than SaveName, changing the SavePath has little consequences as long as you remember what you are doing.

- --- - - - -
Parameters:SavePath (None / str) – If provided, a str that overrides the automatically generated saving path
-
- -
-
-set_USRdict(USRdict=None)[source]¶
-

Set the USRdict to enable the user to store arbitrary information about the instance created

-

It may sometimes be useful to store unforeseen arbitrary info about some objects created, like the manufacturing date of a diode, the material used for a filter... -The USRdict attribute is a user-defined dictionary for this purpose.

- --- - - - -
Parameters:USRdict (None / dict) – If provided, a user-defined dictionary containing information about the instance considered relevant (e.g.: thickness of the diode, date of installation...)
-
- -
- -
-
-tofu.pathfile.CheckSameObj(obj0, obj1, LFields=None)[source]¶
-

Check two variable refer to the same instance of a ToFu class by checking some key attributes

-

Sometimes two different variables can refer to the same instance (for example if an object was created and assigned to obj0, then later saved and loaded and assigned to obj1). -Occasionally it may be useful to check whether two variables really represent the same instance, according to important criteria from the point of view of ToFu.

- --- - - - - - -
Parameters:
    -
  • obj0 (tofu object) – A variable refering to a ToFu object of any class
  • -
  • obj1 (tofu object) – A variable refering to a ToFu object of any class (but the same class as obj0)
  • -
  • LFields (None / str / list) –
    -
    The criteria against which the two objects are evaluated, if not None, must be str matching an attribute of the ID class or an attribute of the object class itself (or a list of such)
    -
      -
    • None: True is returned
    • -
    • str or list: tests whether the attributes have the same value or not and only returns True if all do
    • -
    -
    -
    -
  • -
-
Returns:

A (bool)

-
-
- -
-
-tofu.pathfile.Save_Generic(obj, SaveName=None, Path=None, Mode='npz', compressed=False)[source]¶
-

Save a ToFu object under file name SaveName, in folder Path, using specified mode

-

ToFu provides built-in saving and loading functions for ToFu objects. -They can be saved at their default SavePath under their default SaveName or user-defined values can be forced if necessary. -Saving can be done in two ways :

-
-
    -
  • by direct object saving using cPickle (straightforward but heavy)
  • -
  • by mapping the key object attributes to a dictionary and using numpy.savez_compressed() (faster and lighter, recommended)
  • -
-
-

ToFu now automatically saves information on smaller objects on which the object of interest depends (like apertures for detectors), so that all info is stored in a single file. -In particular, provided the Ves object is saved separately, a whole camera can be saved in a single file (i.e.: all detectors and apertures).

- --- - - - -
Parameters:
    -
  • SaveName (str) – The name to be used to for the saved file, if None (recommended) uses obj.Id.SaveName
  • -
  • Path (str) – Path specifying where to save the file, if None (recommended) uses obj.Id.SavePath
  • -
  • Mode (str) – Flag specifying whether to save the object as a numpy array file (‘.npz’, recommended) or an object using cPickle (not recommended, may cause retro-compatibility issues with later versions)
  • -
  • compressed (bool) – Flag, used when Mode=’npz’, indicating whether to use np.savez or np.savez_compressed (slower saving and loading but smaller files)
  • -
-
-
- -
-
-tofu.pathfile.Open(pathfileext=None, shot=None, t=None, Dt=None, Mesh=None, Deg=None, Deriv=None, Sep=True, Pos=True, OutPath=None, ReplacePath=None, Ves=None, out='full', Verb=False)[source]¶
-

Open a ToFu object saved file

-

This generic open function identifies the required loading routine by detecting how the object was saved from the file name extension. -Also, it uses FindSolFile() to identify the relevant file in case key criteria such as shot, Deg... are provided instead of the file name itself. -Finally, once all the relevant data is loaded from the file, a ToFu object is re-created, if necessary by implicitly loading all other objects it may depend on (i.e.: vessel, apertures...)

-

If pathfileext is not provided (None), then the following keyword arguments are fed to FindSolFile(): shot, t, Dt, Mesh, Deg, Deriv, Sep, Pos

- --- - - - - - -
Parameters:
    -
  • pathfileext (None / str) – If provided, the name of the file to load
  • -
  • OutPath (None / str) – If provided, the absolute path where the file is to be found
  • -
  • ReplacePath (str) – If provided, ? (to finish)
  • -
  • Ves (None /) – If provided, the tofu.geom.Ves object that shall be used to reconstruct the object (if not provided, the appropriate vessel will be loaded).
  • -
  • out (str) – Flag indicating whether the object should be loaded completely (‘full’), in a light dismissing the heaviest attributes (‘light’) or whether only the Id or a list of Id should be returned (‘Id’), valid only for ‘.npz’
  • -
  • Verb (bool) – Flag indicating whether to pring intermediate comments on the loading procedure
  • -
-
Returns:

obj ToFu object – The loaded and re-created ToFu object

-
-
- -
-

3.1. Indices and tables¶

- -
-
- - -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/build/html/Auto_tofu.plugins.AUG.SXR.geom.html b/doc/build/html/Auto_tofu.plugins.AUG.SXR.geom.html deleted file mode 100644 index 65aba80aa..000000000 --- a/doc/build/html/Auto_tofu.plugins.AUG.SXR.geom.html +++ /dev/null @@ -1,251 +0,0 @@ - - - - - - - - 4.2.1. AUG.SXR — tofu v1.1 - - - - - - - - - - - - - - - - - -
-
-
-
- -
-

4.2.1. AUG.SXR¶

-
-

4.2.1.1. AUG.SXR.geom¶

-
-
-tofu.plugins.AUG.SXR.geom.create(shot=0, VesName='V1', SavePathObj=None, Root='/afs/ipp-garching.mpg.de/home/d/didiv/Python/tofu', forceshot=False, overwrite=False, save=True, dtime=None, dtFormat='D%Y%m%d_T%H%M%S', CalcEtend=True, CalcSpanImp=True, CalcCone=True, CalcPreComp=True, Calc=True, Verb=True, Etend_Method='quad', Etend_RelErr=0.001, Etend_dX12=[0.01, 0.01], Etend_dX12Mode='rel', Etend_Ratio=0.02, Colis=True, LOSRef='Cart', Cone_DRY=0.0025, Cone_DXTheta=0.0030679615757712823, Cone_DZ=0.0025, Cone_NPsi=20, Cone_Nk=60)[source]¶
-

Create, save and return all the GDetect objects relevant for the input shot, unless already created for a relevant reference shot

-

Create the tofu.geom.GDetect objects (i.e.: the cameras, which are groups of detectors) from geometry taken from CSX disgnostic for the proposed shot or earlier (looks for the oldest version of the matching geometry) and stores them in the SavePathObj.

-

All extra arguments are fed to Detect

- --- - - - - - -
Parameters:
    -
  • shot (int) – Shot number for which to build the geometry
  • -
  • VesName (str) – Name of the tfg.Ves object to be fed as an input to the tofu.geom.GDetect objects
  • -
  • SavePathObj (None / str) – Absolute path where the created tofu.geom.GDetect objects should be saved (if save=True), if None the default is used
  • -
  • Root (str) – If SavePathObj=None, a default value is created by appending ‘/tofu/plugins/AUG/SXR/geom/Objects/’ to Root
  • -
  • forceshot (bool) – Flag indicating whether the shot number shall be downgraded to the oldest shot with the same geometry (False) or whether the provided shot number shall be enforced (True, for all camera heads)
  • -
  • overwrite (bool) – Flag indicating whether new tofu.geom.GDetect objects shall be computed (and possibly saved) when similar ones already exist (True)
  • -
  • save (bool) – Flag indicating whether to save the created tofu.geom.GDetect objects (in SavePathObj)
  • -
  • dtime (None / dtm.datetime) – If provided (i.e.: not None), used as a label of the created tofu.geom.GDetect objects (mostly used for debugging)
  • -
  • dtFormat (str) – The time format to be used for labelling the created tofu.geom.GDetect objects (mostly used for debugging)
  • -
-
Returns:

LGD (list) – A list of all the created tfg.GDetect objects

-
-
- -
-
-tofu.plugins.AUG.SXR.geom.load(Cams=None, shot=None, SavePathObj=None, Root='/afs/ipp-garching.mpg.de/home/d/didiv/Python/tofu', sort=False, out='full', Test=True)[source]¶
-

Load and return the desired GDetect objects (i.e.: camera heads)

-

Directly fecthes and loads the desired GDetect objects.

- --- - - - -
Parameters:
    -
  • Cams (str / list) – A name or a list of names of the camera heads to be loaded (available are [‘F’,’G’,’H1’,’H2’,’H3’,’I1’,’I2’,’I3’,’J1’,’J2’,’J3’,’K1’,’K2’,’L’,’M’])
  • -
  • shot (int / float / np.float) – A shot number indicating which version of the geometry should be loaded (the )
  • -
  • SavePathObj (None / str) – Absolute path where the created tofu.geom.GDetect objects should be saved (if save=True), if None the default is used
  • -
  • Root (str) – If SavePathObj=None, a default value is created by appending ‘/tofu/plugins/AUG/SXR/geom/Objects/’ to Root
  • -
  • sort (bool) – Flag indicating whether the loaded tofu.geom.GDetect objects shall be returned sorted by alphabetical order of the names (True) or in the same order as asked in Cams (False)
  • -
  • out (str) – Flag indicating whether the object should be loaded completely (‘full’), in a light dismissing the heaviest attributes (‘light’) or whether only the Id or a list of Id should be returned (‘Id’), valid only for ‘.npz’
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
  • Returns
  • -
  • --------
  • -
  • LGD (list / tofu.geom.GDetect) – The loaded tofu.geom.GDetect, returned as a single object if Cams was provided as a single name, as a list otherwise
  • -
-
-
- -
-
-

4.2.1.2. AUG.SXR.data¶

-
-
-tofu.plugins.AUG.SXR.data.load(shot=None, Names=None, Mode='SSX', Dt=None, Join=True, tRef='fmin', Method='interp', NoGeom=True, Tofu=True, Verb=True, Test=True)[source]¶
-

Load SXR data from the AUG database and returns it either as numpy arrays or a ToFu-compatible object with appropriate methods

-

Part of the difficulty is that all channels do not have the same sampling frequency and time vector. -Hence, there is an option to uniformize the time base.

- --- - - - - - -
Parameters:
    -
  • shot (int) – Shot number for which the SXR data should be loaded
  • -
  • Names (None / str / list) – If provided, data is loaded only for the specified channel(s)
  • -
  • Mode (str) – Flag indicating whether data should be loaded from a down-sampled database (‘SSX’, , faster loading) or from the complete database ( depending on the channel)
  • -
  • Dt (None / iterable) – If provided, a len()=2 iterable giving the time interval of interest (recommended to avoid very large data files)
  • -
  • Join (bool) – Flag, useful when Mode=’SX’, indicating whether the different time bases of the channels shall be uniformized
  • -
  • tRef (None / str / np.ndarray) –
    -
    Flag or time vector, useful when Mode=’SX’ and Join=True, indicating which time basis should be used as a reference
    -
      -
    • ‘fmin’: the time vector of the channel presenting the smallest sampling frequency is used as a reference
    • -
    • ‘fmax’: the time vector of the channel presenting the highest sampling frequency is used as a reference
    • -
    • any channel name: the time vector of the specifiec channel is used as a reference
    • -
    • np.ndarray: the provided time vector is used as a reference
    • -
    -
    -
    -
  • -
  • Method (str) – Flag, usefule when Mode=’SX’ and Join=True, indicating how the
  • -
  • NoGeom (bool) –
    -
    Flag indicating whether the data should be stripped of its geometrical calibration factor (thus being expressed in W instead of W/m2), to allow for:
    -
      -
    • Application of a tofu-computed etendue in case of a LOS approach
    • -
    • Direct use of the signal in case of a VOS approach
    • -
    -
    -
    -
  • -
  • Tofu (bool) – Flag indicating whether the loaded data should be returned as (SXR, t, Names) where the first two are np.ndarrays and Names is a list or as a tofu.data.PreData object
  • -
  • Verb (bool) – Flag indicating whether extra comments should be printed to give feedback on the progress of the routine
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

out (tuple / tofu.data.PreData)

-
-
- -
-
-

4.2.1.3. Indices and tables¶

- -
-
- - -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/build/html/Auto_tofu.plugins.AUG.html b/doc/build/html/Auto_tofu.plugins.AUG.html deleted file mode 100644 index e91553873..000000000 --- a/doc/build/html/Auto_tofu.plugins.AUG.html +++ /dev/null @@ -1,281 +0,0 @@ - - - - - - - - 4.1.1. AUG — tofu v1.1 - - - - - - - - - - - - - - - - - -
-
-
-
- -
-

4.1.1. AUG¶

-
-

4.1.1.1. AUG.Ves¶

-

Contains all functions specific to the AUG vessel (creating the Ves object from Inputs, loading pre-created Ves objects...)

-
-
-tofu.plugins.AUG.Ves.load(Name='V1', SavePathObj=None, Root='/afs/ipp-garching.mpg.de/home/d/didiv/Python/tofu', Test=True)[source]¶
-

Load and return the selected Ves object (selected by name or file name)

-

Several Ves object might exist for the same experiment depending changes to the experiment in time for example -This function loads the one specified by its name.

- --- - - - - - -
Parameters:
    -
  • Name (str / list) – Name of the file to be loaded, or a subset of this name or a list of subsets, the file with a name matching all the subsets will be loaded. An error is issued in case of ambiguity
  • -
  • SavePathObj (str) – Absolute path where the objects can be found, if None sets to default
  • -
  • Root (str) – If SavePathObj=None, a default value is created by appending ‘/tofu/plugins/AUG/Ves/Objects/’ to Root
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

Ves (tofu.geom.Ves) – The loaded Ves object

-
-
- -
-
-

4.1.1.2. AUG.SXR.geom¶

-
-
-tofu.plugins.AUG.SXR.geom.create(shot=0, VesName='V1', SavePathObj=None, Root='/afs/ipp-garching.mpg.de/home/d/didiv/Python/tofu', forceshot=False, overwrite=False, save=True, dtime=None, dtFormat='D%Y%m%d_T%H%M%S', CalcEtend=True, CalcSpanImp=True, CalcCone=True, CalcPreComp=True, Calc=True, Verb=True, Etend_Method='quad', Etend_RelErr=0.001, Etend_dX12=[0.01, 0.01], Etend_dX12Mode='rel', Etend_Ratio=0.02, Colis=True, LOSRef='Cart', Cone_DRY=0.0025, Cone_DXTheta=0.0030679615757712823, Cone_DZ=0.0025, Cone_NPsi=20, Cone_Nk=60)[source]¶
-

Create, save and return all the GDetect objects relevant for the input shot, unless already created for a relevant reference shot

-

Create the tofu.geom.GDetect objects (i.e.: the cameras, which are groups of detectors) from geometry taken from CSX disgnostic for the proposed shot or earlier (looks for the oldest version of the matching geometry) and stores them in the SavePathObj.

-

All extra arguments are fed to Detect

- --- - - - - - -
Parameters:
    -
  • shot (int) – Shot number for which to build the geometry
  • -
  • VesName (str) – Name of the tfg.Ves object to be fed as an input to the tofu.geom.GDetect objects
  • -
  • SavePathObj (None / str) – Absolute path where the created tofu.geom.GDetect objects should be saved (if save=True), if None the default is used
  • -
  • Root (str) – If SavePathObj=None, a default value is created by appending ‘/tofu/plugins/AUG/SXR/geom/Objects/’ to Root
  • -
  • forceshot (bool) – Flag indicating whether the shot number shall be downgraded to the oldest shot with the same geometry (False) or whether the provided shot number shall be enforced (True, for all camera heads)
  • -
  • overwrite (bool) – Flag indicating whether new tofu.geom.GDetect objects shall be computed (and possibly saved) when similar ones already exist (True)
  • -
  • save (bool) – Flag indicating whether to save the created tofu.geom.GDetect objects (in SavePathObj)
  • -
  • dtime (None / dtm.datetime) – If provided (i.e.: not None), used as a label of the created tofu.geom.GDetect objects (mostly used for debugging)
  • -
  • dtFormat (str) – The time format to be used for labelling the created tofu.geom.GDetect objects (mostly used for debugging)
  • -
-
Returns:

LGD (list) – A list of all the created tfg.GDetect objects

-
-
- -
-
-tofu.plugins.AUG.SXR.geom.load(Cams=None, shot=None, SavePathObj=None, Root='/afs/ipp-garching.mpg.de/home/d/didiv/Python/tofu', sort=False, out='full', Test=True)[source]¶
-

Load and return the desired GDetect objects (i.e.: camera heads)

-

Directly fecthes and loads the desired GDetect objects.

- --- - - - -
Parameters:
    -
  • Cams (str / list) – A name or a list of names of the camera heads to be loaded (available are [‘F’,’G’,’H1’,’H2’,’H3’,’I1’,’I2’,’I3’,’J1’,’J2’,’J3’,’K1’,’K2’,’L’,’M’])
  • -
  • shot (int / float / np.float) – A shot number indicating which version of the geometry should be loaded (the )
  • -
  • SavePathObj (None / str) – Absolute path where the created tofu.geom.GDetect objects should be saved (if save=True), if None the default is used
  • -
  • Root (str) – If SavePathObj=None, a default value is created by appending ‘/tofu/plugins/AUG/SXR/geom/Objects/’ to Root
  • -
  • sort (bool) – Flag indicating whether the loaded tofu.geom.GDetect objects shall be returned sorted by alphabetical order of the names (True) or in the same order as asked in Cams (False)
  • -
  • out (str) – Flag indicating whether the object should be loaded completely (‘full’), in a light dismissing the heaviest attributes (‘light’) or whether only the Id or a list of Id should be returned (‘Id’), valid only for ‘.npz’
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
  • Returns
  • -
  • --------
  • -
  • LGD (list / tofu.geom.GDetect) – The loaded tofu.geom.GDetect, returned as a single object if Cams was provided as a single name, as a list otherwise
  • -
-
-
- -
-
-

4.1.1.3. AUG.SXR.data¶

-
-
-tofu.plugins.AUG.SXR.data.load(shot=None, Names=None, Mode='SSX', Dt=None, Join=True, tRef='fmin', Method='interp', NoGeom=True, Tofu=True, Verb=True, Test=True)[source]¶
-

Load SXR data from the AUG database and returns it either as numpy arrays or a ToFu-compatible object with appropriate methods

-

Part of the difficulty is that all channels do not have the same sampling frequency and time vector. -Hence, there is an option to uniformize the time base.

- --- - - - - - -
Parameters:
    -
  • shot (int) – Shot number for which the SXR data should be loaded
  • -
  • Names (None / str / list) – If provided, data is loaded only for the specified channel(s)
  • -
  • Mode (str) – Flag indicating whether data should be loaded from a down-sampled database (‘SSX’, , faster loading) or from the complete database ( depending on the channel)
  • -
  • Dt (None / iterable) – If provided, a len()=2 iterable giving the time interval of interest (recommended to avoid very large data files)
  • -
  • Join (bool) – Flag, useful when Mode=’SX’, indicating whether the different time bases of the channels shall be uniformized
  • -
  • tRef (None / str / np.ndarray) –
    -
    Flag or time vector, useful when Mode=’SX’ and Join=True, indicating which time basis should be used as a reference
    -
      -
    • ‘fmin’: the time vector of the channel presenting the smallest sampling frequency is used as a reference
    • -
    • ‘fmax’: the time vector of the channel presenting the highest sampling frequency is used as a reference
    • -
    • any channel name: the time vector of the specifiec channel is used as a reference
    • -
    • np.ndarray: the provided time vector is used as a reference
    • -
    -
    -
    -
  • -
  • Method (str) – Flag, usefule when Mode=’SX’ and Join=True, indicating how the
  • -
  • NoGeom (bool) –
    -
    Flag indicating whether the data should be stripped of its geometrical calibration factor (thus being expressed in W instead of W/m2), to allow for:
    -
      -
    • Application of a tofu-computed etendue in case of a LOS approach
    • -
    • Direct use of the signal in case of a VOS approach
    • -
    -
    -
    -
  • -
  • Tofu (bool) – Flag indicating whether the loaded data should be returned as (SXR, t, Names) where the first two are np.ndarrays and Names is a list or as a tofu.data.PreData object
  • -
  • Verb (bool) – Flag indicating whether extra comments should be printed to give feedback on the progress of the routine
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

out (tuple / tofu.data.PreData)

-
-
- -
-
-

4.1.1.4. Indices and tables¶

- -
-
- - -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/build/html/Auto_tofu.plugins.ITER.Bolo.geom.html b/doc/build/html/Auto_tofu.plugins.ITER.Bolo.geom.html deleted file mode 100644 index b2777221e..000000000 --- a/doc/build/html/Auto_tofu.plugins.ITER.Bolo.geom.html +++ /dev/null @@ -1,126 +0,0 @@ - - - - - - - - 4.2.2. tofu.plugins.ITER.Bolo.geom — tofu v1.1 - - - - - - - - - - - - - - - - -
-
-
-
- -
-

4.2.2. tofu.plugins.ITER.Bolo.geom¶

-
-

4.2.2.1. Indices and tables¶

- -
-
- - -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/build/html/Auto_tofu.plugins.ITER.html b/doc/build/html/Auto_tofu.plugins.ITER.html deleted file mode 100644 index bd7679e90..000000000 --- a/doc/build/html/Auto_tofu.plugins.ITER.html +++ /dev/null @@ -1,383 +0,0 @@ - - - - - - - - 4.1.2. ITER — tofu v1.1 - - - - - - - - - - - - - - - - -
-
-
-
- -
-

4.1.2. ITER¶

-
-

4.1.2.1. ITER.Ves¶

-

Contains all functions specific to the AUG vessel (creating the Ves object from Inputs, loading pre-created Ves objects...)

-

Created on Wed May 18 2016

-

@version: 0.9 -@author: didiervezinet -@author_email: didier.vezinet@gmail.com

-
-
-tofu.plugins.ITER.Ves.create(Name='ITER_D_2N9J75 v1.7-1', Poly=['PoloidalCurvesCoordinates', 'ITER', '2N9J75', 'csv'], shot=0, SavePathInp=None, SavePathObj=None, Root='/afs/ipp-garching.mpg.de/home/d/didiv/Python/tofu', save=True, skiprows=4, comments='#', units='mm', dtime=None, dtFormat='D%Y%m%d_T%H%M%S', dtimeIn=False, Test=True)[source]¶
-

Create and save a Ves object from givn input file or Ves object

-

A Ves object can be created from an input file, a np.ndarray or another Ves object

- --- - - - - - -
Parameters:
    -
  • Name (str) – The name to be given to the created Ves instance
  • -
  • Poly (None / str / tofu.geom.Ves / np.ndarray) –
    -
    The source where the polygon is to be found, either:
    -
      -
    • str: the name of a file containing the coordinates of a polygon to be loaded with numpy.loadtxt()
    • -
    • A tofu.geom.Ves object: to re-use its Poly attribute and build one with different name
    • -
    • np.ndarray: an 2-dimensional array containing the 2D cartesian coordinates of a polygon
    • -
    -
    -
    -
  • -
  • shot (int) – A shot number, to be used as a reference point in time, marking from when the provided geometry is valid
  • -
  • SavePathInp (None / str) – If provided, forces the routine to search for the input file at SavePathInp, if not provided SavePathInp is automatically set to default (i.e. tofu/plugin/Ves/Inputs/)
  • -
  • SavePathObj (None / str) – If provided, forces the routine to save the created instance at SavePathObj, if not provided SavePathObj is automatically set to default (i.e. tofu/plugin/Ves/Objects/)
  • -
  • Root (str) – If SavePathObj=None, a default value is created by appending ‘/tofu/plugins/ITER/Ves/Objects/’ to Root
  • -
  • save (bool) – Flag indicating whether the created Ves instance shall be saved automatically (in SavePathObj)
  • -
  • skiprows (int) – Parameter fed to np.loadtxt() for reading the polygon from a txt file
  • -
  • comments (str) – Parameter fed to np.loadtxt() for reading the polygon from a txt file
  • -
  • units (str) – Flag indicating in which units the input polygon is provided (in [‘m’,’cm’,’mm’])
  • -
  • dtime (None / dtm.datetime) – A datetime instance used for labelling the created instance (mostly used for debugging)
  • -
  • dtFormat (str) – The format of the labelling (mostly used for debugging)
  • -
  • dtimeIn (bool) – Flag indicating whether to include the label in the file name (mostly used for debugging)
  • -
  • Test (bool) – Flag indicating whether the inpurts should be checked for conformity
  • -
-
Returns:

Ves (tofu.geom.Ves) – The created tfg.Ves instance

-
-
- -
-
-tofu.plugins.ITER.Ves.load(Name=None, SavePathObj=None, Root='/afs/ipp-garching.mpg.de/home/d/didiv/Python/tofu', Test=True)[source]¶
-

Load and return the selected Ves object (selected by name or file name)

-

Several Ves object might exist for the same experiment depending changes to the experiment in time for example -This function loads the one specified by its name.

- --- - - - - - -
Parameters:
    -
  • Name (str / list) – Name of the file to be loaded, or a subset of this name or a list of subsets, the file with a name matching all the subsets will be loaded. An error is issued in case of ambiguity (no or several matches)
  • -
  • SavePathObj (None / str) – Absolute path where the objects can be found, if None sets to default
  • -
  • Root (str) – If SavePathObj=None, a default value is created by appending ‘/tofu/plugins/AUG/Ves/Objects/’ to Root
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

Ves (tofu.geom.Ves) – The loaded Ves object

-
-
- -
-
-

4.1.2.2. ITER.Struct¶

-

Contains all functions specific to the ITER structural elements

-
-
-tofu.plugins.ITER.Struct.plot(Elt='BPV', EltStruct='P', EltVes='P', Lax=None, Proj='Cross', shot=0, SavePathInp='/afs/ipp-garching.mpg.de/home/d/didiv/Python/tofu/tofu/plugins/ITER/Struct/Inputs/', SavePathObj='/afs/ipp-garching.mpg.de/home/d/didiv/Python/tofu/tofu/plugins/ITER/Struct/Objects/', Ves=None, NameVes=None, SavePathVes=None, skiprows=0, comments='#', units='mm', dtime=None, dtFormat='D%Y%m%d_T%H%M%S', dtimeIn=False, Test=True)[source]¶
-

Create and plot the required Struct object on the required axes

-

The coordinates of the polygons of the Struct objects are taken from SavePathInp

- --- - - - - - -
Parameters:
    -
  • Elt (str) –
    -
    Flag indicating which elements to plot, one capital letter per element
    -
      -
    • ‘B’ : the Beams
    • -
    • ‘P’ : the ports
    • -
    • ‘V’ : the associated Ves object
    • -
    -
    -
    -
  • -
  • Lax (None / plt.Axes / list) – If provided, the axes or list of axes on which the poloidal and / or horizontal projections of the structure elements shall be plotted
  • -
  • shot (int) – A shot number, to be used as a reference point in time, marking from when the provided geometry is valid
  • -
  • SavePathInp (None / str) – If provided, forces the routine to search for the input file at SavePathInp, if not provided SavePathInp is automatically set to default (i.e. tofu/plugin/Ves/Inputs/)
  • -
  • SavePathObj (None / str) – (optional) Absolute path where the created object will be saved
  • -
  • Ves (None / tofu.geom.Ves) – If provided, associates the Struct objects with this Ves object, otherwise a default Ves is loaded from SavePathVes if provided
  • -
  • NameVes (str) – Use if Ves is not provided, fed to tofu.plugins.ITER.Ves.load() for loading a default Ves
  • -
  • SavePathVes (None / str) – If provided, path from which a default Ves object can be loaded
  • -
  • skiprows (int) – Parameter fed to np.loadtxt() for reading the polygon from a txt file
  • -
  • comments (str) – Parameter fed to np.loadtxt() for reading the polygon from a txt file
  • -
  • units (str) – Flag indicating in which units the input polygon is provided (in [‘m’,’cm’,’mm’])
  • -
  • dtime (None / dtm.datetime) – A datetime instance used for labelling the created instance (mostly used for debugging)
  • -
  • dtFormat (str) – The format of the labelling (mostly used for debugging)
  • -
  • dtimeIn (bool) – Flag indicating whether to include the label in the file name (mostly used for debugging)
  • -
  • Test (bool) – Flag indicating whether the inpurts should be checked for conformity
  • -
-
Returns:

LS (list) – The list of all created tofu.geom.Struct instances

-
-
- -
-
-

4.1.2.3. ITER.Bolo.geom¶

-
-
-tofu.plugins.ITER.Bolo.geom.create_Apert(Name, Ves, Poly, shot=0, SavePathVes='/afs/ipp-garching.mpg.de/home/g/gav/ToFu_ITER/Objects_ITER/', SavePathObj='/afs/ipp-garching.mpg.de/home/g/gav/ToFu_ITER/Objects_ITER/', SavePathInp='/afs/ipp-garching.mpg.de/home/g/gav/ToFu_ITER/Inputs_ITER/', comments='#', skiprows=0, units='m', save=True)[source]¶
-

Create a Apert object (i.e.: aperture) with specified Name from either a file (.dat,.txt,.csv) or directly from a (2,N) or (N,2) numpy array -Object is created, Saved in SavePathObj and returned -If an input file is specified and the file name does not include an absolute path, the path specified in SavePathInp is used

- --- - - - - - -
Parameters:
    -
  • Name (str) – Name of the object to be created
  • -
  • Ves (str / tofu.geom.Ves) – Ves object to which the aperture is associated, a file name can also be used if the Ves object was previously Saved
  • -
  • Poly (str / np.ndarray) – Numpy array or input file name (fed to numpy.loadtxt) used to specify the polygon to be used (should be (2,N) or (N,2) for N points)
  • -
  • shot (int) – Shot number from which the provided geometry is valid (useful for geometry changes bewteen campaigns)
  • -
  • SavePathVes (None / str) – (optional) if Ves is a str (i.e.: file name) or a list (i.e.: list of strings contained in the file name), specifies the path at which the file is to be found
  • -
  • SavePathObj (None / str) – (optional) Absolute path where the created object will be saved
  • -
  • SavePathInp (None / str) – (optional) Absolute path where the input file is to be found
  • -
  • comments (str) – (optional) str specifying the flag for comments in the Poly file (if Poly is a file name), fed to numpy.loadtxt
  • -
  • skiprows (int) – (optional) number of rows to be skipped in the Poly file (if Poly is a file name), fed to numpy.loadtxt
  • -
  • units (str) – Flag indicating in which units the input polygon is provided (in [‘m’,’cm’,’mm’])
  • -
  • save (bool) – (optional) Flag indicating whether the created object should be Saved
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

Apert (tofu.geom.Apert) – The created Apert object

-
-
- -
-
-tofu.plugins.ITER.Bolo.geom.create_Detect(Name, Ves, Poly, LApert, shot=0, SavePathVes='/afs/ipp-garching.mpg.de/home/g/gav/ToFu_ITER/Objects_ITER/', SavePathObj='/afs/ipp-garching.mpg.de/home/g/gav/ToFu_ITER/Objects_ITER/', SavePathInp='/afs/ipp-garching.mpg.de/home/g/gav/ToFu_ITER/Inputs_ITER/', comments='#', skiprows=0, Cone_DRY=0.0025, Cone_DXTheta=0.0030679615757712823, Cone_DZ=0.0025, Cone_NPsi=20, Cone_Nk=60, Synth_dX12=[0.005, 0.005], Synth_dX12Mode='abs', Synth_ds=0.005, Synth_dsMode='abs', Synth_Colis=True, Calc=True, CalcEtend=True, CalcSpanImp=True, CalcCone=True, CalcPreComp=True, save=True, save_SynthDiag=False)[source]¶
-

Create a tofu.geom.Detect object (i.e.: detector) with specified Name from either a file (.dat,.txt,.csv) or directly from a (2,N) or (N,2) numpy array -Object is created, optionally Saved in SavePathObj and returned -If an input file is specified and the file name does not include an absolute path, the path specified in SavePathInp is used

- --- - - - - - -
Parameters:
    -
  • Name (str) – Name of the object to be created
  • -
  • Ves (tofu.geom.Ves or str) – Ves object to which the aperture is associated, a file name can also be used if the Ves object was previously Saved
  • -
  • Poly (str or np.ndarray) – Numpy array or input file name (fed to numpy.loadtxt) used to specify the polygon to be used (should be (2,N) or (N,2) for N points)
  • -
  • LApert (list) – List of Apert objects to be associated to the detector
  • -
  • SavePathVes (None / str) – (optional) if Ves is a str (i.e.: file name) or a list (i.e.: list of strings contained in the file name), specifies the path at which the file is to be found
  • -
  • SavePathObj (str) – (optional) Absolute path where the created object will be Saved
  • -
  • SavePathInp (str) – (optional) Absolute path where the input file is to be found
  • -
  • comments (str) – (optional) str specifying the flag for comments in the Poly file (if Poly is a file name), fed to numpy.loadtxt
  • -
  • skiprows (int) – (optional) number of rows to be skipped in the Poly file (if Poly is a file name), fed to numpy.loadtxt
  • -
  • save (bool) – (optional) Flag indicating whether the created object should be Saved
  • -
  • save_SynthDiag (bool) – (optional) Flag indicating whether the pre-computed synthetic diagnostic mesh should also be saved (larger files) or whether it should be recomputed upon loading
  • -
  • compute the VOS, tofu tests all points inside a 3D grid to see if each point is visible from the detector through the apertures or not (To) –
  • -
  • Cone_DR (float) – Resolution of the grid in the R direction, in meters
  • -
  • Cone_DTheta (float) – Resolution of the grid in the toroidal direction, in radians
  • -
  • Cone_DZ (float) – Resolution of the grid in the Z direction, in meters
  • -
  • the particular case when the LOS of the detector lies entirely inside one poloidal cross-section (e.g. (In) –
  • -
  • also computes the integral in the toroidal direction of the solid angle on a regular mesh (for faster computation of the geometry assuming toroidaly invariant basis functions) (tofu) –
  • -
  • regular mesh is defined in 2D, by the distance between a mesh point and the detector (k) and by the poloidal angle between the LOS and the line going from the detector to the mesh point (psi) (This) –
  • -
  • Cone_NPsi (20) – Number of points of the regular mesh in psi direction (angle)
  • -
  • Cone_Nk (60) – Number of points of the regular mesh in k direction (distance)
  • -
  • compute synthetic signal faster for any simulated emissivity, tofu can pre-compute a 3D mesh of the VOS and store it, with the associates solid angles (To) –
  • -
  • 3D mesh is computed with respect to the LOS. One coordinate (s) is the distance along the LOS, the two others (1 and 2) are the distances in directions perpendicular to the LOS (This) –
  • -
  • Synth_dX12 (list) – Resolution of the mesh in the two directions perpendicular to the LOS
  • -
  • Synth_dX12Mode (str) – Flag indicating whether dX12 is an absolute value (‘abs’, in meters) or a fraction of the maximum local with of the VOS (‘rel’)
  • -
  • Synth_ds (float) – Resolution of the mesh in the direction parallel to the LOS
  • -
  • Synth_dsMode (str) – Flag indicating whether ds is an absolute value (‘abs’, in meters) or a fraction of the maximum local with of the VOS (‘rel’)
  • -
  • Synth_Colis (bool) – Flag indicating whether the collision detection should be activated
  • -
-
Returns:

Detect (TFG.Detect) – The created TFG.Detect object

-
-
- -
-
-tofu.plugins.ITER.Bolo.geom.create_GDetect(Name, LDetect, SavePathObj='/afs/ipp-garching.mpg.de/home/g/gav/ToFu_ITER/Objects_ITER/', save=True, save_SynthDiag=False)[source]¶
-

Create a tofu.geom.GDetect object (i.e.: group of detectors, or camera) with specified Name from a list of Detect objects -Object is created, optionally Saved in SavePathObj and returned

- --- - - - - - -
Parameters:
    -
  • Name (str) – Name of the object to be created
  • -
  • LDetect (list) – List of already-created Detect objects
  • -
  • SavePathObj (str) – (optional) Absolute path where the created object will be Saved
  • -
  • save (bool) – (optional) Flag indicating whether the created object should be Saved
  • -
  • save_SynthDiag (bool) – (optional) Flag indicating whether the pre-computed synthetic diagnostic mesh should also be saved (larger files) or whether it should be recomputed upon loading
  • -
-
Returns:

GD (tofu.geom.GDetect) – The created object

-
-
- -
-
-tofu.plugins.ITER.Bolo.geom.load(Name, Cls='GDetect', SavePathObj='/afs/ipp-garching.mpg.de/home/g/gav/ToFu_ITER/Objects_ITER/')[source]¶
-

Load the desired object, identified by name and saving path

-

Searches in SavePathObj a ToFu object of the specified class (Cls) saved under the specified name (Name). -If a single match is found, the object is loaded and returned, otherwise an error is raised

- --- - - - -
Parameters:
    -
  • Name (str) – Name of the object
  • -
  • Cls (str) – Class of the object, in [‘Ves’,’Apert’,’Detect’,’GDetect’]
  • -
  • SavePathObj (str) – Path under which the object is to be found
  • -
-
-
- -
-
-

4.1.2.4. Indices and tables¶

- -
-
- - -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/build/html/Auto_tofu.plugins.html b/doc/build/html/Auto_tofu.plugins.html deleted file mode 100644 index f2c255070..000000000 --- a/doc/build/html/Auto_tofu.plugins.html +++ /dev/null @@ -1,153 +0,0 @@ - - - - - - - - 4. tofu.plugins — tofu v1.1 - - - - - - - - - - - - - - - - -
-
-
-
- -
-

4. tofu.plugins¶

-

In an effort to adapt ToFu to several experiments and ensure a smooth use for non-specialists users, plugins can be developped to adapt ToFu to the local specificities of each laboratory or environment (local computer systems and networks, local geometry and nomenclature, local data storing systems...).

-

While ToFu in itself is open-source, the plugins, which concentrate everything that is machine-specific, are writen on demand and customized for the local needs, they remain on the local servers and are not provided on the GitHub page of ToFu. It is via the laboratories that you may have access to them.

-

The following plugins have been / are being developped:

-
-

4.1. Machine-oriented plugins¶

- -
-
-

4.2. Code-oriented plugins¶

-
    -
  1. CAID
  2. -
-
-
-

4.3. Indices and tables¶

- -
-
- - -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/build/html/Auto_tofu.treat.html b/doc/build/html/Auto_tofu.treat.html deleted file mode 100644 index 00e75dcd3..000000000 --- a/doc/build/html/Auto_tofu.treat.html +++ /dev/null @@ -1,605 +0,0 @@ - - - - - - - - 2. tofu.treat — tofu v1.1 - - - - - - - - - - - - - - - - -
-
-
-
- -
-

2. tofu.treat¶

-

Provide data handling class and methods (storing, processing, plotting...)

-
-
-class tofu.treat.PreData(data, t=None, Chans=None, Id=None, Exp='AUG', shot=None, Diag='SXR', dtime=None, dtimeIn=False, SavePath=None, LIdDet=None, DtRef=None, MovMeanfreq=100, Resamp=True, interpkind='linear', indOut=None, indCorr=None, DF=None, Harm=True, DFEx=None, HarmEx=True, lt=[], lNames=[], Calc=True)[source]¶
-

A class defining a data-handling object, data is stored as read-only attribute, copies of it can be modified, methods for plotting, saving...

-

The name of the class refers to Pre-treatment Data (i.e.: in the context of tomography, data that is pre-treated before being fed to an inversion algorithm). -ToFu provide a generic data-handling class, which comes a robust data storing policy: the input data is stored in a read-only attribute and the data-processing methods are used on a copy (e.g.: for computing the SVD, Fourier transform, shorten the time interval of interest, eliminate some channels...). -Furthermore, methods for interactive plotting are provided as well as a saving method

-
-
obj
- : PreData
The created instance
-
-
-
-Corr_add(Val=[], LCrit=['Name', 'Cam', 'CamHead'], indCorr=None, Calc=True)[source]¶
-

Add channels to the list of channels that are thought to need correction

-

When a channel is suspected to need correction (mismatching retrofit due for example to wrong calibration), it can be included in a dedicated correction list. -Channels in this list can then be discarded for the inversion, a correction coefficient can be computed from the retrofit, and the inversion can be re-done using this correction coefficient. -This list works like the list of excluded / corrupted channels self.Out_list()

- --- - - - -
Parameters:
    -
  • Val (list) – Fed to self.select(), list of values for criteria in LCrit that should be used to exclude channels (e.g.: list of channel names of camera names)
  • -
  • LCrit (list) – Fed to self.select(), list of criteria against which to select the channels matching the values in Val (should be attributes of tofu.pathfile.ID or of its USRdict attribute)
  • -
  • indCorr (None / np.ndarray) – Alternatively, you can directly pass a (N,) bool array whereN matches the number of channels and True means that a channel should be excluded, thus setting self._indCorr
  • -
  • Calc (bool) – Flag indicating whether the calculation should be triggered immediately
  • -
-
-
- -
-
-Corr_list(Out='Name')[source]¶
-

Return the list of channel names needing correction

-

This lists the channels indicated by self._indOut, populated using self.Out_add() and de-populated using self.In_add(). -The output can be returned as a list of channel Names

- --- - - - - - -
Parameters:Out (str) – Flag indicating in which form to return the output (fed to select())
Returns:L (list) – List of excluded channels in the required form
-
- -
-
-Corr_remove(Val=[], LCrit=['Name', 'Cam', 'CamHead'], Calc=True)[source]¶
-

Add channels to the list of channels to be re-inserted as valid channels

-

Works like self.In_add() (i.e.: opposite of self.Corr_add())

- --- - - - -
Parameters:
    -
  • Val (list) – Fed to self.select(), list of values for criteria in LCrit that should be used to exclude channels (e.g.: list of channel names of camera names)
  • -
  • LCrit (list) – Fed to self.select(), list of criteria against which to select the channels matching the values in Val (should be attributes of tofu.pathfile.ID or of its USRdict attribute)
  • -
  • indCorr (None / np.ndarray) – Alternatively, you can directly pass a (N,) bool array whereN matches the number of channels and True means that a channel should be excluded, thus setting self._indCorr
  • -
  • Calc (bool) – Flag indicating whether the calculation should be triggered immediately
  • -
-
-
- -
-
-In_add(LVal=[], LCrit=['Name', 'Cam', 'CamHead'], Calc=True)[source]¶
-

Add channels to the list of channels to be re-included as valid channels

-

Provides a mechanism opposite to Out_add(). -We you change your mind about a series of channel and think they should be re-included as valid, pass them to this method using the same arguments as self.Out_add()

- --- - - - -
Parameters:
    -
  • Val (list) – Fed to self.select(), list of values for criteria in LCrit that should be used to exclude channels (e.g.: list of channel names of camera names)
  • -
  • LCrit (list) – Fed to self.select(), list of criteria against which to select the channels matching the values in Val (should be attributes of tofu.pathfile.ID or of its USRdict attribute)
  • -
  • indOut (None / np.ndarray) – Alternatively, you can directly pass a (N,) bool array whereN matches the number of channels and True means that a channel should be excluded, thus setting self._indOut
  • -
  • Calc (bool) – Flag indicating whether the calculation should be triggered immediately
  • -
-
-
- -
-
-In_list(Out='Name')[source]¶
-

Return the list of included channel names (considered valid)

-

The equivalent of Out_list(), but this time returning the complementary list

- --- - - - - - -
Parameters:Out (str) – Flag indicating in which form to return the output (fed to select())
Returns:L (list) – List of excluded channels in the required form
-
- -
-
-Out_add(Val=[], LCrit=['Name', 'Cam', 'CamHead'], indOut=None, Calc=True)[source]¶
-

Add desired channels to the list of channels to be excluded

-

It is possible to store a list a list of channels that are thought to be corrupted or more generally that, after closer inspection, are considered not fit. -This list is then automatically passed on to further ToFu objects (e.g.: for inversions), so that the corresponding data is excluded from all further processes. -PreData provides methods to append channel names to this list (in fact you can even exclude whole cameras).

- --- - - - -
Parameters:
    -
  • Val (list) – Fed to self.select(), list of values for criteria in LCrit that should be used to exclude channels (e.g.: list of channel names of camera names)
  • -
  • LCrit (list) – Fed to self.select(), list of criteria against which to select the channels matching the values in Val (should be attributes of tofu.pathfile.ID or of its USRdict attribute)
  • -
  • indOut (None / np.ndarray) – Alternatively, you can directly pass a (N,) bool array whereN matches the number of channels and True means that a channel should be excluded, thus setting self._indOut
  • -
  • Calc (bool) – Flag indicating whether the calculation should be triggered immediately
  • -
-
-
- -
-
-Out_list(Out='Name')[source]¶
-

Return the list of excluded channel names (considered corrupted)

-

This lists the channels indicated by self._indOut, populated using self.Out_add() and de-populated using self.In_add(). -The output can be returned as a list of channel Names

- --- - - - - - -
Parameters:Out (str) – Flag indicating in which form to return the output (fed to select())
Returns:L (list) – List of excluded channels in the required form
-
- -
-
-interp(lt=[], lNames=[], Calc=True)[source]¶
-

Perform linear interpolation of data at chosen times for chosen channels

-

As opposed to self.set_t(), this method shall be used to interpolate data of a small number of channels at a small sumber of time points. -Use this to correct a small number of time points that are clearly corrupted when you think the rest shall be preserved.

-

!!! This is done with respect to the reference time vector and dataset, to avoid propagating errors through later data treatment (use self.plot(V=’Ref’) to plot the reference data set) !!!

- --- - - - -
Parameters:
    -
  • lt (list) – Times at which linear interpolation should be performed
  • -
  • lNames (list) –
    -
    Channels for which interpolation should be performed, one element per corresponding time point, elements can be:
    -
      -
    • list of str: list of channel names that should be interpolated for the corresponding time point
    • -
    • str: single channel name that should be interpolated for the corresponding time point
    • -
    • ‘All’: all channels should be interpolated for the corresponding time point
    • -
    -
    -
    -
  • -
  • Calc (bool) – Flag indicating whether data should be updated immediately
  • -
-
-

Examples

-
-
>> obj.interp(lt=[2.55, 5.10, 6.84], lNames=[[‘H_021’,’J_014’], ‘F_10’, ‘All’], Calc=True)
-
Will perform interpolation for 2 channels for the first time point, for one channel for the second, and for all channels for the last time point
-
-
- -
-
-plot(a4=False)[source]¶
-

Plot the signal in an interactive window, no arguments needed

-

Plot an interactive matplotlib window to explore the data

- --- - - - - - -
Parameters:a4 (bool) – Flag indicating whether the figure should be the size of a a4 sheet of paper (to facilitate printing)
Returns:Lax (list) – List of plt.Axes on which the plots are made
-
- -
-
-plot_fft(Val=None, Crit='Name', V='simple', tselect=None, Fselect=None, PreExp=None, PostExp=None, Log='or', InOut='In', SpectNorm=True, DTF=None, RatDef=100.0, Inst=True, MainF=True, ylim=(None, None), cmap=<matplotlib.colors.LinearSegmentedColormap object>, a4=False)[source]¶
-

Plot the power spectrum (fft) of the chosen signals

-

Computes the fft of the data and plots the power spectrum, normalized or not, for the chosen channels

-

Parameters Val, Crit, PreExp, PostExp, Log and InOut are for channel selection and are fed to select()

- --- - - - - - -
Parameters:
    -
  • V (str) – Flag indicating whether the plot should be interactive, values in [‘simple’,’inter’]
  • -
  • tselect (None /) –
  • -
  • Fselect (None /) –
  • -
  • SpectNorm (bool) – Flag, if True the power spectrum is normalised to its maximum at each time step (default: True)
  • -
  • DTF (float) – Size (in seconds) of the running time window to be used for the windowed fft
  • -
  • RatDef (float) – Used if DTF not provided, the number by which the total signal duration is divided to get a time window
  • -
  • Inst (bool) – Flag, if true, the average of the signal is substracted at each time step to emphasize high frequencies (higher than the one associated to the running time window, default: True)
  • -
  • MainF (bool) – Flag
  • -
  • ylim (tuple) – Each limit which is not None is fed to plt.Axes.set_ylim()
  • -
  • a4 (bool) – Flag, if true the figure is sized so as to fill a a4 paper sheet
  • -
-
Returns:

Lax (list) – List of plt.Axes on which the plots were made

-
-
- -
-
-plot_svd(Modes=10, NRef=None, a4=False, Test=True)[source]¶
-

Plot the chosen modes (topos and chronos) of the svd of the data, and the associated spectrum on a separate figure

-

Performs a svd of the data and plots the singular values, the temporal and spacial modes

-
-
Modes
- : int / iterable
-
Index of the modes to be plotted, the modes and sorted in decreasing order of singular value
-
    -
  • int : plots all modes in range(0,Modes)
  • -
  • iterable : plots all modes whose index is contained in Modes
  • -
-
-
-
-
NRef
- : None
Number of columns in the plot, if None set to len(Modes)/2 (i.e.: 2 modes plotted per axes)
-
a4
- : bool
Flag indicating whether the figure should be the size of a a4 sheet of paper (to facilitate printing)
-
Test
- : bool
Flag indicating whether the inputs should be tested for conformity
-
- --- - - - -
Returns:Lax (list) – List of plt.Axes on which the plots were made
-
- -
-
-save(SaveName=None, Path=None, Mode='npz', compressed=False)[source]¶
-

Save the object in folder Name, under file name SaveName, using specified mode

-

Most tofu objects can be saved automatically as numpy arrays (.npz, recommended) at the default location (recommended) by simply calling self.save()

- --- - - - -
Parameters:
    -
  • SaveName (None / str) – The name to be used for the saved file, if None (recommended) uses self.Id.SaveName
  • -
  • Path (None / str) – Path specifying where to save the file, if None (recommended) uses self.Id.SavePath
  • -
  • Mode (str) – Flag specifying whether to save the object as a numpy array file (‘.npz’, recommended) or an object using cPickle (not recommended, heavier and may cause retro-compatibility issues)
  • -
  • compressed (bool) – Flag, used when Mode=’npz’, indicating whether to use np.savez or np.savez_compressed (slower saving and loading but smaller files)
  • -
-
-
- -
-
-select(Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In', Out=<type 'bool'>, ToIn=False)[source]¶
-

Return a sub-set of the data (channels-wise selection)

-

Return an array of indices of channels selected according to the chosen criteria with chosen values -Use either Val or (PreExp and PostExp)

- --- - - - - - -
Parameters:
    -
  • Val (list or str) – List of values that the chosen criteria must match (converted to one-item list if str)
  • -
  • Crit (str) – Criterion used to select some channels, must be among their tfpf.ID class attributes (e.g.: ‘Name’, ‘SaveName’...) or IFTF.ID.USRdict (‘Cam’,...)
  • -
  • PreExp (list or str) – List of str expressions to be fed to eval(PreExp[ii]+” Detect.Crit “+PostExp[ii]) or eval(PreExp[ii]+” Detect.USRdict.Crit “+PostExp[ii])
  • -
  • PostExp (list or str) – List of str expressions to be fed to eval(PreExp[ii]+” Detect.Crit “+PostExp[ii]) or eval(PreExp[ii]+” Detect.USRdict.Crit “+PostExp[ii])
  • -
  • Log (str) – Flag (‘or’ or ‘and’) indicating whether to select the channels matching all criteria or any
  • -
  • InOut (str) – Flag (‘In’ or ‘Out’) indicating whether to select all channels matching the criterion, or all except those
  • -
  • Out (type or str) – Flag (bool, int or an attribute of tfpf.ID or tfpf.ID.USRdict) indicating whether to return an array of boolean indices or int indices, or a list of the chosen attributes (e.g.: ‘Name’)
  • -
  • ToIn (bool) – Flag indicating whether indices should be returned with respect to the channels that are considered as included only (see obj.In_list() to see these channels)
  • -
-
Returns:

ind (np.ndarray) – Indices of the selected channels, as a bool or int array

-
-

Examples

-
-
>> ind = TFT.PreData.select(Val=[‘H’,’J’], Crit=’Cam’, Log=’any’, InOut=’In’, Out=bool)
-
Will return a bool array of the indices of all channels for which ‘Cam’ is ‘H’ or ‘J’
-
>> ind = PreData.select(Crit=’Name’, PreExp=[“‘F’ in ”, “‘6’ in “], Log=’and’, InOut=’In’, Out=int)
-
Will return an int array of indices of all channels for which ‘F’ and ‘6’ are both included in the name
-
>> ind = PreData.select(Crit=’CamHead’, PreExp=[“‘F’ in ”, “‘2’ in “], Log=’any’, InOut=’Out’, Out=’Name’)
-
Will return the names (as a list) of all channels except those that have a camera head name that includes a ‘F’ or a ‘2’ (i.e.: except camera heads ‘F’ and ‘H2’, ‘I2’, ‘J2’, ‘K2’)
-
-
- -
-
-set_Dt(Dt=None, Calc=True)[source]¶
-

Set the time interval to which the data should be limited (does not affect the reference data)

-

While the original data set and time base are always preserved in the background, you can change your mind and focus on a smaller interval included in the original one. -This can be convenient for applying data treatment (SVD, fft...) to parts of the signal lifetime only.

- --- - - - -
Parameters:
    -
  • Dt (None / list) – The time interval of interest, as a list of len()=2 in increasing values
  • -
  • Calc (bool) – Flag indicating whether the calculation should be triggered immediately
  • -
-
-
- -
-
-set_PhysNoise(Mode='svd', Phys=[0, 1, 2, 3, 4, 5, 6, 7], DF=[10000.0, 11000.0], DFEx=None, Harm=True, HarmEx=True, Deg=0, Nbin=3, LimRatio=0.05, Plot=False)[source]¶
-

Use a svd or a fft to estimate the physical part of the signal and the part which can be assimilated to noise, then uses specified degree for polynomial noise model

-

This method provides an easy way to compute the noise level on each channel. -It can be done in 2 different ways:

-
-
    -
  • ‘svd’: you have to provide the mode numbers that you think can be considered as physical, the signal will be re-constructed from these and the rest discarded as noise
  • -
  • ‘fft’: you have to provide the frequency window that you think is physical (optionaly the higher harmonics can be included), the signal is re-constructed via inverse fourier and the rest discarded as noise
  • -
-
-

To help you decide which mode numbers of frequency interval to use, you can preliminarily use self.plot_svd() and self.plot_fft() to visualize the decompositions.

-

Note : this is only used to compute a noise estimate, stored separately, the total original signal is preserved

- --- - - - -
Parameters:
    -
  • Mode (str) – Flag indicating with which method should the noise be estimated (‘svd’ or ‘fft’)
  • -
  • list (DFEx) – Modes to be extracted from the svd (default: first 8 modes), use method .plot_svd() to choose the modes
  • -
  • list – 2 values delimiting a frequency interval (in Hz) from which to extract signal using a fft and rfft
  • -
  • bool (Plot) – Flag, if True all the available higher harmonics of FreqIn will also be included in the physical signal
  • -
  • list – 2 values delimiting a frequency interval (in Hz) that shall be avoided in the physical signal (relevant if some high harmonics of DF intersect DFEx)
  • -
  • bool – Flag, if True all the available higher harmonics of Freqout will also be avoided in the physical signal
  • -
  • int (Nbin) – Degree to be used for the polynomial noise model
  • -
  • int – Number of bins to be used for evaluating the noise (std) at various signal values
  • -
  • float (LimRatio) – Ratio ... to be finished...
  • -
  • bool – Flag, if True the histogram of the estimated noise is plotted
  • -
-
-

Examples

-
-
>> obj.set_PhysNoise(Mode=’svd’, Phys=[0,1,2,3,4,5], Deg=0)
-
Will take the first 6 modes of the signal svd and consider as physical, the rest is used to compute a constant (Deg=0) noise estimate on each channel
-
-
- -
-
-set_Resamp(t=None, f=None, Method='movavrg', interpkind='linear', Calc=True)[source]¶
-

Re-sample the data and time vector

-
-
Use a new time vector that can either be:
-
    -
  • provided directly (if t is not None)
  • -
  • computed from an input sampling frequency (if f is not None)
  • -
-
-
-

If but t and f are provided, t is used as the time vector and f is only used for the moving average

-

Then, the data is re-computed on this new time vector using either interpolation (‘interp’) or moving average (‘movavrg’)

- --- - - - -
Parameters:
    -
  • t (None / np.ndarray) –
  • -
  • f (None / int / float) –
  • -
  • Method (str) –
  • -
  • Resamp (bool) –
  • -
  • interpkind (str) –
  • -
  • Calc (bool) – Flag indicating whether the calculation should be triggered immediately
  • -
-
-
- -
-
-set_fft(DF=None, Harm=True, DFEx=None, HarmEx=True, Calc=True)[source]¶
-

Return the FFT-filtered signal (and the rest) in the chosen frequency window (in Hz) and in all the higher harmonics (optional)

-

Can also exclude a given interval and its higher harmonics from the filtering (optional)

- --- - - - -
Parameters:
    -
  • DF (iterable) – Iterable of len()=2, containing the lower and upper bounds of the frequency interval (Hz) to be used for filtering
  • -
  • Harm (bool) – If True all the higher harmonics of the interval DF will also be included
  • -
  • DFEx (list) – List or tuple of len()=2, containing the lower and upper bounds of the frequency interval to be excluded from filtering (in case it overlaps with some high harmonics of DF)
  • -
  • HarmEx (bool) – If True all the higher harmonics of the interval DFEx will also be excluded
  • -
-
-
- -
-
-substract_Dt(tsub=None, Calc=True)[source]¶
-

Allows subtraction of data at one time step from all data

-

Can be convenient for plotting background-subtracted signal (background meaning signal before a reference time step).

- --- - - - -
Parameters:
    -
  • tsub (int / float / iterable) –
    -
    A time value, or a time interval indicating which part of the signal is to be considered as reference and subtracted from the rest
    -
      -
    • int / float :
    • -
    -
    -
    -
  • -
  • Calc (bool) – Flag indicating whether data should be updated immediately
  • -
-
-
- -
- -
-

2.1. Indices and tables¶

- -
-
- - -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/build/html/Autodoc.html b/doc/build/html/Autodoc.html deleted file mode 100644 index 20fe79bd2..000000000 --- a/doc/build/html/Autodoc.html +++ /dev/null @@ -1,2256 +0,0 @@ - - - - - - - - tofu.geom — tofu v1.1 - - - - - - - - - - - - - - - -
-
-
-
- -
-

tofu.geom¶

-

Load all core packages and modules which are all machine-independent, diagnostic-independent and code-independent

-

Created on Wed May 18 2016

-

@version: 0.9 -@author: didiervezinet -@author_email: didier.vezinet@gmail.com

-
-
-class tofu.geom.Ves(Id, Poly, Type='Tor', DLong=None, Sino_RefPt=None, Sino_NP=50, Clock=False, arrayorder='C', Exp=None, shot=None, dtime=None, dtimeIn=False, SavePath=None)[source]¶
-

A class defining a Linear or Toroidal vaccum vessel (i.e. a 2D polygon representing a cross-section and assumed to be linearly or toroidally invariant)

-

A Ves object is mostly defined by a close 2D polygon, which can be understood as a poloidal cross-section in (R,Z) cylindrical coordinates if Type=’Tor’ (toroidal shape) or as a straight cross-section through a cylinder in (Y,Z) cartesian coordinates if Type=’Lin’ (linear shape). -Attributes such as the surface, the angular volume (if Type=’Tor’) or the center of mass are automatically computed. -The instance is identified thanks to an attribute Id (which is itself a tofu.ID class object) which contains informations on the specific instance (name, Type...).

- --- - - - - - -
Parameters:
    -
  • Id (str / tfpf.ID) – A name string or a pre-built tfpf.ID class to be used to identify this particular instance, if a string is provided, it is fed to tfpf.ID()
  • -
  • Poly (np.ndarray) – An array (2,N) or (N,2) defining the contour of the vacuum vessel in a cross-section, if not closed, will be closed automatically
  • -
  • Type (str) – Flag indicating whether the vessel will be a torus (‘Tor’) or a linear device (‘Lin’)
  • -
  • DLong (list / np.ndarray) – Array or list of len=2 indicating the limits of the linear device volume on the x axis
  • -
  • Sino_RefPt (None / np.ndarray) – Array specifying a reference point for computing the sinogram (i.e. impact parameter), if None automatically set to the (surfacic) center of mass of the cross-section
  • -
  • Sino_NP (int) – Number of points in [0,2*pi] to be used to plot the vessel sinogram envelop
  • -
  • Clock (bool) – Flag indicating whether the input polygon should be made clockwise (True) or counter-clockwise (False)
  • -
  • arrayorder (str) – Flag indicating whether the attributes of type=np.ndarray (e.g.: Poly) should be made C-contiguous (‘C’) or Fortran-contiguous (‘F’)
  • -
  • Exp (None / str) – Flag indicating which experiment the object corresponds to, allowed values are in [None,’AUG’,’MISTRAL’,’JET’,’ITER’,’TCV’,’TS’,’Misc’]
  • -
  • shot (None / int) – Shot number from which this Ves is usable (in case of change of geometry)
  • -
  • SavePath (None / str) – If provided, forces the default saving path of the object to the provided value
  • -
  • dtime (None / dtm.datetime) – A time reference to be used to identify this particular instance (used for debugging mostly)
  • -
  • dtimeIn (bool) – Flag indicating whether dtime should be included in the SaveName (used for debugging mostly)
  • -
-
Returns:

Ves (Ves object) – The created Ves object, with all necessary computed attributes and methods

-
-
-
-BaryS¶
-

Return the (surfacic) center of mass of the polygon defining the vessel cross-section

-
- -
-
-BaryV¶
-

Return the (volumic) center of mass of the polygon defining the vessel cross-section

-
- -
-
-Id¶
-

Return the tfpf.ID object of the vessel

-
- -
-
-Poly¶
-

Return the polygon defining the vessel cross-section

-
- -
-
-Sino_NP¶
-

Return the number of points used used for plotting the Ves polygon in projection space

-
- -
-
-Sino_RefPt¶
-

Return the 2D coordinates of the points used as a reference for computing the Ves polygon in projection space (where sinograms are plotted)

-
- -
-
-Surf¶
-

Return the area of the polygon defining the vessel cross-section

-
- -
-
-Type¶
-

Return the type of vessel

-
- -
-
-Vect¶
-

Return the polygon elementary vectors

-
- -
-
-Vin¶
-

Return the normalized vectors pointing inwards for each segment of the polygon

-
- -
-
-VolLin¶
-

Return the angular volume of the polygon defining the vessel cross-section of Tor type

-
- -
-
-arrayorder¶
-

Return the flag indicating which order is used for multi-dimensional array attributes

-
- -
-
-get_InsideConvexPoly(RelOff=0.05, ZLim='Def', Spline=True, Splprms=[100.0, 2.0, 3], NP=100, Plot=False, Test=True)[source]¶
-

Return a polygon that is a smaller and smoothed approximation of Ves.Poly, useful for excluding the divertor region in a Tokamak

-

For some uses, it can be practical to approximate the polygon defining the Ves object (which can be non-convex, like with a divertor), by a simpler, sligthly smaller and convex polygon. -This method provides a fast solution for computing such a proxy.

- --- - - - - - -
Parameters:
    -
  • RelOff (float) – Fraction by which an homothetic polygon should be reduced (1.-RelOff)*(Poly-BaryS)
  • -
  • ZLim (None / str / tuple) – Flag indicating what limits shall be put to the height of the polygon (used for excluding divertor)
  • -
  • Spline (bool) – Flag indiating whether the reduced and truncated polygon shall be smoothed by 2D b-spline curves
  • -
  • Splprms (list) – List of 3 parameters to be used for the smoothing [weights,smoothness,b-spline order], fed to scipy.interpolate.splprep()
  • -
  • NP (int) – Number of points to be used to define the smoothed polygon
  • -
  • Plot (bool) – Flag indicating whether the result shall be plotted for visual inspection
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

Poly (np.ndarray) – (2,N) polygon resulting from homothetic transform, truncating and optional smoothing

-
-
- -
-
-get_MeshCrossSection(CrossMesh=[0.01, 0.01], CrossMeshMode='abs', Test=True)[source]¶
-

Return a (2,N) array of 2D points coordinates meshing the Ves cross-section using the spacing specified by CrossMesh for each direction (taken as absolute distance or relative to the total size)

-

Method used for fast automatic meshing of the cross-section using a rectangular mesh uniform in each direction. -Returns the flattened points coordinates array, as well as the two increasing vectors and number of points.

- --- - - - - - -
Parameters:
    -
  • CrossMesh (iterable) – Iterable of len()==2 specifying the distance to be used between points in each direction (R or Y and Z), in absolute value or relative to the total size of the Ves in each direction
  • -
  • CrossMeshMode (str) – Flag specifying whether the distances provided in CrossMesh are absolute (‘abs’) or relative (‘rel’)
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

    -
  • Pts (np.ndarray) – Array of shape (2,N), comtaining the 2D coordinates of the N points consituting the mesh, only points lying inside the cross-section are returned
  • -
  • X1 (np.ndarray) – Flat array of the unique first coordinates of the mesh points (R or Y)
  • -
  • X2 (np.ndarray) – Flat array of the unique second coordinates of the mesh points (Z)
  • -
  • NumX1 (int) – Number of unique values in X1 (=X1.size)
  • -
  • NumX2 (int) – Number of unique values in X2 (=X2.size)
  • -
-

-
-
- -
-
-isInside(Pts, In='(X, Y, Z)')[source]¶
-

Return an array of booleans indicating whether each point lies inside the Ves volume

-

Tests for each point whether it lies inside the Ves object. -The points coordinates can be provided in 2D or 3D, just specify which coordinate system is provided using the ‘In’ parameter. -An array of boolean flags is returned.

- --- - - - - - -
Parameters:
    -
  • Pts (np.ndarray) – (2,N) or (3,N) array with the coordinates of the points to be tested
  • -
  • In (str) – Flag indicating the coordinate system in which the points are provided, in [‘(X,Y,Z)’,’(R,Z)’,’‘]
  • -
-
Returns:

ind (np.ndarray) – Array of booleans of shape (N,), True if a point is inside the Ves volume

-
-
- -
-
-plot(Lax=None, Proj='All', Elt='PIBsBvV', Pdict=None, Idict={'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, Bsdict={'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, Bvdict={'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, Vdict={'color': 'r', 'scale': 10}, IdictHor={'c': 'k', 'ls': 'dashed'}, BsdictHor={'c': 'b', 'ls': 'dashed'}, BvdictHor={'c': 'g', 'ls': 'dashed'}, Lim=[1.5707963267948966, 6.283185307179586], Nstep=50, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, draw=True, a4=False, Test=True)[source]¶
-

Plot the polygon defining the vessel, with a cross-section view, a longitudinal view or both, and optionally its reference point for plotting it in projection space

-

Generic method for plotting the Ves object, the projections to be plotted, the elements to plot, and the dictionaries or properties to be used for plotting each elements can all be specified using keyword arguments. -If an ax is not provided a default one is created.

- --- - - - - - -
Parameters:
    -
  • Lax (list or plt.Axes) – The axes to be used for plotting (provide a list of 2 axes if Proj=’All’), if None a new figure with axes is created
  • -
  • Proj (str) – Flag specifying the kind of projection used for the plot (‘Cross’ for a cross-section, ‘Hor’ for a horizontal plane, or ‘All’ for the two plots)
  • -
  • Elt (str) –
    -
    Flag specifying which elements to plot, each capital letter corresponds to an element
    -
      -
    • ‘P’: polygon
    • -
    • ‘I’: point used as a reference for computing impact parameters
    • -
    • ‘Bs’: (surfacic) center of mass
    • -
    • ‘Bv’: (volumic) center of mass for Tor type
    • -
    • ‘V’: vector pointing inward perpendicular to each segment defining the polygon
    • -
    -
    -
    -
  • -
  • Pdict (dict or None) – Dictionary of properties used for plotting the polygon, fed to plt.Axes.plot() or plt.plot_surface() if Proj=‘3d’, set to ToFu_Defauts.py if None
  • -
  • Idict (dict) – Dictionary of properties used for plotting point ‘I’ in Cross-section projection, fed to plt.Axes.plot()
  • -
  • IdictHor (dict) – Dictionary of properties used for plotting point ‘I’ in horizontal projection, fed to plt.Axes.plot()
  • -
  • Bsdict (dict) – Dictionary of properties used for plotting point ‘Bs’ in Cross-section projection, fed to plt.Axes.plot()
  • -
  • BsdictHor (dict) – Dictionry of properties used for plotting point ‘Bs’ in horizontal projection, fed to plt.Axes.plot()
  • -
  • Bvdict (dict) – Dictionary of properties used for plotting point ‘Bv’ in Cross-section projection, fed to plt.Axes.plot()
  • -
  • BvdictHor (dict) – Dictionary of properties used for plotting point ‘Bv’ in horizontal projection, fed to plt.Axes.plot()
  • -
  • Vdict (dict) – Dictionary of properties used for plotting point ‘V’ in cross-section projection, fed to plt.Axes.quiver()
  • -
  • LegDict (dict or None) – Dictionary of properties used for plotting the legend, fed to plt.legend(), the legend is not plotted if None
  • -
  • Lim (list or tuple) – Array of a lower and upper limit of angle (rad.) or length for plotting the ‘3d’ Proj
  • -
  • Nstep (int) – Number of points for sampling in ignorable coordinate (toroidal angle or length)
  • -
  • draw (bool) – Flag indicating whether the fig.canvas.draw() shall be called automatically
  • -
  • a4 (bool) – Flag indicating whether the figure should be plotted in a4 dimensions for printing
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

La list or plt.Axes Handles of the axes used for plotting (list if several axes where used)

-
-
- -
-
-plot_Sinogram(Proj='Cross', ax=None, Ang='theta', AngUnit='rad', Sketch=True, Pdict=None, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, draw=True, a4=False, Test=True)[source]¶
-

Plot the sinogram of the vessel polygon, by computing its envelopp in a cross-section, can also plot a 3D version of it

-

The envelop of the polygon is computed using self.Sino_RefPt as a reference point in projection space, and plotted using the provided dictionary of properties. -Optionaly a smal sketch can be included illustrating how the angle and the impact parameters are defined (if the axes is not provided).

- --- - - - - - -
Parameters:
    -
  • Proj (str) – Flag indicating whether to plot a classic sinogram (‘Cross’) from the vessel cross-section (assuming 2D), or an extended 3D version ‘3d’ of it with additional angle
  • -
  • ax (None or plt.Axes) – The axes on which the plot should be done, if None a new figure and axes is created
  • -
  • Ang (str) – Flag indicating which angle to use for the impact parameter, the angle of the line itself (xi) or of its impact parameter (theta)
  • -
  • AngUnit (str) – Flag for the angle units to be displayed, ‘rad’ for radians or ‘deg’ for degrees
  • -
  • Sketch (bool) – Flag indicating whether a small skecth showing the definitions of angles ‘theta’ and ‘xi’ should be included or not
  • -
  • Pdict (dict) – Dictionary of properties used for plotting the polygon envelopp, fed to plt.plot() if Proj=’Cross’ and to plt.plot_surface() if Proj=‘3d’
  • -
  • LegDict (None or dict) – Dictionary of properties used for plotting the legend, fed to plt.legend(), the legend is not plotted if None
  • -
  • draw (bool) – Flag indicating whether the fig.canvas.draw() shall be called automatically
  • -
  • a4 (bool) – Flag indicating whether the figure should be plotted in a4 dimensions for printing
  • -
  • Test (bool) – Flag indicating whether the inputs shall be tested for conformity
  • -
-
Returns:

ax (plt.Axes) – The axes used to plot

-
-
- -
-
-save(SaveName=None, Path=None, Mode='npz')[source]¶
-

Save the object in folder Name, under file name SaveName, using specified mode

-

Most tofu objects can be saved automatically as numpy arrays (.npz, recommended) at the default location (recommended) by simply calling self.save()

- --- - - - -
Parameters:
    -
  • SaveName (None / str) – The name to be used for the saved file, if None (recommended) uses self.Id.SaveName
  • -
  • Path (None / str) – Path specifying where to save the file, if None (recommended) uses self.Id.SavePath
  • -
  • Mode (str) – Flag specifying whether to save the object as a numpy array file (‘.npz’, recommended) or an object using cPickle (not recommended, heavier and may cause retro-compatibility issues)
  • -
-
-
- -
- -
-
-class tofu.geom.Struct(Id, Poly, Type='Tor', DLong=None, Ves=None, Clock=False, arrayorder='C', Exp=None, shot=None, dtime=None, dtimeIn=False, SavePath=None)[source]¶
-

A class defining a Linear or Toroidal structural element (i.e. a 2D polygon representing a cross-section and assumed to be linearly or toroidally invariant), like a Ves but with less properties.

-

A Struct object is mostly defined by a close 2D polygon, which can be understood as a poloidal cross-section in (R,Z) cylindrical coordinates if Type=’Tor’ (toroidal shape) or as a straight cross-section through a cylinder in (Y,Z) cartesian coordinates if Type=’Lin’ (linear shape). -Attributes such as the surface, the angular volume (if Type=’Tor’) or the center of mass are automatically computed. -The instance is identified thanks to an attribute Id (which is itself a tofu.ID class object) which contains informations on the specific instance (name, Type...).

- --- - - - - - -
Parameters:
    -
  • Id (str / tfpf.ID) – A name string or a pre-built tfpf.ID class to be used to identify this particular instance, if a string is provided, it is fed to tfpf.ID()
  • -
  • Poly (np.ndarray) – An array (2,N) or (N,2) defining the contour of the vacuum vessel in a cross-section, if not closed, will be closed automatically
  • -
  • Type (str) – Flag indicating whether the vessel will be a torus (‘Tor’) or a linear device (‘Lin’)
  • -
  • DLong (list / np.ndarray) – Array or list of len=2 indicating the limits of the linear device volume on the x axis
  • -
  • Ves (None or Ves) – An optional associated vessel
  • -
  • Clock (bool) – Flag indicating whether the input polygon should be made clockwise (True) or counter-clockwise (False)
  • -
  • arrayorder (str) – Flag indicating whether the attributes of type=np.ndarray (e.g.: Poly) should be made C-contiguous (‘C’) or Fortran-contiguous (‘F’)
  • -
  • Exp (None / str) – Flag indicating which experiment the object corresponds to, allowed values are in [None,’AUG’,’MISTRAL’,’JET’,’ITER’,’TCV’,’TS’,’Misc’]
  • -
  • shot (None / int) – Shot number from which this Ves is usable (in case of change of geometry)
  • -
  • SavePath (None / str) – If provided, forces the default saving path of the object to the provided value
  • -
  • dtime (None / dtm.datetime) – A time reference to be used to identify this particular instance (used for debugging mostly)
  • -
  • dtimeIn (bool) – Flag indicating whether dtime should be included in the SaveName (used for debugging mostly)
  • -
-
Returns:

struct (Struct object) – The created Struct object, with all necessary computed attributes and methods

-
-
-
-BaryS¶
-

Return the (surfacic) center of mass of the polygon defining the vessel cross-section

-
- -
-
-BaryV¶
-

Return the (volumic) center of mass of the polygon defining the vessel cross-section

-
- -
-
-DLong¶
-

Return the length spanned by the object in the ignorable coordinate

-
- -
-
-Id¶
-

Return the tfpf.ID object of the structure

-
- -
-
-Poly¶
-

Return the polygon defining the vessel cross-section

-
- -
-
-Surf¶
-

Return the area of the polygon defining the vessel cross-section

-
- -
-
-Type¶
-

Return the type of structure

-
- -
-
-Vect¶
-

Return the polygon elementary vectors

-
- -
-
-Ves¶
-

Return the associated Ves object, if any

-
- -
-
-Vin¶
-

Return the normalized vectors pointing inwards for each segment of the polygon

-
- -
-
-VolLin¶
-

Return the angular volume of the polygon defining the vessel cross-section of Tor type

-
- -
-
-arrayorder¶
-

Return the flag indicating which order is used for multi-dimensional array attributes

-
- -
-
-isInside(Pts, In='(X, Y, Z)')[source]¶
-

Return an array of booleans indicating whether each point lies inside the Ves volume

-

Tests for each point whether it lies inside the Ves object. -The points coordinates can be provided in 2D or 3D, just specify which coordinate system is provided using the ‘In’ parameter. -An array of boolean flags is returned.

- --- - - - - - -
Parameters:
    -
  • Pts (np.ndarray) – (2,N) or (3,N) array with the coordinates of the points to be tested
  • -
  • In (str) – Flag indicating the coordinate system in which the points are provided, in [‘(X,Y,Z)’,’(R,Z)’,’‘]
  • -
-
Returns:

ind (np.ndarray) – Array of booleans of shape (N,), True if a point is inside the Ves volume

-
-
- -
-
-plot(Lax=None, Proj='All', Elt='PBsBvV', Pdict=None, Bsdict={'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, Bvdict={'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, Vdict={'color': 'r', 'scale': 10}, BsdictHor={'c': 'b', 'ls': 'dashed'}, BvdictHor={'c': 'g', 'ls': 'dashed'}, Lim=[1.5707963267948966, 6.283185307179586], Nstep=50, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, draw=True, a4=False, Test=True)[source]¶
-

Plot the polygon defining the vessel, with a cross-section view, a longitudinal view or both, and optionally its reference point for plotting it in projection space

-

Generic method for plotting the Ves object, the projections to be plotted, the elements to plot, and the dictionaries or properties to be used for plotting each elements can all be specified using keyword arguments. -If an ax is not provided a default one is created.

- --- - - - - - -
Parameters:
    -
  • Lax (list or plt.Axes) – The axes to be used for plotting (provide a list of 2 axes if Proj=’All’), if None a new figure with axes is created
  • -
  • Proj (str) – Flag specifying the kind of projection used for the plot (‘Cross’ for a cross-section, ‘Hor’ for a horizontal plane, or ‘All’ for the two plots)
  • -
  • Elt (str) –
    -
    Flag specifying which elements to plot, each capital letter corresponds to an element
    -
      -
    • ‘P’: polygon
    • -
    • ‘Bs’: (surfacic) center of mass
    • -
    • ‘Bv’: (volumic) center of mass for Tor type
    • -
    • ‘V’: vector pointing inward perpendicular to each segment defining the polygon
    • -
    -
    -
    -
  • -
  • Pdict (dict or None) – Dictionary of properties used for plotting the polygon, fed to plt.Axes.plot() or plt.plot_surface() if Proj=‘3d’, set to ToFu_Defauts.py if None
  • -
  • Bsdict (dict) – Dictionary of properties used for plotting point ‘Bs’ in Cross-section projection, fed to plt.Axes.plot()
  • -
  • BsdictHor (dict) – Dictionry of properties used for plotting point ‘Bs’ in horizontal projection, fed to plt.Axes.plot()
  • -
  • Bvdict (dict) – Dictionary of properties used for plotting point ‘Bv’ in Cross-section projection, fed to plt.Axes.plot()
  • -
  • BvdictHor (dict) – Dictionary of properties used for plotting point ‘Bv’ in horizontal projection, fed to plt.Axes.plot()
  • -
  • Vdict (dict) – Dictionary of properties used for plotting point ‘V’ in cross-section projection, fed to plt.Axes.quiver()
  • -
  • LegDict (dict or None) – Dictionary of properties used for plotting the legend, fed to plt.legend(), the legend is not plotted if None
  • -
  • Lim (list or tuple) – Array of a lower and upper limit of angle (rad.) or length for plotting the ‘3d’ Proj
  • -
  • Nstep (int) – Number of points for sampling in ignorable coordinate (toroidal angle or length)
  • -
  • draw (bool) – Flag indicating whether the fig.canvas.draw() shall be called automatically
  • -
  • a4 (bool) – Flag indicating whether the figure should be plotted in a4 dimensions for printing
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

La list or plt.Axes Handles of the axes used for plotting (list if several axes where used)

-
-
- -
-
-save(SaveName=None, Path=None, Mode='npz')[source]¶
-

Save the object in folder Name, under file name SaveName, using specified mode

-

Most tofu objects can be saved automatically as numpy arrays (.npz, recommended) at the default location (recommended) by simply calling self.save()

- --- - - - -
Parameters:
    -
  • SaveName (None / str) – The name to be used for the saved file, if None (recommended) uses self.Id.SaveName
  • -
  • Path (None / str) – Path specifying where to save the file, if None (recommended) uses self.Id.SavePath
  • -
  • Mode (str) – Flag specifying whether to save the object as a numpy array file (‘.npz’, recommended) or an object using cPickle (not recommended, heavier and may cause retro-compatibility issues)
  • -
-
-
- -
- -
-
-class tofu.geom.LOS(Id, Du, Ves=None, Sino_RefPt=None, arrayorder='C', Clock=False, Type=None, Exp=None, Diag=None, shot=None, dtime=None, dtimeIn=False, SavePath=None)[source]¶
-

A Line-Of-Sight object (semi-line with signed direction) with all useful geometrical parameters, associated Ves object and built-in methods for plotting, defined in (X,Y,Z) cartesian coordinates

-

A Line of Sight (LOS) is a semi-line. It is a useful approximate representation of a (more accurate) Volume of Sight (VOS) when the latter is narrow and elongated. -It is usually associated to a detector placed behind apertures. -When associated to a Ves object, special points are automatically computed (entry point, exit point, closest point to the center of the Ves object...) as well as a projection in a cross-section. -While tofu provides the possibility of creating LOS objects for academic and simplification pueposes, it is generally not recommended to use them for doing physics, consider using a Detect object instead (which will provide you with a proper and automatically-computed VOS as well as with a LOS if you want).

- --- - - - -
Parameters:
    -
  • Id (str / tfpf.ID) – A name string or a pre-built tfpf.ID class to be used to identify this particular instance, if a string is provided, it is fed to tfpf.ID()
  • -
  • Du (list / tuple) – List of 2 arrays of len=3, the (X,Y,Z) coordinates of respectively the starting point D of the LOS and its directing vector u (will be automatically normalized)
  • -
  • Ves (Ves) – A Ves instance to be associated to the created LOS
  • -
  • Sino_RefPt (None or np.ndarray) – If provided, array of size=2 containing the (R,Z) (for ‘Tor’ Type) or (Y,Z) (for ‘Lin’ Type) coordinates of the reference point for the sinogram
  • -
  • arrayorder (str) – Flag indicating whether the attributes of type=np.ndarray (e.g.: Poly) should be made C-contiguous (‘C’) or Fortran-contiguous (‘F’)
  • -
  • Type (None) – (not used in the current version)
  • -
  • Exp (None / str) – Experiment to which the Lens belongs, should be identical to Ves.Id.Exp if Ves is provided, if None and Ves is provided, Ves.Id.Exp is used
  • -
  • Diag (None / str) – Diagnostic to which the Lens belongs
  • -
  • shot (None / int) – Shot number from which this Lens is usable (in case its position was changed from a previous configuration)
  • -
  • SavePath (None / str) – If provided, forces the default saving path of the object to the provided value
  • -
  • dtime (None / dtm.datetime) – A time reference to be used to identify this particular instance (used for debugging mostly)
  • -
  • dtimeIn (bool) – Flag indicating whether dtime should be included in the SaveName (used for debugging mostly)
  • -
-
-
-
-plot(Lax=None, Proj='All', Lplot='Tot', Elt='LDIORP', EltVes='', Leg='', Ldict={'lw': 2, 'c': 'k'}, MdictD={'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, MdictI={'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, MdictO={'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, MdictR={'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, MdictP={'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, Vesdict={'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'BsdictHor': {'c': 'b', 'ls': 'dashed'}, 'Bvdict': {'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, 'Lim': [1.5707963267948966, 6.283185307179586], 'Test': True, 'Proj': 'All', 'IdictHor': {'c': 'k', 'ls': 'dashed'}, 'Elt': 'PIBsBvV', 'Pdict': None, 'Vdict': {'color': 'r', 'scale': 10}, 'Idict': {'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, 'Bsdict': {'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, 'Lax': None, 'BvdictHor': {'c': 'g', 'ls': 'dashed'}, 'Nstep': 50}, draw=True, a4=False, Test=True)[source]¶
-

Plot the LOS, in a cross-section projection, a horizontal projection or both, and optionally the Ves object associated to it.

-

Plot the desired projections of the LOS object. -The plot can include the special points, the directing vector, and the properties of the plotted objects are specified by dictionaries.

- --- - - - - - -
Parameters:
    -
  • Lax (list / plt.Axes) – The axes to be used for plotting (provide a list of 2 axes if Proj=’All’), if None a new figure with axes is created
  • -
  • Proj (str) – Flag specifying the kind of projection used for the plot (‘Cross’ for a cross-section, ‘Hor’ for a horizontal plane, ‘All’ both and ‘3d’ for 3d)
  • -
  • Elt (str) –
    -
    Flag specifying which elements to plot, each capital letter corresponds to an element
    -
      -
    • ‘L’: LOS
    • -
    • ‘D’: Starting point of the LOS
    • -
    • ‘I’: Input point (i.e.: where the LOS enters the Vessel)
    • -
    • ‘O’: Output point (i.e.: where the LOS exits the Vessel)
    • -
    • ‘R’: Point of minimal major radius R (only for Vessel of Type=’Tor’)
    • -
    • ‘P’: Point of used for impact parameter (i.e.: minimal distance to reference point Sino_RefPt)
    • -
    -
    -
    -
  • -
  • Lplot (str) – Flag specifying whether to plot the full LOS (‘Tot’: from starting point output point) or only the fraction inside the vessel (‘In’: from input to output point)
  • -
  • EltVes (str) – Flag specifying the elements of the Vessel to be plotted, fed to plot()
  • -
  • Leg (str) – Legend to be used to identify this LOS, if Leg=’’ the LOS name is used
  • -
  • Ldict (dict / None) – Dictionary of properties used for plotting the polygon, fed to plt.Axes.plot() or plt.plot_surface() if Proj=‘3d’, set to ToFu_Defauts.py if None
  • -
  • MdictD (dict) – Dictionary of properties used for plotting point ‘D’, fed to plt.Axes.plot()
  • -
  • MdictI (dict) – Dictionary of properties used for plotting point ‘I’, fed to plt.Axes.plot()
  • -
  • MdictO (dict) – Dictionary of properties used for plotting point ‘O’, fed to plt.Axes.plot()
  • -
  • MdictR (dict) – Dictionary of properties used for plotting point ‘R’, fed to plt.Axes.plot()
  • -
  • MdictP (dict) – Dictionary of properties used for plotting point ‘P’, fed to plt.Axes.plot()
  • -
  • LegDict (dict or None) – Dictionary of properties used for plotting the legend, fed to plt.legend(), the legend is not plotted if None
  • -
  • Vesdict (dict) – Dictionary of kwdargs to fed to plot(), and ‘EltVes’ is used instead of ‘Elt’
  • -
  • draw (bool) – Flag indicating whether the fig.canvas.draw() shall be called automatically
  • -
  • a4 (bool) – Flag indicating whether the figure should be plotted in a4 dimensions for printing
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

La (list / plt.Axes) – Handles of the axes used for plotting (list if several axes where used)

-
-
- -
-
-plot_Sinogram(Proj='Cross', ax=None, Elt='LV', Sketch=True, Ang='theta', AngUnit='rad', Ldict={'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, Vdict={'edgecolor': (0.8, 0.8, 0.8, 1.0), 'linewidth': 1, 'linestyle': 'solid', 'facecolor': (0.8, 0.8, 0.8, 1.0)}, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, draw=True, a4=False, Test=True)[source]¶
-

Plot the sinogram of the vessel polygon, by computing its envelopp in a cross-section, can also plot a 3D version of it

-

Plot the LOS in projection space (where sinograms are plotted) as a point. -You can plot the conventional projection-space (in 2D in a cross-section), or a 3D extrapolation of it, where the third coordinate is provided by the angle that the LOS makes with the cross-section plane (useful in case of multiple LOS with a partially tangential view).

- --- - - - - - -
Parameters:
    -
  • Proj (str) – Flag indicating whether to plot a classic sinogram (‘Cross’) from the vessel cross-section (assuming 2D), or an extended 3D version (‘3d’) of it with additional angle
  • -
  • ax (None or plt.Axes) – The axes on which the plot should be done, if None a new figure and axes is created
  • -
  • Elt (str) –
    -
    Flag indicating which elements to plot, each capital letter stands for one element
    -
      -
    • ‘L’: LOS
    • -
    • ‘V’: Vessel
    • -
    -
    -
    -
  • -
  • Ang (str) – Flag indicating which angle to use for the impact parameter, the angle of the line itself (xi) or of its impact parameter (theta)
  • -
  • AngUnit (str) – Flag for the angle units to be displayed, ‘rad’ for radians or ‘deg’ for degrees
  • -
  • Sketch (bool) – Flag indicating whether a small skecth showing the definitions of angles ‘theta’ and ‘xi’ should be included or not
  • -
  • Ldict (dict) – Dictionary of properties used for plotting the LOS point, fed to plt.plot() if Proj=’Cross’ and to plt.plot_surface() if Proj=‘3d’
  • -
  • Vdict (dict) – Dictionary of properties used for plotting the polygon envelopp, fed to plt.plot() if Proj=’Cross’ and to plt.plot_surface() if Proj=‘3d’
  • -
  • LegDict (None or dict) – Dictionary of properties used for plotting the legend, fed to plt.legend(), the legend is not plotted if None
  • -
  • draw (bool) – Flag indicating whether to draw the figure
  • -
  • a4 (bool) – Flag indicating whether the figure should be plotted in a4 dimensions for printing
  • -
  • Test (bool) – Flag indicating whether the inputs shall be tested for conformity
  • -
-
Returns:

ax (plt.Axes) – The axes used to plot

-
-
- -
-
-save(SaveName=None, Path=None, Mode='npz')[source]¶
-

Save the object in folder Name, under file name SaveName, using specified mode

-

Most tofu objects can be saved automatically as numpy arrays (.npz, recommended) at the default location (recommended) by simply calling self.save()

- --- - - - -
Parameters:
    -
  • SaveName (None / str) – The name to be used for the saved file, if None (recommended) uses self.Id.SaveName
  • -
  • Path (None / str) – Path specifying where to save the file, if None (recommended) uses self.Id.SavePath
  • -
  • Mode (str) – Flag specifying whether to save the object as a numpy array file (‘.npz’, recommended) or an object using cPickle (not recommended, heavier and may cause retro-compatibility issues)
  • -
-
-
- -
- -
-
-class tofu.geom.GLOS(Id, LLOS, Ves=None, Sino_RefPt=None, Type=None, Exp=None, Diag=None, shot=None, arrayorder='C', Clock=False, dtime=None, dtimeIn=False, SavePath=None)[source]¶
-

An object regrouping a group of LOS objects with some common features (e.g.: all belong to the same camera) and the same Ves object, provides methods for common computing and plotting

-

Usually LOS correspond to detectors which are naturally grouped in ‘cameras’ (sets of detectors located in the same place or sharing an aperture or a data acquisition system). -The GLOS object provided by tofu provides the object-oriented equivalent. -The GLOS objects provides the same methods as the LOS objects, plus extra methods for fast handling or selecting of the whole set. -Note that you must first create each LOS independently and then provide them as a list argument to a GLOS object.

- --- - - - -
Parameters:
    -
  • Id (str / tfpf.ID) – A name string or a pre-built tfpf.ID class to be used to identify this particular instance, if a string is provided, it is fed to tfpf.ID()
  • -
  • LLOS (list / :class:'LOS') – List of LOS instances with the same Ves instance
  • -
  • Type (None) – (not used in the current version)
  • -
  • Exp (None / str) – Experiment to which the Lens belongs, should be identical to Ves.Id.Exp if Ves is provided, if None and Ves is provided, Ves.Id.Exp is used
  • -
  • Diag (None / str) – Diagnostic to which the Lens belongs
  • -
  • shot (None / int) – Shot number from which this Lens is usable (in case its position was changed from a previous configuration)
  • -
  • Sino_RefPt (None / iterable) – If provided, array of size=2 containing the (R,Z) (for ‘Tor’ Type) or (Y,Z) (for ‘Lin’ Type) coordinates of the reference point for the sinogram
  • -
  • arrayorder (str) – Flag indicating whether the attributes of type=np.ndarray (e.g.: Poly) should be made C-contiguous (‘C’) or Fortran-contiguous (‘F’)
  • -
  • SavePath (None / str) – If provided, forces the default saving path of the object to the provided value
  • -
  • None / dtm.datetime (dtime) – A time reference to be used to identify this particular instance (used for debugging mostly)
  • -
  • bool (dtimeIn) – Flag indicating whether dtime should be included in the SaveName (used for debugging mostly)
  • -
-
-
-
-plot(Lax=None, Proj='All', Lplot='Tot', Elt='LDIORP', EltVes='', Leg='', Ldict={'lw': 2, 'c': 'k'}, MdictD={'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, MdictI={'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, MdictO={'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, MdictR={'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, MdictP={'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, ind=None, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In', Vesdict={'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'BsdictHor': {'c': 'b', 'ls': 'dashed'}, 'Bvdict': {'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, 'Lim': [1.5707963267948966, 6.283185307179586], 'Test': True, 'Proj': 'All', 'IdictHor': {'c': 'k', 'ls': 'dashed'}, 'Elt': 'PIBsBvV', 'Pdict': None, 'Vdict': {'color': 'r', 'scale': 10}, 'Idict': {'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, 'Bsdict': {'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, 'Lax': None, 'BvdictHor': {'c': 'g', 'ls': 'dashed'}, 'Nstep': 50}, draw=True, a4=False, Test=True)[source]¶
-

Plot the GLOS, with a cross-section view, a horizontal view or both, and optionally the Ves object associated to it.

-

Plot all the LOS of the GLOS, or only a selection of them (using the same parameters as self.select()).

- --- - - - - - -
Parameters:
    -
  • Lax (list or plt.Axes) – The axes to be used for plotting (provide a list of 2 axes if Proj=’All’), if None a new figure with axes is created
  • -
  • Proj (str) – Flag specifying the kind of projection used for the plot (‘Cross’ for a cross-section, ‘Hor’ for a horizontal plane, ‘All’ both and ‘3d’ for 3d)
  • -
  • Elt (str) –
    -
    Flag specifying which elements to plot, each capital letter corresponds to an element
    -
      -
    • ‘L’: LOS
    • -
    • ‘D’: Starting point of the LOS
    • -
    • ‘I’: Input point (i.e.: where the LOS enters the Vessel)
    • -
    • ‘O’: Output point (i.e.: where the LOS exits the Vessel)
    • -
    • ‘R’: Point of minimal major radius R (only for Vessel of Type=’Tor’)
    • -
    • ‘P’: Point of used for impact parameter (i.e.: minimal distance to reference point ImpRZ)
    • -
    -
    -
    -
  • -
  • Lplot (str) – Flag specifying whether to plot the full LOS (‘Tot’: from starting point output point) or only the fraction inside the vessel (‘In’: from input to output point)
  • -
  • EltVes (str) – Flag specifying the elements of the Vessel to be plotted, fed to plot()
  • -
  • Leg (str) – Legend to be used to identify this LOS, if Leg=’’ the LOS name is used
  • -
  • Ldict (dict or None) – Dictionary of properties used for plotting the polygon, fed to plt.Axes.plot() or plt.plot_surface() if Proj=‘3d’, set to ToFu_Defauts.py if None
  • -
  • MdictD (dict) – Dictionary of properties used for plotting point ‘D’, fed to plt.Axes.plot()
  • -
  • MdictI (dict) – Dictionary of properties used for plotting point ‘I’, fed to plt.Axes.plot()
  • -
  • MdictO (dict) – Dictionary of properties used for plotting point ‘O’, fed to plt.Axes.plot()
  • -
  • MdictR (dict) – Dictionary of properties used for plotting point ‘R’, fed to plt.Axes.plot()
  • -
  • MdictP (dict) – Dictionary of properties used for plotting point ‘P’, fed to plt.Axes.plot()
  • -
  • LegDict (dict or None) – Dictionary of properties used for plotting the legend, fed to plt.legend(), the legend is not plotted if None
  • -
  • Vesdict (dict) – Dictionary of kwdargs to fed to plot(), and ‘EltVes’ is used instead of ‘Elt’
  • -
  • Lim (list or tuple) – Array of a lower and upper limit of angle (rad.) or length for plotting the ‘3d’ Proj
  • -
  • draw (bool) – Flag indicating whether the fig.canvas.draw() shall be called automatically
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
  • None or np.ndarray (ind) – Array of indices (int or bool) of the LOS to be plotted if only some of them are to be plotted
  • -
  • kwdargs – kwdargs to be fed to GLOS.select() if ind=None and only a fraction of the LOS are to be plotted
  • -
-
Returns:

La (list or plt.Axes) – Handles of the axes used for plotting (list if several axes where used)

-
-
- -
-
-plot_Sinogram(Proj='Cross', ax=None, Elt='LV', Sketch=True, Ang='theta', AngUnit='rad', Ldict={'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, Vdict={'edgecolor': (0.8, 0.8, 0.8, 1.0), 'linewidth': 1, 'linestyle': 'solid', 'facecolor': (0.8, 0.8, 0.8, 1.0)}, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, draw=True, a4=False, Test=True, ind=None, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In')[source]¶
-

Plot the sinogram of the vessel polygon, by computing its envelopp in a cross-section, can also plot a 3D version of it

-

Plot all the LOS of the GLOS, or only a selection of them in projection space

- --- - - - - - -
Parameters:
    -
  • Proj (str) – Flag indicating whether to plot a classic sinogram (‘Cross’) from the vessel cross-section (assuming 2D), or an extended 3D version ‘3d’ of it with additional angle, default: ‘Cross’
  • -
  • ax (None or plt.Axes) – The axes on which the plot should be done, if None a new figure and axes is created, default: None
  • -
  • Elt (str) –
    -
    Flag indicating which elements to plot, each capital letter stands for one element, default: ‘LV’
    -
      -
    • ‘L’: LOS
    • -
    • ‘V’: Vessel
    • -
    -
    -
    -
  • -
  • Ang (str) – Flag indicating which angle to use for the impact parameter, the angle of the line itself (xi) or of its impact parameter (theta), default: ‘theta’
  • -
  • AngUnit (str) – Flag for the angle units to be displayed, ‘rad’ for radians or ‘deg’ for degrees, default: ‘rad’
  • -
  • Sketch (bool) – Flag indicating whether a small skecth showing the definitions of angles ‘theta’ and ‘xi’ should be included or not
  • -
  • Ldict (dict) – Dictionary of properties used for plotting the LOS point, fed to plt.plot() if Proj=’Cross’ and to plt.plot_surface() if Proj=‘3d’, default: see ToFu_Defaults.py
  • -
  • Vdict (dict) – Dictionary of properties used for plotting the polygon envelopp, fed to plt.plot() if Proj=’Cross’ and to plt.plot_surface() if Proj=‘3d’, default: see ToFu_Defaults.py
  • -
  • LegDict (None or dict) – Dictionary of properties used for plotting the legend, fed to plt.legend(), the legend is not plotted if None, default: see ToFu_Defaults.py
  • -
  • draw (bool) – Flag indicating whether to draw the figure, default: True
  • -
  • Test (bool) – Flag indicating whether the inputs shall be tested for conformity, default: True
  • -
-
Returns:

ax (plt.Axes) – The axes used to plot

-
-
- -
-
-save(SaveName=None, Path=None, Mode='npz')[source]¶
-

Save the object in folder Name, under file name SaveName, using specified mode

-

Most tofu objects can be saved automatically as numpy arrays (.npz, recommended) at the default location (recommended) by simply calling self.save()

- --- - - - -
Parameters:
    -
  • SaveName (None / str) – The name to be used for the saved file, if None (recommended) uses self.Id.SaveName
  • -
  • Path (None / str) – Path specifying where to save the file, if None (recommended) uses self.Id.SavePath
  • -
  • Mode (str) – Flag specifying whether to save the object as a numpy array file (‘.npz’, recommended) or an object using cPickle (not recommended, heavier and may cause retro-compatibility issues)
  • -
-
-
- -
-
-select(Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In', Out=<type 'bool'>)[source]¶
-

Return the indices or instances of all instances matching the specified criterion.

-

The selection can be done according to 2 different mechanism (1) and (2).

-

For mechanism (1): the user provides the value (Val) that the specified criterion (Crit) should take for a LOS to be selected. -The criteria are typically attributes of the self.Id attribute (i.e.: name of the instance, or user-defined attributes like the camera head...)

-

For mechanism (2), used if Val=None: the user provides a str expression (or a list of such) to be fed to eval(), used to check on quantitative criteria, placed before the criterion value (e.g.: ‘not ‘ or ‘<=’). -Another str or list of str expressions can be provided that will be placed after the criterion value.

-

Other parameters are used to specify logical operators for the selection (match any or all the criterion...) and the type of output.

- --- - - - - - -
Parameters:
    -
  • Crit (str) – Flag indicating which criterion to use for discrimination -Can be set to any attribute of the tofu.pathfile.ID class (e.g.: ‘Name’,’SaveName’,’SavePath’...) or any key of ID.USRdict (e.g.: ‘Exp’...)
  • -
  • Val (list, str or None) – The value to match for the chosen criterion, can be a list of different values -Used for selection mechanism (1)
  • -
  • PreExp (list, str or None) – A str of list of str expressions to be fed to eval(), used to check on quantitative criteria, placed before the criterion value (e.g.: ‘not ‘) -Used for selection mechanism (2)
  • -
  • PostExp (list, str or None) – A str of list of str expressions to be fed to eval(), used to check on quantitative criteria, placed after the criterion value (e.g.: ‘>=5.’) -Used for selection mechanism (2)
  • -
  • Log (str) – Flag indicating whether the criterion shall match all provided values or one of them (‘any’ or ‘all’)
  • -
  • InOut (str) – Flag indicating whether the returned indices are the ones matching the criterion (‘In’) or the ones not matching it (‘Out’)
  • -
  • Out (type / str) – Flag indicating in which form shall the result be returned, as an array of integer indices (int), an array of booleans (bool), a list of names (‘Names’) or a list of instances (‘LOS’)
  • -
-
Returns:

ind (list / np.ndarray) – The computed output (array of index, list of names or instances depending on parameter ‘Out’)

-
-

Examples

-
>>> import tofu.geom as tfg
->>> ves = tfg.Ves('ves', [[0.,1.,1.,0.],[0.,0.,1.,1.]], DLong=[-1.,1.], Type='Lin', Exp='Misc', shot=0)
->>> los1 = tfg.LOS('los1', ([0.,-0.1,-0.1],[0.,1.,1.]), Ves=ves, Exp='Misc', Diag='D', shot=0)
->>> los2 = tfg.LOS('los2', ([0.,-0.1,-0.1],[0.,0.5,1.]), Ves=ves, Exp='Misc', Diag='D', shot=1)
->>> los3 = tfg.LOS('los3', ([0.,-0.1,-0.1],[0.,1.,0.5]), Ves=ves, Exp='Misc', Diag='D', shot=1)
->>> glos = tfg.GLOS('glos', [los1,los2,los3])
->>> ind = glos.select(Val=['los1','los3'], Log='any', Out='LOS')
->>> print [ii.Id.Name for ii in ind]
-['los1', 'los3']
->>> ind = glos.select(Val=['los1','los3'], Log='any', InOut='Out', Out=int)
-array([1])
-
-
-
- -
- -
-
-class tofu.geom.Lens(Id, O, nIn, Rad, F1, F2=inf, R1=None, R2=None, dd=None, Ves=None, Type='Sph', Exp=None, Diag=None, shot=None, arrayorder='C', Clock=False, SavePath=None, dtime=None, dtimeIn=False)[source]¶
-

A Lens class with all geometrical data and built-in methods, defined as a planar polygon in 3D cartesian coordinates, with optional Ves object

-

A Lens object is useful for implementing one of the two possible optical arrangements available in tofu. -A Lens (implicitly convergent) is used for focusing incoming light on a detector of reduced size (i.e.g: like the end of an optic fiber cable). -In this case, anmd in its current version, tofu only handles spherical lenses and assumes that the detector has a circular active surface, centered on the same axis as the lens and located in its focal plane.

- --- - - - -
Parameters:
    -
  • Id (str or tfpf.ID) – A name string or a pre-built tfpf.ID class to be used to identify this particular instance, if a string is provided, it is fed to tfpf.ID()
  • -
  • O (iterable) – Array of 3D cartesian coordinates of the center of the Lens
  • -
  • nIn (iterable) – Array of 3D cartesian coordiantes of the vector defining the axis of the Lens
  • -
  • Rad (float) – Radius of the Lens
  • -
  • F1 (float) – Focal length of the Lens, on the detector side
  • -
  • F2 (float) – Focal length of the Lens, on the plasma side (only np.inf supported so far)
  • -
  • Type (str) – Flag indicating the type of Lens (only ‘Sph’ - for spherical lens - supported so far)
  • -
  • R1 (None or float) – Radius of the first face of the Lens, for full description only
  • -
  • R2 (None or float) – Radius of the second face of the Lens, for full description only
  • -
  • dd (None or float) – Width of the Lens along its axis, for full description only
  • -
  • Ves (Ves) – Ves object to which the aperture is assigned
  • -
  • Exp (None or str) – Experiment to which the Lens belongs, should be identical to Ves.Id.Exp if Ves is provided, if None and Ves is provided, Ves.Id.Exp is used
  • -
  • Diag (None or str) – Diagnostic to which the Lens belongs
  • -
  • shot (None or int) – Shot number from which this Lens is usable (in case its position was changed from a previous configuration)
  • -
  • SavePath (None / str) – If provided, forces the default saving path of the object to the provided value
  • -
  • Clock (bool) – Flag indicating whether the input polygon should be made clockwise (True) or counter-clockwise (False), default: False
  • -
  • arrayorder (str) – Flag indicating whether the attributes of type=np.ndarray (e.g.: Poly) should be made C-contiguous (‘C’) or Fortran-contiguous (‘F’), default: ‘C’
  • -
  • dtime (None or dtm.datetime) – A time reference to be used to identify this particular instance (used for debugging mostly), default: None
  • -
  • dtimeIn (bool) – Flag indicating whether dtime should be included in the SaveName (used for debugging mostly), default: False
  • -
-
-
-
-Poly¶
-

Return a simple representation of the Lens as a 3D circle (if Lens.Type=’Sph’)

-
- -
-
-plot(Lax=None, Proj='All', Elt='PV', EltVes='', Leg=None, LVIn=0.1, Pdict={'lw': 2, 'c': 'k', 'ls': 'solid'}, Vdict={'color': 'r', 'lw': 2, 'ls': 'solid'}, Vesdict={'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'BsdictHor': {'c': 'b', 'ls': 'dashed'}, 'Bvdict': {'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, 'Lim': [1.5707963267948966, 6.283185307179586], 'Test': True, 'Proj': 'All', 'IdictHor': {'c': 'k', 'ls': 'dashed'}, 'Elt': 'PIBsBvV', 'Pdict': None, 'Vdict': {'color': 'r', 'scale': 10}, 'Idict': {'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, 'Bsdict': {'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, 'Lax': None, 'BvdictHor': {'c': 'g', 'ls': 'dashed'}, 'Nstep': 50}, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, draw=True, a4=False, Test=True)[source]¶
-

Plot the Lens object, optionally with the associated Ves object

-

Plot the chosen projections of the Lens polygon.

- --- - - - - - -
Parameters:
    -
  • Lax (list or plt.Axes) – The axes to be used for plotting (provide a list of 2 axes if Proj=’All’), if None a new figure with axes is created
  • -
  • Proj (str) – Flag specifying the kind of projection used for the plot (‘Cross’ for a cross-section, ‘Hor’ for a horizontal plane, ‘All’ both and ‘3d’ for 3d)
  • -
  • Elt (str) –
    -
    Flag specifying which elements to plot, each capital letter corresponds to an element
    -
      -
    • ‘P’: polygon
    • -
    • ‘V’: vector perpendicular to the polygon, oriented towards the interior of the Vessel
    • -
    -
    -
    -
  • -
  • EltVes (str) – Flag specifying the elements of the Vessel to be plotted, fed to plot()
  • -
  • Leg (str) – Legend to be used to identify this LOS, if Leg=’’ the LOS name is used
  • -
  • LVIn (float) – Length (in data coordinates, meters) of the vector ‘V’
  • -
  • Pdict (dict) – Dictionary of properties used for plotting the polygon, fed to plt.Axes.plot() or plt.plot_surface() if Proj=‘3d’, set to ToFu_Defauts.py if None (default: None)
  • -
  • Vdict (dict) – Dictionary of properties used for plotting vector ‘V’, fed to plt.Axes.plot()
  • -
  • Vesdict (dict) – Dictionary of kwdargs to fed to plot(), and ‘EltVes’ is used instead of ‘Elt’
  • -
  • LegDict (dict or None) – Dictionary of properties used for plotting the legend, fed to plt.legend(), the legend is not plotted if None
  • -
  • draw (bool) – Flag indicating whether the fig.canvas.draw() shall be called automatically
  • -
  • a4 (bool) – Flag indicating whether the figure should be a4 size (for printing or saving as pdf for example)
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

Lax (list or plt.Axes) – Handles of the axes used for plotting (list if several axes where used)

-
-
- -
-
-plot_alone(ax=None, V='red', nin=1.5, nout=1.0, Lmax='F', V_NP=50, src=None, draw=True, a4=False, Test=True)[source]¶
-

Plot a 2D representation of the Lens object, optionally with 2D viewing cone and rays of several sources in the plane, either with reduced of full representation

-

Plot a sketch of the Lens, optionally with ray-traced incoming light beams. -This plotting routine does not consider any syurrounding and plots everything assuming the origine of the coordinate system is on the Lens

- --- - - - - - -
Parameters:
    -
  • ax (None or plt.Axes) – Axes to be used for plotting, if None a new figure with axes is created (default: None)
  • -
  • V (str) – Flag indicating whether the Lens should be considered in its reduced geometry model (‘red’) or its full version (‘full’), default: ‘red’
  • -
  • nin (float) – Value of the optical index to be used inside the Lens (useful when V=’full’ only)
  • -
  • nout (float) – Value of the optical index to be used outside the Lens (useful when V=’full’ only)
  • -
  • Lmax (float) – Maximum length on which the source beams should be plotted after going through the Lens, if ‘F’ all beams are plotted up to the focal plane
  • -
  • V_NP (int) – Number of points to be used to plot each circle fraction of the full version of the Lens geometry (useful when V=’full’ only)
  • -
  • src (None or dict) –
    -
    Dictionary of parameters for the source of ray beams:
    -
      -
    • ‘Pt’: iterable of len()=2 with the 2D cartesian coordinates of the point where the source should be located with reference to the Lens center (0,0) and axis (1,0)
    • -
    • ‘Type’: Flag indicating whether the source should a point (‘Pt’) or an array of parallel beams perpendicular to a plane passing through Pt
    • -
    • ‘nn’: iterable of len()=2 with the 2D cartesian coordinates of a vector directing the array of parallel beams
    • -
    • ‘NP’: int, number of beams to be plotted from the source
    • -
    -
    -
    -
  • -
  • draw (bool) – Flag indicating whether the fig.canvas.draw() shall be called automatically, default: True
  • -
  • a4 (bool) – Flag indicating whether the figure should be a4 size (for printing or saving as pdf for example)
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity, default: True
  • -
-
Returns:

ax (plt.Axes) – Handle of the axes used for plotting

-
-
- -
-
-save(SaveName=None, Path=None, Mode='npz')[source]¶
-

Save the object in folder Name, under file name SaveName, using specified mode

-

Most tofu objects can be saved automatically as numpy arrays (.npz, recommended) at the default location (recommended) by simply calling self.save()

- --- - - - -
Parameters:
    -
  • SaveName (None / str) – The name to be used for the saved file, if None (recommended) uses self.Id.SaveName
  • -
  • Path (None / str) – Path specifying where to save the file, if None (recommended) uses self.Id.SavePath
  • -
  • Mode (str) – Flag specifying whether to save the object as a numpy array file (‘.npz’, recommended) or an object using cPickle (not recommended, heavier and may cause retro-compatibility issues)
  • -
-
-
- -
- -
-
-class tofu.geom.Apert(Id, Poly, Type=None, Ves=None, Exp=None, Diag=None, shot=None, arrayorder='C', Clock=False, SavePath=None, dtime=None, dtimeIn=False)[source]¶
-

An Aperture class with all geometrical data and built-in methods, defined as a planar polygon in 3D cartesian coordinates, with optional Ves object

-

An Apert object is useful for implementing one of the two possible optical arrangements available in tofu. -An aperture is modelled as a planar polygon (of any non self-intersecting shape) through which light can pass (fully transparent) and around which light cannot pass (fully non-transparent). -One of the added-values of tofu is that it allows to create several non-coplanar aperture and assign them to a single detector. It then computes automatically the volume of sight by assuming that a detectable photon should go through all apertures.

- --- - - - -
Parameters:
    -
  • Id (str or tfpf.ID) – A name string or a pre-built tfpf.ID class to be used to identify this particular instance, if a string is provided, it is fed to tfpf.ID()
  • -
  • Poly (np.ndarray) – An array (2,N) or (N,2) defining the contour of the aperture in 3D (X,Y,Z) cartesian coordinates, if not closed, will be closed automatically
  • -
  • Ves (Ves) – Ves object to which the aperture is assigned
  • -
  • Type (None or str) – Flag specifying the type of Apert
  • -
  • Exp (None or str) – Experiment to which the Lens belongs, should be identical to Ves.Id.Exp if Ves is provided, if None and Ves is provided, Ves.Id.Exp is used
  • -
  • Diag (None or str) – Diagnostic to which the Lens belongs
  • -
  • shot (None or int) – Shot number from which this Lens is usable (in case its position was changed from a previous configuration)
  • -
  • SavePath (None / str) – If provided, forces the default saving path of the object to the provided value
  • -
  • Clock (bool) – Flag indicating whether the input polygon should be made clockwise (True) or counter-clockwise (False)
  • -
  • dtime (None or dtm.datetime) – A time reference to be used to identify this particular instance (mostly used for debugging)
  • -
  • dtimeIn (bool) – Flag indicating whether dtime should be included in the SaveName (mostly used for debugging)
  • -
-
-
-
-BaryS¶
-

Return the (surfacic) center of mass of the polygon (in 3D cartesian coordinates)

-
- -
-
-Id¶
-

Return the associated tfpf.ID object

-
- -
-
-NP¶
-

Return the number of points defining the polygon

-
- -
-
-Poly¶
-

Return the planar polygon defining the aperture (in 3D cartesian coordinates)

-
- -
-
-Surf¶
-

Return the area of the polygon

-
- -
-
-Ves¶
-

Return the associated Ves object

-
- -
-
-nIn¶
-

Return the normalized vector perpendicular to the polygon surface and oriented towards the interior of the associated vessel (in 3D cartesian coordinates)

-
- -
-
-plot(Lax=None, Proj='All', Elt='PV', EltVes='', Leg=None, LVIn=0.1, Pdict={'lw': 2, 'c': 'k', 'ls': 'solid'}, Vdict={'color': 'r', 'lw': 2, 'ls': 'solid'}, Vesdict={'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'BsdictHor': {'c': 'b', 'ls': 'dashed'}, 'Bvdict': {'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, 'Lim': [1.5707963267948966, 6.283185307179586], 'Test': True, 'Proj': 'All', 'IdictHor': {'c': 'k', 'ls': 'dashed'}, 'Elt': 'PIBsBvV', 'Pdict': None, 'Vdict': {'color': 'r', 'scale': 10}, 'Idict': {'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, 'Bsdict': {'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, 'Lax': None, 'BvdictHor': {'c': 'g', 'ls': 'dashed'}, 'Nstep': 50}, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, draw=True, a4=False, Test=True)[source]¶
-

Plot the Apert, with a cross-section view, a horizontal view or both, or a 3d view, and optionally the Ves object associated to it.

-

Plot the desired projections of the polygon defining the aperture.

- --- - - - - - -
Parameters:
    -
  • list or plt.Axes (Lax) – The axes to be used for plotting (provide a list of 2 axes if Proj=’All’), if None a new figure with axes is created
  • -
  • str (Leg) – Flag specifying the kind of projection used for the plot (‘Cross’ for a cross-section, ‘Hor’ for a horizontal plane, ‘All’ both and ‘3d’ for 3d)
  • -
  • str
    -
    Flag specifying which elements to plot, each capital letter corresponds to an element
    -
      -
    • ‘P’: polygon
    • -
    • ‘V’: vector perpendicular to the polygon, oriented towards the interior of the Vessel
    • -
    -
    -
    -
  • -
  • str – Flag specifying the elements of the Vessel to be plotted, fed to plot()
  • -
  • str – Legend to be used to identify this LOS, if Leg=’’ the LOS name is used
  • -
  • float (LVIn) – Length (in data coordinates, meters) of the vector ‘V’
  • -
  • dict (Vesdict) – Dictionary of properties used for plotting the polygon, fed to plt.Axes.plot() or plt.plot_surface() if Proj=‘3d’, set to ToFu_Defauts.py if None
  • -
  • dict – Dictionary of properties used for plotting vector ‘V’, fed to plt.Axes.plot()
  • -
  • dict – Dictionary of kwdargs to fed to plot(), and ‘EltVes’ is used instead of ‘Elt’
  • -
  • dict or None (LegDict) – Dictionary of properties used for plotting the legend, fed to plt.legend(), the legend is not plotted if None
  • -
  • bool (Test) – Flag indicating whether the fig.canvas.draw() shall be called automatically
  • -
  • bool – Flag indicating whether the figure should be a4 size (for printing or saving as pdf for example)
  • -
  • bool – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

La list or plt.Axes – Handles of the axes used for plotting (list if several axes where used)

-
-
- -
-
-save(SaveName=None, Path=None, Mode='npz')[source]¶
-

Save the object in folder Name, under file name SaveName, using specified mode

-

Most tofu objects can be saved automatically as numpy arrays (.npz, recommended) at the default location (recommended) by simply calling self.save()

- --- - - - -
Parameters:
    -
  • SaveName (None / str) – The name to be used for the saved file, if None (recommended) uses self.Id.SaveName
  • -
  • Path (None / str) – Path specifying where to save the file, if None (recommended) uses self.Id.SavePath
  • -
  • Mode (str) – Flag specifying whether to save the object as a numpy array file (‘.npz’, recommended) or an object using cPickle (not recommended, heavier and may cause retro-compatibility issues)
  • -
-
-
- -
- -
-
-class tofu.geom.Detect(Id, Poly, Optics=None, Ves=None, Sino_RefPt=None, CalcEtend=True, CalcSpanImp=True, CalcCone=True, CalcPreComp=True, Calc=True, Verb=True, Etend_Method='quad', Etend_RelErr=0.001, Etend_dX12=[0.01, 0.01], Etend_dX12Mode='rel', Etend_Ratio=0.02, Colis=True, LOSRef='Cart', Cone_DRY=0.0025, Cone_DXTheta=None, Cone_DZ=0.0025, Cone_NPsi=20, Cone_Nk=60, arrayorder='C', Clock=False, Type=None, Exp=None, Diag=None, shot=None, dtime=None, dtimeIn=False, SavePath=None)[source]¶
-

A Detector class with all geometrical data and built-in methods, defined as a planar polygon in 3D cartesian coordinates, with optional aperture objects

-

A Detect object is at the core of tofu’s added value and is mostly defined by a 3D planar polygon of any non self-intersecting shape representing the active surface of a detector. -It can then be associated to optics (a Lens or a list of Apert objects) and to a Ves to automatically compute a natural :class:’LOS’ (with its etendue) and, most importantly, a proper VOS (that can be discretized for 3D numerical integration). -It can be 2 different types: either ‘Circ’ if it is associated to a Lens (in which case it is simply defined by radius and is assumed to be circular and placed at the focal plane of the Lens object), or None in the more general case in which it is associated to a set of apertures. -Most of the commonly used quantities are automatically calculated (etendue of the LOS, VOS...) and it comes with built-in methods for plotting and computing synthetic data.

-

To compute the VOS, tofu tests all points inside a 3D grid to see if each point is visible from the detector through the apertures or not. -The meshed space is determined by the volume spanned by a LOS sampling of the VOS. -Then, a contour function is used to find the polygons limiting the cross-section and horizontal projections of the VOS. -Once computed, the viewing cones are assigned to attributes of the Detect instance.

-

In the particular case (1) when the LOS of the detector lies entirely inside one cross-section (e.g.: tomography diagnostics), tofu also computes the integral in the direction of the ignorable coordinate of the solid angle on a regular mesh (for faster computation of the geometry assuming toroidaly invariant basis functions). -This regular mesh is defined in 2D, by the distance between a mesh point and the detector (k) and by the poloidal angle between the LOS and the line going from the detector to the mesh point (psi)

- --- - - - -
Parameters:
    -
  • Id (str or tfpf.ID) – A name string or a pre-built tfpf.ID class to be used to identify this particular instance, if a string is provided, it is fed to tfpf.ID()
  • -
  • Poly (dict or np.ndarray) –
    -
    Contains the information regarding the geometry of the Detect object
    -
      -
    • np.ndarray: (2,N) or (N,2) defining the contour of the detector active surface in 3D (X,Y,Z) cartesian coordinates, if not closed, will be closed automatically, if Type=None
    • -
    • dict: dictionary of properties for a circular detector placed in the focal plane of a Lens on its axis, contains field ‘Rad’=float (radius), if Optics is Lens and Type=’Circ’
    • -
    -
    -
    -
  • -
  • Optics (list or Lens) – The optics to be associated to the detector, either a spherical Lens or a list of apertures Apert
  • -
  • Ves (Ves or None) – Ves object to which the detector is assigned
  • -
  • Sino_RefPt (np.ndarray or None) – Array of size=2 containing the (R,Z) (for ‘Tor’ Type) or (Y,Z) (for ‘Lin’ Type) coordinates of the reference point for the sinogram
  • -
  • CalcEtend (bool) – Flag indicating whether to compute the etendue
  • -
  • CalcSpanImp (bool) – Flag indicating whether to compute the maximal span of the viewing volume
  • -
  • CalcCone (bool) – Flag indicating whether to compute the viewing volume or viewing cone and its two projections
  • -
  • CalcPreComp (bool) – Flag indicating whether to pre-compute a set of pre-defined points inside the viewing volume for faster computation of signal from 3D emissivity
  • -
  • Calc (bool) – Flag indicating whether to compute all the above
  • -
  • Verb (bool) – Flag indicating whether the creation of the object should be verbose (comments for each step)
  • -
  • Etend_Method (str) – Flag indicating which numerical integration to use for the computation of the etendue (picked from scipy.integrate : ‘quad’, ‘simps’, ‘trapz’)
  • -
  • Etend_RelErr (float) – If Etend_Method=’quad’, specifies the maximum relative error to be tolerated on the value of the integral (i.e.: etendue)
  • -
  • Etend_dX12 (list) – If Etend_Method in [‘simps’,’trapz’], which implies a discretization of the plane perpendicular to the LOS, specifies the resolution of the discretization
  • -
  • Etend_dX12Mode (str) – If Etend_Method in [‘simps’,’trapz’], specifies whether Etend_dX12 should be iunderstood as an absolute distance (‘abs’) or a fraction of the maximum width (‘rel’)
  • -
  • Etend_Ratio (float) – The numerical integration is performed on an automatically-deterimned interval, this ratio (fraction of unity) is a safety margin to increase a bit the interval and make sure all non-zero values are included
  • -
  • Colis (bool) – Flag indicating whether the collision detection mechanism should be considered when computing the VOS
  • -
  • LOSRef (str) – Key indicating which of the LOS in the LOS dictionary should be considered as the reference LOS
  • -
  • Cone_DRY (float) – Resolution of the grid in the R (for ‘Tor’ vessel types) or Y (for ‘Lin’ vessel types) direction, in meters
  • -
  • Cone_DXTheta (float) – Resolution of the grid in the toroidal (for ‘Tor’ vessel types, in radians) or X (for ‘Lin’ vessel types, in meters) direction
  • -
  • Cone_DZ (float) – Resolution of the grid in the Z direction, in meters
  • -
  • Cone_NPsi (int) – Number of points of the regular mesh in psi direction (angle), in case (1)
  • -
  • Cone_Nk (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
  • Type (None / str) – If the detector is associated to a Lens, it should be of type ‘Circ’ (only circular shaped detectors are handled by tofu behind spherical lenses)
  • -
  • Exp (None or str) – Experiment to which the Lens belongs, should be identical to Ves.Id.Exp if Ves is provided, if None and Ves is provided, Ves.Id.Exp is used
  • -
  • Diag (None or str) – Diagnostic to which the Lens belongs
  • -
  • shot (None or int) – Shot number from which this Lens is usable (in case its position was changed from a previous configuration)
  • -
  • SavePath (None / str) – If provided, forces the default saving path of the object to the provided value
  • -
  • Clock (bool) – Flag indicating whether the input polygon should be made clockwise (True) or counter-clockwise (False), default: False
  • -
  • arrayorder (str) – Flag indicating whether the attributes of type=np.ndarray (e.g.: Poly) should be made C-contiguous (‘C’) or Fortran-contiguous (‘F’), default: ‘C’
  • -
  • dtime (None or dtm.datetime) – A time reference to be used to identify this particular instance (used for debugging mostly)
  • -
  • dtimeIn (bool) – Flag indicating whether dtime should be included in the SaveName (used for debugging mostly)
  • -
-
-
-
-BaryS¶
-

Return the (surfacic) center of mass of the polygon (in 3D cartesian coordinates)

-
- -
-
-Cone_PolyCross¶
-

Return the polygon that is the projection in a cross-section of the viewing cone

-
- -
-
-Cone_PolyHor¶
-

Return the polygon that is the projection in a horizontal plane of the viewing cone

-
- -
-
-Id¶
-

Return the associated tfpf.ID object

-
- -
-
-LOS¶
-

Return the dictionary of associated LOS objects

-
- -
-
-NP¶
-

Return the number of points defining the polygon

-
- -
-
-Optics¶
-

Return the list of associated Optics objects (Lens or list of Apert)

-
- -
-
-OpticsNb¶
-

Return the number of associated Optics

-
- -
-
-OpticsType¶
-

Return the type of associated Optics objects

-
- -
-
-Poly¶
-

Return the planar polygon defining the aperture (in 3D cartesian coordinates)

-
- -
-
-Rad¶
-

Return the radius of the polygon (if Type=’Circ’, else None)

-
- -
-
-SAngCross_Int¶
-

Return the integral of the solid angle at pre-computed points of the VOS in a cross-section projection

-
- -
-
-SAngCross_Points¶
-

Return the pre-computed points of the VOS in a cross-section projection

-
- -
-
-SAngHor_Int¶
-

Return the integral of the solid angle at pre-computed points of the VOS in a horizontal projection

-
- -
-
-SAngHor_Points¶
-

Return the pre-computed points of the VOS in a horizontal projection

-
- -
-
-Sino_RefPt¶
-

Return the coordinates (R,Z) or (Y,Z) for Ves of Type ‘Tor’ or (Y,Z) for Ves of Type ‘Lin’ of the reference point used to compute the sinogram

-
- -
-
-Surf¶
-

Return the area of the polygon

-
- -
-
-Ves¶
-

Return the associated Ves object

-
- -
-
-calc_Etendue_AlongLOS(Length='', NP=20, Modes=['trapz', 'quad'], RelErr=0.001, dX12=[0.005, 0.005], dX12Mode='abs', Ratio=0.02, Colis=True, LOSRef=None, Test=True)[source]¶
-

Return the etendue computed at different points along the LOS, with various numerical methods, with or without collision detection

-

Computing the etendue along the LOS of a Detect object can be useful for checking whether the etendue is constant (as it should be if the LOS approximation is to be used). -Cases with non-constant etendue include in particular partially obstructed VOS in the divertor region of Tokamaks. -Also useful for debugging: if the etendue is not constant but the VOS is not obstructed, something might be wrong with the computation of the etendue or with the model (e.g.: for Lens optics). -Indeed, the model implemented for a Lens is ideal, but a close look at the etendue shows that the model is not perfect (but sufficiently accurate for most uses though).

- --- - - - - - -
Parameters:
    -
  • Length (str) – Flag indicating whether to use the full length of the VOS (including partially obstructed parts: ‘’), or just the length of the LOS unil its exit point (‘LOS’).
  • -
  • NP (int) – Number of points (uniformly distributed along the LOS) where the etendue should be computed
  • -
  • Modes (list or str) – Flag or list of flags indicating which numerical integration methods shoud be used in [‘quad’,’simps’,’trapz’]
  • -
  • RelErr (float) – For ‘quad’, a positive float defining the relative tolerance allowed
  • -
  • dX12 (list) – For ‘simps’ or ‘trapz’, a list of 2 floats defining the resolution of the sampling in X1 and X2
  • -
  • dX12Mode (str) – For ‘simps’ or’trapz’, ‘rel’ or ‘abs’, if ‘rel’ the resolution dX12 is in dimensionless units in [0;1] (hence a value of 0.1 means 10 discretisation points between the extremes), if ‘abs’ dX12 is in meters
  • -
  • Ratio (float) – A float specifying the relative margin to be taken for integration boundaries
  • -
  • Colis (bool) – Flag indicating whether collision detection should be used
  • -
  • LOSRef (None or str) – Flag indicating which LOS should be used
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

    -
  • Etend (np.ndarray) – Computed etendues
  • -
  • Pts (np.ndarray) – (3,NP) array specifying the 3D (X,Y,Z) coordinates of the points along the LOS where the etendue was computed
  • -
  • kPts (np.ndarray) – (NP,) array of the distance-coordinate k along the LOS
  • -
  • LOSRef (str) – The LOS that was used
  • -
-

-
-
- -
-
-calc_SAngNb(Pts=None, Proj='Cross', Slice='Int', DRY=None, DXTheta=None, DZ=None, Colis=True)[source]¶
-

Compute the solid angle subtended by the Detect+Optics system as seen for desired points, in a slice or integrated manner

-

Mostly useful in the GDetect object when there are several detectors. -Computes, for each point in the desired projection, the total solid angle subtended by all the detectors (or its integral) and the number of detectors that ‘see’ each point.

- --- - - - - - -
Parameters:
    -
  • Pts (None / np.ndarray) – (3,N) array of cartesian (X,Y,Z) coordinates of the provided N points, if None a default set of points is computed according to DRY, DXTheta and DZ
  • -
  • Proj (str) – Flag indicating to which projection of the VOS the method should be applied
  • -
  • Slice (str) – Flag indicating whether to compute the solid angle (‘Slice’), the maximum solid angle along the ignorable coordinate (‘Max’), or the integral over the ignorable coordinate (‘Int’)
  • -
  • DRY (None / float) – Resolution (in horizontal direction of the cross-section) of the mesh to be constructed if the points are not provided
  • -
  • DXTheta (None / float) – Resolution (in ignorable coordinate direction) of the mesh to be constructed if the points are not provided
  • -
  • DZ (None / float) – Resolution (in vertical direction) of the mesh to be constructed if the points are not provided
  • -
  • Colis (bool) – Flag indicating whether collision detection should be used
  • -
-
Returns:

    -
  • SA (np.ndarray) – Array of (ND,NP) solid angle values, where ND is the number of detectors and NP the number of points
  • -
  • Nb (np.ndarray) – Array of (ND,NP) booleans, True if a point is seen by a detector
  • -
  • Pts (np.ndarray) – The computed points (in case they were not provided)
  • -
-

-
-
- -
-
-calc_SAngVect(Pts, In='(X, Y, Z)', Colis=True, Test=True)[source]¶
-

Return the Solid Angle of the Detect-Apert system as seen from the specified points, including collisions detection or not

-

Compute the solid angle and the directing vector subtended by the Detect-Optics system as seen from the desired points (provided in the specified coordinates). -This can be useful for visualizing the solid angle distribution or for computing synthetic signal from simulated emissivity in a 3D numerical integration manner. -The automtic detection of collisions with the edges of the Ves object can be switched off (not recommended).

- --- - - - - - -
Parameters:
    -
  • Pts (np.ndarray) – (2,N) or (3,N) array of coordinates of the provided N points
  • -
  • In (str) – Flag indicating in which coordinate system the Pts are provided, must be in [‘(R,Z)’,’(X,Y,Z)’,’(R,phi,Z)’]
  • -
  • Colis (bool) – Flag indicating whether collision detection should be activated
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

SAng (np.ndarray) – (N,) array of floats, the computed solid angles

-
-
- -
-
-calc_Sig(ff, extargs={}, Method='Vol', Mode='simps', PreComp=True, epsrel=0.0001, dX12=[0.005, 0.005], dX12Mode='abs', ds=0.005, dsMode='abs', MarginS=0.001, Colis=True, Test=True)[source]¶
-

Return the signal computed from an input emissivity function, using a 3D or LOS method

-

The synthetic signal resulting from a simulated emissivity can be computed automatically in several ways. -The user can choose between a VOS and a LOS approach (volume integration or line integration with etendue). -In each case the user can choose between the numerical integration method (from scipy.integrate + np.sum()). -It is possible to specify that, for a VOS approach, you want to use the pre-conputed mesh for faster computation (see set_SigPrecomp()). -For a VOS approach, the user can specify how fine the discretization should be. -The collision detection with the edges of the Ves object can be switched off (not recommended).

- --- - - - - - -
Parameters:
    -
  • ff (function) –
    -
    Input emissiviy function, should take one input as follows:
    -
      -
    • ff(Pts), where Points is a np.ndarray of shape=(3,N), with the (X,Y,Z) coordinates of any N number of points
    • -
    -
    -
    -
  • -
  • Method (str) – Flag indicating whether the spatial integration should be done with a volume (‘Vol’) or a LOS (‘LOS’) approach
  • -
  • Mode (str) – Flag indicating the numerical integration method in [‘quad’,’simps’,’trapz’,’nptrapz’,’sum’]
  • -
  • PreComp (bool) – Flag indicating whether the pre-computed grid should be used
  • -
  • epsrel (float) – Float specifying the tolerated relative error on the numerical integration, used for ‘quad’
  • -
  • dX12 (list) – Array of the 2 resolutions to be used to define the grid in a plane perpendicular to the LOS
  • -
  • dX12Mode (str) – Flag specifying whether the values in dX12 are absolute distances or relative values (i.e. fraction of the total width [0;1])
  • -
  • ds (float) – Float indicating the resolution in the longitudinal direction
  • -
  • dsMode (str) – Flag specifying whether ds is an absolute distance or relative (i.e. fraction of the total length [0;1])
  • -
  • Colis (bool) – Flag indicating whether collision detection should be used
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

Sig (float) – The computed signal

-
-
- -
-
-isInside(Points, In='(X, Y, Z)', Test=True)[source]¶
-

Return an array of indices indicating whether each point lies both in the cross-section and horizontal porojections of the viewing cone

-

Like for the Ves object, points can be provided in 2D or 3D coordinates (specified by ‘In’), and an array of booleans is returned.

- --- - - - - - -
Parameters:
    -
  • Points (np.ndarray) – (2,N) or (3,N) array of coordinates of the N points to be tested
  • -
  • In (str) –
    -
    Flag indicating in which coordinate system the Points are provided, must be in [‘(R,Z)’,’(Y,Z)’,’(X,Y)’,’(X,Y,Z)’,’(R,phi,Z)’]
    -
      -
    • ‘(R,Z)’: All points are assumed to lie in the horizontal projection, for ‘Tor’ vessel type only
    • -
    • ‘(Y,Z)’: All points are assumed to lie in the horizontal projection, for ‘Lin’ vessel type only
    • -
    • ‘(X,Y)’: All points are assumed to lie in the cross-section projection
    • -
    -
    -
    -
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

ind (np.ndarray) – (N,) array of booleans with True if a point lies inside both projections of the viewing cone

-
-
- -
-
-nIn¶
-

Return the normalized vector perpendicular to the polygon surface and oriented towards the interior of the associated vessel (in 3D cartesian coordinates)

-
- -
-
-plot(Lax=None, Proj='All', Elt='PVC', EltLOS='LDIORP', EltOptics='P', EltVes='', Leg=None, LOSRef=None, Pdict={'lw': 2, 'c': 'k', 'ls': 'solid'}, Vdict={'color': 'r', 'lw': 2, 'ls': 'solid'}, Cdict={'edgecolors': 'k', 'antialiaseds': False, 'linestyles': '-', 'linewidths': 0.0, 'alpha': 0.2, 'facecolors': (0.8, 0.8, 0.8, 0.2)}, LVIn=0.1, LOSdict={'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'EltVes': '', 'Proj': 'All', 'Test': True, 'Elt': 'LDIORP', 'MdictP': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, 'MdictR': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, 'Leg': '', 'Lplot': 'Tot', 'Lax': None, 'Vesdict': {'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'BsdictHor': {'c': 'b', 'ls': 'dashed'}, 'Bvdict': {'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, 'Lim': [1.5707963267948966, 6.283185307179586], 'Test': True, 'Proj': 'All', 'IdictHor': {'c': 'k', 'ls': 'dashed'}, 'Elt': 'PIBsBvV', 'Pdict': None, 'Vdict': {'color': 'r', 'scale': 10}, 'Idict': {'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, 'Bsdict': {'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, 'Lax': None, 'BvdictHor': {'c': 'g', 'ls': 'dashed'}, 'Nstep': 50}, 'MdictI': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, 'Ldict': {'lw': 2, 'c': 'k'}, 'MdictO': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, 'MdictD': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}}, Opticsdict={'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'Pdict': {'lw': 2, 'c': 'k', 'ls': 'solid'}, 'Vdict': {'color': 'r', 'lw': 2, 'ls': 'solid'}, 'EltVes': '', 'Leg': '', 'Lax': None, 'Vesdict': {'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'BsdictHor': {'c': 'b', 'ls': 'dashed'}, 'Bvdict': {'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, 'Lim': [1.5707963267948966, 6.283185307179586], 'Test': True, 'Proj': 'All', 'IdictHor': {'c': 'k', 'ls': 'dashed'}, 'Elt': 'PIBsBvV', 'Pdict': None, 'Vdict': {'color': 'r', 'scale': 10}, 'Idict': {'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, 'Bsdict': {'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, 'Lax': None, 'BvdictHor': {'c': 'g', 'ls': 'dashed'}, 'Nstep': 50}, 'LVIn': 0.1, 'Test': True, 'Elt': 'PV', 'Proj': 'All'}, Vesdict={'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'BsdictHor': {'c': 'b', 'ls': 'dashed'}, 'Bvdict': {'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, 'Lim': [1.5707963267948966, 6.283185307179586], 'Test': True, 'Proj': 'All', 'IdictHor': {'c': 'k', 'ls': 'dashed'}, 'Elt': 'PIBsBvV', 'Pdict': None, 'Vdict': {'color': 'r', 'scale': 10}, 'Idict': {'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, 'Bsdict': {'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, 'Lax': None, 'BvdictHor': {'c': 'g', 'ls': 'dashed'}, 'Nstep': 50}, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, draw=True, a4=False, Test=True)[source]¶
-

Plot the Detect instance in a projection or in 3D, its polygon, perpendicular vector, projected viewing cones and optionally its LOS, Apert, and Ves objects

-

The Detect instance can be plotted in a cross-section or horizontal projection, or in 3D. -Several of its attributes can be plotted too using the usual ‘Elt’ keyword argument. -Dedicated ‘Elt’ keyword arguments are also usable to specify the elements to be plotted for sub-classes like LOS, Apert, and Ves. -Dedicated dictionary help specify how each element sshould be plotted.

- --- - - - - - -
Parameters:
    -
  • Lax (None, plt.Axes or list) – Axes or list of axes to be used for plotting, if None a new figure and appropriate axes are created
  • -
  • Proj (str) – Flag indicating whether to plot the cross-section (‘Cross’), the horizontal projection (‘Hor’), both (‘All’) or a 3D representation (‘3D’)
  • -
  • Elt (str) –
    -
    Flag indicating which elements of the Detect instance to plot, each capital letter stands for an element
    -
      -
    • ‘P’: polygon
    • -
    • ‘V’: perpendicular vector
    • -
    • ‘C’: viewing cone
    • -
    -
    -
    -
  • -
  • EltLOS (None or str) – Flag indicating which elements of the LOS to plot, will be fed to LOS.plot(), if None uses the ‘Elt’ arg of LOSdict instead
  • -
  • EltOptics (None or str) – Flag indicating which elements of the Aperts to plot, will be fed to Apert.plot(), if None uses the ‘Elt’ arg of Apertdict instead
  • -
  • EltVes (None or str) – Flag indicating which elements of the Ves to plot, will be fed to plot(), if None uses the ‘Elt’ arg of Vesdict instead
  • -
  • Leg (str) – Legend to be used for the detector, if ‘’ the Detect.iD.Name is used
  • -
  • LOSRef (None or str) – Flag indicating which LOS should be represented, if None Detect._LOSRef is used
  • -
  • Pdict (dict) – Dictionary of properties for the Polygon
  • -
  • Vdict (dict) – Dictionary of properties for the Vector
  • -
  • Cdict (dict) – Dictionary of properties for the Cone
  • -
  • LVIn (float) – Length of the Vector
  • -
  • LOSdict (dict) – Dictionary of properties for the LOS if EltLOS is not ‘’, fed to LOS.plot()
  • -
  • Apertdict (dict) – Dictionary of properties for the Apert if EltOptics is not ‘’, fed to Apert.plot()
  • -
  • Vesdict (dict) – Dictionary of properties for the Ves if EltVes is not ‘’, fed to plot()
  • -
  • LegDict (dict) – Dictionary of properties for the legend, fed to plt.legend()
  • -
  • draw (bool) – Flag indicating whether to draw the figure
  • -
  • a4 (bool) – Flag indicating whether the default figure should be of size a4 paper
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

Lax plt.Axes or list – Axes or list of axes used for plotting

-
-
- -
-
-plot_Etend_AlongLOS(ax=None, NP=20, kMode='rel', Modes=['trapz'], Length='', RelErr=0.001, dX12=[0.005, 0.005], dX12Mode='abs', Ratio=0.02, LOSRef=None, LOSPts=True, Ldict={'lw': 2, 'c': 'k', 'ls': 'solid'}, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, Colis=True, draw=True, a4=True, Test=True)[source]¶
-

Plot the etendue of the selected LOS along it, with or without collision detection

-

The number of points along the LOS where the etendue is computed can be specified via arguments, as well as the numerical integration method. -Arguments Length, NP, Modes, RelErr, dX12, dX12Mode, Ratio, Colis, LOSRef are fed to calc_Etendue_AlongLOS()

- --- - - - - - -
Parameters:
    -
  • ax (None or plt.Axes) – Axes to be used for plotting, if None a new figure and appropriate axes are created
  • -
  • kMode (str) – Flag indicating whether the distance on the line should be plotted as abolute distance (‘abs’) or relative to the total length (‘rel’)
  • -
  • Ldict (dict) – Dictionary of properties for plotting the result
  • -
  • LegDict (None / dict) – If None, no legend is plotted, else LegDict is fed to :meth:’~matplotlib.pyplot.Axes.legend’
  • -
  • draw (bool) – Flag indicating whether to draw the figure
  • -
  • a4 (bool) – Flag indicating whether the created figure should have a4 dimensions (useful for printing)
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

ax (plt.Axes) – The axes used for plotting

-
-
- -
-
-plot_SAngNb(Lax=None, Proj='Cross', Slice='Int', Pts=None, plotfunc='scatter', DRY=None, DXTheta=None, DZ=None, Elt='P', EltVes='P', EltLOS='', EltOptics='P', Pdict={'lw': 2, 'c': 'k', 'ls': 'solid'}, Vdict={'color': 'r', 'lw': 2, 'ls': 'solid'}, Cdict={'edgecolors': 'k', 'antialiaseds': False, 'linestyles': '-', 'linewidths': 0.0, 'alpha': 0.2, 'facecolors': (0.8, 0.8, 0.8, 0.2)}, LVIn=0.1, LOSdict={'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'EltVes': '', 'Proj': 'All', 'Test': True, 'Elt': 'LDIORP', 'MdictP': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, 'MdictR': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, 'Leg': '', 'Lplot': 'Tot', 'Lax': None, 'Vesdict': {'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'BsdictHor': {'c': 'b', 'ls': 'dashed'}, 'Bvdict': {'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, 'Lim': [1.5707963267948966, 6.283185307179586], 'Test': True, 'Proj': 'All', 'IdictHor': {'c': 'k', 'ls': 'dashed'}, 'Elt': 'PIBsBvV', 'Pdict': None, 'Vdict': {'color': 'r', 'scale': 10}, 'Idict': {'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, 'Bsdict': {'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, 'Lax': None, 'BvdictHor': {'c': 'g', 'ls': 'dashed'}, 'Nstep': 50}, 'MdictI': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, 'Ldict': {'lw': 2, 'c': 'k'}, 'MdictO': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, 'MdictD': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}}, Opticsdict={'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'Pdict': {'lw': 2, 'c': 'k', 'ls': 'solid'}, 'Vdict': {'color': 'r', 'lw': 2, 'ls': 'solid'}, 'EltVes': '', 'Leg': '', 'Lax': None, 'Vesdict': {'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'BsdictHor': {'c': 'b', 'ls': 'dashed'}, 'Bvdict': {'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, 'Lim': [1.5707963267948966, 6.283185307179586], 'Test': True, 'Proj': 'All', 'IdictHor': {'c': 'k', 'ls': 'dashed'}, 'Elt': 'PIBsBvV', 'Pdict': None, 'Vdict': {'color': 'r', 'scale': 10}, 'Idict': {'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, 'Bsdict': {'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, 'Lax': None, 'BvdictHor': {'c': 'g', 'ls': 'dashed'}, 'Nstep': 50}, 'LVIn': 0.1, 'Test': True, 'Elt': 'PV', 'Proj': 'All'}, Vesdict={'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'BsdictHor': {'c': 'b', 'ls': 'dashed'}, 'Bvdict': {'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, 'Lim': [1.5707963267948966, 6.283185307179586], 'Test': True, 'Proj': 'All', 'IdictHor': {'c': 'k', 'ls': 'dashed'}, 'Elt': 'PIBsBvV', 'Pdict': None, 'Vdict': {'color': 'r', 'scale': 10}, 'Idict': {'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, 'Bsdict': {'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, 'Lax': None, 'BvdictHor': {'c': 'g', 'ls': 'dashed'}, 'Nstep': 50}, CDictSA=None, CDictNb=None, Colis=True, a4=False, draw=True, Test=True)[source]¶
-

Plot the solid angle projections (integrated ‘Int’ or maximum ‘Max’) as well as the number of detectors visible from each point in the plasma

-

Mostly useful with the GDetect object, used to visualize the goemetrical coverage in terms of total solid angle and number of detectors ‘seeing’ each point for a set of detectors (see calc_SAngNb() method for details).

- --- - - - - - -
Parameters:
    -
  • Lax (None or list or plt.Axes) – Axes or list of Axes to be used for plotting, if None a new figure and appropriate axes are created
  • -
  • Proj (str) – Flag indicating whether to plot the cross-section (‘Cross’) or the horizontal projection (‘Hor’)
  • -
  • Mode (str, None or float) –
    -
    Flag indicating whether to plot:
    -
      -
    • ‘Int’: the integrated value along the projected coordinates
    • -
    • ‘Max’: the maximum value along the projected coordinates
    • -
    • float: the projected coordinate at which to plot the slice (Theta or X if Proj=’Cross’, Z if Proj=’Hor’)
    • -
    • None: the slice is done in the middle of the viewing volume
    • -
    -
    -
    -
  • -
  • plotfunc (str) – Flag indicating which plotting method to use (‘scatter’, ‘contour’, ‘contourf’ or ‘imshow’)
  • -
  • DCross (float) – Resolution along the 1st cross-section coordinate (R for Type=’Tor’, Y for Type=’Lin’)
  • -
  • DXTheta (float) – Resolution along the ignorable coordinate (Theta for Type=’Tor’, X for Type=’Lin’)
  • -
  • DZ (float) – Vertical resolution (for both Types)
  • -
  • CDictSA (dict) – Properties of the solid angle plot, to be fed to the function chosen by plotfunc
  • -
  • CDictNb (dict) – Properties of the Nb plot, to be fed to the chsoen plotting routine
  • -
  • Colis (bool) – Flag indicating whether collision detection should be used
  • -
  • a4 (bool) – Flag indicating whether to use a4 dimensions to create a new figure if Lax=None
  • -
  • draw (bool) – Flag indicating whether to draw the figure
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

Lax (plt.Axes or list) – List of the axes used for plotting

-
-
- -
-
-plot_Sinogram(ax=None, Proj='Cross', Elt='DLV', Ang='theta', AngUnit='rad', Sketch=True, Ddict={'lw': 1, 'c': 'k', 'ls': 'solid'}, Ldict={'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, Vdict={'edgecolor': (0.8, 0.8, 0.8, 1.0), 'linewidth': 1, 'linestyle': 'solid', 'facecolor': (0.8, 0.8, 0.8, 1.0)}, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, LOSRef=None, draw=True, a4=False, Test=True)[source]¶
-

Plot the the Detect VOS in projection space, optionally also the associated Ves object and reference LOS

-

In projection space, a VOS is a patch (as opposed to a LOS which is a point). -The patch is estimated by plotting a large number of LOS sampling the VOS and taking the convex hull of the resulting points on projection space. -Notice that this method results in irrelevant patches for VOS lying at the edges of the projection space. -See plot_Sinogram() for details.

- --- - - - - - -
Parameters:
    -
  • ax (None / plt.Axes) – Axes on which to plot the Etendue, if None a default axes is created
  • -
  • Proj (str) – Flag indicating whether to plot the traditional sinogram in a cross-section (‘Cross’) or a 3D sinogram (‘3d’), cannot be ‘3d’ if ‘D’ in Elt.
  • -
  • Elt (str) – Flags indicating whether to plot the VOS of the Detect (‘D’ in Elt => only Proj=’Cross’), the LOS (‘L’ in Elt) and the Ves (‘V’ in Elt)
  • -
  • Ang (str) – Flag indicating which angle to use for the plot, with respect to the considered line () or to the impact parameter line ()
  • -
  • AngUnit (str) – Flag indicating whether the angle should be measured in ‘rad’ or ‘deg’
  • -
  • Sketch (bool) – Flag indicating whether a small sketch illustrating the definitions of angles and impact parameter should be included
  • -
  • Ddict (dict) – Plotting properties of the VOS of the Detect, fed to plt.plot()
  • -
  • Ldict (dict) – Plotting properties of the LOS, fed to plt.plot()
  • -
  • Vdict (dict) – Plotting properties of the Ves, fed to plt.plot()
  • -
  • LegDict (None / dict) – Plotting properties of the legend, if None no legend is plotted
  • -
  • LOSRef (None / str) – Flag indicating which LOS to plot, if None self._LOSRef is used
  • -
  • draw (bool) – Flag indicating whether to draw the figure
  • -
  • a4 (bool) – Flag indicating whether the created figure should have a4 dimensions (useful for printing)
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

ax (plt.Axes) – The axes used for plotting

-
-
- -
-
-refine_ConePoly(dMax=0.02, Proj='Cross', indPoly=0, Verb=True, Test=True)[source]¶
-

Reduce the number of points of the selected Cone_Poly projection using the provided maximum distance and checking for convexity

-

Provide a built-in method to simplify the 2 projections of the viewing cone (VOS). -In its raw form, the projection of the VOS is a polygon with potentially a high number of points (computed using matplotlib._cntr() function). -A re-sampled version of this polygon is computed by taking its convex hull and checking, for each edge, how far it is from the original edge. -Each edge (2 points) of the convex hull is then compared to the set of original edges it encloses. -If the maximum distance between this convex hull-derived edge and the original set of edges is smaller than dMax, then the convex hull-derived egde is used, otherwise the original edges are preserved. -The method does not return a value, instead it assigns the new polygon to a dedicated attribute of the object, thus ensuring that both the original and the re-sampled projections of the VOS are available.

- --- - - - -
Parameters:
    -
  • dMax (float) – Threshold absolute distance that limits the acceptable discrepancy between the original polygon and its convex hull (checked for each edge of the convex hull)
  • -
  • Proj (str) – Flag indicating to which projection of the VOS the method should be applied
  • -
  • indPoly (int) – Index of the polygon to be treated (i.e.: in case one projection of the VOS results in a list of several polygons instead of just one polygon as is usually the case)
  • -
  • Verb (bool) – Flag indicating whether a one-line comment should be printed at the end of the calculation giving the number of points of the new polygon vs the number of points of the original polygon
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
-
- -
-
-save(SaveName=None, Path=None, Mode='npz', SynthDiag=False)[source]¶
-

Save the object in folder Name, under file name SaveName, using specified mode

-

Most tofu objects can be saved automatically as numpy arrays (.npz, recommended) at the default location (recommended) by simply calling self.save() -In the case of Detect and GDetect instances, there is an additional keyword argument ‘SynthDiag’ which allows to not save the pre-computed 3D mesh of the VOS for synthetic diagnostic. -Indeed, this pre-computed data is often large and results in big files. Not saving it results in significantly smaller files, and it can be re-computed when loading the instance.

- --- - - - -
Parameters:
    -
  • SaveName (None / str) – The name to be used for the saved file, if None (recommended) uses self.Id.SaveName
  • -
  • Path (None / str) – Path specifying where to save the file, if None (recommended) uses self.Id.SavePath
  • -
  • Mode (str) – Flag specifying whether to save the object as a numpy array file (‘.npz’, recommended) or an object using cPickle (not recommended, heavier and may cause retro-compatibility issues)
  • -
  • SynthDiag (bool) – Flag indicating whether the pre-computed mesh for synthetic diagnostics calculations shall be saved too (can be heavy, if False, it will be re-computed when opening the saved object)
  • -
-
-
- -
-
-set_SigPrecomp(CalcPreComp=True, dX12=None, dX12Mode=None, ds=None, dsMode=None, MarginS=None, Colis=None)[source]¶
-

Precompute a 3D grid for fast integration of a 3D emissivity for a synthetic diagnostic approach

-

In order to accelerate the computation of synthetic signal from simulated emissivity, it is possible to pre-compute a discretisation of the VOS (mesh points + solid angle) and store it as an attribute of the Detect object. -While such pre-computation does speed-up significantly the numerical integration, it also burdens the object with heavy attributes that can make it too big to save. -Hence, the saving method has a special argument that allows to specify that these pre-computed attributes should not be saved but should instead be re-computed automatically when loading the file. -The parameters dX12, dX12Mode, ds and dsMode give the user control over how fine the discretization of the VOS should be, which affects both the accuracy of the numerical integration and the size of the resulting mesh.

- --- - - - -
Parameters:
    -
  • CalcPreComp (bool) – Flag indicating whether the pre-computation should be run
  • -
  • dX12 (list) – Array of the 2 resolutions to be used to define the grid in a plane perpendicular to the LOS
  • -
  • dX12Mode (str) – Flag specifying whether the values in dX12 are absolute distances or relative values (i.e. fraction of the total width [0;1])
  • -
  • ds (float) – Float indicating the resolution in the longitudinal direction
  • -
  • dsMode (str) – Flag specifying whether ds is an absolute distance or relative (i.e. fraction of the total length [0;1])
  • -
  • MarginS (float) – Float specifying
  • -
  • Colis (bool) – Flag indicating whether collision detection should be used
  • -
-
-
- -
- -
-
-class tofu.geom.GDetect(Id, LDetect, Type=None, Exp=None, Diag=None, shot=None, Sino_RefPt=None, LOSRef=None, arrayorder='C', Clock=False, dtime=None, dtimeIn=False, SavePath=None)[source]¶
-

An object grouping a list of Detect objects with some common features (e.g.: all belong to the same camera) and the same Ves object, provides methods for common computing and plotting

-

A GDetect object is a convenient tool for managing groups of detectors, applying common treatment, plotting... -It is typically suited for a camera (e.g.: a group of detectors sharing a common aperture)

- --- - - - -
Parameters:
    -
  • Id (str or tfpf.ID) – A name string or a pre-built tfpf.ID class to be used to identify this particular instance, if a string is provided, it is fed to ID
  • -
  • LDetect (list or Detect) – List of Detect instances with the same Ves instance
  • -
  • Type (None) – Not used in the current verion of tofu
  • -
  • Exp (None or str) – Experiment to which the Lens belongs, should be identical to Ves.Id.Exp if Ves is provided, if None and Ves is provided, Ves.Id.Exp is used
  • -
  • Diag (None or str) – Diagnostic to which the Lens belongs
  • -
  • shot (None or int) – Shot number from which this Lens is usable (in case its position was changed from a previous configuration)
  • -
  • SavePath (None / str) – If provided, forces the default saving path of the object to the provided value
  • -
  • Sino_RefPt (None or iterable) – If provided, forces the common Sino_RefPt to the provided value for all Detect instances
  • -
  • arrayorder (str) – Flag indicating whether the attributes of type=np.ndarray (e.g.: Poly) should be made C-contiguous (‘C’) or Fortran-contiguous (‘F’)
  • -
  • dtime (None or dtm.datetime) – A time reference to be used to identify this particular instance (used for debugging mostly)
  • -
  • dtimeIn (bool) – Flag indicating whether dtime should be included in the SaveName (used for debugging mostly)
  • -
-
-
-
-Id¶
-

the associated tfpf.ID object

-
- -
-
-LDetect¶
-

Return the list of Detect instances the GDetect object comprises

-
- -
-
-Optics¶
-

Return the list of optics the GDetect object comprises (either Lens or Apert)

-
- -
-
-Sino_RefPt¶
-

Return the coordinates (R,Z) or (Y,Z) for Ves of Type ‘Tor’ or (Y,Z) for Ves of Type ‘Lin’ of the reference point used to compute the sinogram

-
- -
-
-Ves¶
-

Return the Ves instance associated to the GDetect object

-
- -
-
-calc_SAngVect(Pts, In='(X, Y, Z)', Colis=True, Test=True)[source]¶
-

Applies calc_SAngVect() to all Detect instances

-

Return the result as two 2D arrays where the first dimension is the number of Detect instances -see calc_SAngVect() for details

-
- -
-
-calc_Sig(ff, extargs={}, Method='Vol', Mode='simps', PreComp=True, epsrel=0.0001, dX12=[0.005, 0.005], dX12Mode='abs', ds=0.005, dsMode='abs', MarginS=0.001, Colis=True, Test=True, ind=None, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In')[source]¶
-

Applies calc_Sig() to all Detect instances

-

See calc_Sig() for details -Arguments ind, Val, Crit, PreExp, PostExp, Log and InOut are fed to select()

-
- -
-
-get_GLOS(Name=None, LOSRef=None)[source]¶
-

Return the GLOS instance that can be built by grouping the LOS of each Detect instance

-

Can be useful for handling a GLOS instead of a GDetect (heavier) instance

- --- - - - - - -
Parameters:
    -
  • Name (None / str) – Name to be given to the GLOS instance, if None a name is built from the name of the GDetect object by appending ‘_GLOS’
  • -
  • LOSRef (None / str) – Key indicating which LOS to be used, if None the default LOSRef is used
  • -
-
Returns:

glos (GLOS) – The constructed GLOS instance

-
-
- -
-
-isInside(Points, In='(X, Y, Z)', Test=True)[source]¶
-

Return an array of indices indicating whether each point lies both in the cross-section and horizontal porojections of the viewing cone of each Detect

-

see isInside() for details

- --- - - - - - -
Parameters:
    -
  • Points (np.ndarray) – (2,N) or (3,N) array of coordinates of the N points to be tested
  • -
  • In (str) –
    -
    Flag indicating in which coordinate system the Points are provided, must be in [‘(R,Z)’,’(Y,Z)’,’(X,Y)’,’(X,Y,Z)’,’(R,phi,Z)’]
    -
      -
    • ‘(R,Z)’: All points are assumed to lie in the horizontal projection, for ‘Tor’ vessel type only
    • -
    • ‘(Y,Z)’: All points are assumed to lie in the horizontal projection, for ‘Lin’ vessel type only
    • -
    • ‘(X,Y)’: All points are assumed to lie in the cross-section projection
    • -
    -
    -
    -
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

ind (np.ndarray) – (ND,N) array of booleans with True if a point lies inside both projections of the viewing cone, where ND is the number of Detect instances

-
-
- -
-
-nDetect¶
-

Return the number of Detect instances the GDetect object comprises

-
- -
-
-plot(Lax=None, Proj='All', Elt='PVC', EltLOS='LDIORP', EltOptics='P', EltVes='', Leg=None, LOSRef=None, Pdict={'lw': 2, 'c': 'k', 'ls': 'solid'}, Vdict={'color': 'r', 'lw': 2, 'ls': 'solid'}, Cdict={'edgecolors': 'k', 'antialiaseds': False, 'linestyles': '-', 'linewidths': 0.0, 'alpha': 0.2, 'facecolors': (0.8, 0.8, 0.8, 0.2)}, LVIn=0.1, LOSdict={'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'EltVes': '', 'Proj': 'All', 'Test': True, 'Elt': 'LDIORP', 'MdictP': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, 'MdictR': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, 'Leg': '', 'Lplot': 'Tot', 'Lax': None, 'Vesdict': {'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'BsdictHor': {'c': 'b', 'ls': 'dashed'}, 'Bvdict': {'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, 'Lim': [1.5707963267948966, 6.283185307179586], 'Test': True, 'Proj': 'All', 'IdictHor': {'c': 'k', 'ls': 'dashed'}, 'Elt': 'PIBsBvV', 'Pdict': None, 'Vdict': {'color': 'r', 'scale': 10}, 'Idict': {'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, 'Bsdict': {'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, 'Lax': None, 'BvdictHor': {'c': 'g', 'ls': 'dashed'}, 'Nstep': 50}, 'MdictI': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, 'Ldict': {'lw': 2, 'c': 'k'}, 'MdictO': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, 'MdictD': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}}, Opticsdict={'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'Pdict': {'lw': 2, 'c': 'k', 'ls': 'solid'}, 'Vdict': {'color': 'r', 'lw': 2, 'ls': 'solid'}, 'EltVes': '', 'Leg': '', 'Lax': None, 'Vesdict': {'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'BsdictHor': {'c': 'b', 'ls': 'dashed'}, 'Bvdict': {'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, 'Lim': [1.5707963267948966, 6.283185307179586], 'Test': True, 'Proj': 'All', 'IdictHor': {'c': 'k', 'ls': 'dashed'}, 'Elt': 'PIBsBvV', 'Pdict': None, 'Vdict': {'color': 'r', 'scale': 10}, 'Idict': {'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, 'Bsdict': {'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, 'Lax': None, 'BvdictHor': {'c': 'g', 'ls': 'dashed'}, 'Nstep': 50}, 'LVIn': 0.1, 'Test': True, 'Elt': 'PV', 'Proj': 'All'}, Vesdict={'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'BsdictHor': {'c': 'b', 'ls': 'dashed'}, 'Bvdict': {'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, 'Lim': [1.5707963267948966, 6.283185307179586], 'Test': True, 'Proj': 'All', 'IdictHor': {'c': 'k', 'ls': 'dashed'}, 'Elt': 'PIBsBvV', 'Pdict': None, 'Vdict': {'color': 'r', 'scale': 10}, 'Idict': {'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, 'Bsdict': {'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, 'Lax': None, 'BvdictHor': {'c': 'g', 'ls': 'dashed'}, 'Nstep': 50}, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, draw=True, a4=False, Test=True, ind=None, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In')[source]¶
-

Plot all or a subset of the Detect instances in a projection or in 3D

-

See plot() for details -Arguments ind, Val, Crit, PreExp, PostExp, Log and InOut are fed to select()

- --- - - - - - -
Parameters:
    -
  • Lax (None, plt.Axes or list) – Axes or list of axes to be used for plotting, if None a new figure and appropriate axes are created
  • -
  • Proj (str) – Flag indicating whether to plot the cross-section (‘Cross’), the horizontal projection (‘Hor’), both (‘All’) or a 3D representation (‘3D’)
  • -
  • Elt (str) –
    -
    Flag indicating which elements of the Detect instance to plot, each capital letter stands for an element
    -
      -
    • ‘P’: polygon
    • -
    • ‘V’: perpendicular vector
    • -
    • ‘C’: viewing cone
    • -
    -
    -
    -
  • -
  • EltLOS (None or str) – Flag indicating which elements of the LOS to plot, will be fed to LOS.plot(), if None uses the ‘Elt’ arg of LOSdict instead
  • -
  • EltOptics (None or str) – Flag indicating which elements of the Aperts to plot, will be fed to Apert.plot(), if None uses the ‘Elt’ arg of Apertdict instead
  • -
  • EltVes (None or str) – Flag indicating which elements of the Ves to plot, will be fed to plot(), if None uses the ‘Elt’ arg of Vesdict instead
  • -
  • Leg (str) – Legend to be used for the detector, if ‘’ the Detect.iD.Name is used
  • -
  • LOSRef (None or str) – Flag indicating which LOS should be represented, if None Detect._LOSRef is used
  • -
  • Pdict (dict) – Dictionary of properties for the Polygon
  • -
  • Vdict (dict) – Dictionary of properties for the Vector
  • -
  • Cdict (dict) – Dictionary of properties for the Cone
  • -
  • LVIn (float) – Length of the Vector
  • -
  • LOSdict (dict) – Dictionary of properties for the LOS if EltLOS is not ‘’, fed to LOS.plot()
  • -
  • Apertdict (dict) – Dictionary of properties for the Apert if EltOptics is not ‘’, fed to Apert.plot()
  • -
  • Vesdict (dict) – Dictionary of properties for the Ves if EltVes is not ‘’, fed to plot()
  • -
  • LegDict (dict) – Dictionary of properties for the legend, fed to plt.legend()
  • -
  • draw (bool) – Flag indicating whether to draw the figure
  • -
  • a4 (bool) – Flag indicating whether the default figure should be of size a4 paper
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

Lax plt.Axes or list – Axes or list of axes used for plotting

-
-
- -
-
-plot_Etend_AlongLOS(ax=None, NP=20, kMode='rel', Modes=['trapz'], RelErr=None, dX12=None, dX12Mode=None, Ratio=None, LOSRef=None, LOSPts=True, Ldict={'lw': 2, 'c': 'k', 'ls': 'solid'}, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, Colis=True, draw=True, a4=True, Test=True, ind=None, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In')[source]¶
-

Plot the etendue of the selected LOS along it, with or without collision detection

-

The number of points along the LOS where the etendue is computed can be specified via arguments, as well as the numerical integration method. -See plot_Etendue_AlongLOS() for details -Arguments Length, NP, Modes, RelErr, dX12, dX12Mode, Ratio, Colis, LOSRef are fed to calc_Etendue_AlongLOS() -Arguments ind, Val, Crit, PreExp, PostExp, Log and InOut are fed to select()

- --- - - - - - -
Parameters:
    -
  • ax (None or plt.Axes) – Axes to be used for plotting, if None a new figure and appropriate axes are created
  • -
  • NP (int) – Number of points along the LOS at which the Etendue should be computed
  • -
  • kMode (str) – Flag indicating whether the distance on the line should be plotted as abolute distance (‘abs’) or relative to the total length (‘rel’)
  • -
  • Modes (str or list) – Flag or list of flags indicating which integration method should be used
  • -
  • Colis (bool) – Flag indicating whether collision detection should be used
  • -
  • LOSRef (None or str) – Flag indicating which LOS should be used
  • -
  • Ldict (dict) – Dictionary of properties for plotting the result
  • -
  • LegDict (None / dict) – If None, no legend is plotted, else LegDict is fed to :meth:’~matplotlib.pyplot.Axes.legend’
  • -
  • draw (bool) – Flag indicating whether to draw the figure
  • -
  • a4 (bool) – Flag indicating whether the created figure should have a4 dimensions (useful for printing)
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

ax (plt.Axes) – The axes used for plotting

-
-
- -
-
-plot_Etendues(Mode='Etend', Elt='', ax=None, Adict={'marker': '+', 'lw': 2, 'c': 'k', 'ls': 'None'}, Rdict={'marker': 'x', 'lw': 2, 'c': 'b', 'ls': 'None'}, Edict={'marker': 'o', 'lw': 2, 'c': 'g', 'ls': 'None'}, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, draw=True, a4=False, Test=True, ind=None, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In')[source]¶
-

Plot the etendues of all or a subset of the Detect instances for the chosen LOS

-

A given Detect+Optics system has a VOS, under proper conditions, this VOS can be approximated by a LOS, but the choice of the LOS is not unique, there is an infinite number of possible LOS in a single VOS. -The LOS automatically computed by tofu os the ‘natural’ option : goes from the midlle of the Detect area throught the middle of the optics. -Then tofu automatically computes the associated etendue. -This methods plots all the etendues of all the chosen Detect instances for the chosen LOS, which is by default the ‘natural’ LOS computed by tofu

- --- - - - - - -
Parameters:
    -
  • Mode (str) – Flasg indicating whether to plot the etendue (‘Etend’) or a geometrical calibration factor (‘Calib’) computed as the 4pi/etendue
  • -
  • Elt (str) – Flag indicating whether to plot, in addition to the etendue, also the direct (‘A’) and reverse (‘R’) 0-order approximation of the etendue
  • -
  • ax (None or plt.Axes) – Axes to be used for plotting, if None a new figure and appropriate axes are created
  • -
  • Adict (dict) – Dictionary of properties for plotting the direct 0-order approximation of the etendue (if ‘A’ in Elt), fed to plot()
  • -
  • Rdict (dict) – Dictionary of properties for plotting the reverse 0-order approximation of the etendue (if ‘R’ in Elt), fed to plot()
  • -
  • Edict (dict) – Dictionary of properties for plotting the etendue, fed to plot()
  • -
  • LegDict (dict) – If None, no legend is plotted, else LegDict is fed to :meth:’~matplotlib.pyplot.Axes.legend’
  • -
  • draw (bool) – Flag indicating whether to draw the figure
  • -
  • a4 (bool) – Flag indicating whether the created figure should have a4 dimensions (useful for printing)
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

ax (plt.Axes) – The axes used for plotting

-
-
- -
-
-plot_SAngNb(Lax=None, Proj='Cross', Slice='Int', Pts=None, plotfunc='scatter', DRY=None, DXTheta=None, DZ=None, Elt='P', EltVes='P', EltLOS='', EltOptics='P', Pdict={'lw': 2, 'c': 'k', 'ls': 'solid'}, Vdict={'color': 'r', 'lw': 2, 'ls': 'solid'}, Cdict={'edgecolors': 'k', 'antialiaseds': False, 'linestyles': '-', 'linewidths': 0.0, 'alpha': 0.2, 'facecolors': (0.8, 0.8, 0.8, 0.2)}, LVIn=0.1, LOSdict={'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'EltVes': '', 'Proj': 'All', 'Test': True, 'Elt': 'LDIORP', 'MdictP': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, 'MdictR': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, 'Leg': '', 'Lplot': 'Tot', 'Lax': None, 'Vesdict': {'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'BsdictHor': {'c': 'b', 'ls': 'dashed'}, 'Bvdict': {'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, 'Lim': [1.5707963267948966, 6.283185307179586], 'Test': True, 'Proj': 'All', 'IdictHor': {'c': 'k', 'ls': 'dashed'}, 'Elt': 'PIBsBvV', 'Pdict': None, 'Vdict': {'color': 'r', 'scale': 10}, 'Idict': {'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, 'Bsdict': {'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, 'Lax': None, 'BvdictHor': {'c': 'g', 'ls': 'dashed'}, 'Nstep': 50}, 'MdictI': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, 'Ldict': {'lw': 2, 'c': 'k'}, 'MdictO': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, 'MdictD': {'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}}, Opticsdict={'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'Pdict': {'lw': 2, 'c': 'k', 'ls': 'solid'}, 'Vdict': {'color': 'r', 'lw': 2, 'ls': 'solid'}, 'EltVes': '', 'Leg': '', 'Lax': None, 'Vesdict': {'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'BsdictHor': {'c': 'b', 'ls': 'dashed'}, 'Bvdict': {'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, 'Lim': [1.5707963267948966, 6.283185307179586], 'Test': True, 'Proj': 'All', 'IdictHor': {'c': 'k', 'ls': 'dashed'}, 'Elt': 'PIBsBvV', 'Pdict': None, 'Vdict': {'color': 'r', 'scale': 10}, 'Idict': {'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, 'Bsdict': {'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, 'Lax': None, 'BvdictHor': {'c': 'g', 'ls': 'dashed'}, 'Nstep': 50}, 'LVIn': 0.1, 'Test': True, 'Elt': 'PV', 'Proj': 'All'}, Vesdict={'draw': True, 'LegDict': {'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, 'BsdictHor': {'c': 'b', 'ls': 'dashed'}, 'Bvdict': {'marker': 'x', 'mew': 2, 'c': 'g', 'markersize': 8, 'ls': 'dashed'}, 'Lim': [1.5707963267948966, 6.283185307179586], 'Test': True, 'Proj': 'All', 'IdictHor': {'c': 'k', 'ls': 'dashed'}, 'Elt': 'PIBsBvV', 'Pdict': None, 'Vdict': {'color': 'r', 'scale': 10}, 'Idict': {'marker': 'x', 'mew': 2, 'c': 'k', 'markersize': 8, 'ls': 'dashed'}, 'Bsdict': {'marker': 'x', 'mew': 2, 'c': 'b', 'markersize': 8, 'ls': 'dashed'}, 'Lax': None, 'BvdictHor': {'c': 'g', 'ls': 'dashed'}, 'Nstep': 50}, CDictSA=None, CDictNb=None, Colis=True, a4=False, draw=True, Test=True, ind=None, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In')[source]¶
-

Plot the solid angle projections (integrated ‘Int’ or maximum ‘Max’) as well as the number of detectors visible from each point in the plasma

-

See plot_SAngNb() for details -Arguments ind, Val, Crit, PreExp, PostExp, Log and InOut are fed to select()

- --- - - - - - -
Parameters:
    -
  • Lax (None or list or plt.Axes) – Axes or list of Axes to be used for plotting, if None a new figure and appropriate axes are created
  • -
  • Proj (str) – Flag indicating whether to plot the cross-section (‘Cross’) or the horizontal projection (‘Hor’)
  • -
  • Mode (str, None or float) –
    -
    Flag indicating whether to plot:
    -
      -
    • ‘Int’: the integrated value along the projected coordinates
    • -
    • ‘Max’: the maximum value along the projected coordinates
    • -
    • float: the projected coordinate at which to plot the slice (Theta or X if Proj=’Cross’, Z if Proj=’Hor’)
    • -
    • None: the slice is done in the middle of the viewing volume
    • -
    -
    -
    -
  • -
  • plotfunc (str) – Flag indicating which plotting method to use (‘scatter’, ‘contour’, ‘contourf’ or ‘imshow’)
  • -
  • DCross (float) – Resolution along the 1st cross-section coordinate (R for Type=’Tor’, Y for Type=’Lin’)
  • -
  • DXTheta (float) – Resolution along the ignorable coordinate (Theta for Type=’Tor’, X for Type=’Lin’)
  • -
  • DZ (float) – Vertical resolution (for both Types)
  • -
  • CDictSA (dict) – Properties of the solid angle plot, to be fed to the function chosen by plotfunc
  • -
  • CDictNb (dict) – Properties of the Nb plot, to be fed to ...
  • -
  • Colis (bool) – Flag indicating whether collision detection should be used
  • -
  • a4 (bool) – Flag indicating whether to use a4 dimensions to create a new figure if Lax=None
  • -
  • draw (bool) – Flag indicating whether to draw the figure
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

Lax plt.Axes or list List of the axes used for plotting

-
-
- -
-
-plot_Sig(ffSig, extargs={}, Method='Vol', Mode='simps', ax=None, Leg='', Sdict={'marker': '+', 'lw': 2, 'c': 'k', 'ls': 'solid'}, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, draw=True, a4=False, Test=True, PreComp=True, epsrel=0.0001, dX12=[0.005, 0.005], dX12Mode='abs', ds=0.005, dsMode='abs', MarginS=0.001, Colis=True, ind=None, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In')[source]¶
-

Plot the ignal computed for each or a subset of the Detect instances

-

If the signal is not directly provided as an array, it is computed from a function. -If ffSig is a callable function, arguments ffSig, extargs, Method, Mode, PreComp, epsrel, dX12, dX12Mode, ds, dsMode, MarginS, Colis and Test are fed to calc_Sig() -Arguments ind, Val, Crit, PreExp, PostExp, Log and InOut are fed to select()

- --- - - - - - -
Parameters:
    -
  • np.ndarray or callable (ffSig) – Either a np.ndarray containing the signal to be plotted (of shape (ND,) or (N,ND) where ND is the number of detectors to be plotted) or a callable to be fed to for computing the signal
  • -
  • ax (None or plt.Axes) – Axes to be used for plotting, if None a new figure and appropriate axes are created
  • -
  • Sdict (dict) – Dictionary of properties for plotting the signal, fed to plot()
  • -
  • Leg (str) – Label to be used for the plot
  • -
  • LegDict (dict) – If None, no legend is plotted, else LegDict is fed to :meth:’~matplotlib.pyplot.Axes.legend’
  • -
  • draw (bool) – Flag indicating whether to draw the figure
  • -
  • a4 (bool) – Flag indicating whether the created figure should have a4 dimensions (useful for printing)
  • -
  • Test (bool) – Flag indicating whether the inputs should be tested for conformity
  • -
-
Returns:

ax (plt.Axes) – The axes used for plotting

-
-
- -
-
-plot_Sinogram(ax=None, Proj='Cross', Elt='DLV', Ang='theta', AngUnit='rad', Sketch=True, Ddict={'lw': 1, 'c': 'k', 'ls': 'solid'}, Ldict={'c': 'k', 'markersize': 8, 'lw': 2, 'mew': 2, 'ls': 'None', 'marker': 'x'}, Vdict={'edgecolor': (0.8, 0.8, 0.8, 1.0), 'linewidth': 1, 'linestyle': 'solid', 'facecolor': (0.8, 0.8, 0.8, 1.0)}, LegDict={'loc': 2, 'bbox_to_anchor': (1.01, 1), 'prop': {'size': 10}, 'ncol': 1, 'borderaxespad': 0.0, 'frameon': False}, LOSRef=None, draw=True, a4=False, Test=True, ind=None, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In')[source]¶
-

Plot the VOS of all or of a subset of the Detect instances in projection space, optionally also the associated Ves object and reference LOS

-

See plot_Sinogram() for details -Arguments ind, Val, Crit, PreExp, PostExp, Log and InOut are fed to select()

-
- -
-
-save(SaveName=None, Path=None, Mode='npz', SynthDiag=False)[source]¶
-

Save the object in folder Name, under file name SaveName, using specified mode

-

Most tofu objects can be saved automatically as numpy arrays (.npz, recommended) at the default location (recommended) by simply calling self.save() -In the case of Detect and GDetect instances, there is an additional keyword argument ‘SynthDiag’ which allows to not save the pre-computed 3D mesh of the VOS for synthetic diagnostic. -Indeed, this pre-computed data is often large and results in big files. Not saving it results in significantly smaller files, and it can be re-computed when loading the instance.

- --- - - - -
Parameters:
    -
  • SaveName (None / str) – The name to be used for the saved file, if None (recommended) uses self.Id.SaveName
  • -
  • Path (None / str) – Path specifying where to save the file, if None (recommended) uses self.Id.SavePath
  • -
  • Mode (str) – Flag specifying whether to save the object as a numpy array file (‘.npz’, recommended) or an object using cPickle (not recommended, heavier and may cause retro-compatibility issues)
  • -
  • SynthDiag (bool) – Flag indicating whether the pre-computed mesh for synthetic diagnostics calculations shall be saved too (can be heavy, if False, it will be re-computed when opening the saved object)
  • -
-
-
- -
-
-select(Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In', Out=<type 'bool'>)[source]¶
-

Return the indices or instances of all instances matching the specified criterion.

-

The selection can be done according to 2 different mechanism (1) and (2).

-

For mechanism (1): the user provides the value (Val) that the specified criterion (Crit) should take for a tofu.geom.Detect to be selected. -The criteria are typically attributes of the self.Id attribute (i.e.: name of the instance, or user-defined attributes like the camera head...)

-

For mechanism (2), used if Val=None: the user provides a str expression (or a list of such) to be fed to eval(), used to check on quantitative criteria, placed before the criterion value (e.g.: ‘not ‘ or ‘<=’). -Another str or list of str expressions can be provided that will be placed after the criterion value.

-

Other parameters are used to specify logical operators for the selection (match any or all the criterion...) and the type of output. -See select() for examples

- --- - - - - - -
Parameters:
    -
  • Crit (str) – Flag indicating which criterion to use for discrimination -Can be set to any attribute of the tofu.pathfile.ID class (e.g.: ‘Name’,’SaveName’,’SavePath’...) or any key of ID.USRdict (e.g.: ‘Exp’...)
  • -
  • Val (list, str or None) – The value to match for the chosen criterion, can be a list of different values -Used for selection mechanism (1)
  • -
  • PreExp (list, str or None) – A str of list of str expressions to be fed to eval(), used to check on quantitative criteria, placed before the criterion value (e.g.: ‘not ‘) -Used for selection mechanism (2)
  • -
  • PostExp (list, str or None) – A str of list of str expressions to be fed to eval(), used to check on quantitative criteria, placed after the criterion value (e.g.: ‘>=5.’) -Used for selection mechanism (2)
  • -
  • Log (str) – Flag indicating whether the criterion shall match all provided values or one of them (‘any’ or ‘all’)
  • -
  • InOut (str) – Flag indicating whether the returned indices are the ones matching the criterion (‘In’) or the ones not matching it (‘Out’)
  • -
  • Out (type / str) – Flag indicating in which form shall the result be returned, as an array of integer indices (int), an array of booleans (bool), a list of names (‘Names’) or a list of instances (‘Detect’)
  • -
-
Returns:

ind (list / np.ndarray) – The computed output (array of index, list of names or instances depending on parameter ‘Out’)

-
-
- -
-
-set_SigPrecomp(CalcPreComp=True, dX12=[0.005, 0.005], dX12Mode='abs', ds=0.005, dsMode='abs', MarginS=0.001, Colis=True)[source]¶
-

Applies set_SigPrecomp() to all Detect instances

-
- -
- -
-
-tofu.plugins.AUG.SXR.geom.create(shot=0, VesName='V1', SavePathObj=None, RootpluginElt='/afs/ipp-garching.mpg.de/home/d/didiv/Python/tofu/tofu/plugins/AUG/SXR/geom', forceshot=False, overwrite=False, save=True, CamHeads=['F', 'G', 'H1', 'H2', 'H3', 'I1', 'I2', 'I3', 'J1', 'J2', 'J3', 'K1', 'K2', 'L', 'M'], dtime=None, dtFormat='D%Y%m%d_T%H%M%S', CalcEtend=True, CalcSpanImp=True, CalcCone=True, CalcPreComp=True, Calc=True, Verb=True, Etend_Method='quad', Etend_RelErr=0.001, Etend_dX12=[0.01, 0.01], Etend_dX12Mode='rel', Etend_Ratio=0.02, Colis=True, LOSRef='Cart', Cone_DRY=0.0025, Cone_DXTheta=0.0030679615757712823, Cone_DZ=0.0025, Cone_NPsi=20, Cone_Nk=60)[source]¶
-

Create the tfg.GDetect objects (i.e.: the cameras, which are groups of detectors) from geometry taken from CSX disgnostic for the proposed shot or earlier (looks for the oldest version of the matching geometry) and stores them in the SavePathObj

- --- - - - -
Parameters:
    -
  • shot (int) – Shot number for which to build the geometry
  • -
  • VesName (str) – Name of the tfg.Ves object to be fed as an input to the tfg.GDetect objects
  • -
  • SavePathObj (None / str) – Absolute path where the created tfg.GDetect objects should be saved (if save=True), if None the default is used
  • -
  • RootpluginElt (str) – If SavePathObj=None, a default value is created by appending ‘/Objects/’ to RootpluginElt
  • -
  • forceshot (bool) – Flag indicating whether the shot number shall be downgraded to the oldest shot with the same geometry (False) or whether the provided shot number shall be enforced (True, for all camera heads)
  • -
  • overwrite (bool) – Flag indicating whether new tfg.GDetect objects shall be computed (and possibly saved) when similar ones already exist (True)
  • -
  • save (bool) – Flag indicating whether to save the created tfg.GDetect objects (in SavePathObj)
  • -
  • dtime (None / dtm.datetime) – If provided (i.e.: not None), used as a label of the created tfg.GDetect objects (mostly used for debugging)
  • -
  • dtFormat (str) – The time format to be used for labelling the created tfg.GDetect objects (mostly used for debugging)
  • -
-
-

:param All other arguments are fed to Detect:

- --- - - - -
Returns:LGD (list) – A list of all the created tfg.GDetect objects
-
- -
-
-tofu.plugins.AUG.SXR.geom.load(Cams=[], shot=inf, SavePathObj=None, RootpluginElt='/afs/ipp-garching.mpg.de/home/d/didiv/Python/tofu/tofu/plugins/AUG/SXR/geom', sort=False)[source]¶
-

Load and return the desired tfg.GDetect objects (i.e.: camera heads)

- --- - - - -
Parameters:
    -
  • Cams (list / tfg.GDetect) – A name or a list of names of the camera heads to be loaded (available are [‘F’,’G’,’H1’,’H2’,’H3’,’I1’,’I2’,’I3’,’J1’,’J2’,’J3’,’K1’,’K2’,’L’,’M’])
  • -
  • shot (int / float / np.float) – A shot number indicating which version of the geometry should be loaded (the )
  • -
  • SavePathObj (None / str) – Absolute path where the created tfg.GDetect objects should be saved (if save=True), if None the default is used
  • -
  • RootpluginElt (str) – If SavePathObj=None, a default value is created by appending ‘/Objects/’ to RootpluginElt
  • -
  • sort (bool) – Flag indicating whether the loaded GDetect objects shall be returned sorted by alphabetical order of the names (True) or in the same order as asked in Cams (False)
  • -
  • Returns
  • -
  • --------
  • -
  • Cams – The loaded tfg.GDetect objects, returned as a single object if Cams was provided as a single name, as a list otherwise
  • -
-
-
- -
- - -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/build/html/Citation.html b/doc/build/html/Citation.html deleted file mode 100644 index 9a7ab54e1..000000000 --- a/doc/build/html/Citation.html +++ /dev/null @@ -1,137 +0,0 @@ - - - - - - - - Citing ToFu: — tofu v1.1 - - - - - - - - - - - - - - -
-
-
-
- -
-

Citing ToFu:¶

-

An article dedicated to describing ToFu and its capacities is in preparation, in the meantime please cite this one [1], which briefly describes it and uses it to present physics results. Since this paper may not present enough details for the interested reader, please also include a url pointing to this web-based documentation.

- - - - - -
[1]
    -
  1. Vezinet et al., ‘Non-monotonic growth rates of sawtooth precursors evidenced with a new method on ASDEX Upgrade’, Nuclear Fusion 56, 086001, 2016
  2. -
-
-

Bibtex:

-
@article{0029-5515-56-8-086001,
-  author={D. Vezinet and V. Igochine and M. Weiland and Q. Yu and A. Gude and D. Meshcheriakov and M. Sertoli and the Asdex Upgrade
-Team and the EUROfusion MST1 Team},
-  title={Non-monotonic growth rates of sawtooth precursors evidenced with a new method on ASDEX Upgrade},
-  journal={Nuclear Fusion},
-  volume={56},
-  number={8},
-  pages={086001},
-  url={http://stacks.iop.org/0029-5515/56/i=8/a=086001},
-  year={2016},
-}
-
-
-
-

Indices and tables¶

- -
-
- - -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/build/html/Dependencies.html b/doc/build/html/Dependencies.html deleted file mode 100644 index ba2a30031..000000000 --- a/doc/build/html/Dependencies.html +++ /dev/null @@ -1,151 +0,0 @@ - - - - - - - - Dependencies — tofu v1.1 - - - - - - - - - - - - - - -
-
-
-
- -
-

Dependencies¶

-

ToFu uses the following generic packages:

-
    -
  • python/2.7.3
  • -
  • ipython/1.1.0
  • -
  • dateutil/2.4.0
  • -
  • docutils/0.12.0
  • -
  • distribute/0.6.34
  • -
-

Scientific computing and plotting:

-
    -
  • numpy/1.9.1
  • -
  • scipy/0.15.1
  • -
  • matplotlib/1.2.1
  • -
  • polygon2
  • -
  • datetime
  • -
-

Some part of ToFu are coded using Cython, which requires Cython and a compiler:

-
    -
  • cython/0.19.1
  • -
  • gcc or intel
  • -
-

Testing:

-
    -
  • nose/1.3.4
  • -
-

Documentation:

-
    -
  • pygments/1.5
  • -
-

To be determined:

-
    -
  • pyzmq/13.0.2
  • -
  • tornado/2.4.1
  • -
  • setuptools
  • -
  • mdsplus/5.0_11
  • -
  • pip
  • -
  • git/1.8.4
  • -
-
-

Indices and tables¶

- -
-
- - -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/build/html/Todos.html b/doc/build/html/Todos.html deleted file mode 100644 index 3cbb1cfd5..000000000 --- a/doc/build/html/Todos.html +++ /dev/null @@ -1,129 +0,0 @@ - - - - - - - - To do for contributors — tofu v1.1 - - - - - - - - - - - - - - -
-
-
-
- -
-

To do for contributors¶

-

This to do list includes aspects that require a few hours up to a few months of work. -Whenever possible, a link to a document describing the problem in details is provided.

-
-

Math and geometry:¶

-
    -
  • Write a C routine for (very) fast computation of solid angle in non-trival cases using spherical geometry and write a python / cython wrapper (weeks)
  • -
-
-
-

Coding:¶

-
    -
  • Parallelize (frist CPU then GPU) the key functions of the geometry module (months)
  • -
  • Branch the meshing module to allow compatibility with CAID/Pigasus (months)
  • -
  • Branch the matrix computation module for the same reason (months)
  • -
  • Branch the inversion module for the same reason (months)
  • -
-
-
-

Long term:¶

-
    -
  • Create a parallel library called ToFuG, which provides all ToFu functionalities through a GUI for each ToFu module (year)
  • -
-
-
- - -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/build/html/Tutorial_AUG.html b/doc/build/html/Tutorial_AUG.html deleted file mode 100644 index 615d6ac5a..000000000 --- a/doc/build/html/Tutorial_AUG.html +++ /dev/null @@ -1,154 +0,0 @@ - - - - - - - - AUG-specific tutorial — tofu v1.1 - - - - - - - - - - - - - - -
-
-
-
- -
-

AUG-specific tutorial¶

-
-

How to access the ToFu library¶

-

The plugin for ASDEX Upgrade (AUG) is hosted on the theory (Tok) clusters of the Max-Planck Institute for Plasma Physics (IPP) in Garching. -If you have an account in IPP, you can then connect to one of the tok clusters where the library is hosted, via the command:

-
>>> ssh toki01
-
-
-

Enter your password and then you need to load the module in the terminal

-
>>> module load tofu
-
-
-

You may need to load other modules on which ToFu depends (see the dependencies).

-

You can then start a ipython console and load the AUG plugin for ToFu:

-
>>> import tofu.plugins.AUG as tfAUG
-
-
-
-
-

How to load existing geometry¶

-

You can now load the geometry that was already computed and stored for some diagnostics (only the Soft X-Ray diagnostic at this date). -In general loading the geometry means using a method of the plugin that will load and return a list of tofu.geom.GDetect instances. -On AUG, each tofu.geom.GDetect instance corresponds to a camera head. -Since the geometry (position, aperture size...) of each camera head may change in time (changes are sometimes implemented between experimental campaigns), you can specify a shot number and the plugin will return the latest geometry that was computed before that shot number (only a few have been computed so far, but more will come).

-
>>> LGD = tfAUG.SXR.geom.load(shot=31801)
-
-
-

This command returns a list of tofu.geom.GDetect instances with the latest geometry computed before shot 31801.

-
-
-

How to load SXR data¶

-

the ToFu plugin for AUG also comes with a data loading and formatting routine. -In addition to a shot number and a time window, you can choose whether the data is returned as numpy arrays or as a ToFu-compatible object for data pre-treatment via the Tofu keyword argument.

-
>>> pre = tfAUG.SXR.data.load(shot=30801, Dt=[2.,2.01], Method='SX', Tofu=True)
-
-
-

This command will return the SXR data for shot 30801 in the [2.,2.01] s time window using diagnostic ‘SX.’ (instead of SSX), in the form of a ToFu-compatible object. -See the documentation of the method for more details.

-
-
-

Indices and tables¶

- -
-
- - -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/build/html/Tutorial_Geom_Advanced.html b/doc/build/html/Tutorial_Geom_Advanced.html deleted file mode 100644 index 7e8059fc7..000000000 --- a/doc/build/html/Tutorial_Geom_Advanced.html +++ /dev/null @@ -1,191 +0,0 @@ - - - - - - - - How to create a diagnostic geometry — tofu v1.1 - - - - - - - - - - - - - - -
-
-
-
- -
-

How to create a diagnostic geometry¶

-

It is the geometry module that provides all the necessary tools for creating a new diagnostic. -A diagnostic comprises a set of detectors (ToFu creates one object for each detector and you can then group them into a larger object to represent cameras). -Each detector is basically defined by its active surface, which should be a planar polygon, and by a set of optics through which it ‘sees’ the plasma. -The optics can be a converging spherical lens or an arbitrary number of apertures (of arbitrary shape). -Each detector is also assigned to a vessel, which defines the linear or toroidal volume in which the plasma can exist.

-

The following guides you through the creation of these objects in the famous ‘hello-world’ example:

-

To find out more about what you can do with the geometry module check out the advanced tutorial.

-
-

Creating a vessel¶

-

If a vessel object does not exist yet, you have to create one (otherwise you can just load it an existing one). -A vessel object is basically defined by a 2D simple polygon (i.e.: non self-intersecting),

-
-
Open-source:
-

ToFu is distributed under the very permissive MIT license, thus allowing free use, keeping in mind that neither the author nor any of the laboratories in which he worked can be held responsible for unwanted behaviour or results. -It is instead transparency that is considered for as a warranty of quality on the long-term.

-

ToFu is hosted on github.

-
-
-
-
Versions:
-
A list of the successive versions of ToFu, with a brief description can be found here.
-
-
-
Dependences:
-
ToFu uses the following python packages.
-
-
-
Citing ToFu:
-
If you decide to use ToFu for research and published results please acknowledge this work by citing the project.
-
-
-
-

Contents:¶

-

Description of the library modules:

-
- -
-

Code documentation:

- -
-
Tutorials and how to’s:
-
    -
  • -
    How to build a diagnostic geometry
    -

    Create apertures and detectors to test a new configuration, to apply ToFu to your own problems, to design a prospetive diagnostic...

    -
    -
    -
  • -
  • -
    How to compute integrated signal from 2D or 3D synthetic emissivity
    -

    Use an already-existing diagnostic geometry in a synthetic diagnostic approach to solve the direct problem and compute the line Of Sight and / or Volume of Sight integrated signals from a simulated emissivity field that you provide as an input.

    -
    -
    -
  • -
  • -
    How to compute tomographic inversions
    -

    Use existing diagnostic geometry and signals to solve the inverse problem and compute tomographic inversions using a choice of discretization basis functions and regularisation functionals.

    -
    -
    -
  • -
  • How to contribute (to do’s)

    -
  • -
-
-
-
-
-
-

Indices and tables¶

- -
- - -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/build/html/Tutorial_Geom_HowToCreateGeometry.html b/doc/build/html/Tutorial_Geom_HowToCreateGeometry.html deleted file mode 100644 index 9973b455b..000000000 --- a/doc/build/html/Tutorial_Geom_HowToCreateGeometry.html +++ /dev/null @@ -1,292 +0,0 @@ - - - - - - - - How to create a diagnostic geometry — tofu v1.1 - - - - - - - - - - - - - - -
-
-
-
- -
-

How to create a diagnostic geometry¶

-

It is the geometry module that provides all the necessary tools for creating a new diagnostic. -A diagnostic comprises a set of detectors (ToFu creates one object for each detector and you can then group them into a larger object to represent cameras). -Each detector is basically defined by its active surface, which should be a planar polygon, and by a set of optics through which it ‘sees’ the plasma. -The optics can be a converging spherical lens or an arbitrary number of apertures (of arbitrary shape). -Each detector is also assigned to a vessel, which defines the linear or toroidal volume in which the plasma can exist.

-

The following guides you through the creation of these objects in the famous ‘hello-world’ example:

-

To find out more about what you can do with the geometry module check out the advanced tutorial.

-

As a pre-requisite, let’s load some basic useful libraries in a ipython session, as well as the geometry module of ToFu:

-
>>> import numpy as np
->>> import matplotlib.pyplot as plt
->>> plt.ion()
->>> # tofu-specific
->>> import tofu.geom as tfg
-
-
-
-

Creating, plotting and saving a vessel¶

-

If a vessel object does not exist yet, you have to create one (otherwise you can just load it an existing one). -A vessel object is basically defined by a 2D simple polygon (i.e.: non self-intersecting), that is then expanded linearly or toroidally depending on the desired configuration. -This polygon limits the volume available for the plasma, where the emissivity can be non-zero. It is typically defined by the inner wall in a tokamak.

-

Let’s define the polygon limiting the vessel as a circle with a divertor-like shape at the bottom:

-
>>> # Define the center, radius and lower limit
->>> R0, Z0, rad, ZL = 2., 0., 1., -0.85
->>> # Define the key points in the divertor region below ZL
->>> Div_R, Div_Z = [R0-0.2, R0, R0+0.2], [-1.2, -0.9, -1.2]
->>> # Find the angles corresponding to ZL and span the rest
->>> thet1 = np.arcsin((ZL-Z0)/rad)
->>> thet2 = np.pi - thet1
->>> thet = np.linspace(thet1,thet2,100)
->>> # Assemble the polygon
->>> poly_R = np.append(R0+rad*np.cos(thet), Div_R)
->>> poly_Z = np.append(Z0+rad*np.sin(thet), Div_Z)
->>> # Plot for checking
->>> f, l, a = plt.figure(facecolor='w', figsize=(6,6)), plt.plot(poly_R, poly_Z), plt.axis('equal')
-
-
-
-Polygon used for defining the vaccum vessel where the plasma may live -

Polygon used for defining the vaccum vessel where the plasma may live

-
-

Notice that the polygon does not have to be closed, ToFu will anyway check that and close it automatically if necessary

-

Now let’s feed this 2D polygon to the appropriate ToFu class and specify that it should be a toroidal type (if linear type is chosen, the length should be specified by the ‘DLong’ keyword argument). -ToFu also asks for a name to be associated to this instance, and an experiment (‘Exp’) and a shot number (useful when the same experiment changes geometry in time).

-
>>> # Create a toroidal Ves instance with name 'World', associated to experiment 'Misc' (for 'Miscellaneous') and shot number 0
->>> ves = tfg.Ves('HelloWorld', [poly_R,poly_Z], Type='Tor', Exp='Misc', shot=0)
-
-
-

Now the vessel instance is created. I provides you with several key attributes and methods (see Ves for details). -Among them the Id attribute is itself a class instance that contains all useful information about this vessel instance for identification, saving... In particular, that’s where the name, the default saving path, the Type, the experiment, the shot number... are all stored. -A default name for saving was also created that automatically includes not only the name you gave but also the module from which this instance was created (tofu.geom or tfg), the type of object, the experiment, the shot number... -This recommended default pattern is useful for quick identification of saved object, it is advised not to modify it.

-
>>> print ves.Id.SaveName
-TFG_VesTor_Misc_World_sh0
-
-
-

Now, we can simply visualise the created vessel by using the dedicated method (keyword argument ‘Elt’ specifies the elements of the instance we want to plot, typically one letter corresponds to one element, here we just want the polygon):

-
>>> # Plot the polygon, by default in two projections (cross-section and horizontal) and return the list of axes
->>> Lax = ves.plot(Elt='P')
-
-
-
-The created vessel instance, plotted in cross-section and horizontal projections -

The created vessel instance, plotted in cross-section and horizontal projections

-
-

Since the vessel is an important object (it defines where the plasma can live), all the other ToFu objects rely on it. It is thus important that you save it so that it can be used by other ToFu objects when necessary.

-
>>> ves.save(Path='./')
-
-
-

This method will save the instance as a numpy compressed file (.npz), using the path and file name found in ves.Id.SavePath and ves.Id.SaveName. -While it is highly recommended to stick to the default value for the SaveName, but you can easily modify the saving path if you want by specifying it using keyword argument Path.

-
-
-

Creating, plotting and saving structural elements¶

-

Unlike the vessel, which is important for physics reasons, the structural elements that ToFu allows to create are purely for illustrative purposes. They are entirely passive and have no effect whatsoever on the computation of the volume of sight of the detectors or on the plasma volume and are just made available for illustrations.

-

Like for a vessel, a structural element is mostly defined by a 2D polygon. If a vessel instance is provided, the type of the structural element (toroidal or linear) is automatically the same as the type of the vessel, otherwise the type must be specified. -For plotting, structural elements that enclose the entirety of a vessel are automatically transparent, and gray if they don’t.

-
>>> # Define two polygons, one that does not enclose the vessel and one that does
->>> thet = np.linspace(0.,2.*np.pi,100)
->>> poly1 = [[2.5,3.5,3.5,2.5],[0.,0.,0.5,0.5]]
->>> poly2 = [R0+1.5*np.cos(thet),1.5*np.sin(thet)]
->>> # Create the structural elements with the appropriate ToFu class, specifying the experiment and a shot number for keeping track of changes
->>> s1 = tfg.Struct('S1', poly1, Ves=ves, Exp='Misc', shot=0)
->>> s2 = tfg.Struct('S2', poly2, Ves=ves, Exp='Misc', shot=0)
->>> # Plot them on top of the vessel
->>> Lax = ves.plot(Elt='P')
->>> # Re-use the same list of axes to overlay the plots
->>> Lax = s1.plot(Lax=Lax)
->>> Lax = s2.plot(Lax=Lax)
-
-
-
-The created structural elements, plotted over the structural elements on both projections -

The created structural elements, plotted over the structural elements on both projections

-
-

It is not necessary for ToFu (since structural elements are used by no other objects) but for convenience you can save a structral element using the same save() method as for any other object.

-
-
-

Creating apertures¶

-

An aperture is also mosly defined by a planar polygon, except that the polygon coordinates should be provided in 3D cartesian coordinates (even though the polygon is planar, it mey not live in the same plane as other apertures or as the detector).

-

We can easily define two different polygons for two different apertures

-
>>> # Define the planes in which they will live by a point (O) and a vector (n)
->>> O1, n1 = (3.0,0.00,0.52), (-1.,0.1,-0.9)
->>> O2, n2 = (2.9,0.01,0.48), (-1.,0.0,-1.0)
->>> # Compute local orthogonal basis vectors in the planes
->>> e11, e21 = np.cross(n1,(0.,0.,1.)), np.cross(n2,(0.,0.,1.))
->>> e12, e22 = np.cross(e11,n1), np.cross(e21,n2)
->>> # Normalize
->>> e11, e12 = e11/np.linalg.norm(e11), e12/np.linalg.norm(e12)
->>> e21, e22 = e21/np.linalg.norm(e21), e22/np.linalg.norm(e22)
->>> # Implement the planar polygons 2D coordinates
->>> p1_2D = 0.005*np.array([[-1.,1.,1.,-1],[-1.,-1.,1.,1.]])
->>> p2_2D = 0.01*np.array([[-1.,1.,1.,-1],[-1.,-1.,1.,1.]])
->>> # Compute the 3D coordinates
->>> p1 = [O1[0] + e11[0]*p1_2D[0,:] + e12[0]*p1_2D[1,:], O1[1] + e11[1]*p1_2D[0,:] + e12[1]*p1_2D[1,:], O1[2] + e11[2]*p1_2D[0,:] + e12[2]*p1_2D[1,:]]
->>> p2 = [O2[0] + e21[0]*p2_2D[0,:] + e22[0]*p2_2D[1,:], O2[1] + e21[1]*p2_2D[0,:] + e22[1]*p2_2D[1,:], O2[2] + e21[2]*p2_2D[0,:] + e22[2]*p2_2D[1,:]]
->>> # Create the apertures, specifying also the diagnostic the apertures belong to
->>> a1 = tfg.Apert('A1', p1, Ves=ves, Exp='Misc', shot=0, Diag='misc')
->>> a2 = tfg.Apert('A2', p2, Ves=ves, Exp='Misc', shot=0, Diag='misc')
->>> # Plot them, both the polygon and the vector, with the associated vessel (using EltVes), in 3D
->>> Lax = a1.plot(Elt='PV', EltVes='P')
->>> Lax = a2.plot(Lax=Lax, Elt='PV')
-
-
-
-The created apertures, plotted over the vessel on both projections -

The created apertures, plotted over the vessel on both projections

-
-

ToFu allows you to save the apertures, if you wish, but if you created then only to pass tem on to detectors, you can also skip saving them. Indeed, once the detector associated to these apertures is created, you will save the detector object instead, and ToFu will automatically store all information about the apertures (everything necessary to re-create them when loading the detector object).

-
-
-

Creating, plotting and saving detectors objects¶

-

A detector object is defined in the same way as an aperture, except that it needs to know which optics it is associated to. The optics can be either a converging spherical lens or, as in this case, a list of apertures. -In the folloing we will thus create two detectors (re-using the same planes as for the apertures for simplicity, but they could lie in any plane).

-
>>> # Choose different reference points for the 2 planes
->>> Od1, Od2 = (3.05,0.00,0.54), (3.05,0.00,0.50)
->>> # Implement the planar polygons 2D coordinates
->>> pd1_2D = 0.005*np.array([[-1.,1.,1.,-1],[-1.,-1.,1.,1.]])
->>> pd2_2D = 0.005*np.array([[-1.,1.,1.,-1],[-1.,-1.,1.,1.]])
->>> # Compute the 3D coordinates
->>> pd1 = [Od1[0] + e11[0]*pd1_2D[0,:] + e12[0]*pd1_2D[1,:], Od1[1] + e11[1]*pd1_2D[0,:] + e12[1]*pd1_2D[1,:], Od1[2] + e11[2]*pd1_2D[0,:] + e12[2]*pd1_2D[1,:]]
->>> pd2 = [Od2[0] + e21[0]*pd2_2D[0,:] + e22[0]*pd2_2D[1,:], Od2[1] + e21[1]*pd2_2D[0,:] + e22[1]*pd2_2D[1,:], Od2[2] + e21[2]*pd2_2D[0,:] + e22[2]*pd2_2D[1,:]]
->>> # Create the detectors, specifying also the diagnostic and the Optics
->>> d1 = tfg.Detect('D1', pd1, Optics=[a1,a2], Ves=ves, Exp='Misc', shot=0, Diag='misc')
->>> d2 = tfg.Detect('D2', pd2, Optics=[a2], Ves=ves, Exp='Misc', shot=0, Diag='misc')
-
-
-

The computation of the detectors may take a while (~3 min) because ToFu automatically computes the natural Line Of Sight (LOS) and its etendue, the Volume Of Sight (VOS), a pre-computed 3D grid of the VOS for faster computation of synthetic signal... -Some of these automatic computations can be de-activacted using the proper keyword arguments, or the resolution of the discretization can downgraded for faster computation (see Detect for details).

-

A Detect object is at the core of the added value of ToFu: all relevant quantities are automatically computed, and can be obtained and plotted via attributes and methods.

-
>>> # Plot the detectors, specifying we want not only the polygon but also the perpendicular vector and the viewing cone ('C'), as well as elements of the LOS, Optics and vessel
->>> Lax = d1.plot(Elt='PVC', EltOptics='P', EltLOS='L', EltVes='P')
->>> Lax = d2.plot(Lax=Lax, Elt='PVC', EltOptics='P', EltLOS='L')
-
-
-
-The created detectors, with associated apertures and vessel, on both projections -

The created detectors, with associated apertures and vessel, on both projections

-
-

Using d1.save() would save detector 1 and all necessary info about its associated optics (i.e.:apertures) will also be included in the file so it is not necessary to save the apertures separately (unless you need to for something else). -Usually, tomography diagnostics do not have a few but many different detectors, grouped in cameras (often a group of detectors sharing a common aperture). -ToFu provides an GDetect object that allows you to group a list of detectors and treat them like a single object (each method is automatically applied to all the detectors included in the GDetect object).

-
-
-

Creating, plotting and saving GDetect objects¶

-

Once several Detect objects are created, they can be fed to a GDetect object to be handle as a single object.

-
>>> # Create the group of detectors by feeding a list of detectors
->>> gd = tfg.GDetect('GD', [d1,d2], Exp='Misc', shot=0)
->>> # Plot the group of detectors as a single set
->>> Lax = gd.plot(Elt='PVC', EltOptics='P', EltLOS='L', EltVes='P')
-
-
-

The last command yields the same result as the previous figure.

-

Congratulations ! You completed the basic tutorial for getting started and creating your own geometry, take you time now to explore all the methods and attributes of the classes introduced in tofu.geom.

-
-
-

Indices and tables¶

- -
-
- - -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/build/html/Tutorial_Geom_SynthDiag_Basic.html b/doc/build/html/Tutorial_Geom_SynthDiag_Basic.html deleted file mode 100644 index 7f9f28e32..000000000 --- a/doc/build/html/Tutorial_Geom_SynthDiag_Basic.html +++ /dev/null @@ -1,186 +0,0 @@ - - - - - - - - How to compute integrated signal from synthetic emissivity — tofu v1.1 - - - - - - - - - - - - - - -
-
-
-
- -
-

How to compute integrated signal from synthetic emissivity¶

-

We are assuming here that you have access to an existing geometry (i.e. to Detect or GDetect objects that you or someone else created or that you can load). -It if is not the case you should first create the geometry you need, by following the basic geometry tutorial.

-

We are also assuming that you have a code that can produce as output a simulated isotropic emissivity. Either directly or by spacial interpolation, you should be able to write a python function that computes an emissivity value in any arbitrary point inside the vessel volume.

-

As a prerequisite load the necessary modules:

-
>>> import numpy as np
->>> import matplotlib.pyplot as plt
->>> plt.ion()
->>> # tofu-specific
->>> import tofu.pathfile as tfpf
-
-
-
-

Writing the input function¶

-

In the following, all is done assuming gd is a GDetect object, but the same would apply if it is just a Detect object. -If the GDetect object you want to use is not already existing in your session, you can load it (with its absolute path and file name) using the tofu.pathfile.Open() function or a dedicated plugin function.

-

Instances of GDetect have a method called calc_Sig(), which takes as input ff a python function able to evaluate the emissivity value in any number of points provided in 3D cartesian coordinates.

-
-
This function should obey the following constraints:
-
    -
  • It is a callable with one input argument and optionally keyword arguments
  • -
  • The input argument is a (3,N) numpy.ndarray, where N is the number of points at which one wants to evaluate the emissivity, provided in 3D cartesian coordinates (X,Y,Z)
  • -
-
-
-

Hence, suppose that we simulate a 2D (i.e.: invariant along the 3rd dimension) gaussian emissivity centered on point (2.,0.), we can define ff as

-
>>> def ff(Pts, A=1., DR=1., DZ=1.):
->>>     R = np.hypot(Pts[0,:],Pts[1,:])
->>>     Z = Pts[2,:]
->>>     Emiss = A*np.exp(-(R-2.)**2/DR**2 - (Z-0.)**2/DZ**2)
->>>     return Emiss
-
-
-
-
What will happen when we feed ff to calc_Sig() depends on the choice of method for the integration:
-
    -
  • If we want a volumic integration, the VOS of each detector will be discretized and ff will be called to evaluate the emissivity at each point before perfoming the integration
  • -
  • If a Line Of Sight integration is desired, only the LOS is discretized for integration and the result is multiplied by the etendue
  • -
-
-
-

By default, the method uses a pre-computed discretization of the VOS (because re-computing the solid angle for each point every time is costly), but this feature can be suppressed by setting PreComp=False if you want to use customized integration parameters. -For example, in both cases, the numerical integration can be done by choosing the resolution of the discretization, or by using an iterative algorithm that only stops when the required relative error on the integral value is reached. -In our case:

-
>>> # Compute synthetic signal using a volume approach with resolution-fixed numerical integration method
->>> sigVOS, ldet = gd.calc_Sig(ff, extargs={'A':1.,'DR':1.,'DZ':1.}, Method='Vol', Mode='simps', PreComp=False)
->>> sigLOS, ldet = gd.calc_Sig(ff, extargs={'A':1.}, Method='LOS', Mode='quad', PreComp=False)
->>> print sigVOS, sigLOS
-[[  1.31675917e-06   1.40620027e-06]] [[  1.31408026e-06   1.39941326e-06]]
-
-
-

Notice that when using the ‘quad’ numerical integration method, only one extra argument can be passed on to ff. -Notice the small differences in the volume and LOS approaches, due to the small non-zero second derivative of the emissivity field and to boundary effects (where there is small partial obstruction of the VOS).

-
-
-

If your code gives a tabulated emissivity field¶

-

Then you simply have to include an intermediate function that interpolates your emissivity field to compute it at any point. Like in the following example:

-
>>> def ff(Pts):
->>>     R = np.hypot(Pts[0,:],Pts[1,:])
->>>     Z = Pts[2,:]
->>>     Emiss = ff_interp(R,Z)
->>>     return Emiss
-
-
-

Where ff_interp() is an interpolating function using tabulated output from your code.

-
-
-

Plotting the result¶

-

The plot_Sig() method provides a way of plotting the result, either by feeding it the output signal of calc_Sig() or directly ff (in which case it simply calls plot_Sig() for you). -This feature is only available for GDetect objects since the signal of a single detector is just a single value that does not really require plotting...

-
-
-

Indices and tables¶

- -
-
- - -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/build/html/Tutorial_ITER.html b/doc/build/html/Tutorial_ITER.html deleted file mode 100644 index c8f0f0cb4..000000000 --- a/doc/build/html/Tutorial_ITER.html +++ /dev/null @@ -1,143 +0,0 @@ - - - - - - - - ITER-specific tutorial — tofu v1.1 - - - - - - - - - - - - - - -
-
-
-
- -
-

ITER-specific tutorial¶

-
-

How to access the ToFu library¶

-

The plugin for ITER is hosted on the theory (Tok) clusters of the Max-Planck Institute for Plasma Physics (IPP) in Garching. -If you have an account in IPP, you can then connect to one of the tok clusters where the library is hosted, via the command:

-
>>> ssh toki01
-
-
-

Enter your password and then you need to load the module in the terminal

-
>>> module load tofu
-
-
-

You may need to load other modules on which ToFu depends (see the dependencies).

-

You can then start a ipython console and load the AUG plugin for ToFu:

-
>>> import tofu.plugins.ITER as tfITER
-
-
-
-
-

How to load existing geometry¶

-

You can now load the geometry that was already computed and stored for some diagnostics (only the Soft X-Ray diagnostic at this date). -In general loading the geometry means using a method of the plugin that will load and return a list of tofu.geom.GDetect instances. -On AUG, each tofu.geom.GDetect instance corresponds to a camera head. -Since the geometry (position, aperture size...) of each camera head may change in time (changes are sometimes implemented between experimental campaigns), you can specify a shot number and the plugin will return the latest geometry that was computed before that shot number (only a few have been computed so far, but more will come).

-
>>> LGD = tfAUG.SXR.geom.load(shot=31801)
-
-
-

This command returns a list of tofu.geom.GDetect instances with the latest geometry computed before shot 31801.

-
-
-

Indices and tables¶

- -
-
- - -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/build/html/Versions.html b/doc/build/html/Versions.html deleted file mode 100644 index 59bee1393..000000000 --- a/doc/build/html/Versions.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - - - Versions of ToFu: — tofu v1.1 - - - - - - - - - - - - - - -
-
-
-
- -
-

Versions of ToFu:¶

-

Many versions of ToFu have been developped before reaching a stable and somewhat satisfactory state. Several versions were already used for producing physcis results and tomographic inversions before the open-source release, which requires documentation and a certain degree of user-friendlyness, thus more work.

-

The versioning convention used by ToFu is semantic versioning and the module metadata is implemented according to PEP426.

-

The following only lists the versions advanced enough for release:

-
    -
  • -
    1.1.0 (default)
    -

    This is the first version released in open-source, it only includes the geometry module (for diagnostic designing and synthetic diagnostic) and the pre-treatment module (for data handling)

    -
    -
    -
  • -
-
-

Indices and tables¶

- -
-
- - -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/build/html/_images/Fig_Tutor_BigPicture_General.png b/doc/build/html/_images/Fig_Tutor_BigPicture_General.png deleted file mode 100644 index 1775bce9f..000000000 Binary files a/doc/build/html/_images/Fig_Tutor_BigPicture_General.png and /dev/null differ diff --git a/doc/build/html/_images/Fig_Tutor_BigPicture_SynthDiag.png b/doc/build/html/_images/Fig_Tutor_BigPicture_SynthDiag.png deleted file mode 100644 index dc3d31461..000000000 Binary files a/doc/build/html/_images/Fig_Tutor_BigPicture_SynthDiag.png and /dev/null differ diff --git a/doc/build/html/_images/Fig_Tutor_BigPicture_Tomo.png b/doc/build/html/_images/Fig_Tutor_BigPicture_Tomo.png deleted file mode 100644 index d886f4757..000000000 Binary files a/doc/build/html/_images/Fig_Tutor_BigPicture_Tomo.png and /dev/null differ diff --git a/doc/build/html/_images/Fig_Tutor_Geom_Basic_01.png b/doc/build/html/_images/Fig_Tutor_Geom_Basic_01.png deleted file mode 100644 index 8eb45a703..000000000 Binary files a/doc/build/html/_images/Fig_Tutor_Geom_Basic_01.png and /dev/null differ diff --git a/doc/build/html/_images/Fig_Tutor_Geom_Basic_02.png b/doc/build/html/_images/Fig_Tutor_Geom_Basic_02.png deleted file mode 100644 index 736a37a54..000000000 Binary files a/doc/build/html/_images/Fig_Tutor_Geom_Basic_02.png and /dev/null differ diff --git a/doc/build/html/_images/Fig_Tutor_Geom_Basic_03.png b/doc/build/html/_images/Fig_Tutor_Geom_Basic_03.png deleted file mode 100644 index aec9b6cb4..000000000 Binary files a/doc/build/html/_images/Fig_Tutor_Geom_Basic_03.png and /dev/null differ diff --git a/doc/build/html/_images/Fig_Tutor_Geom_Basic_04.png b/doc/build/html/_images/Fig_Tutor_Geom_Basic_04.png deleted file mode 100644 index 0b664d614..000000000 Binary files a/doc/build/html/_images/Fig_Tutor_Geom_Basic_04.png and /dev/null differ diff --git a/doc/build/html/_images/Fig_Tutor_Geom_Basic_05.png b/doc/build/html/_images/Fig_Tutor_Geom_Basic_05.png deleted file mode 100644 index 43f686bb8..000000000 Binary files a/doc/build/html/_images/Fig_Tutor_Geom_Basic_05.png and /dev/null differ diff --git a/doc/build/html/_modules/index.html b/doc/build/html/_modules/index.html deleted file mode 100644 index a069b46ad..000000000 --- a/doc/build/html/_modules/index.html +++ /dev/null @@ -1,96 +0,0 @@ - - - - - - - - Overview: module code — tofu v1.1 - - - - - - - - - - - - - - -
-
- -
- -
-
- - - - \ No newline at end of file diff --git a/doc/build/html/_modules/tofu/geom.html b/doc/build/html/_modules/tofu/geom.html deleted file mode 100644 index 2784a7947..000000000 --- a/doc/build/html/_modules/tofu/geom.html +++ /dev/null @@ -1,129 +0,0 @@ - - - - - - - - - - tofu.geom — tofu v1.1 - - - - - - - - - - - - - - - -
-
-
-
- -

Source code for tofu.geom

-# -*- coding: utf-8 -*-
-#! /usr/bin/python
-
-
-"""
-Load all core packages and modules which are all machine-independent, diagnostic-independent and code-independent
-
-
-Created on Wed May 18 2016
-
-@version: 0.9
-@author: didiervezinet
-@author_email: didier.vezinet@gmail.com
-"""
-
-
-from ._core import *
-from . import General_Geom_cy as _GG
-
-del _core, General_Geom_cy
-
-#__name__ = ""
-__version__ = "1.1"
-__author__ = "Didier Vezinet"
-__author_email__="didier.vezinet@gmail.com"
-__date__ = "$Tuesday 07 June 2016$"
-#__copyright__ = ""
-#__license__ = ""
-#__url__ = ""
-#__path__ =
-
-
-__all__ = ['Ves','LOS','GLOS','Lens','Apert','Detect','GDetect',
-           'Calc_Resolution','Plot_Resolution']
-
- -
-
-
-
-
- - -
-
-
-
- - - - \ No newline at end of file diff --git a/doc/build/html/_modules/tofu/geom/_core.html b/doc/build/html/_modules/tofu/geom/_core.html deleted file mode 100644 index f31deeeaf..000000000 --- a/doc/build/html/_modules/tofu/geom/_core.html +++ /dev/null @@ -1,4518 +0,0 @@ - - - - - - - - tofu.geom._core — tofu v1.1 - - - - - - - - - - - - - - - -
-
-
-
- -

Source code for tofu.geom._core

-"""
-This module is the geometrical part of the ToFu general package
-It includes all functions and object classes necessary for tomography on Tokamaks
-"""
-
-import warnings
-import numpy as np
-import datetime as dtm
-
-# ToFu-specific
-import tofu.defaults as tfd
-import tofu.pathfile as tfpf
-from . import General_Geom_cy as _tfg_gg
-from . import _compute as _tfg_c
-from . import _plot as _tfg_p
-
-__author__ =    "D. Vezinet"
-__all__ = ['Ves','Struct','LOS','GLOS','Lens','Apert','Detect','GDetect']
-
-
-
-
-"""
-###############################################################################
-###############################################################################
-                        Ves class and functions
-###############################################################################
-"""
-
-
[docs]class Ves(object): - """ A class defining a Linear or Toroidal vaccum vessel (i.e. a 2D polygon representing a cross-section and assumed to be linearly or toroidally invariant) - - A Ves object is mostly defined by a close 2D polygon, which can be understood as a poloidal cross-section in (R,Z) cylindrical coordinates if Type='Tor' (toroidal shape) or as a straight cross-section through a cylinder in (Y,Z) cartesian coordinates if Type='Lin' (linear shape). - Attributes such as the surface, the angular volume (if Type='Tor') or the center of mass are automatically computed. - The instance is identified thanks to an attribute Id (which is itself a tofu.ID class object) which contains informations on the specific instance (name, Type...). - - Parameters - ---------- - Id : str / tfpf.ID - A name string or a pre-built tfpf.ID class to be used to identify this particular instance, if a string is provided, it is fed to tfpf.ID() - Poly : np.ndarray - An array (2,N) or (N,2) defining the contour of the vacuum vessel in a cross-section, if not closed, will be closed automatically - Type : str - Flag indicating whether the vessel will be a torus ('Tor') or a linear device ('Lin') - DLong : list / np.ndarray - Array or list of len=2 indicating the limits of the linear device volume on the x axis - Sino_RefPt : None / np.ndarray - Array specifying a reference point for computing the sinogram (i.e. impact parameter), if None automatically set to the (surfacic) center of mass of the cross-section - Sino_NP : int - Number of points in [0,2*pi] to be used to plot the vessel sinogram envelop - Clock : bool - Flag indicating whether the input polygon should be made clockwise (True) or counter-clockwise (False) - arrayorder: str - Flag indicating whether the attributes of type=np.ndarray (e.g.: Poly) should be made C-contiguous ('C') or Fortran-contiguous ('F') - Exp : None / str - Flag indicating which experiment the object corresponds to, allowed values are in [None,'AUG','MISTRAL','JET','ITER','TCV','TS','Misc'] - shot : None / int - Shot number from which this Ves is usable (in case of change of geometry) - SavePath : None / str - If provided, forces the default saving path of the object to the provided value - dtime : None / dtm.datetime - A time reference to be used to identify this particular instance (used for debugging mostly) - dtimeIn : bool - Flag indicating whether dtime should be included in the SaveName (used for debugging mostly) - - Returns - ------- - Ves : Ves object - The created Ves object, with all necessary computed attributes and methods - - """ - - def __init__(self, Id, Poly, Type='Tor', DLong=None, Sino_RefPt=None, Sino_NP=tfd.TorNP, Clock=False, arrayorder='C', Exp=None, shot=None, dtime=None, dtimeIn=False, SavePath=None): - - self._Done = False - tfpf._check_NotNone({'Clock':Clock,'arrayorder':arrayorder}) - self._check_inputs(Clock=Clock, arrayorder=arrayorder) - self._arrayorder = arrayorder - self._Clock = Clock - self._set_Id(Id, Type=Type, Exp=Exp, shot=shot, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - self._set_Poly(Poly, DLong=DLong, Clock=Clock, Sino_RefPt=Sino_RefPt, Sino_NP=Sino_NP) - self._set_arrayorder(arrayorder) - self._Done = True - - @property - def Id(self): - """Return the tfpf.ID object of the vessel""" - return self._Id - @property - def Type(self): - """Return the type of vessel""" - return self.Id.Type - @property - def Poly(self): - """Return the polygon defining the vessel cross-section""" - return self._Poly - @property - def Vect(self): - """Return the polygon elementary vectors""" - return self._Vect - @property - def Vin(self): - """Return the normalized vectors pointing inwards for each segment of the polygon""" - return self._Vin - @property - def DLong(self): - return self._DLong - @property - def Surf(self): - """Return the area of the polygon defining the vessel cross-section""" - return self._Surf - @property - def VolLin(self): - """Return the angular volume of the polygon defining the vessel cross-section of Tor type""" - return self._VolLin - @property - def BaryS(self): - """Return the (surfacic) center of mass of the polygon defining the vessel cross-section""" - return self._BaryS - @property - def BaryV(self): - """Return the (volumic) center of mass of the polygon defining the vessel cross-section""" - return self._BaryV - @property - def Sino_RefPt(self): - """Return the 2D coordinates of the points used as a reference for computing the Ves polygon in projection space (where sinograms are plotted)""" - return self._Sino_RefPt - @property - def Sino_NP(self): - """Return the number of points used used for plotting the Ves polygon in projection space""" - return self._Sino_NP - @property - def arrayorder(self): - """Return the flag indicating which order is used for multi-dimensional array attributes""" - return self._arrayorder - - - def _check_inputs(self, Id=None, Poly=None, Type=None, DLong=None, Sino_RefPt=None, Sino_NP=None, Clock=None, arrayorder=None, Exp=None, shot=None, dtime=None, dtimeIn=None, SavePath=None): - _Ves_check_inputs(Id=Id, Poly=Poly, Type=Type, DLong=DLong, Sino_RefPt=Sino_RefPt, Sino_NP=Sino_NP, Clock=Clock, arrayorder=arrayorder, Exp=Exp, shot=shot, dtime=dtime, dtimeIn=dtimeIn, SavePath=SavePath) - - def _set_Id(self, Val, Type=None, Exp=None, shot=None, dtime=None, dtimeIn=False, SavePath=None): - if self._Done: - Out = tfpf._get_FromItself(self.Id,{'Type':Type, 'Exp':Exp, 'shot':shot, 'dtime':dtime, '_dtimeIn':dtimeIn, 'SavePath':SavePath}) - Type, Exp, shot, dtime, dtimeIn, SavePath = Out['Type'], Out['Exp'], Out['shot'], Out['dtime'], Out['dtimeIn'], Out['SavePath'] - tfpf._check_NotNone({'Id':Val}) - self._check_inputs(Id=Val) - if type(Val) is str: - tfpf._check_NotNone({'Type':Type, 'Exp':Exp, 'shot':shot,'dtimeIn':dtimeIn}) - self._check_inputs(Type=Type, Exp=Exp, shot=shot, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - Val = tfpf.ID('Ves', Val, Type=Type, Exp=Exp, shot=shot, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - self._Id = Val - - def _set_arrayorder(self, arrayorder): - tfpf._set_arrayorder(self, arrayorder) - - def _set_Poly(self, Poly, DLong=None, Clock=False, Sino_RefPt=None, Sino_NP=tfd.TorNP): - if self._Done: - Out = tfpf._get_FromItself(self, {'DLong':DLong, '_Clock':Clock}) - DLong, Clock = Out['DLong'], Out['Clock'] - tfpf._check_NotNone({'Poly':Poly, 'Clock':Clock}) - self._Poly, self._NP, self._P1Max, self._P1Min, self._P2Max, self._P2Min, self._BaryP, self._BaryL, self._Surf, self._BaryS, self._DLong, self._VolLin, self._BaryV, self._Vect, self._Vin = _tfg_c._Ves_set_Poly(Poly, self.arrayorder, self.Type, DLong=DLong, Clock=Clock) - self._set_Sino(Sino_RefPt, NP=Sino_NP) - - def _set_Sino(self, RefPt=None, NP=tfd.TorNP): - if self._Done: - Out = tfpf._get_FromItself(self, {'Sino_RefPt':RefPt, 'Sino_NP':NP}) - RefPt, NP = Out['Sino_RefPt'], Out['Sino_NP'] - tfpf._check_NotNone({'Sino_NP':NP}) - if RefPt is None: - RefPt = self.BaryS - RefPt = np.asarray(RefPt).flatten() - self._Sino_EnvTheta, self._Sino_EnvMinMax = _tfg_gg.Calc_ImpactEnv(RefPt, self.Poly, NP=NP, Test=False) - self._Sino_RefPt, self._Sino_NP = RefPt, NP - -
[docs] def isInside(self, Pts, In='(X,Y,Z)'): - """ Return an array of booleans indicating whether each point lies inside the Ves volume - - Tests for each point whether it lies inside the Ves object. - The points coordinates can be provided in 2D or 3D, just specify which coordinate system is provided using the 'In' parameter. - An array of boolean flags is returned. - - Parameters - ---------- - Pts : np.ndarray - (2,N) or (3,N) array with the coordinates of the points to be tested - In : str - Flag indicating the coordinate system in which the points are provided, in ['(X,Y,Z)','(R,Z)',''] - - Returns - ------- - ind : np.ndarray - Array of booleans of shape (N,), True if a point is inside the Ves volume - - """ - return _tfg_c._Ves_isInside(self.Poly, self.Type, self.DLong, Pts, In=In)
- -
[docs] def get_InsideConvexPoly(self, RelOff=tfd.TorRelOff, ZLim='Def', Spline=True, Splprms=tfd.TorSplprms, NP=tfd.TorInsideNP, Plot=False, Test=True): - """ Return a polygon that is a smaller and smoothed approximation of Ves.Poly, useful for excluding the divertor region in a Tokamak - - For some uses, it can be practical to approximate the polygon defining the Ves object (which can be non-convex, like with a divertor), by a simpler, sligthly smaller and convex polygon. - This method provides a fast solution for computing such a proxy. - - Parameters - ---------- - RelOff : float - Fraction by which an homothetic polygon should be reduced (1.-RelOff)*(Poly-BaryS) - ZLim : None / str / tuple - Flag indicating what limits shall be put to the height of the polygon (used for excluding divertor) - Spline : bool - Flag indiating whether the reduced and truncated polygon shall be smoothed by 2D b-spline curves - Splprms : list - List of 3 parameters to be used for the smoothing [weights,smoothness,b-spline order], fed to scipy.interpolate.splprep() - NP : int - Number of points to be used to define the smoothed polygon - Plot : bool - Flag indicating whether the result shall be plotted for visual inspection - Test : bool - Flag indicating whether the inputs should be tested for conformity - - Returns - ------- - Poly : np.ndarray - (2,N) polygon resulting from homothetic transform, truncating and optional smoothing - - """ - return _tfg_c._Ves_get_InsideConvexPoly(self.Poly, self._P2Min, self._P2Max, self.BaryS, RelOff=RelOff, ZLim=ZLim, Spline=Spline, Splprms=Splprms, NP=NP, Plot=Plot, Test=Test)
- -
[docs] def get_MeshCrossSection(self, CrossMesh=[0.01,0.01], CrossMeshMode='abs', Test=True): - """ Return a (2,N) array of 2D points coordinates meshing the Ves cross-section using the spacing specified by CrossMesh for each direction (taken as absolute distance or relative to the total size) - - Method used for fast automatic meshing of the cross-section using a rectangular mesh uniform in each direction. - Returns the flattened points coordinates array, as well as the two increasing vectors and number of points. - - Parameters - ---------- - CrossMesh : iterable - Iterable of len()==2 specifying the distance to be used between points in each direction (R or Y and Z), in absolute value or relative to the total size of the Ves in each direction - CrossMeshMode : str - Flag specifying whether the distances provided in CrossMesh are absolute ('abs') or relative ('rel') - Test : bool - Flag indicating whether the inputs should be tested for conformity - - Returns - ------- - Pts : np.ndarray - Array of shape (2,N), comtaining the 2D coordinates of the N points consituting the mesh, only points lying inside the cross-section are returned - X1 : np.ndarray - Flat array of the unique first coordinates of the mesh points (R or Y) - X2 : np.ndarray - Flat array of the unique second coordinates of the mesh points (Z) - NumX1 : int - Number of unique values in X1 (=X1.size) - NumX2 : int - Number of unique values in X2 (=X2.size) - - """ - Pts, X1, X2, NumX1, NumX2 = _tfg_c._Ves_get_MeshCrossSection(self._P1Min, self._P1Max, self._P2Min, self._P2Max, self.Poly, self.Type, DLong=self.DLong, CrossMesh=CrossMesh, CrossMeshMode=CrossMeshMode, Test=Test) - return Pts, X1, X2, NumX1, NumX2
- - - -
[docs] def plot(self, Lax=None, Proj='All', Elt='PIBsBvV', Pdict=None, Idict=tfd.TorId, Bsdict=tfd.TorBsd, Bvdict=tfd.TorBvd, Vdict=tfd.TorVind, - IdictHor=tfd.TorITord, BsdictHor=tfd.TorBsTord, BvdictHor=tfd.TorBvTord, Lim=tfd.Tor3DThetalim, Nstep=tfd.TorNTheta, LegDict=tfd.TorLegd, draw=True, a4=False, Test=True): - """ Plot the polygon defining the vessel, with a cross-section view, a longitudinal view or both, and optionally its reference point for plotting it in projection space - - Generic method for plotting the Ves object, the projections to be plotted, the elements to plot, and the dictionaries or properties to be used for plotting each elements can all be specified using keyword arguments. - If an ax is not provided a default one is created. - - Parameters - ---------- - Lax : list or plt.Axes - The axes to be used for plotting (provide a list of 2 axes if Proj='All'), if None a new figure with axes is created - Proj : str - Flag specifying the kind of projection used for the plot ('Cross' for a cross-section, 'Hor' for a horizontal plane, or 'All' for the two plots) - Elt : str - Flag specifying which elements to plot, each capital letter corresponds to an element - * 'P': polygon - * 'I': point used as a reference for computing impact parameters - * 'Bs': (surfacic) center of mass - * 'Bv': (volumic) center of mass for Tor type - * 'V': vector pointing inward perpendicular to each segment defining the polygon - Pdict : dict or None - Dictionary of properties used for plotting the polygon, fed to plt.Axes.plot() or plt.plot_surface() if Proj='3d', set to ToFu_Defauts.py if None - Idict : dict - Dictionary of properties used for plotting point 'I' in Cross-section projection, fed to plt.Axes.plot() - IdictHor : dict - Dictionary of properties used for plotting point 'I' in horizontal projection, fed to plt.Axes.plot() - Bsdict : dict - Dictionary of properties used for plotting point 'Bs' in Cross-section projection, fed to plt.Axes.plot() - BsdictHor : dict - Dictionry of properties used for plotting point 'Bs' in horizontal projection, fed to plt.Axes.plot() - Bvdict : dict - Dictionary of properties used for plotting point 'Bv' in Cross-section projection, fed to plt.Axes.plot() - BvdictHor : dict - Dictionary of properties used for plotting point 'Bv' in horizontal projection, fed to plt.Axes.plot() - Vdict : dict - Dictionary of properties used for plotting point 'V' in cross-section projection, fed to plt.Axes.quiver() - LegDict : dict or None - Dictionary of properties used for plotting the legend, fed to plt.legend(), the legend is not plotted if None - Lim : list or tuple - Array of a lower and upper limit of angle (rad.) or length for plotting the '3d' Proj - Nstep : int - Number of points for sampling in ignorable coordinate (toroidal angle or length) - draw : bool - Flag indicating whether the fig.canvas.draw() shall be called automatically - a4 : bool - Flag indicating whether the figure should be plotted in a4 dimensions for printing - Test : bool - Flag indicating whether the inputs should be tested for conformity - - Returns - ------- - La list or plt.Axes Handles of the axes used for plotting (list if several axes where used) - - """ - return _tfg_p.Ves_plot(self, Lax=Lax, Proj=Proj, Elt=Elt, Pdict=Pdict, Idict=Idict, Bsdict=Bsdict, Bvdict=Bvdict, Vdict=Vdict, - IdictHor=IdictHor, BsdictHor=BsdictHor, BvdictHor=BvdictHor, Lim=Lim, Nstep=Nstep, LegDict=LegDict, draw=draw, a4=a4, Test=Test)
- - """ - def plot_3D_mlab(self,f=None,Tdict=Dict_3D_mlab_Tor_Def,LegDict=LegDict_Def,Test=True): - f = Plot_3D_mlab_Tor(self,fig=f,Tdict=Tdict,LegDict=LegDict,Test=Test) - return f - """ - -
[docs] def plot_Sinogram(self, Proj='Cross', ax=None, Ang=tfd.LOSImpAng, AngUnit=tfd.LOSImpAngUnit, Sketch=True, Pdict=None, LegDict=tfd.TorLegd, draw=True, a4=False, Test=True): - """ Plot the sinogram of the vessel polygon, by computing its envelopp in a cross-section, can also plot a 3D version of it - - The envelop of the polygon is computed using self.Sino_RefPt as a reference point in projection space, and plotted using the provided dictionary of properties. - Optionaly a smal sketch can be included illustrating how the angle and the impact parameters are defined (if the axes is not provided). - - Parameters - ---------- - Proj : str - Flag indicating whether to plot a classic sinogram ('Cross') from the vessel cross-section (assuming 2D), or an extended 3D version '3d' of it with additional angle - ax : None or plt.Axes - The axes on which the plot should be done, if None a new figure and axes is created - Ang : str - Flag indicating which angle to use for the impact parameter, the angle of the line itself (xi) or of its impact parameter (theta) - AngUnit : str - Flag for the angle units to be displayed, 'rad' for radians or 'deg' for degrees - Sketch : bool - Flag indicating whether a small skecth showing the definitions of angles 'theta' and 'xi' should be included or not - Pdict : dict - Dictionary of properties used for plotting the polygon envelopp, fed to plt.plot() if Proj='Cross' and to plt.plot_surface() if Proj='3d' - LegDict : None or dict - Dictionary of properties used for plotting the legend, fed to plt.legend(), the legend is not plotted if None - draw : bool - Flag indicating whether the fig.canvas.draw() shall be called automatically - a4 : bool - Flag indicating whether the figure should be plotted in a4 dimensions for printing - Test : bool - Flag indicating whether the inputs shall be tested for conformity - - Returns - ------- - ax : plt.Axes - The axes used to plot - - """ - if Test: - assert not self.Sino_RefPt is None, 'The impact parameters must be computed first !' - assert Proj in ['Cross','3d'], "Arg Proj must be in ['Cross','3d'] !" - if Proj=='Cross': - Pdict = tfd.TorPFilld if Pdict is None else Pdict - ax = _tfg_p.Plot_Impact_PolProjPoly(self, ax=ax, Ang=Ang, AngUnit=AngUnit, Sketch=Sketch, Leg=self.Id.NameLTX, Pdict=Pdict, LegDict=LegDict, draw=False, a4=a4, Test=Test) - else: - Pdict = tfd.TorP3DFilld if Pdict is None else Pdict - ax = _tfg_p.Plot_Impact_3DPoly(self, ax=ax, Ang=Ang, AngUnit=AngUnit, Pdict=Pdict, LegDict=LegDict, draw=False, a4=a4, Test=Test) - if draw: - ax.figure.canvas.draw() - return ax
- -
[docs] def save(self, SaveName=None, Path=None, Mode='npz', compressed=False): - """ Save the object in folder Name, under file name SaveName, using specified mode - - Most tofu objects can be saved automatically as numpy arrays (.npz, recommended) at the default location (recommended) by simply calling self.save() - - Parameters - ---------- - SaveName : None / str - The name to be used for the saved file, if None (recommended) uses self.Id.SaveName - Path : None / str - Path specifying where to save the file, if None (recommended) uses self.Id.SavePath - Mode : str - Flag specifying whether to save the object as a numpy array file ('.npz', recommended) or an object using cPickle (not recommended, heavier and may cause retro-compatibility issues) - compressed : bool - Flag, used when Mode='npz', indicating whether to use np.savez or np.savez_compressed (slower saving and loading but smaller files) - - """ - tfpf.Save_Generic(self, SaveName=SaveName, Path=Path, Mode=Mode, compressed=compressed)
- - - - -def _Ves_check_inputs(Id=None, Poly=None, Type=None, DLong=None, Sino_RefPt=None, Sino_NP=None, Clock=None, arrayorder=None, Exp=None, shot=None, dtime=None, dtimeIn=None, SavePath=None): - if not Id is None: - assert type(Id) in [str,tfpf.ID], "Arg Id must be a str or a tfpf.ID object !" - if not Poly is None: - assert hasattr(Poly,'__iter__') and np.asarray(Poly).ndim==2 and 2 in np.asarray(Poly).shape, "Arg Poly must be a dict or an iterable with 2D coordinates of cross section poly !" - bools = [Clock,dtimeIn] - if any([not aa is None for aa in bools]): - assert all([aa is None or type(aa) is bool for aa in bools]), " Args [Clock,dtimeIn] must all be bool !" - if not arrayorder is None: - assert arrayorder in ['C','F'], "Arg arrayorder must be in ['C','F'] !" - if not Type is None: - assert Type in ['Tor','Lin'], "Arg Type must be in ['Tor','Lin'] !" - if not Exp is None: - assert Exp in tfd.AllowedExp, "Ar Exp must be in "+str(tfd.AllowedExp)+" !" - strs = [SavePath] - if any([not aa is None for aa in strs]): - assert all([aa is None or type(aa) is str for aa in strs]), "Args [Type,Exp,SavePath] must all be str !" - Iter2 = [DLong,Sino_RefPt] - if any([not aa is None for aa in Iter2]): - assert all([aa is None or (hasattr(aa,'__iter__') and np.asarray(aa).ndim==1 and np.asarray(aa).size==2) for aa in Iter2]), "Args [DLong,Sino_RefPt] must be an iterable with len()=2 !" - Ints = [Sino_NP,shot] - if any([not aa is None for aa in Ints]): - assert all([aa is None or type(aa) is int for aa in Ints]), "Args [Sino_NP,shot] must be int !" - if not dtime is None: - assert type(dtime) is dtm.datetime, "Arg dtime must be a dtm.datetime !" - - - - - - - - - - -""" -############################################################################### -############################################################################### - Sruct class and functions -############################################################################### -""" - -# A class defining a Linear or Toroidal structural element (i.e. a 2D polygon representing a cross-section and assumed to be linearly or toroidally invariant), has no physical role, just used for illustrative purposes in plots - - -
[docs]class Struct(object): - """ A class defining a Linear or Toroidal structural element (i.e. a 2D polygon representing a cross-section and assumed to be linearly or toroidally invariant), like a :class:`~tofu.geom.Ves` but with less properties. - - A Struct object is mostly defined by a close 2D polygon, which can be understood as a poloidal cross-section in (R,Z) cylindrical coordinates if Type='Tor' (toroidal shape) or as a straight cross-section through a cylinder in (Y,Z) cartesian coordinates if Type='Lin' (linear shape). - Attributes such as the surface, the angular volume (if Type='Tor') or the center of mass are automatically computed. - The instance is identified thanks to an attribute Id (which is itself a tofu.ID class object) which contains informations on the specific instance (name, Type...). - - Parameters - ---------- - Id : str / tfpf.ID - A name string or a pre-built tfpf.ID class to be used to identify this particular instance, if a string is provided, it is fed to tfpf.ID() - Poly : np.ndarray - An array (2,N) or (N,2) defining the contour of the vacuum vessel in a cross-section, if not closed, will be closed automatically - Type : str - Flag indicating whether the vessel will be a torus ('Tor') or a linear device ('Lin') - DLong : list / np.ndarray - Array or list of len=2 indicating the limits of the linear device volume on the x axis - Ves : None or :class:`~tofu.geom.Ves` - An optional associated vessel - Clock : bool - Flag indicating whether the input polygon should be made clockwise (True) or counter-clockwise (False) - arrayorder: str - Flag indicating whether the attributes of type=np.ndarray (e.g.: Poly) should be made C-contiguous ('C') or Fortran-contiguous ('F') - Exp : None / str - Flag indicating which experiment the object corresponds to, allowed values are in [None,'AUG','MISTRAL','JET','ITER','TCV','TS','Misc'] - shot : None / int - Shot number from which this Ves is usable (in case of change of geometry) - SavePath : None / str - If provided, forces the default saving path of the object to the provided value - dtime : None / dtm.datetime - A time reference to be used to identify this particular instance (used for debugging mostly) - dtimeIn : bool - Flag indicating whether dtime should be included in the SaveName (used for debugging mostly) - - Returns - ------- - struct : Struct object - The created Struct object, with all necessary computed attributes and methods - - """ - - def __init__(self, Id, Poly, Type='Tor', DLong=None, Ves=None, Clock=False, arrayorder='C', Exp=None, shot=None, dtime=None, dtimeIn=False, SavePath=None): - - self._Done = False - tfpf._check_NotNone({'Id':Id, 'Poly':Poly, 'Type':Type, 'Clock':Clock,'arrayorder':arrayorder}) - self._check_inputs(Clock=Clock, arrayorder=arrayorder) - self._arrayorder = arrayorder - self._Clock = Clock - Type = Type if Ves is None else Ves.Id.Type - self._set_Id(Id, Type=Type, Exp=Exp, shot=shot, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - self._set_Ves(Ves) - self._set_Poly(Poly, DLong=DLong, Clock=Clock) - self._set_arrayorder(arrayorder) - self._Done = True - - @property - def Id(self): - """Return the tfpf.ID object of the structure """ - return self._Id - @property - def Type(self): - """Return the type of structure """ - return self.Id.Type - @property - def Poly(self): - """Return the polygon defining the vessel cross-section""" - return self._Poly - @property - def Vect(self): - """Return the polygon elementary vectors""" - return self._Vect - @property - def Vin(self): - """Return the normalized vectors pointing inwards for each segment of the polygon""" - return self._Vin - @property - def DLong(self): - """ Return the length spanned by the object in the ignorable coordinate """ - return self._DLong - @property - def Surf(self): - """Return the area of the polygon defining the vessel cross-section""" - return self._Surf - @property - def VolLin(self): - """Return the angular volume of the polygon defining the vessel cross-section of Tor type""" - return self._VolLin - @property - def BaryS(self): - """Return the (surfacic) center of mass of the polygon defining the vessel cross-section""" - return self._BaryS - @property - def BaryV(self): - """Return the (volumic) center of mass of the polygon defining the vessel cross-section""" - return self._BaryV - @property - def Ves(self): - """ Return the associated :class:`~tofu.goem.Ves` object, if any """ - return self._Ves - @property - def arrayorder(self): - """Return the flag indicating which order is used for multi-dimensional array attributes""" - return self._arrayorder - - - def _check_inputs(self, Id=None, Poly=None, Type=None, DLong=None, Ves=None, Clock=None, arrayorder=None, Exp=None, shot=None, dtime=None, dtimeIn=None, SavePath=None): - _Struct_check_inputs(Id=Id, Poly=Poly, Type=Type, DLong=DLong, Vess=Ves, Clock=Clock, arrayorder=arrayorder, Exp=Exp, shot=shot, dtime=dtime, dtimeIn=dtimeIn, SavePath=SavePath) - - def _set_Id(self, Val, Type=None, Exp=None, shot=None, dtime=None, dtimeIn=False, SavePath=None): - if self._Done: - Out = tfpf._get_FromItself(self.Id,{'Type':Type, 'Exp':Exp, 'shot':shot, 'dtime':dtime, '_dtimeIn':dtimeIn, 'SavePath':SavePath}) - Type, Exp, shot, dtime, dtimeIn, SavePath = Out['Type'], Out['Exp'], Out['shot'], Out['dtime'], Out['dtimeIn'], Out['SavePath'] - tfpf._check_NotNone({'Id':Val}) - self._check_inputs(Id=Val) - if type(Val) is str: - tfpf._check_NotNone({'Type':Type, 'Exp':Exp, 'shot':shot, 'dtimeIn':dtimeIn}) - self._check_inputs(Type=Type, Exp=Exp, shot=shot, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - Val = tfpf.ID('Struct', Val, Type=Type, Exp=Exp, shot=shot, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - self._Id = Val - - def _set_arrayorder(self, arrayorder): - tfpf._set_arrayorder(self, arrayorder) - - def _set_Ves(self, Ves): - self._check_inputs(Ves=Ves, Type=self.Id.Type) - if not Ves is None: - self.Id.set_LObj([Ves.Id]) - self._Ves = Ves - - def _set_Poly(self, Poly, DLong=None, Clock=False, Sino_RefPt=None, Sino_NP=tfd.TorNP): - if self._Done: - Out = tfpf._get_FromItself(self, {'DLong':DLong, '_Clock':Clock}) - DLong, Clock = Out['DLong'], Out['Clock'] - tfpf._check_NotNone({'Poly':Poly, 'Clock':Clock}) - if self.Ves is not None and self.Ves.Type=='Lin' and DLong is None: - DLong = self.Ves.DLong - Out = _tfg_c._Ves_set_Poly(Poly, self.arrayorder, self.Type, DLong=DLong, Clock=Clock) - self._Poly, self._NP, self._P1Max, self._P1Min, self._P2Max, self._P2Min, self._BaryP, self._BaryL, self._Surf, self._BaryS, self._DLong, self._VolLin, self._BaryV, self._Vect, self._Vin = Out - -
[docs] def isInside(self, Pts, In='(X,Y,Z)'): - """ Return an array of booleans indicating whether each point lies inside the Ves volume - - Tests for each point whether it lies inside the Ves object. - The points coordinates can be provided in 2D or 3D, just specify which coordinate system is provided using the 'In' parameter. - An array of boolean flags is returned. - - Parameters - ---------- - Pts : np.ndarray - (2,N) or (3,N) array with the coordinates of the points to be tested - In : str - Flag indicating the coordinate system in which the points are provided, in ['(X,Y,Z)','(R,Z)',''] - - Returns - ------- - ind : np.ndarray - Array of booleans of shape (N,), True if a point is inside the Ves volume - - """ - return _tfg_c._Ves_isInside(self.Poly, self.Type, self.DLong, Pts, In=In)
- -
[docs] def plot(self, Lax=None, Proj='All', Elt='P', Pdict=None, Bsdict=tfd.TorBsd, Bvdict=tfd.TorBvd, Vdict=tfd.TorVind, - BsdictHor=tfd.TorBsTord, BvdictHor=tfd.TorBvTord, Lim=tfd.Tor3DThetalim, Nstep=tfd.TorNTheta, LegDict=tfd.TorLegd, draw=True, a4=False, Test=True): - """ Plot the polygon defining the vessel, with a cross-section view, a longitudinal view or both, and optionally its reference point for plotting it in projection space - - Generic method for plotting the Ves object, the projections to be plotted, the elements to plot, and the dictionaries or properties to be used for plotting each elements can all be specified using keyword arguments. - If an ax is not provided a default one is created. - - Parameters - ---------- - Lax : list or plt.Axes - The axes to be used for plotting (provide a list of 2 axes if Proj='All'), if None a new figure with axes is created - Proj : str - Flag specifying the kind of projection used for the plot ('Cross' for a cross-section, 'Hor' for a horizontal plane, or 'All' for the two plots) - Elt : str - Flag specifying which elements to plot, each capital letter corresponds to an element - * 'P': polygon - * 'Bs': (surfacic) center of mass - * 'Bv': (volumic) center of mass for Tor type - * 'V': vector pointing inward perpendicular to each segment defining the polygon - Pdict : dict or None - Dictionary of properties used for plotting the polygon, fed to plt.Axes.plot() or plt.plot_surface() if Proj='3d', set to ToFu_Defauts.py if None - Bsdict : dict - Dictionary of properties used for plotting point 'Bs' in Cross-section projection, fed to plt.Axes.plot() - BsdictHor : dict - Dictionry of properties used for plotting point 'Bs' in horizontal projection, fed to plt.Axes.plot() - Bvdict : dict - Dictionary of properties used for plotting point 'Bv' in Cross-section projection, fed to plt.Axes.plot() - BvdictHor : dict - Dictionary of properties used for plotting point 'Bv' in horizontal projection, fed to plt.Axes.plot() - Vdict : dict - Dictionary of properties used for plotting point 'V' in cross-section projection, fed to plt.Axes.quiver() - LegDict : dict or None - Dictionary of properties used for plotting the legend, fed to plt.legend(), the legend is not plotted if None - Lim : list or tuple - Array of a lower and upper limit of angle (rad.) or length for plotting the '3d' Proj - Nstep : int - Number of points for sampling in ignorable coordinate (toroidal angle or length) - draw : bool - Flag indicating whether the fig.canvas.draw() shall be called automatically - a4 : bool - Flag indicating whether the figure should be plotted in a4 dimensions for printing - Test : bool - Flag indicating whether the inputs should be tested for conformity - - Returns - ------- - La list or plt.Axes Handles of the axes used for plotting (list if several axes where used) - - """ - return _tfg_p.Struct_plot(self, Lax=Lax, Proj=Proj, Elt=Elt, Pdict=Pdict, Bsdict=Bsdict, Bvdict=Bvdict, Vdict=Vdict, - BsdictHor=BsdictHor, BvdictHor=BvdictHor, Lim=Lim, Nstep=Nstep, LegDict=LegDict, draw=draw, a4=a4, Test=Test)
- -
[docs] def save(self, SaveName=None, Path=None, Mode='npz', compressed=False): - """ Save the object in folder Name, under file name SaveName, using specified mode - - Most tofu objects can be saved automatically as numpy arrays (.npz, recommended) at the default location (recommended) by simply calling self.save() - - Parameters - ---------- - SaveName : None / str - The name to be used for the saved file, if None (recommended) uses self.Id.SaveName - Path : None / str - Path specifying where to save the file, if None (recommended) uses self.Id.SavePath - Mode : str - Flag specifying whether to save the object as a numpy array file ('.npz', recommended) or an object using cPickle (not recommended, heavier and may cause retro-compatibility issues) - compressed : bool - Flag, used when Mode='npz', indicating whether to use np.savez or np.savez_compressed (slower saving and loading but smaller files) - - """ - tfpf.Save_Generic(self, SaveName=SaveName, Path=Path, Mode=Mode, compressed=compressed)
- - - - -def _Struct_check_inputs(Id=None, Poly=None, Type=None, DLong=None, Vess=None, Clock=None, arrayorder=None, Exp=None, shot=None, dtime=None, dtimeIn=None, SavePath=None): - if not Id is None: - assert type(Id) in [str,tfpf.ID], "Arg Id must be a str or a tfpf.ID object !" - if not Poly is None: - assert hasattr(Poly,'__iter__') and np.asarray(Poly).ndim==2 and 2 in np.asarray(Poly).shape, "Arg Poly must be a dict or an iterable with 2D coordinates of cross section poly !" - bools = [Clock,dtimeIn] - if any([not aa is None for aa in bools]): - assert all([aa is None or type(aa) is bool for aa in bools]), " Args [Clock,dtimeIn] must all be bool !" - if not arrayorder is None: - assert arrayorder in ['C','F'], "Arg arrayorder must be in ['C','F'] !" - if not Type is None: - assert Type in ['Tor','Lin'], "Arg Type must be in ['Tor','Lin'] !" - if not Exp is None: - assert Exp in tfd.AllowedExp, "Ar Exp must be in "+str(tfd.AllowedExp)+" !" - strs = [SavePath] - if any([not aa is None for aa in strs]): - assert all([aa is None or type(aa) is str for aa in strs]), "Args [Type,Exp,SavePath] must all be str !" - Iter2 = [DLong] - if any([not aa is None for aa in Iter2]): - assert all([aa is None or (hasattr(aa,'__iter__') and np.asarray(aa).ndim==1 and np.asarray(aa).size==2) for aa in Iter2]), "Args [DLong,Sino_RefPt] must be an iterable with len()=2 !" - if not Vess is None: - assert type(Vess) is Ves, "Arg Ves must be a tofu.geom.Ves instance !" - if not Type is None: - assert Type==Vess.Type, "Arg Ves must have same Type as the Struct instance !" - if not dtime is None: - assert type(dtime) is dtm.datetime, "Arg dtime must be a dtm.datetime !" - - - - - - - - - - - - - - - - - - - - - - - - - -""" -############################################################################### -############################################################################### - LOS class and functions -############################################################################### -""" - - -
[docs]class LOS(object): - """ A Line-Of-Sight object (semi-line with signed direction) with all useful geometrical parameters, associated :class:`~tofu.geom.Ves` object and built-in methods for plotting, defined in (X,Y,Z) cartesian coordinates - - A Line of Sight (LOS) is a semi-line. It is a useful approximate representation of a (more accurate) Volume of Sight (VOS) when the latter is narrow and elongated. - It is usually associated to a detector placed behind apertures. - When associated to a :class:`~tofu.geom.Ves` object, special points are automatically computed (entry point, exit point, closest point to the center of the :class:`~tofu.geom.Ves` object...) as well as a projection in a cross-section. - While tofu provides the possibility of creating LOS objects for academic and simplification pueposes, it is generally not recommended to use them for doing physics, consider using a Detect object instead (which will provide you with a proper and automatically-computed VOS as well as with a LOS if you want). - - Parameters - ---------- - Id : str / tfpf.ID - A name string or a pre-built tfpf.ID class to be used to identify this particular instance, if a string is provided, it is fed to tfpf.ID() - Du : list / tuple - List of 2 arrays of len=3, the (X,Y,Z) coordinates of respectively the starting point D of the LOS and its directing vector u (will be automatically normalized) - Ves : :class:`~tofu.geom.Ves` - A :class:`~tofu.geom.Ves` instance to be associated to the created LOS - Sino_RefPt : None or np.ndarray - If provided, array of size=2 containing the (R,Z) (for 'Tor' Type) or (Y,Z) (for 'Lin' Type) coordinates of the reference point for the sinogram - arrayorder : str - Flag indicating whether the attributes of type=np.ndarray (e.g.: Poly) should be made C-contiguous ('C') or Fortran-contiguous ('F') - Type : None - (not used in the current version) - Exp : None / str - Experiment to which the Lens belongs, should be identical to Ves.Id.Exp if Ves is provided, if None and Ves is provided, Ves.Id.Exp is used - Diag : None / str - Diagnostic to which the Lens belongs - shot : None / int - Shot number from which this Lens is usable (in case its position was changed from a previous configuration) - SavePath : None / str - If provided, forces the default saving path of the object to the provided value - dtime : None / dtm.datetime - A time reference to be used to identify this particular instance (used for debugging mostly) - dtimeIn : bool - Flag indicating whether dtime should be included in the SaveName (used for debugging mostly) - - """ - - def __init__(self, Id, Du, Ves=None, Sino_RefPt=None, arrayorder='C', Clock=False, Type=None, Exp=None, Diag=None, shot=None, dtime=None, dtimeIn=False, SavePath=None): - self._Done = False - tfpf._check_NotNone({'Clock':Clock,'arrayorder':arrayorder}) - self._check_inputs(Clock=Clock, arrayorder=arrayorder) - self._arrayorder = arrayorder - self._Clock = Clock - if not Ves is None: - Exp = Exp if not Exp is None else Ves.Id.Exp - assert Exp==Ves.Id.Exp, "Arg Exp must be identical to the Ves.Exp !" - self._set_Id(Id, Type=Type, Exp=Exp, Diag=Diag, shot=shot, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - self._set_Du(Du, Calc=False) - self._set_Ves(Ves) - self._set_Sino(RefPt=Sino_RefPt) - self._Done = True - - @property - def Id(self): - return self._Id - @property - def D(self): - return self._Du[0] - @property - def u(self): - return self._Du[1] - @property - def Du(self): - return self._Du - @property - def Ves(self): - return self._Ves - @property - def PIn(self): - return self._PIn - @property - def POut(self): - return self._POut - @property - def kPIn(self): - return self._kPIn - @property - def kPOut(self): - return self._kPOut - @property - def PRMin(self): - return self._PRMin - @property - def Sino_RefPt(self): - return self._Sino_RefPt - @property - def Sino_P(self): - return self._Sino_P - @property - def Sino_Pk(self): - return self._Sino_Pk - @property - def Sino_p(self): - return self._Sino_p - @property - def Sino_theta(self): - return self._Sino_theta - - def _check_inputs(self, Id=None, Du=None, Ves=None, Type=None, Sino_RefPt=None, Clock=None, arrayorder=None, Exp=None, shot=None, Diag=None, dtime=None, dtimeIn=None, SavePath=None, Calc=None): - _LOS_check_inputs(Id=Id, Du=Du, Vess=Ves, Type=Type, Sino_RefPt=Sino_RefPt, Clock=Clock, arrayorder=arrayorder, Exp=Exp, shot=shot, Diag=Diag, dtime=dtime, dtimeIn=dtimeIn, SavePath=SavePath, Calc=Calc) - - - def _set_Id(self, Val, Type=None, Exp=None, Diag=None, shot=None, SavePath=None, dtime=None, dtimeIn=False): - if self._Done: - Out = tfpf._get_FromItself(self.Id, {'Type':Type, 'Exp':Exp, 'shot':shot, 'Diag':Diag, 'dtime':dtime, '_dtimeIn':dtimeIn, 'SavePath':SavePath}) - Type, Exp, shot, Diag, dtime, dtimeIn, SavePath = Out['Type'], Out['Exp'], Out['shot'], Out['Diag'], Out['dtime'], Out['dtimeIn'], Out['SavePath'] - tfpf._check_NotNone({'Id':Val}) - self._check_inputs(Id=Val) - if type(Val) is str: - tfpf._check_NotNone({'Exp':Exp, 'shot':shot, 'Diag':Diag, 'dtimeIn':dtimeIn}) - self._check_inputs(Type=Type, Exp=Exp, shot=shot, Diag=Diag, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - Val = tfpf.ID('LOS', Val, Type=Type, Exp=Exp, Diag=Diag, shot=shot, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - self._Id = Val - - def _set_Du(self, Du, Calc=True): - tfpf._check_NotNone({'Du':Du,'Calc':Calc}) - self._check_inputs(Du=Du, Calc=Calc) - DD, uu = np.asarray(Du[0]).flatten(), np.asarray(Du[1]).flatten() - uu = uu/np.linalg.norm(uu,2) - self._Du = (DD,uu) - if Calc: - self._calc_InOutPolProj() - - def _set_Ves(self, Ves=None): - tfpf._check_NotNone({'Ves':Ves, 'Exp':self.Id.Exp}) - self._check_inputs(Ves=Ves, Exp=self.Id.Exp) - if not Ves is None: - self.Id.set_LObj([Ves.Id]) - self._Ves = Ves - self._calc_InOutPolProj() - - def _calc_InOutPolProj(self): - PIn, POut, kPOut, kPIn = np.NaN*np.ones((3,)), np.NaN*np.ones((3,)), np.nan, np.nan - if not self.Ves is None: - PIn, POut, kPIn, kPOut, Err = _tfg_c._LOS_calc_InOutPolProj(self.Ves.Type, self.Ves.Poly, self.Ves.Vin, self.Ves.DLong, self.D, self.u, self.Id.Name) - if Err: - La = _tfg_p._LOS_calc_InOutPolProj_Debug(self,PIn, POut) - self._PIn, self._POut, self._kPIn, self._kPOut = PIn, POut, kPIn, kPOut - self._set_CrossProj() - - def _set_CrossProj(self): - if np.isnan(self.kPIn) or np.isnan(self.kPOut): - print('LOS '+self.Id.Name+' has no PIn or POut for computing the PolProj !') - return - self._PRMin, self._RMin, self._kRMin, self._PolProjAng, self._PplotOut, self._PplotIn = _tfg_c._LOS_set_CrossProj(self.Ves.Type, self.D, self.u, self.kPIn, self.kPOut) - - def _set_Sino(self, RefPt=None): - self._check_inputs(Sino_RefPt=RefPt) - RefPt = self.Ves.Sino_RefPt if RefPt is None else np.asarray(RefPt).flatten() - self._Sino_RefPt = RefPt - self._Ves._set_Sino(RefPt) - kMax = self.kPOut - if np.isnan(kMax): - kMax = np.inf - if self.Ves.Type=='Tor': - self._Sino_P, self._Sino_Pk, self._Sino_Pr, self._Sino_PTheta, self._Sino_p, self._Sino_theta, self._Sino_Phi = _tfg_gg.Calc_Impact_Line(self.D, self.u, RefPt, kOut=kMax) - elif self.Ves.Type=='Lin': - self._Sino_P, self._Sino_Pk, self._Sino_Pr, self._Sino_PTheta, self._Sino_p, self._Sino_theta, self._Sino_Phi = _tfg_gg.Calc_Impact_Line_Lin(self.D, self.u, RefPt, kOut=kMax) - -
[docs] def plot(self, Lax=None, Proj='All', Lplot=tfd.LOSLplot, Elt='LDIORP', EltVes='', Leg='', - Ldict=tfd.LOSLd, MdictD=tfd.LOSMd, MdictI=tfd.LOSMd, MdictO=tfd.LOSMd, MdictR=tfd.LOSMd, MdictP=tfd.LOSMd, LegDict=tfd.TorLegd, - Vesdict=tfd.Vesdict, draw=True, a4=False, Test=True): - """ Plot the LOS, in a cross-section projection, a horizontal projection or both, and optionally the :class:`~tofu.geom.Ves` object associated to it. - - Plot the desired projections of the LOS object. - The plot can include the special points, the directing vector, and the properties of the plotted objects are specified by dictionaries. - - Parameters - ---------- - Lax : list / plt.Axes - The axes to be used for plotting (provide a list of 2 axes if Proj='All'), if None a new figure with axes is created - Proj : str - Flag specifying the kind of projection used for the plot ('Cross' for a cross-section, 'Hor' for a horizontal plane, 'All' both and '3d' for 3d) - Elt : str - Flag specifying which elements to plot, each capital letter corresponds to an element - * 'L': LOS - * 'D': Starting point of the LOS - * 'I': Input point (i.e.: where the LOS enters the Vessel) - * 'O': Output point (i.e.: where the LOS exits the Vessel) - * 'R': Point of minimal major radius R (only for Vessel of Type='Tor') - * 'P': Point of used for impact parameter (i.e.: minimal distance to reference point Sino_RefPt) - Lplot : str - Flag specifying whether to plot the full LOS ('Tot': from starting point output point) or only the fraction inside the vessel ('In': from input to output point) - EltVes : str - Flag specifying the elements of the Vessel to be plotted, fed to :meth:`~tofu.geom.Ves.plot` - Leg : str - Legend to be used to identify this LOS, if Leg='' the LOS name is used - Ldict : dict / None - Dictionary of properties used for plotting the polygon, fed to plt.Axes.plot() or plt.plot_surface() if Proj='3d', set to ToFu_Defauts.py if None - MdictD : dict - Dictionary of properties used for plotting point 'D', fed to plt.Axes.plot() - MdictI : dict - Dictionary of properties used for plotting point 'I', fed to plt.Axes.plot() - MdictO : dict - Dictionary of properties used for plotting point 'O', fed to plt.Axes.plot() - MdictR : dict - Dictionary of properties used for plotting point 'R', fed to plt.Axes.plot() - MdictP : dict - Dictionary of properties used for plotting point 'P', fed to plt.Axes.plot() - LegDict : dict or None - Dictionary of properties used for plotting the legend, fed to plt.legend(), the legend is not plotted if None - Vesdict : dict - Dictionary of kwdargs to fed to :meth:`~tofu.geom.Ves.plot`, and 'EltVes' is used instead of 'Elt' - draw : bool - Flag indicating whether the fig.canvas.draw() shall be called automatically - a4 : bool - Flag indicating whether the figure should be plotted in a4 dimensions for printing - Test : bool - Flag indicating whether the inputs should be tested for conformity - - Returns - ------- - La : list / plt.Axes - Handles of the axes used for plotting (list if several axes where used) - - """ - return _tfg_p.GLLOS_plot(self, Lax=Lax, Proj=Proj, Lplot=Lplot, Elt=Elt, EltVes=EltVes, Leg=Leg, - Ldict=Ldict, MdictD=MdictD, MdictI=MdictI, MdictO=MdictO, MdictR=MdictR, MdictP=MdictP, LegDict=LegDict, - Vesdict=Vesdict, draw=draw, a4=a4, Test=Test)
- - -# def plot_3D_mlab(self,Lplot='Tot',PDIOR='DIOR',axP='None',axT='None', Ldict=Ldict_Def,Mdict=Mdict_Def,LegDict=LegDict_Def): -# fig = Plot_3D_mlab_GLOS() -# return fig - -
[docs] def plot_Sinogram(self, Proj='Cross', ax=None, Elt=tfd.LOSImpElt, Sketch=True, Ang=tfd.LOSImpAng, AngUnit=tfd.LOSImpAngUnit, - Ldict=tfd.LOSMImpd, Vdict=tfd.TorPFilld, LegDict=tfd.TorLegd, draw=True, a4=False, Test=True): - """ Plot the sinogram of the vessel polygon, by computing its envelopp in a cross-section, can also plot a 3D version of it - - Plot the LOS in projection space (where sinograms are plotted) as a point. - You can plot the conventional projection-space (in 2D in a cross-section), or a 3D extrapolation of it, where the third coordinate is provided by the angle that the LOS makes with the cross-section plane (useful in case of multiple LOS with a partially tangential view). - - Parameters - ---------- - Proj : str - Flag indicating whether to plot a classic sinogram ('Cross') from the vessel cross-section (assuming 2D), or an extended 3D version ('3d') of it with additional angle - ax : None or plt.Axes - The axes on which the plot should be done, if None a new figure and axes is created - Elt : str - Flag indicating which elements to plot, each capital letter stands for one element - * 'L': LOS - * 'V': Vessel - Ang : str - Flag indicating which angle to use for the impact parameter, the angle of the line itself (xi) or of its impact parameter (theta) - AngUnit : str - Flag for the angle units to be displayed, 'rad' for radians or 'deg' for degrees - Sketch : bool - Flag indicating whether a small skecth showing the definitions of angles 'theta' and 'xi' should be included or not - Ldict : dict - Dictionary of properties used for plotting the LOS point, fed to plt.plot() if Proj='Cross' and to plt.plot_surface() if Proj='3d' - Vdict : dict - Dictionary of properties used for plotting the polygon envelopp, fed to plt.plot() if Proj='Cross' and to plt.plot_surface() if Proj='3d' - LegDict : None or dict - Dictionary of properties used for plotting the legend, fed to plt.legend(), the legend is not plotted if None - draw : bool - Flag indicating whether to draw the figure - a4 : bool - Flag indicating whether the figure should be plotted in a4 dimensions for printing - Test : bool - Flag indicating whether the inputs shall be tested for conformity - - Returns - ------- - ax : plt.Axes - The axes used to plot - - """ - return _tfg_p.GLOS_plot_Sinogram(self, Proj=Proj, ax=ax, Elt=Elt, Sketch=Sketch, Ang=Ang, AngUnit=AngUnit, - Ldict=Ldict, Vdict=Vdict, LegDict=LegDict, draw=draw, a4=a4, Test=Test)
- - -
[docs] def save(self, SaveName=None, Path=None, Mode='npz', compressed=False): - """ Save the object in folder Name, under file name SaveName, using specified mode - - Most tofu objects can be saved automatically as numpy arrays (.npz, recommended) at the default location (recommended) by simply calling self.save() - - Parameters - ---------- - SaveName : None / str - The name to be used for the saved file, if None (recommended) uses self.Id.SaveName - Path : None / str - Path specifying where to save the file, if None (recommended) uses self.Id.SavePath - Mode : str - Flag specifying whether to save the object as a numpy array file ('.npz', recommended) or an object using cPickle (not recommended, heavier and may cause retro-compatibility issues) - compressed : bool - Flag, used when Mode='npz', indicating whether to use np.savez or np.savez_compressed (slower saving and loading but smaller files) - - """ - tfpf.Save_Generic(self, SaveName=SaveName, Path=Path, Mode=Mode, compressed=compressed)
- - - - - - -def _LOS_check_inputs(Id=None, Du=None, Vess=None, Type=None, Sino_RefPt=None, Clock=None, arrayorder=None, Exp=None, shot=None, Diag=None, dtime=None, dtimeIn=None, SavePath=None, Calc=None): - if not Id is None: - assert type(Id) in [str,tfpf.ID], "Arg Id must be a str or a tfpf.ID object !" - if not Du is None: - assert hasattr(Du,'__iter__') and len(Du)==2 and all([hasattr(du,'__iter__') and len(du)==3 for du in Du]), "Arg Du must be an iterable containing of two iterables of len()=3 (cartesian coordinates) !" - if not Vess is None: - assert type(Vess) is Ves, "Arg Ves must be a Ves instance !" - if not Exp is None: - assert Exp==Vess.Id.Exp, "Arg Exp must be the same as Ves.Id.Exp !" - bools = [Clock,dtimeIn,Calc] - if any([not aa is None for aa in bools]): - assert all([aa is None or type(aa) is bool for aa in bools]), " Args [Clock,dtimeIn,Calc] must all be bool !" - if not arrayorder is None: - assert arrayorder in ['C','F'], "Arg arrayorder must be in ['C','F'] !" - assert Type is None, "Arg Type must be None for a LOS object !" - if not Exp is None: - assert Exp in tfd.AllowedExp, "Arg Exp must be in "+str(tfd.AllowedExp)+" !" - strs = [Diag,SavePath] - if any([not aa is None for aa in strs]): - assert all([aa is None or type(aa) is str for aa in strs]), "Args [Diag,SavePath] must all be str !" - Iter2 = [Sino_RefPt] - if any([not aa is None for aa in Iter2]): - assert all([aa is None or (hasattr(aa,'__iter__') and np.asarray(aa).ndim==1 and np.asarray(aa).size==2) for aa in Iter2]), "Args [DLong,Sino_RefPt] must be an iterable with len()=2 !" - Ints = [shot] - if any([not aa is None for aa in Ints]): - assert all([aa is None or type(aa) is int for aa in Ints]), "Args [Sino_NP,shot] must be int !" - if not dtime is None: - assert type(dtime) is dtm.datetime, "Arg dtime must be a dtm.datetime !" - - - - - -
[docs]class GLOS(object): - """ An object regrouping a group of LOS objects with some common features (e.g.: all belong to the same camera) and the same :class:`~tofu.geom.Ves` object, provides methods for common computing and plotting - - Usually :class:`LOS` correspond to detectors which are naturally grouped in 'cameras' (sets of detectors located in the same place or sharing an aperture or a data acquisition system). - The GLOS object provided by tofu provides the object-oriented equivalent. - The GLOS objects provides the same methods as the :class:`LOS` objects, plus extra methods for fast handling or selecting of the whole set. - Note that you must first create each :class:`LOS` independently and then provide them as a list argument to a GLOS object. - - Parameters - ---------- - Id : str / tfpf.ID - A name string or a pre-built tfpf.ID class to be used to identify this particular instance, if a string is provided, it is fed to tfpf.ID() - LLOS : list / :class:'LOS' - List of LOS instances with the same :class:`~tofu.geom.Ves` instance - Type : None - (not used in the current version) - Exp : None / str - Experiment to which the Lens belongs, should be identical to Ves.Id.Exp if Ves is provided, if None and Ves is provided, Ves.Id.Exp is used - Diag : None / str - Diagnostic to which the Lens belongs - shot : None / int - Shot number from which this Lens is usable (in case its position was changed from a previous configuration) - Sino_RefPt : None / iterable - If provided, array of size=2 containing the (R,Z) (for 'Tor' Type) or (Y,Z) (for 'Lin' Type) coordinates of the reference point for the sinogram - arrayorder : str - Flag indicating whether the attributes of type=np.ndarray (e.g.: Poly) should be made C-contiguous ('C') or Fortran-contiguous ('F') - SavePath : None / str - If provided, forces the default saving path of the object to the provided value - dtime None / dtm.datetime - A time reference to be used to identify this particular instance (used for debugging mostly) - dtimeIn bool - Flag indicating whether dtime should be included in the SaveName (used for debugging mostly) - - """ - def __init__(self, Id, LLOS, Ves=None, Sino_RefPt=None, Type=None, Exp=None, Diag=None, shot=None, arrayorder='C', Clock=False, dtime=None, dtimeIn=False, SavePath=None): - self._Done = False - tfpf._check_NotNone({'Clock':Clock,'arrayorder':arrayorder}) - self._check_inputs(Clock=Clock, arrayorder=arrayorder) - self._arrayorder = arrayorder - self._Clock = Clock - - self._check_inputs(Exp=Exp, Diag=Diag, shot=shot, Ves=Ves, LLOS=LLOS) - Exp = Exp if not Exp is None else LLOS[0].Id.Exp - assert Exp==LLOS[0].Id.Exp, "Arg Exp must be identical to the LLOS !" - Diag = Diag if not Diag is None else LLOS[0].Id.Diag - assert Diag==LLOS[0].Id.Diag, "Arg Diag must be identical to the LLOS !" - shot = shot if not shot is None else LLOS[0].Id.shot - assert shot==LLOS[0].Id.shot, "Arg shot must be identical to the LLOS !" - - self._set_Id(Id, Exp=Exp, Diag=Diag, shot=shot, Type=Type, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - self._set_LLOS(LLOS) - if not Ves is None and not tfpf.CheckSameObj(LLOS[0].Ves, Ves, ['Poly','Type','Name','Exp']): - self._set_Ves(Ves) - - self._set_Sino(RefPt=Sino_RefPt) - self._Done = True - - - @property - def Id(self): - return self._Id - @property - def LLOS(self): - return self._LLOS - @property - def Ves(self): - return self._LLOS[0].Ves - @property - def nLOS(self): - return self._nLOS - @property - def Sino_RefPt(self): - return self._LLOS[0].Sino_RefPt - - def _check_inputs(self, Id=None, LLOS=None, Ves=None, Sino_RefPt=None, Type=None, Exp=None, Diag=None, shot=None, arrayorder=None, Clock=None, dtime=None, dtimeIn=False, SavePath=None): - _GLOS_check_inputs(Id=Id, LLOS=LLOS, Vess=Ves, Sino_RefPt=Sino_RefPt, Type=Type, Exp=Exp, Diag=Diag, shot=shot, arrayorder=arrayorder, Clock=Clock, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - - def _set_Id(self, Val, Type=None, Exp=None, Diag=None, shot=None, SavePath=None, dtime=None, dtimeIn=False): - if self._Done: - Out = tfpf._get_FromItself(self.Id, {'Type':Type, 'Exp':Exp, 'shot':shot, 'Diag':Diag, 'dtime':dtime, '_dtimeIn':dtimeIn, 'SavePath':SavePath}) - Type, Exp, shot, Diag, dtime, dtimeIn, SavePath = Out['Type'], Out['Exp'], Out['shot'], Out['Diag'], Out['dtime'], Out['dtimeIn'], Out['SavePath'] - tfpf._check_NotNone({'Id':Val}) - self._check_inputs(Id=Val) - if type(Val) is str: - tfpf._check_NotNone({'Exp':Exp, 'shot':shot, 'Diag':Diag, 'dtimeIn':dtimeIn}) - self._check_inputs(Type=Type, Exp=Exp, shot=shot, Diag=Diag, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - Val = tfpf.ID('GLOS', Val, Type=Type, Exp=Exp, Diag=Diag, shot=shot, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - self._Id = Val - - - def _set_LLOS(self, LLOS): - self._check_inputs(LLOS=LLOS) - if isinstance(LLOS,LOS): - LLOS = [LLOS] - self._nLOS = len(LLOS) - self._LLOS = LLOS - LObj = [ll.Id for ll in LLOS] - if not LLOS[0].Ves is None: - LObj.append(LLOS[0].Ves.Id) - self.Id.set_LObj(LObj) - - def _set_Ves(self, Ves=None): - self._check_inputs(Ves=V) - for ii in range(0,self.nLOS): - self._LLOS[ii]._set_Ves(Ves) - if not Ves is None: - self.Id.set_LObj([Ves.Id]) - - def _set_Sino(self, RefPt=None): - self._check_inputs(Sino_RefPt=RefPt) - for ii in range(self.nLOS): - self._LLOS[ii]._set_Sino(RefPt=RefPt) - -
[docs] def select(self, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In', Out=bool): - """ Return the indices or instances of all instances matching the specified criterion. - - The selection can be done according to 2 different mechanism (1) and (2). - - For mechanism (1): the user provides the value (Val) that the specified criterion (Crit) should take for a :class:`LOS` to be selected. - The criteria are typically attributes of the self.Id attribute (i.e.: name of the instance, or user-defined attributes like the camera head...) - - For mechanism (2), used if Val=None: the user provides a str expression (or a list of such) to be fed to eval(), used to check on quantitative criteria, placed before the criterion value (e.g.: 'not ' or '<='). - Another str or list of str expressions can be provided that will be placed after the criterion value. - - Other parameters are used to specify logical operators for the selection (match any or all the criterion...) and the type of output. - - Parameters - ---------- - Crit : str - Flag indicating which criterion to use for discrimination - Can be set to any attribute of the tofu.pathfile.ID class (e.g.: 'Name','SaveName','SavePath'...) or any key of ID.USRdict (e.g.: 'Exp'...) - Val : list, str or None - The value to match for the chosen criterion, can be a list of different values - Used for selection mechanism (1) - PreExp : list, str or None - A str of list of str expressions to be fed to eval(), used to check on quantitative criteria, placed before the criterion value (e.g.: 'not ') - Used for selection mechanism (2) - PostExp : list, str or None - A str of list of str expressions to be fed to eval(), used to check on quantitative criteria, placed after the criterion value (e.g.: '>=5.') - Used for selection mechanism (2) - Log : str - Flag indicating whether the criterion shall match all provided values or one of them ('any' or 'all') - InOut : str - Flag indicating whether the returned indices are the ones matching the criterion ('In') or the ones not matching it ('Out') - Out : type / str - Flag indicating in which form shall the result be returned, as an array of integer indices (int), an array of booleans (bool), a list of names ('Names') or a list of instances ('LOS') - - Returns - ------- - ind : list / np.ndarray - The computed output (array of index, list of names or instances depending on parameter 'Out') - - Examples - -------- - - >>> import tofu.geom as tfg - >>> ves = tfg.Ves('ves', [[0.,1.,1.,0.],[0.,0.,1.,1.]], DLong=[-1.,1.], Type='Lin', Exp='Misc', shot=0) - >>> los1 = tfg.LOS('los1', ([0.,-0.1,-0.1],[0.,1.,1.]), Ves=ves, Exp='Misc', Diag='D', shot=0) - >>> los2 = tfg.LOS('los2', ([0.,-0.1,-0.1],[0.,0.5,1.]), Ves=ves, Exp='Misc', Diag='D', shot=1) - >>> los3 = tfg.LOS('los3', ([0.,-0.1,-0.1],[0.,1.,0.5]), Ves=ves, Exp='Misc', Diag='D', shot=1) - >>> glos = tfg.GLOS('glos', [los1,los2,los3]) - >>> ind = glos.select(Val=['los1','los3'], Log='any', Out='LOS') - >>> print [ii.Id.Name for ii in ind] - ['los1', 'los3'] - >>> ind = glos.select(Val=['los1','los3'], Log='any', InOut='Out', Out=int) - array([1]) - - """ - if not Out=='LOS': - ind = tfpf.SelectFromListId([ll.Id for ll in self.LLOS], Val=Val, Crit=Crit, PreExp=PreExp, PostExp=PostExp, Log=Log, InOut=InOut, Out=Out) - else: - ind = tfpf.SelectFromListId([ll.Id for ll in self.LLOS], Val=Val, Crit=Crit, PreExp=PreExp, PostExp=PostExp, Log=Log, InOut=InOut, Out=int) - ind = [self.LLOS[ii] for ii in ind] - return ind
- - -
[docs] def plot(self, Lax=None, Proj='All', Lplot=tfd.LOSLplot, Elt='LDIORP', EltVes='', Leg='', - Ldict=tfd.LOSLd, MdictD=tfd.LOSMd, MdictI=tfd.LOSMd, MdictO=tfd.LOSMd, MdictR=tfd.LOSMd, MdictP=tfd.LOSMd, LegDict=tfd.TorLegd, - ind=None, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In', - Vesdict=tfd.Vesdict, draw=True, a4=False, Test=True): - """ Plot the GLOS, with a cross-section view, a horizontal view or both, and optionally the :class:`~tofu.geom.Ves` object associated to it. - - Plot all the :class:`LOS` of the GLOS, or only a selection of them (using the same parameters as self.select()). - - Parameters - ---------- - Lax : list or plt.Axes - The axes to be used for plotting (provide a list of 2 axes if Proj='All'), if None a new figure with axes is created - Proj : str - Flag specifying the kind of projection used for the plot ('Cross' for a cross-section, 'Hor' for a horizontal plane, 'All' both and '3d' for 3d) - Elt : str - Flag specifying which elements to plot, each capital letter corresponds to an element - * 'L': LOS - * 'D': Starting point of the LOS - * 'I': Input point (i.e.: where the LOS enters the Vessel) - * 'O': Output point (i.e.: where the LOS exits the Vessel) - * 'R': Point of minimal major radius R (only for Vessel of Type='Tor') - * 'P': Point of used for impact parameter (i.e.: minimal distance to reference point ImpRZ) - Lplot : str - Flag specifying whether to plot the full LOS ('Tot': from starting point output point) or only the fraction inside the vessel ('In': from input to output point) - EltVes : str - Flag specifying the elements of the Vessel to be plotted, fed to :meth:`~tofu.geom.Ves.plot` - Leg : str - Legend to be used to identify this LOS, if Leg='' the LOS name is used - Ldict : dict or None - Dictionary of properties used for plotting the polygon, fed to plt.Axes.plot() or plt.plot_surface() if Proj='3d', set to ToFu_Defauts.py if None - MdictD : dict - Dictionary of properties used for plotting point 'D', fed to plt.Axes.plot() - MdictI : dict - Dictionary of properties used for plotting point 'I', fed to plt.Axes.plot() - MdictO : dict - Dictionary of properties used for plotting point 'O', fed to plt.Axes.plot() - MdictR : dict - Dictionary of properties used for plotting point 'R', fed to plt.Axes.plot() - MdictP : dict - Dictionary of properties used for plotting point 'P', fed to plt.Axes.plot() - LegDict : dict or None - Dictionary of properties used for plotting the legend, fed to plt.legend(), the legend is not plotted if None - Vesdict : dict - Dictionary of kwdargs to fed to :meth:`~tofu.geom.Ves.plot`, and 'EltVes' is used instead of 'Elt' - Lim : list or tuple - Array of a lower and upper limit of angle (rad.) or length for plotting the '3d' Proj - draw : bool - Flag indicating whether the fig.canvas.draw() shall be called automatically - Test : bool - Flag indicating whether the inputs should be tested for conformity - - ind None or np.ndarray - Array of indices (int or bool) of the LOS to be plotted if only some of them are to be plotted - kwdargs - kwdargs to be fed to GLOS.select() if ind=None and only a fraction of the LOS are to be plotted - - Returns - ------- - La : list or plt.Axes - Handles of the axes used for plotting (list if several axes where used) - - """ - return _tfg_p.GLLOS_plot(self, Lax=Lax, Proj=Proj, Lplot=Lplot, Elt=Elt, EltVes=EltVes, Leg=Leg, - Ldict=Ldict, MdictD=MdictD, MdictI=MdictI, MdictO=MdictO, MdictR=MdictR, MdictP=MdictP, LegDict=LegDict, - Vesdict=Vesdict, draw=draw, a4=a4, Test=Test, - ind=ind, Val=Val, Crit=Crit, PreExp=PreExp, PostExp=PostExp, Log=Log, InOut=InOut)
- -# def plot_3D_mlab(self,Lplot='Tot',PDIOR='DIOR',ax='None', Ldict=Ldict_Def,Mdict=Mdict_Def,LegDict=LegDict_Def): -# fig = Plot_3D_mlab_GLOS() -# return fig - -
[docs] def plot_Sinogram(self, Proj='Cross', ax=None, Elt=tfd.LOSImpElt, Sketch=True, Ang=tfd.LOSImpAng, AngUnit=tfd.LOSImpAngUnit, - Ldict=tfd.LOSMImpd, Vdict=tfd.TorPFilld, LegDict=tfd.TorLegd, draw=True, a4=False, Test=True, - ind=None, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In'): - """ Plot the sinogram of the vessel polygon, by computing its envelopp in a cross-section, can also plot a 3D version of it - - Plot all the :class:`LOS` of the GLOS, or only a selection of them in projection space - - Parameters - ---------- - Proj : str - Flag indicating whether to plot a classic sinogram ('Cross') from the vessel cross-section (assuming 2D), or an extended 3D version '3d' of it with additional angle, default: 'Cross' - ax : None or plt.Axes - The axes on which the plot should be done, if None a new figure and axes is created, default: None - Elt : str - Flag indicating which elements to plot, each capital letter stands for one element, default: 'LV' - * 'L': LOS - * 'V': Vessel - Ang : str - Flag indicating which angle to use for the impact parameter, the angle of the line itself (xi) or of its impact parameter (theta), default: 'theta' - AngUnit : str - Flag for the angle units to be displayed, 'rad' for radians or 'deg' for degrees, default: 'rad' - Sketch : bool - Flag indicating whether a small skecth showing the definitions of angles 'theta' and 'xi' should be included or not - Ldict : dict - Dictionary of properties used for plotting the LOS point, fed to plt.plot() if Proj='Cross' and to plt.plot_surface() if Proj='3d', default: see ToFu_Defaults.py - Vdict : dict - Dictionary of properties used for plotting the polygon envelopp, fed to plt.plot() if Proj='Cross' and to plt.plot_surface() if Proj='3d', default: see ToFu_Defaults.py - LegDict : None or dict - Dictionary of properties used for plotting the legend, fed to plt.legend(), the legend is not plotted if None, default: see ToFu_Defaults.py - draw : bool - Flag indicating whether to draw the figure, default: True - Test : bool - Flag indicating whether the inputs shall be tested for conformity, default: True - - Returns - ------- - ax : plt.Axes - The axes used to plot - - """ - return _tfg_p.GLOS_plot_Sinogram(self, Proj=Proj, ax=ax, Elt=Elt, Sketch=Sketch, Ang=Ang, AngUnit=AngUnit, - Ldict=Ldict, Vdict=Vdict, LegDict=LegDict, draw=draw, a4=a4, Test=Test, - ind=ind, Val=Val, Crit=Crit, PreExp=PreExp, PostExp=PostExp, Log=Log, InOut=InOut)
- - - -
[docs] def save(self,SaveName=None,Path=None,Mode='npz', compressed=False): - """ Save the object in folder Name, under file name SaveName, using specified mode - - Most tofu objects can be saved automatically as numpy arrays (.npz, recommended) at the default location (recommended) by simply calling self.save() - - Parameters - ---------- - SaveName : None / str - The name to be used for the saved file, if None (recommended) uses self.Id.SaveName - Path : None / str - Path specifying where to save the file, if None (recommended) uses self.Id.SavePath - Mode : str - Flag specifying whether to save the object as a numpy array file ('.npz', recommended) or an object using cPickle (not recommended, heavier and may cause retro-compatibility issues) - compressed : bool - Flag, used when Mode='npz', indicating whether to use np.savez or np.savez_compressed (slower saving and loading but smaller files) - - """ - tfpf.Save_Generic(self, SaveName=SaveName, Path=Path, Mode=Mode, compressed=compressed)
- - - - -def _GLOS_check_inputs(Id=None, LLOS=None, Vess=None, Type=None, Sino_RefPt=None, Clock=None, arrayorder=None, Exp=None, shot=None, Diag=None, dtime=None, dtimeIn=None, SavePath=None): - if not Id is None: - assert type(Id) in [str,tfpf.ID], "Arg Id must be a str or a tfpf.ID object !" - if not Vess is None: - assert type(Vess) is Ves, "Arg Ves must be a Ves instance !" - if not Exp is None: - assert Exp==Vess.Id.Exp, "Arg Exp must be identical to Ves.Id.Exp !" - if not arrayorder is None: - assert arrayorder in ['C','F'], "Arg arrayorder must be in ['C','F'] !" - if not LLOS is None: - assert all([type(ll) is LOS for ll in LLOS]), "Arg LLOS must be a list of LOS objects !" - assert all([ll.Id.Exp==LLOS[0].Id.Exp for ll in LLOS]), "All LOS must have the same Exp !" - assert all([ll.Id.Type==LLOS[0].Id.Type for ll in LLOS]), "All LOS must have the same Type !" - assert all([tfpf.CheckSameObj(LLOS[0].Ves,ll.Ves, ['Poly','Type','Name','Exp','SaveName','shot']) for ll in LLOS]), "All LOS in LLOS must have the same Ves instance !" - assert all([ll._arrayorder==LLOS[0].Ves._arrayorder for ll in LLOS]), "All LOS should have the same arrayorder !" - assert all([ll.Id.Diag==LLOS[0].Id.Diag for ll in LLOS]), "All LOS should have the same Diag !" - if not arrayorder is None: - assert LLOS[0]._arrayorder==arrayorder, "All LOS should have the same arrayorder as provided !" - assert Type is None, "Arg Type must be None for a GLOS object !" - bools = [Clock,dtimeIn] - if any([not aa is None for aa in bools]): - assert all([aa is None or type(aa) is bool for aa in bools]), " Args [Clock,dtimeIn] must all be bool !" - if not Exp is None: - assert Exp in tfd.AllowedExp, "Arg Exp must be in "+str(tfd.AllowedExp)+" !" - strs = [Diag,SavePath] - if any([not aa is None for aa in strs]): - assert all([aa is None or type(aa) is str for aa in strs]), "Args [Diag,SavePath] must all be str !" - Ints = [shot] - if any([not aa is None for aa in Ints]): - assert all([aa is None or type(aa) is int for aa in Ints]), "Args [Sino_NP,shot] must be int !" - Iter2 = [Sino_RefPt] - if any([not aa is None for aa in Iter2]): - assert all([aa is None or (hasattr(aa,'__iter__') and np.asarray(aa).ndim==1 and np.asarray(aa).size==2) for aa in Iter2]), "Args [DLong,Sino_RefPt] must be an iterable with len()=2 !" - if not dtime is None: - assert type(dtime) is dtm.datetime, "Arg dtime must be a dtm.datetime !" - - - - - - - -""" -############################################################################### -############################################################################### - Lens class and functions -############################################################################### -""" - - - -
[docs]class Lens(object): - """ A Lens class with all geometrical data and built-in methods, defined as a planar polygon in 3D cartesian coordinates, with optional :class:`~tofu.geom.Ves` object - - A Lens object is useful for implementing one of the two possible optical arrangements available in tofu. - A Lens (implicitly convergent) is used for focusing incoming light on a detector of reduced size (i.e.g: like the end of an optic fiber cable). - In this case, anmd in its current version, tofu only handles spherical lenses and assumes that the detector has a circular active surface, centered on the same axis as the lens and located in its focal plane. - - Parameters - ---------- - Id : str or tfpf.ID - A name string or a pre-built tfpf.ID class to be used to identify this particular instance, if a string is provided, it is fed to tfpf.ID() - O : iterable - Array of 3D cartesian coordinates of the center of the Lens - nIn : iterable - Array of 3D cartesian coordiantes of the vector defining the axis of the Lens - Rad : float - Radius of the Lens - F1 : float - Focal length of the Lens, on the detector side - F2 : float - Focal length of the Lens, on the plasma side (only np.inf supported so far) - Type : str - Flag indicating the type of Lens (only 'Sph' - for spherical lens - supported so far) - R1 : None or float - Radius of the first face of the Lens, for full description only - R2 : None or float - Radius of the second face of the Lens, for full description only - dd : None or float - Width of the Lens along its axis, for full description only - Ves : :class:`~tofu.geom.Ves` - :class:`~tofu.geom.Ves` object to which the aperture is assigned - Exp : None or str - Experiment to which the Lens belongs, should be identical to Ves.Id.Exp if Ves is provided, if None and Ves is provided, Ves.Id.Exp is used - Diag : None or str - Diagnostic to which the Lens belongs - shot : None or int - Shot number from which this Lens is usable (in case its position was changed from a previous configuration) - SavePath : None / str - If provided, forces the default saving path of the object to the provided value - Clock : bool - Flag indicating whether the input polygon should be made clockwise (True) or counter-clockwise (False), default: False - arrayorder : str - Flag indicating whether the attributes of type=np.ndarray (e.g.: Poly) should be made C-contiguous ('C') or Fortran-contiguous ('F'), default: 'C' - dtime : None or dtm.datetime - A time reference to be used to identify this particular instance (used for debugging mostly), default: None - dtimeIn : bool - Flag indicating whether dtime should be included in the SaveName (used for debugging mostly), default: False - - """ - - def __init__(self, Id, O, nIn, Rad, F1, F2=np.inf, R1=None, R2=None, dd=None, Ves=None, Type='Sph', Exp=None, Diag=None, shot=None, arrayorder='C', Clock=False, SavePath=None, dtime=None, dtimeIn=False): - - self._Done = False - tfpf._check_NotNone({'Clock':Clock,'arrayorder':arrayorder}) - self._check_inputs(Clock=Clock, arrayorder=arrayorder) - self._arrayorder = arrayorder - self._Clock = Clock - - if not Ves is None: - Exp = Exp if not Exp is None else Ves.Id.Exp - assert Exp==Ves.Id.Exp, "Arg Exp must be identical to the Ves.Id.Exp !" - - self._set_Id(Id, Type=Type, Exp=Exp, Diag=Diag, shot=shot, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - self._set_geom(O, nIn, Rad, F1, F2=F2, R1=R1, R2=R2, dd=dd) - self._set_Ves(Ves) - self._Done = True - - @property - def Type(self): - return self.Id.Type - @property - def Id(self): - return self._Id - @property - def O(self): - return self._O - @property - def BaryS(self): - return self._O - @property - def Rad(self): - return self._Rad - @property - def F1(self): - return self._F1 - @property - def F2(self): - return self._F2 - @property - def nIn(self): - return self._nIn - @property - def Poly(self,NP=100): - """ Return a simple representation of the Lens as a 3D circle (if Lens.Type='Sph') """ - assert self.Type=='Sph', "Coded only for Lens.Type='Sph' !" - thet = np.linspace(0.,2.*np.pi,NP) - e1 = np.array([-self.nIn[1],self.nIn[0],0.]) - e1 = e1/np.linalg.norm(e1) - e2 = np.cross(self.nIn,e1) - Poly = np.tile(self.O,(NP,1)).T + self.Rad*np.array([np.cos(thet)*e1[0]+np.sin(thet)*e2[0], np.cos(thet)*e1[1]+np.sin(thet)*e2[1], np.cos(thet)*e1[2]+np.sin(thet)*e2[2]]) - Poly = np.ascontiguousarray(Poly) if self._arrayorder=='C' else np.asfortranarray(Poly) - return Poly - @property - def Surf(self): - assert self.Type=='Sph', "Coded only for Lens.Type='Sph' !" - return np.pi*self.Rad**2 - - @property - def Full(self): - return self._Full - @property - def R1(self): - return self._R1 - @property - def R2(self): - return self._R2 - @property - def dd(self): - return self._dd - - @property - def Ves(self): - return self._Ves - - def _check_inputs(self, Id=None, O=None, nIn=None, Rad=None, F1=None, F2=None, R1=None, R2=None, dd=None, Ves=None, Type=None, Exp=None, Diag=None, shot=None, arrayorder=None, Clock=None, SavePath=None, dtime=None, dtimeIn=None): - _Lens_check_inputs(Id=Id, O=O, nIn=nIn, Rad=Rad, F1=F1, F2=F2, R1=R1, R2=R2, dd=dd, Vess=Ves, Type=Type, Exp=Exp, Diag=Diag, shot=shot, arrayorder=arrayorder, Clock=Clock, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - - - def _set_Id(self, Val, Type=None, Exp=None, Diag=None, shot=None, SavePath=None, dtime=None, dtimeIn=False): - if self._Done: - Out = tfpf._get_FromItself(self.Id, {'Type':Type, 'Exp':Exp, 'shot':shot, 'Diag':Diag, 'dtime':dtime, '_dtimeIn':dtimeIn, 'SavePath':SavePath}) - Type, Exp, shot, Diag, dtime, dtimeIn, SavePath = Out['Type'], Out['Exp'], Out['shot'], Out['Diag'], Out['dtime'], Out['dtimeIn'], Out['SavePath'] - tfpf._check_NotNone({'Id':Val}) - self._check_inputs(Id=Val) - if type(Val) is str: - tfpf._check_NotNone({'Type':Type, 'Exp':Exp, 'shot':shot, 'Diag':Diag, 'dtimeIn':dtimeIn}) - self._check_inputs(Type=Type, Exp=Exp, shot=shot, Diag=Diag, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - Val = tfpf.ID('Lens', Val, Type=Type, Exp=Exp, Diag=Diag, shot=shot, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - self._Id = Val - - def _set_geom(self, O, nIn, Rad, F1, F2=np.inf, R1=None, R2=None, dd=None): - tfpf._check_NotNone({'O':O,'nIn':nIn,'Rad':Rad,'F1':F1,'F2':F2}) - self._check_inputs(O=O, nIn=nIn, Rad=Rad, F1=F1, F2=F2, R1=R1, R2=R2, dd=dd) - self._O, self._nIn, self._Rad, self._F1, self._F2 = _tfg_c._Lens_set_geom_reduced(O, nIn, Rad, F1, F2=F2, Type=self.Id.Type) - self._Full, self._R1, self._R2, self._dd, self._C1, self._C2, self._Angmax1, self._Angmax2 = _tfg_c._Lens_set_geom_full(R1=R1, R2=R2, dd=dd, O=self.O, Rad=self.Rad, nIn=self.nIn, Type=self.Id.Type) - - def _set_Ves(self,Ves): - tfpf._check_NotNone({'Ves':Ves, 'Exp':self.Id.Exp}) - self._check_inputs(Ves=Ves, Exp=self.Id.Exp) - if not Ves is None: - self.Id.set_LObj([Ves.Id]) - if Ves.Type=='Tor': - self._nIn = _tfg_c.Calc_nInFromTor_Poly(self.BaryS, self.nIn, Ves.BaryS) - elif Ves.Type=='Lin': - self._nIn = _tfg_c.Calc_nInFromLin_Poly(self.BaryS, self.nIn, Ves.BaryS) - self._set_geom(self.O, self.nIn, self.Rad, self.F1, F2=self.F2, R1=self.R1, R2=self.R2, dd=self.dd) - self._Ves = Ves - - - def _get_CircleInFocPlaneFromPts(self, Pts, Test=True): - """ Compute the image of the lens projected on its focal plane as seen from arbitrary points in the plasma, treated with 3D coordinates and reduced lens model as input - - Parameters - ---------- - Pts : np.ndarray - (3,N) or (3,) array of points 3D cartesian coordinates - Test : bool - Flag indicating whether the inputs should be tested for conformity, default: True - - Returns - ------- - Cents : np.ndarray - (3,N) array of the 3D cartesian coordinates of the centers of the image circles of the lens on the focal plane from points Pts - Rads : np.ndarray - (N,) array of the radius of the image circles of the lens on the focal plane from points Pts - d : np.ndarray - (N,) array of the algebraic distance along the lens axis between the Lens O-point and Pts - r : np.ndarray - (N,) array of the absolute distance between Pts and the Lens axis - rIm : np.ndarray - (N,) array of the absolute distance between Pts images (center of the image circles on the focal plane) and the Lens axis - - """ - Pts = np.asarray(Pts) - if Test: - assert self.Type=='Sph', "Can only be computed for spherical lenses, cylindrical lenses not coded yet !" - assert type(Pts) is np.ndarray and Pts.ndim in [1,2] and 3 in Pts.shape, "Arg Pts must be a (3,N), (N,3) or (3,) np.ndarray !" - assert out.lower() in ['2d','3d'], "Arg out must be '2D' or '3D' !" - assert self.Id.Type=='Sph', "Only coded for spherical lens !" - if Pts.ndim==1: - Pts = Pts.reshape((3,1)) - if not Pts.shape[0]==3 and Pts.shape[1]==3: - Pts = Pts.T - Cs0,Cs1,Cs2, RadIm, din, r, rIm, nperp0,nperp1,nperp2 = _tfg_gg._Lens_get_CircleInFocPlaneFromPts(self.O[0],self.O[1],self.O[2], self.nIn[0],self.nIn[1],self.nIn[2], self.Rad, self.F1, Pts[0,:],Pts[1,:],Pts[2,:], F2=self.F2) - return np.array([Cs0,Cs1,Cs2]), RadIm, din, r, rIm, np.array([nperp0,nperp1,nperp2]) - - -
[docs] def plot_alone(self, ax=None, V='red', nin=1.5, nout=1., Lmax='F', V_NP=50, src=None, draw=True, a4=False, Test=True): - """ Plot a 2D representation of the Lens object, optionally with 2D viewing cone and rays of several sources in the plane, either with reduced of full representation - - Plot a sketch of the Lens, optionally with ray-traced incoming light beams. - This plotting routine does not consider any syurrounding and plots everything assuming the origine of the coordinate system is on the Lens - - Parameters - ---------- - ax : None or plt.Axes - Axes to be used for plotting, if None a new figure with axes is created (default: None) - V : str - Flag indicating whether the Lens should be considered in its reduced geometry model ('red') or its full version ('full'), default: 'red' - nin : float - Value of the optical index to be used inside the Lens (useful when V='full' only) - nout : float - Value of the optical index to be used outside the Lens (useful when V='full' only) - Lmax : float - Maximum length on which the source beams should be plotted after going through the Lens, if 'F' all beams are plotted up to the focal plane - V_NP : int - Number of points to be used to plot each circle fraction of the full version of the Lens geometry (useful when V='full' only) - src : None or dict - Dictionary of parameters for the source of ray beams: - * 'Pt': iterable of len()=2 with the 2D cartesian coordinates of the point where the source should be located with reference to the Lens center (0,0) and axis (1,0) - * 'Type': Flag indicating whether the source should a point ('Pt') or an array of parallel beams perpendicular to a plane passing through Pt - * 'nn': iterable of len()=2 with the 2D cartesian coordinates of a vector directing the array of parallel beams - * 'NP': int, number of beams to be plotted from the source - draw : bool - Flag indicating whether the fig.canvas.draw() shall be called automatically, default: True - a4 : bool - Flag indicating whether the figure should be a4 size (for printing or saving as pdf for example) - Test : bool - Flag indicating whether the inputs should be tested for conformity, default: True - - Returns - -------- - ax : plt.Axes - Handle of the axes used for plotting - - """ - return _tfg_p.Lens_plot_alone(self, ax=ax, V=V, nin=nin, nout=nout, Lmax=Lmax, V_NP=V_NP, src=src, draw=draw, a4=a4, Test=Test)
- - -
[docs] def plot(self, Lax=None, Proj='All', Elt='PV', EltVes='', Leg=None, LVIn=tfd.ApLVin, Pdict=tfd.ApPd, Vdict=tfd.ApVd, Vesdict=tfd.Vesdict, LegDict=tfd.TorLegd, draw=True, a4=False, Test=True): - """ Plot the Lens object, optionally with the associated :class:`~tofu.geom.Ves` object - - Plot the chosen projections of the Lens polygon. - - Parameters - ---------- - Lax : list or plt.Axes - The axes to be used for plotting (provide a list of 2 axes if Proj='All'), if None a new figure with axes is created - Proj : str - Flag specifying the kind of projection used for the plot ('Cross' for a cross-section, 'Hor' for a horizontal plane, 'All' both and '3d' for 3d) - Elt : str - Flag specifying which elements to plot, each capital letter corresponds to an element - * 'P': polygon - * 'V': vector perpendicular to the polygon, oriented towards the interior of the Vessel - EltVes : str - Flag specifying the elements of the Vessel to be plotted, fed to :meth:`~tofu.geom.Ves.plot` - Leg : str - Legend to be used to identify this LOS, if Leg='' the LOS name is used - LVIn : float - Length (in data coordinates, meters) of the vector 'V' - Pdict : dict - Dictionary of properties used for plotting the polygon, fed to plt.Axes.plot() or plt.plot_surface() if Proj='3d', set to ToFu_Defauts.py if None (default: None) - Vdict : dict - Dictionary of properties used for plotting vector 'V', fed to plt.Axes.plot() - Vesdict : dict - Dictionary of kwdargs to fed to :meth:`~tofu.geom.Ves.plot`, and 'EltVes' is used instead of 'Elt' - LegDict : dict or None - Dictionary of properties used for plotting the legend, fed to plt.legend(), the legend is not plotted if None - draw : bool - Flag indicating whether the fig.canvas.draw() shall be called automatically - a4 : bool - Flag indicating whether the figure should be a4 size (for printing or saving as pdf for example) - Test : bool - Flag indicating whether the inputs should be tested for conformity - - Returns - ------- - Lax : list or plt.Axes - Handles of the axes used for plotting (list if several axes where used) - - """ - return _tfg_p.LLens_plot(self, Lax=Lax, Proj=Proj, Elt=Elt, EltVes=EltVes, Leg=Leg, LVIn=LVIn, Pdict=Pdict, Vdict=Vdict, Vesdict=Vesdict, LegDict=LegDict, draw=draw, a4=a4, Test=Test)
- - -
[docs] def save(self,SaveName=None,Path=None,Mode='npz', compressed=False): - """ Save the object in folder Name, under file name SaveName, using specified mode - - Most tofu objects can be saved automatically as numpy arrays (.npz, recommended) at the default location (recommended) by simply calling self.save() - - Parameters - ---------- - SaveName : None / str - The name to be used for the saved file, if None (recommended) uses self.Id.SaveName - Path : None / str - Path specifying where to save the file, if None (recommended) uses self.Id.SavePath - Mode : str - Flag specifying whether to save the object as a numpy array file ('.npz', recommended) or an object using cPickle (not recommended, heavier and may cause retro-compatibility issues) - compressed : bool - Flag, used when Mode='npz', indicating whether to use np.savez or np.savez_compressed (slower saving and loading but smaller files) - - """ - tfpf.Save_Generic(self, SaveName=SaveName, Path=Path, Mode=Mode, compressed=compressed)
- - - -def _Lens_check_inputs(Id=None, O=None, nIn=None, Rad=None, F1=None, F2=None, R1=None, R2=None, dd=None, Vess=None, Type=None, Exp=None, Diag=None, shot=None, arrayorder=None, Clock=None, SavePath=None, dtime=None, dtimeIn=None): - if not Id is None: - assert type(Id) in [str,tfpf.ID], "Arg Id must be a str or a tfpf.ID object !" - floats = [Rad,F1,F2,R1,R2,dd] - if any([not oo is None for oo in floats]): - assert all([oo is None or type(oo) in [float,np.float64] for oo in floats]), "Args Rad, F1 and F2 must be floats !" - if not Vess is None: - assert type(Vess) is Ves, "Arg Ves must be a Ves instance !" - if not Exp is None: - assert Exp==Vess.Id.Exp, "Arg Exp must be identical to Ves.Id.Exp !" - if not arrayorder is None: - assert arrayorder in ['C','F'], "Arg arrayorder must be in ['C','F'] !" - if not Type is None: - assert Type in ['Sph'], "Arg Type must be in ['Sph'] !" - bools = [Clock,dtimeIn] - if any([not aa is None for aa in bools]): - assert all([aa is None or type(aa) is bool for aa in bools]), " Args [Clock,dtimeIn] must all be bool !" - if not Exp is None: - assert Exp in tfd.AllowedExp, "Arg Exp must be in "+str(tfd.AllowedExp)+" !" - strs = [Diag,SavePath] - if any([not aa is None for aa in strs]): - assert all([aa is None or type(aa) is str for aa in strs]), "Args [Diag,SavePath] must all be str !" - Ints = [shot] - if any([not aa is None for aa in Ints]): - assert all([aa is None or type(aa) is int for aa in Ints]), "Args [Sino_NP,shot] must be int !" - Iter3 = [O,nIn] - if any([not aa is None for aa in Iter3]): - assert all([aa is None or (hasattr(aa,'__iter__') and np.asarray(aa).shape==(3,)) for aa in Iter3]), "Args [O,nIn] must be an iterable with len()=3 (3D cartesian coordinates) !" - if not dtime is None: - assert type(dtime) is dtm.datetime, "Arg dtime must be a dtm.datetime !" - - - - - - - - - -""" -############################################################################### -############################################################################### - Aperture class and functions -############################################################################### -""" - - -
[docs]class Apert(object): - """ An Aperture class with all geometrical data and built-in methods, defined as a planar polygon in 3D cartesian coordinates, with optional :class:`~tofu.geom.Ves` object - - An Apert object is useful for implementing one of the two possible optical arrangements available in tofu. - An aperture is modelled as a planar polygon (of any non self-intersecting shape) through which light can pass (fully transparent) and around which light cannot pass (fully non-transparent). - One of the added-values of tofu is that it allows to create several non-coplanar aperture and assign them to a single detector. It then computes automatically the volume of sight by assuming that a detectable photon should go through all apertures. - - Parameters - ---------- - Id : str or tfpf.ID - A name string or a pre-built tfpf.ID class to be used to identify this particular instance, if a string is provided, it is fed to tfpf.ID() - Poly : np.ndarray - An array (2,N) or (N,2) defining the contour of the aperture in 3D (X,Y,Z) cartesian coordinates, if not closed, will be closed automatically - Ves : :class:`~tofu.geom.Ves` - :class:`~tofu.geom.Ves` object to which the aperture is assigned - Type : None or str - Flag specifying the type of Apert - Exp : None or str - Experiment to which the Lens belongs, should be identical to Ves.Id.Exp if Ves is provided, if None and Ves is provided, Ves.Id.Exp is used - Diag : None or str - Diagnostic to which the Lens belongs - shot : None or int - Shot number from which this Lens is usable (in case its position was changed from a previous configuration) - SavePath : None / str - If provided, forces the default saving path of the object to the provided value - Clock : bool - Flag indicating whether the input polygon should be made clockwise (True) or counter-clockwise (False) - dtime : None or dtm.datetime - A time reference to be used to identify this particular instance (mostly used for debugging) - dtimeIn : bool - Flag indicating whether dtime should be included in the SaveName (mostly used for debugging) - - """ - - def __init__(self, Id, Poly, Type=None, Ves=None, Exp=None, Diag=None, shot=None, arrayorder='C', Clock=False, SavePath=None, dtime=None, dtimeIn=False): - - self._Done = False - tfpf._check_NotNone({'Clock':Clock,'arrayorder':arrayorder}) - self._check_inputs(Clock=Clock, arrayorder=arrayorder) - self._arrayorder = arrayorder - self._Clock = Clock - - if not Ves is None: - Exp = Exp if not Exp is None else Ves.Id.Exp - assert Exp==Ves.Id.Exp, "Arg Exp must be identical to the Ves.Id.Exp !" - - self._set_Id(Id, Type=Type, Exp=Exp, Diag=Diag, shot=shot, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - self._set_Poly(Poly) - self._set_Ves(Ves) - self._set_arrayorder(arrayorder) - self._Done = True - - @property - def Id(self): - """ Return the associated tfpf.ID object """ - return self._Id - @property - def Poly(self): - """ Return the planar polygon defining the aperture (in 3D cartesian coordinates) """ - return self._Poly - @property - def NP(self): - """ Return the number of points defining the polygon """ - return self._NP - @property - def nIn(self): - """ Return the normalized vector perpendicular to the polygon surface and oriented towards the interior of the associated vessel (in 3D cartesian coordinates) """ - return self._nIn - @property - def BaryS(self): - """ Return the (surfacic) center of mass of the polygon (in 3D cartesian coordinates) """ - return self._BaryS - @property - def Surf(self): - """ Return the area of the polygon """ - return self._Surf - @property - def Rad(self): - return self._Rad - @property - def F1(self): - return None - @property - def Ves(self): - """ Return the associated :class:`~tofu.geom.Ves` object """ - return self._Ves - - def _check_inputs(self, Id=None, Poly=None, Type=None, Ves=None, Exp=None, Diag=None, shot=None, arrayorder=None, Clock=None, SavePath=None, dtime=None, dtimeIn=None): - _Apert_check_inputs(Id=Id, Poly=Poly, Type=Type, Vess=Ves, Exp=Exp, Diag=Diag, shot=shot, arrayorder=arrayorder, Clock=Clock, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - - - def _set_Id(self, Val, Type=None, Exp=None, Diag=None, shot=None, dtime=None, dtimeIn=False, SavePath=None): - if self._Done: - Out = tfpf._get_FromItself(self.Id, {'Type':Type, 'Exp':Exp, 'shot':shot, 'Diag':Diag, 'dtime':dtime, '_dtimeIn':dtimeIn, 'SavePath':SavePath}) - Type, Exp, shot, Diag, dtime, dtimeIn, SavePath = Out['Type'], Out['Exp'], Out['shot'], Out['Diag'], Out['dtime'], Out['dtimeIn'], Out['SavePath'] - tfpf._check_NotNone({'Id':Val}) - self._check_inputs(Id=Val) - if type(Val) is str: - tfpf._check_NotNone({'Exp':Exp, 'shot':shot, 'Diag':Diag, 'dtimeIn':dtimeIn}) - self._check_inputs(Type=Type, Exp=Exp, shot=shot, Diag=Diag, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - Val = tfpf.ID('Apert', Val, Type=Type, Exp=Exp, Diag=Diag, shot=shot, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - self._Id = Val - - def _set_arrayorder(self, arrayorder): - tfpf._set_arrayorder(self, arrayorder) - - def _set_Poly(self, Poly): - tfpf._check_NotNone({'Poly':Poly}) - self._check_inputs(Poly=Poly) - self._Poly, self._NP, self._nIn, self._BaryP, self._Surf, self._BaryS, self._Rad = _tfg_c._ApDetect_set_Poly(Poly, self._arrayorder, Clock=self._Clock) - assert self._Surf>0., "Input Poly has 0 area !" - - def _set_Ves(self, Ves=None): - tfpf._check_NotNone({'Ves':Ves, 'Exp':self.Id.Exp}) - self._check_inputs(Ves=Ves, Exp=self.Id.Exp) - if not Ves is None: - self.Id.set_LObj([Ves.Id]) - if Ves.Type=='Tor': - self._nIn = _tfg_c.Calc_nInFromTor_Poly(self.BaryS, self.nIn, Ves.BaryS) - elif Ves.Type=='Lin': - self._nIn = _tfg_c.Calc_nInFromLin_Poly(self.BaryS, self.nIn, Ves.BaryS) - self._Ves = Ves - - -
[docs] def plot(self, Lax=None, Proj='All', Elt='PV', EltVes='', Leg=None, LVIn=tfd.ApLVin, Pdict=tfd.ApPd, Vdict=tfd.ApVd, - Vesdict=tfd.Vesdict, LegDict=tfd.TorLegd, draw=True, a4=False, Test=True): - """ Plot the Apert, with a cross-section view, a horizontal view or both, or a 3d view, and optionally the :class:`~tofu.geom.Ves` object associated to it. - - Plot the desired projections of the polygon defining the aperture. - - Parameters - ---------- - Lax list or plt.Axes - The axes to be used for plotting (provide a list of 2 axes if Proj='All'), if None a new figure with axes is created - Proj str - Flag specifying the kind of projection used for the plot ('Cross' for a cross-section, 'Hor' for a horizontal plane, 'All' both and '3d' for 3d) - Elt str - Flag specifying which elements to plot, each capital letter corresponds to an element - * 'P': polygon - * 'V': vector perpendicular to the polygon, oriented towards the interior of the Vessel - EltVes str - Flag specifying the elements of the Vessel to be plotted, fed to :meth:`~tofu.geom.Ves.plot` - Leg str - Legend to be used to identify this LOS, if Leg='' the LOS name is used - LVIn float - Length (in data coordinates, meters) of the vector 'V' - Pdict dict - Dictionary of properties used for plotting the polygon, fed to plt.Axes.plot() or plt.plot_surface() if Proj='3d', set to ToFu_Defauts.py if None - Vdict dict - Dictionary of properties used for plotting vector 'V', fed to plt.Axes.plot() - Vesdict dict - Dictionary of kwdargs to fed to :meth:`~tofu.geom.Ves.plot`, and 'EltVes' is used instead of 'Elt' - LegDict dict or None - Dictionary of properties used for plotting the legend, fed to plt.legend(), the legend is not plotted if None - draw bool - Flag indicating whether the fig.canvas.draw() shall be called automatically - a4 bool - Flag indicating whether the figure should be a4 size (for printing or saving as pdf for example) - Test bool - Flag indicating whether the inputs should be tested for conformity - - Returns - ------- - La list or plt.Axes - Handles of the axes used for plotting (list if several axes where used) - - """ - return _tfg_p.LApert_plot(self, Lax=Lax, Proj=Proj, Elt=Elt, EltVes=EltVes, Leg=Leg, LVIn=LVIn, Pdict=Pdict, Vdict=Vdict, Vesdict=Vesdict, LegDict=LegDict, draw=draw, a4=a4, Test=Test)
- - -
[docs] def save(self,SaveName=None,Path=None,Mode='npz', compressed=False): - """ Save the object in folder Name, under file name SaveName, using specified mode - - Most tofu objects can be saved automatically as numpy arrays (.npz, recommended) at the default location (recommended) by simply calling self.save() - - Parameters - ---------- - SaveName : None / str - The name to be used for the saved file, if None (recommended) uses self.Id.SaveName - Path : None / str - Path specifying where to save the file, if None (recommended) uses self.Id.SavePath - Mode : str - Flag specifying whether to save the object as a numpy array file ('.npz', recommended) or an object using cPickle (not recommended, heavier and may cause retro-compatibility issues) - compressed : bool - Flag, used when Mode='npz', indicating whether to use np.savez or np.savez_compressed (slower saving and loading but smaller files) - - """ - tfpf.Save_Generic(self, SaveName=SaveName, Path=Path, Mode=Mode, compressed=compressed)
- - - -def _Apert_check_inputs(Id=None, Poly=None, Type=None, Vess=None, Exp=None, Diag=None, shot=None, arrayorder=None, Clock=None, SavePath=None, dtime=None, dtimeIn=None): - if not Id is None: - assert type(Id) in [str,tfpf.ID], "Arg Id must be a str or a tfpf.ID object !" - if not Poly is None: - assert hasattr(Poly,'__getitem__') and np.asarray(Poly).ndim==2 and 3 in np.asarray(Poly).shape, "Arg Poly must be a dict or an iterable with 3D cartesian coordinates of points !" - if not Vess is None: - assert type(Vess) is Ves, "Arg Ves must be a Ves instance !" - if not Exp is None: - assert Exp==Vess.Id.Exp, "Arg Exp must be the same as the Ves.Id.Exp !" - if not arrayorder is None: - assert arrayorder in ['C','F'], "Arg arrayorder must be in ['C','F'] !" - bools = [Clock,dtimeIn] - if any([not aa is None for aa in bools]): - assert all([aa is None or type(aa) is bool for aa in bools]), " Args [CalcEtend,CalcSpanImp,CalcCone,CalcPreComp,Calc,Verb,Clock,dtimeIn] must all be bool !" - if not Exp is None: - assert Exp in tfd.AllowedExp, "Arg Exp must be in "+str(tfd.AllowedExp)+" !" - assert Type is None, "Arg Type must be None for Apert objects !" - strs = [Diag,SavePath] - if any([not aa is None for aa in strs]): - assert all([aa is None or type(aa) is str for aa in strs]), "Args [Type,Exp,Diag,SavePath] must all be str !" - if not shot is None: - assert type(shot) is int, "Arg shot must be a int !" - if not dtime is None: - assert type(dtime) is dtm.datetime, "Arg dtime must be a dtm.datetime !" - - - - -""" -############################################################################### -############################################################################### - Detector and GDetect classes and functions -############################################################################### -""" - - - - -
[docs]class Detect(object): - """ A Detector class with all geometrical data and built-in methods, defined as a planar polygon in 3D cartesian coordinates, with optional aperture objects - - A Detect object is at the core of tofu's added value and is mostly defined by a 3D planar polygon of any non self-intersecting shape representing the active surface of a detector. - It can then be associated to optics (a :class:`Lens` or a list of :class:`Apert` objects) and to a :class:`~tofu.geom.Ves` to automatically compute a natural :class:'LOS' (with its etendue) and, most importantly, a proper VOS (that can be discretized for 3D numerical integration). - It can be 2 different types: either 'Circ' if it is associated to a :class:`Lens` (in which case it is simply defined by radius and is assumed to be circular and placed at the focal plane of the :class:`Lens` object), or None in the more general case in which it is associated to a set of apertures. - Most of the commonly used quantities are automatically calculated (etendue of the LOS, VOS...) and it comes with built-in methods for plotting and computing synthetic data. - - To compute the VOS, tofu tests all points inside a 3D grid to see if each point is visible from the detector through the apertures or not. - The meshed space is determined by the volume spanned by a LOS sampling of the VOS. - Then, a contour function is used to find the polygons limiting the cross-section and horizontal projections of the VOS. - Once computed, the viewing cones are assigned to attributes of the Detect instance. - - In the particular case (1) when the LOS of the detector lies entirely inside one cross-section (e.g.: tomography diagnostics), tofu also computes the integral in the direction of the ignorable coordinate of the solid angle on a regular mesh (for faster computation of the geometry assuming toroidaly invariant basis functions). - This regular mesh is defined in 2D, by the distance between a mesh point and the detector (k) and by the poloidal angle between the LOS and the line going from the detector to the mesh point (psi) - - - Parameters - ---------- - Id : str or tfpf.ID - A name string or a pre-built tfpf.ID class to be used to identify this particular instance, if a string is provided, it is fed to tfpf.ID() - Poly : dict or np.ndarray - Contains the information regarding the geometry of the Detect object - * np.ndarray: (2,N) or (N,2) defining the contour of the detector active surface in 3D (X,Y,Z) cartesian coordinates, if not closed, will be closed automatically, if Type=None - * dict: dictionary of properties for a circular detector placed in the focal plane of a Lens on its axis, contains field 'Rad'=float (radius), if Optics is Lens and Type='Circ' - Optics : list or Lens - The optics to be associated to the detector, either a spherical :class:`~tofu.geom.Lens` or a list of apertures :class:`~tofu.geom.Apert` - Ves : :class:`~tofu.geom.Ves` or None - :class:`~tofu.geom.Ves` object to which the detector is assigned - Sino_RefPt : np.ndarray or None - Array of size=2 containing the (R,Z) (for 'Tor' Type) or (Y,Z) (for 'Lin' Type) coordinates of the reference point for the sinogram - CalcEtend : bool - Flag indicating whether to compute the etendue - CalcSpanImp : bool - Flag indicating whether to compute the maximal span of the viewing volume - CalcCone : bool - Flag indicating whether to compute the viewing volume or viewing cone and its two projections - CalcPreComp : bool - Flag indicating whether to pre-compute a set of pre-defined points inside the viewing volume for faster computation of signal from 3D emissivity - Calc : bool - Flag indicating whether to compute all the above - Verb : bool - Flag indicating whether the creation of the object should be verbose (comments for each step) - - Etend_Method : str - Flag indicating which numerical integration to use for the computation of the etendue (picked from scipy.integrate : 'quad', 'simps', 'trapz') - Etend_RelErr : float - If Etend_Method='quad', specifies the maximum relative error to be tolerated on the value of the integral (i.e.: etendue) - Etend_dX12 : list - If Etend_Method in ['simps','trapz'], which implies a discretization of the plane perpendicular to the LOS, specifies the resolution of the discretization - Etend_dX12Mode : str - If Etend_Method in ['simps','trapz'], specifies whether Etend_dX12 should be iunderstood as an absolute distance ('abs') or a fraction of the maximum width ('rel') - Etend_Ratio : float - The numerical integration is performed on an automatically-deterimned interval, this ratio (fraction of unity) is a safety margin to increase a bit the interval and make sure all non-zero values are included - Colis : bool - Flag indicating whether the collision detection mechanism should be considered when computing the VOS - LOSRef : str - Key indicating which of the :class:`~tofu.geom.LOS` in the LOS dictionary should be considered as the reference LOS - Cone_DRY : float - Resolution of the grid in the R (for 'Tor' vessel types) or Y (for 'Lin' vessel types) direction, in meters - Cone_DXTheta : float - Resolution of the grid in the toroidal (for 'Tor' vessel types, in radians) or X (for 'Lin' vessel types, in meters) direction - Cone_DZ : float - Resolution of the grid in the Z direction, in meters - Cone_NPsi : int - Number of points of the regular mesh in psi direction (angle), in case (1) - Cone_Nk : bool - Flag indicating whether the inputs should be tested for conformity - - Type : None / str - If the detector is associated to a :class:`~tofu.geom.Lens`, it should be of type 'Circ' (only circular shaped detectors are handled by tofu behind spherical lenses) - Exp : None or str - Experiment to which the Lens belongs, should be identical to Ves.Id.Exp if Ves is provided, if None and Ves is provided, Ves.Id.Exp is used - Diag : None or str - Diagnostic to which the Lens belongs - shot : None or int - Shot number from which this Lens is usable (in case its position was changed from a previous configuration) - SavePath : None / str - If provided, forces the default saving path of the object to the provided value - Clock : bool - Flag indicating whether the input polygon should be made clockwise (True) or counter-clockwise (False), default: False - arrayorder : str - Flag indicating whether the attributes of type=np.ndarray (e.g.: Poly) should be made C-contiguous ('C') or Fortran-contiguous ('F'), default: 'C' - dtime : None or dtm.datetime - A time reference to be used to identify this particular instance (used for debugging mostly) - dtimeIn : bool - Flag indicating whether dtime should be included in the SaveName (used for debugging mostly) - - """ - - def __init__(self, Id, Poly, Optics=None, Ves=None, Sino_RefPt=None, CalcEtend=True, CalcSpanImp=True, CalcCone=True, CalcPreComp=True, Calc=True, Verb=True, - Etend_Method=tfd.DetEtendMethod, Etend_RelErr=tfd.DetEtendepsrel, Etend_dX12=tfd.DetEtenddX12, Etend_dX12Mode=tfd.DetEtenddX12Mode, Etend_Ratio=tfd.DetEtendRatio, Colis=True, LOSRef='Cart', - Cone_DRY=tfd.DetConeDRY, Cone_DXTheta=None, Cone_DZ=tfd.DetConeDZ, Cone_NPsi=20, Cone_Nk=60, - arrayorder='C', Clock=False, Type=None, Exp=None, Diag=None, shot=None, dtime=None, dtimeIn=False, SavePath=None): - - self._Done = False - tfpf._check_NotNone({'Clock':Clock,'arrayorder':arrayorder}) - self._check_inputs(Clock=Clock, arrayorder=arrayorder) - self._arrayorder = arrayorder - self._Clock = Clock - - # Check consistency of Type, Exp, Diag, shot - self._check_inputs(Poly=Poly, Type=Type, Exp=Exp, Diag=Diag, shot=shot, Ves=Ves, Optics=Optics) - Poly, Type, Exp, Diag, shot, Ves = _Detect_set_Defaults(Poly, Type=Type, Exp=Exp, Diag=Diag, shot=shot, Ves=Ves, Optics=Optics) - - # Run all computation routines - self._set_Id(Id, Type=Type, Exp=Exp, Diag=Diag, shot=shot, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - if Verb: - print "TFG.Detect object "+self.Id.Name+" : Creating..." - self._set_Poly(Poly, Calc=False) - self._initAll() - self._set_Optics(Optics, Calc=False) - self._set_Ves(Ves, Calc=False) - self._set_arrayorder(arrayorder) - if Calc: - self._calc_All(Sino_RefPt=Sino_RefPt, CalcEtend=CalcEtend, CalcSpanImp=CalcSpanImp, CalcCone=CalcCone, CalcPreComp=CalcPreComp, Verb=Verb, - Etend_Method=Etend_Method, Etend_RelErr=Etend_RelErr, Etend_dX12=Etend_dX12, Etend_dX12Mode=Etend_dX12Mode, Etend_Ratio=Etend_Ratio, LOSRef=LOSRef, - Cone_DRY=Cone_DRY, Cone_DXTheta=Cone_DXTheta, Cone_DZ=Cone_DZ, - Cone_NPsi=Cone_NPsi, Cone_Nk=Cone_Nk, Colis=Colis) - - if Verb: - print "TFG.Detect object "+self.Id.Name+" : Created !" - self._Done = True - - - - @property - def Id(self): - """ Return the associated tfpf.ID object """ - return self._Id - @property - def Poly(self): - """ Return the planar polygon defining the aperture (in 3D cartesian coordinates) """ - if self.Id.Type=='Circ': - NP = self.NP - thet = np.linspace(0.,2.*np.pi,NP) - e1 = np.array([-self.nIn[1],self.nIn[0],0.]) - e1 = e1/np.linalg.norm(e1) - e2 = np.cross(self.nIn,e1) - Poly = np.tile(self.BaryS,(NP,1)).T + self.Rad*np.array([np.cos(thet)*e1[0]+np.sin(thet)*e2[0], np.cos(thet)*e1[1]+np.sin(thet)*e2[1], np.cos(thet)*e1[2]+np.sin(thet)*e2[2]]) - Poly = np.ascontiguousarray(Poly) if self._arrayorder=='C' else np.asfortranarray(Poly) - return Poly - else: - return self._Poly - @property - def Rad(self): - """ Return the radius of the polygon (if Type='Circ', else None) """ - return self._Rad - @property - def NP(self): - """ Return the number of points defining the polygon """ - return self._NP - @property - def nIn(self): - """ Return the normalized vector perpendicular to the polygon surface and oriented towards the interior of the associated vessel (in 3D cartesian coordinates) """ - return self._nIn - @property - def BaryS(self): - """ Return the (surfacic) center of mass of the polygon (in 3D cartesian coordinates) """ - return self._BaryS - @property - def Surf(self): - """ Return the area of the polygon """ - return self._Surf - @property - def Ves(self): - """ Return the associated :class:`~tofu.geom.Ves` object """ - return self._Ves - @property - def Optics(self): - """ Return the list of associated Optics objects (:class:`Lens` or list of :class:`Apert`) """ - return self._Optics - @property - def OpticsNb(self): - """ Return the number of associated Optics """ - return self._OpticsNb - @property - def OpticsType(self): - """ Return the type of associated Optics objects """ - return self._OpticsType - @property - def LOS(self): - """ Return the dictionary of associated :class:`LOS` objects """ - return self._LOS - @property - def Sino_RefPt(self): - """ Return the coordinates (R,Z) or (Y,Z) for Ves of Type 'Tor' or (Y,Z) for Ves of Type 'Lin' of the reference point used to compute the sinogram """ - return self._Sino_RefPt - @property - def Cone_PolyCross(self): - """ Return the polygon that is the projection in a cross-section of the viewing cone """ - return self._Cone_PolyCrossbis - @property - def Cone_PolyHor(self): - """ Return the polygon that is the projection in a horizontal plane of the viewing cone """ - return self._Cone_PolyHorbis - @property - def SAngCross_Points(self): - """ Return the pre-computed points of the VOS in a cross-section projection """ - return self._SAngCross_Points - @property - def SAngCross_Int(self): - """ Return the integral of the solid angle at pre-computed points of the VOS in a cross-section projection """ - return self._SAngCross_Int - @property - def SAngHor_Points(self): - """ Return the pre-computed points of the VOS in a horizontal projection """ - return self._SAngHor_Points - @property - def SAngHor_Int(self): - """ Return the integral of the solid angle at pre-computed points of the VOS in a horizontal projection """ - return self._SAngHor_Int - - - def _check_inputs(self, Id=None, Poly=None, Type=None, Optics=None, Ves=None, Sino_RefPt=None, Exp=None, Diag=None, shot=None, CalcEtend=None, CalcSpanImp=None, CalcCone=None, CalcPreComp=None, Calc=None, Verb=None, - Etend_RelErr=None, Etend_dX12=None, Etend_dX12Mode=None, Etend_Ratio=None, Colis=None, LOSRef=None, Etend_Method=None, - MarginRMin=None, NEdge=None, NRad=None, Nk=None, - Cone_DRY=None, Cone_DXTheta=None, Cone_DZ=None, Cone_NPsi=None, Cone_Nk=None, - arrayorder=None, Clock=None, SavePath=None, dtime=None, dtimeIn=None): - _Detect_check_inputs(Id=Id, Poly=Poly, Type=Type, Optics=Optics, Vess=Ves, Sino_RefPt=Sino_RefPt, CalcEtend=CalcEtend, CalcSpanImp=CalcSpanImp, CalcCone=CalcCone, CalcPreComp=CalcPreComp, Calc=Calc, Verb=Verb, - Etend_RelErr=Etend_RelErr, Etend_dX12=Etend_dX12, Etend_dX12Mode=Etend_dX12Mode, Etend_Ratio=Etend_Ratio, Colis=Colis, LOSRef=LOSRef, Etend_Method=Etend_Method, - MarginRMin=MarginRMin, NEdge=NEdge, NRad=NRad, Nk=Nk, - Cone_DRY=Cone_DRY, Cone_DXTheta=Cone_DXTheta, Cone_DZ=Cone_DZ, Cone_NPsi=Cone_NPsi, Cone_Nk=Cone_Nk, - arrayorder=arrayorder, Clock=Clock, Exp=Exp, Diag=Diag, shot=shot, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - - def _set_Id(self, Val, Type=None, Exp=None, Diag=None, shot=None, dtime=None, dtimeIn=False, SavePath=None): - if self._Done: - Out = tfpf._get_FromItself(self.Id, {'Type':Type, 'Exp':Exp, 'shot':shot, 'Diag':Diag, 'dtime':dtime, '_dtimeIn':dtimeIn, 'SavePath':SavePath}) - Type, Exp, shot, Diag, dtime, dtimeIn, SavePath = Out['Type'], Out['Exp'], Out['shot'], Out['Diag'], Out['dtime'], Out['dtimeIn'], Out['SavePath'] - tfpf._check_NotNone({'Id':Val}) - self._check_inputs(Id=Val) - if type(Val) is str: - tfpf._check_NotNone({'Exp':Exp, 'shot':shot, 'Diag':Diag, 'dtimeIn':dtimeIn}) - self._check_inputs(Type=Type, Exp=Exp, shot=shot, Diag=Diag, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - Val = tfpf.ID('Detect', Val, Type=Type, Exp=Exp, Diag=Diag, shot=shot, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - self._Id = Val - - def _set_Poly(self, Poly, Calc=True, CalcEtend=True, CalcSpanImp=True, CalcCone=True, CalcPreComp=True, NPDef=100): - tfpf._check_NotNone({'Poly':Poly}) - if self._Done and self.OpticsType=='Lens': - self._check_inputs(Poly=Poly, Optics=self.Optics[0], Calc=Calc, CalcEtend=CalcEtend, CalcSpanImp=CalcSpanImp, CalcCone=CalcCone, CalcPreComp=CalcPreComp) - else: - self._check_inputs(Poly=Poly, Calc=Calc, CalcEtend=CalcEtend, CalcSpanImp=CalcSpanImp, CalcCone=CalcCone, CalcPreComp=CalcPreComp) - self._Poly, self._NP, self._nIn, self._BaryP, self._Surf, self._BaryS, self._Rad = _tfg_c._ApDetect_set_Poly(Poly, Type=self.Id.Type, arrayorder=self._arrayorder, Clock=self._Clock, NP=NPDef) - assert self._Surf>0., "Input Poly has 0 area !" - if Calc: - self._calc_All(CalcEtend=CalcEtend, CalcSpanImp=CalcSpanImp, CalcCone=CalcCone, CalcPreComp=CalcPreComp) - - def _initAll(self): - self._Ves = None - self._Optics, self._nOptics = None, 0 - self._SAngPlane = None - self._LOS_ApertPolyInt, self._LOS_ApertPolyInt_S, self._LOS_ApertPolyInt_BaryS, self._LOS, self._TorAngRef, self._LOS_NP = None, None, None, None, None, None - self._Sino_RefPt, self._Sino_CrossProj, self._LOSRef = None, None, None - self._Span_R, self._Span_Theta, self._Span_X, self._Span_Y, self._Span_Z, self._Span_k, self._Span_NEdge, self._Span_NRad = None, None, None, None, None, None, None, None - self._Cone_PolyCross, self._Cone_PolyHor, self._Cone_PolyCrossbis, self._Cone_PolyHorbis = None, None, None, None - self._Cone_Poly_DR, self._Cone_Poly_DZ, self._Cone_Poly_DTheta, self._Cone_Poly_NEdge, self._Cone_Poly_NRad = None, None, None, None, None - self._Cone_PolyCross_RefLCorners, self._Cone_PolyCross_RefLBary, self._Cone_PolyCross_RefdMax = None, None, None - self._Cone_PolyHor_RefLCorners, self._Cone_PolyHor_RefLBary, self._Cone_PolyHor_RefdMax = None, None, None - self._SAngCross_Points, self._SAngHor_Points, self._SAngCross_Max, self._SAngHor_Max, self._SAngCross_Int, self._SAngHor_Int = None, None, None, None, None, None - self._SAngCross_Reg, self._SAngCross_Reg_K, self._SAngCross_Reg_Psi, self._SAngCross_Reg_Int = False, None, None, None - # Parameters of Synthetic diagnostics - self._SynthDiag_Done = False - self._SynthDiag_ds, self._SynthDiag_dsMode, self._SynthDiag_MarginS, self._SynthDiag_dX12, self._SynthDiag_dX12Mode, self._SynthDiag_Colis = None, None, None, None, None, None - self._reset_SynthDiag() - # Parameters of Resolution computing - self._reset_Res() - - def _set_Optics(self, Optics=None, Calc=True, CalcEtend=True, CalcSpanImp=True, CalcCone=True, CalcPreComp=True): - Polytemp = {'Rad':self.Rad} if self.Id.Type=='Circ' else self.Poly - self._check_inputs(Poly=Polytemp, Optics=Optics, Calc=Calc, CalcEtend=CalcEtend, CalcSpanImp=CalcSpanImp, CalcCone=CalcCone, CalcPreComp=CalcPreComp) - if not Optics is None: - Optics = Optics if type(Optics) is list else [Optics] - self._Optics = Optics - self._OpticsNb = len(Optics) - self._OpticsType = "Lens" if type(Optics[0]) is Lens else "Apert" - self.Id.set_LObj([aa.Id for aa in Optics]) - self._set_Optics_Lens_Cone() - if Calc: - self._calc_All(CalcEtend=CalcEtend, CalcSpanImp=CalcSpanImp, CalcCone=CalcCone, CalcPreComp=CalcPreComp) - - def _set_Optics_Lens_Cone(self): - if self.OpticsType == "Lens": - self._Optics_Lens_ConeHalfAng = np.arctan2(self.Rad,self.Optics[0].F1) - self._Optics_Lens_ConeTip = self.Optics[0].O - self.Optics[0].nIn * self.Optics[0].Rad * self.Optics[0].F1 / self.Rad - else: - self._Optics_Lens_ConeTip = None - self._Optics_Lens_ConeHalfAng = None - - - def _set_Ves(self, Ves, Calc=True, CalcEtend=True, CalcSpanImp=True, CalcCone=True, CalcPreComp=True): - self._check_inputs(Ves=Ves, Calc=Calc, CalcEtend=CalcEtend, CalcSpanImp=CalcSpanImp, CalcCone=CalcCone, CalcPreComp=CalcPreComp) - if not Ves is None: - self._Ves = Ves - self.Id.set_LObj([Ves.Id]) - if Ves.Type=='Tor': - self._nIn = _tfg_c.Calc_nInFromTor_Poly(self.BaryS, self.nIn, Ves.BaryS) - elif Ves.Type=='Lin': - self._nIn = _tfg_c.Calc_nInFromLin_Poly(self.BaryS, self.nIn, Ves.BaryS) - if Calc: - self._calc_All(CalcEtend=CalcEtend, CalcSpanImp=CalcSpanImp, CalcCone=CalcCone, CalcPreComp=CalcPreComp) - - def _set_arrayorder(self, arrayorder): - tfpf._set_arrayorder(self, arrayorder) - - def _calc_All(self, Sino_RefPt=None, CalcEtend=True, CalcSpanImp=True, CalcCone=True, CalcPreComp=True, - Etend_Method=tfd.DetEtendMethod, Etend_RelErr=tfd.DetEtendepsrel, Etend_dX12=tfd.DetEtenddX12, Etend_dX12Mode=tfd.DetEtenddX12Mode, Etend_Ratio=tfd.DetEtendRatio, Colis=tfd.DetCalcEtendColis, LOSRef='Cart', - Cone_DRY=tfd.DetConeDRY, Cone_DXTheta=None, Cone_DZ=tfd.DetConeDZ, Cone_NPsi=20, Cone_Nk=60, Verb=True): - - self._check_inputs(Sino_RefPt=Sino_RefPt, CalcEtend=CalcEtend, CalcSpanImp=CalcSpanImp, CalcCone=CalcCone, CalcPreComp=CalcPreComp, - Etend_Method=Etend_Method, Etend_RelErr=Etend_RelErr, Etend_dX12=Etend_dX12, Etend_dX12Mode=Etend_dX12Mode, Etend_Ratio=Etend_Ratio, LOSRef=LOSRef, - Cone_DRY=Cone_DRY, Cone_DXTheta=Cone_DXTheta, Cone_DZ=Cone_DZ, Cone_NPsi=Cone_NPsi, Cone_Nk=Cone_Nk, Colis=Colis) - - assert self.OpticsNb>0 and not self.Ves is None, "Calculation of [LOS, Etendue, Span and Cone] not possible without Optics and Ves !" - self._set_SAngPnPe1e2() - self._set_LOS(CalcEtend=CalcEtend, Method=Etend_Method, RelErr=Etend_RelErr, dX12=Etend_dX12, dX12Mode=Etend_dX12Mode, Ratio=Etend_Ratio, Colis=Colis, LOSRef=LOSRef, Verb=Verb) - self._set_SinoSpan(CalcSpanImp=CalcSpanImp, Sino_RefPt=Sino_RefPt) - self._set_ConeWidthAlongLOS() - self._set_ConePoly(CalcCone=CalcCone, DRY=Cone_DRY, DXTheta=Cone_DXTheta, DZ=Cone_DZ, NPsi=Cone_NPsi, Nk=Cone_Nk) - self.set_SigPrecomp(CalcPreComp=CalcPreComp) - - def _set_SAngPnPe1e2(self): - if not self.Optics is None: - #sca = np.array([np.sum((aa.BaryS-self.BaryS)*self.nIn) for aa in self.LApert]) - sca = np.array([aa.Surf for aa in self.Optics]) - ind = np.argmax(sca) - e1, e2 = _tfg_gg.Calc_DefaultCheck_e1e2_PLane_1D(self.Optics[ind].BaryS, self.Optics[ind].nIn) - self._SAngPlane = (self.Optics[ind].BaryS, self.Optics[ind].nIn, e1, e2) - - def _set_LOS(self, CalcEtend=True, Method=tfd.DetEtendMethod, RelErr=tfd.DetEtendepsrel, dX12=tfd.DetEtenddX12, dX12Mode=tfd.DetEtenddX12Mode, Ratio=tfd.DetEtendRatio, Colis=tfd.DetCalcEtendColis, LOSRef='Cart', Verb=True): - self._check_inputs(CalcEtend=CalcEtend, Etend_Method=Method, Etend_RelErr=RelErr, Etend_dX12=dX12, Etend_dX12Mode=dX12Mode, Etend_Ratio=Ratio, Colis=Colis, LOSRef=LOSRef, Verb=Verb) - if not (self.Ves is None or self.Optics is None): - #try: - self._LOS_ApertPolyInt, self._LOS_ApertPolyInt_S, self._LOS_ApertPolyInt_BaryS, du = _tfg_c._Detect_set_LOS(self.Id.Name, [oo.Surf for oo in self.Optics], [oo.BaryS for oo in self.Optics], - [oo.nIn for oo in self.Optics], [oo.Poly for oo in self.Optics], self.BaryS, self.Poly, OpType=self.OpticsType, Verb=Verb, Test=True) - LOSCart = LOS(self.Id.Name+"_Cart", (self.BaryS,du), Ves=self.Ves, Exp=self.Id.Exp, Diag=self.Id.Diag, shot=self.Id.shot, - dtime=self.Id.dtime, dtimeIn=self.Id._dtimeIn, SavePath=self.Id.SavePath) - PRef = (LOSCart.POut+LOSCart.PIn)/2. - self._LOS = {'Cart':{'LOS':LOSCart,'PRef':PRef}} - self._LOSRef = LOSRef - if CalcEtend: - self._set_Etendue(Method=Method, RelErr=RelErr, dX12=dX12, dX12Mode=dX12Mode, Ratio=Ratio, Colis=Colis) - #except: - # self._LOS = "Impossible !" - else: - self._LOS = "Impossible !" - - def _set_Etendue(self, Method=tfd.DetEtendMethod, RelErr=tfd.DetEtendepsrel, dX12=tfd.DetEtenddX12, dX12Mode=tfd.DetEtenddX12Mode, Ratio=tfd.DetEtendRatio, Colis=tfd.DetCalcEtendColis): # Pb with Lens quad vs trapz ! - self._check_inputs(Etend_Method=Method, Etend_RelErr=RelErr, Etend_dX12=dX12, Etend_dX12Mode=dX12Mode, Etend_Ratio=Ratio, Colis=Colis) - if not self.LOS in ["Impossible !",None]: - print " "+self.Id.Name+" : Computing Entendue..." - LOPolys = [oo.Poly for oo in self.Optics] - LOnIns = [oo.nIn for oo in self.Optics] - LSurfs = [oo.Surf for oo in self.Optics] - LOBaryS = [oo.BaryS for oo in self.Optics] - - for kk in self.LOS.keys(): - self.LOS[kk]['Etend_0Dir'] = self.Surf * _tfg_gg.Calc_SAngVect_LPolys1Point_Flex([self._LOS_ApertPolyInt], self.BaryS, self._SAngPlane[0], self._SAngPlane[1], self._SAngPlane[2], self._SAngPlane[3])[0] - self.LOS[kk]['Etend_0Inv'] = self._LOS_ApertPolyInt_S * _tfg_gg.Calc_SAngVect_LPolys1Point_Flex([self.Poly], self._LOS_ApertPolyInt_BaryS, self.BaryS, self._SAngPlane[1], self._SAngPlane[2], self._SAngPlane[3])[0] - PRef, LOSu = self.LOS[kk]['PRef'], self.LOS[kk]['LOS'].u - e1, e2 = _tfg_gg.Calc_DefaultCheck_e1e2_PLane_1D(PRef, LOSu) - - self.LOS[kk]['Etend'] = _tfg_c.Calc_Etendue_PlaneLOS(PRef.reshape((3,1)), LOSu.reshape((3,1)), - self.Poly, self.BaryS, self.nIn, LOPolys, LOnIns, LSurfs, LOBaryS, self._SAngPlane, - self.Ves.Poly, self.Ves._Vin, DLong=self.Ves.DLong, - Lens_ConeTip = self._Optics_Lens_ConeTip, Lens_ConeHalfAng=self._Optics_Lens_ConeHalfAng, RadL=self.Optics[0].Rad, RadD=self.Rad, F1=self.Optics[0].F1, - OpType=self.OpticsType, VType=self.Ves.Type, Mode=Method, e1=e1.reshape((3,1)), e2=e2.reshape((3,1)), epsrel=RelErr, Ratio=Ratio, dX12=dX12, dX12Mode=dX12Mode, Colis=Colis, Test=True)[0][0] - - self.LOS[kk]['Etend_Method'], self.LOS[kk]['Etend_Ratio'], self.LOS[kk]['Etend_Colis'] = Method, Ratio, Colis - self.LOS[kk]['Etend_RelErr'] = RelErr if Method=='quad' else None - self.LOS[kk]['Etend_dX12'] = None if Method=='quad' else dX12 - self.LOS[kk]['Etend_dX12Mode'] = None if Method=='quad' else dX12Mode - else: - warnings.warn("Detect "+ self.Id.Name +" : calculation of Etendue not possible because LOS impossible !") - - - def _set_SinoSpan(self, Sino_RefPt=None, CalcSpanImp=True, MarginRMin=tfd.DetSpanRMinMargin, NEdge=tfd.DetSpanNEdge, NRad=tfd.DetSpanNRad): - self._check_inputs(Sino_RefPt=Sino_RefPt, CalcSpanImp=CalcSpanImp, MarginRMin=MarginRMin, NEdge=NEdge, NRad=NRad) - if CalcSpanImp and not (self.LOS=='Impossible !' or self.LOS is None): - print " "+self.Id.Name+" : Computing Span and Sinogram..." - if Sino_RefPt is None: - Sino_RefPt = self.Ves.BaryS - Sino_RefPt = np.asarray(Sino_RefPt).flatten() - for kk in self.LOS.keys(): - self.LOS[kk]['LOS']._set_Sino(RefPt=Sino_RefPt) - P, nP, e1, e2 = self._SAngPlane - LOPolys = [oo.Poly for oo in self.Optics] - LOBaryS = [oo.BaryS for oo in self.Optics] - LOSD, LOSu = self.LOS[self._LOSRef]['LOS'].D, self.LOS[self._LOSRef]['LOS'].u - if self.Ves.Type=='Tor': - RMinMax, ThetaMinMax, ZMinMax, kMinMax, Sino_CrossProj, Span_NEdge, Span_NRad = _tfg_c.Calc_SpanImpBoth_2Steps(self.Poly, self.NP, self.BaryS, LOPolys, LOBaryS, LOSD, LOSu, Sino_RefPt, P, nP, - self.Ves.Poly, self.Ves.Vin, DLong=self.Ves.DLong, VType=self.Ves.Type, e1=e1, e2=e2, OpType=self.OpticsType, Lens_ConeTip=self._Optics_Lens_ConeTip, NEdge=NEdge, NRad=NRad, Test=True) - RMinMax[0] = np.max(np.array([MarginRMin*RMinMax[0],self.Ves._P1Min[0]])) - self._Sino_RefPt, self._Span_R, self._Span_Theta, self._Span_Z, self._Span_k = Sino_RefPt, RMinMax, ThetaMinMax, ZMinMax, kMinMax - self._Span_X, self._Span_Y = None, None - elif self.Ves.Type=='Lin': - XMinMax, YMinMax, ZMinMax, kMinMax, Sino_CrossProj, Span_NEdge, Span_NRad = _tfg_c.Calc_SpanImpBoth_2Steps(self.Poly, self.NP, self.BaryS, LOPolys, LOBaryS, LOSD, LOSu, Sino_RefPt, P, nP, - self.Ves.Poly, self.Ves.Vin, DLong=self.Ves.DLong, VType=self.Ves.Type, e1=e1, e2=e2, OpType=self.OpticsType, Lens_ConeTip=self._Optics_Lens_ConeTip, NEdge=NEdge, NRad=NRad, Test=True) - self._Sino_RefPt, self._Span_X, self._Span_Y, self._Span_Z, self._Span_k = Sino_RefPt, XMinMax, YMinMax, ZMinMax, kMinMax - self._Span_R, self._Span_Theta = None, None - self._Sino_CrossProj, self._Span_NEdge, self._Span_NRad = Sino_CrossProj, Span_NEdge, Span_NRad - # Sino_CrossProj = Imp_PolProj - - def _set_ConeWidthAlongLOS(self,Nk=10): - self._check_inputs(Nk=Nk) - if not (self.LOS=='Impossible !' or self.LOS is None or self._Span_k is None): - k = np.linspace(self._Span_k[0],self._Span_k[1],Nk) - P, u = self.LOS[self._LOSRef]['LOS'].D, self.LOS[self._LOSRef]['LOS'].u - e1, e2 = _tfg_gg.Calc_DefaultCheck_e1e2_PLane_1D(P, u) - Ps = np.array([P[0]+k*u[0], P[1]+k*u[1], P[2]+k*u[2]]) - nPs = np.tile(u,(Nk,1)).T - e1s, e2s = np.tile(e1,(Nk,1)).T, np.tile(e2,(Nk,1)).T - LOPolys = [oo.Poly for oo in self.Optics] - if self.OpticsType=='Apert': - LOSurfs = [oo.Surf for oo in self.Optics] - LOnIns = [oo.nIn for oo in self.Optics] - LnPtemp = np.asarray(LOnIns)*np.tile(LOSurfs,(3,1)).T - MinX1, MinX2, MaxX1, MaxX2, e1, e2 = _tfg_c.Calc_ViewConePointsMinMax_PlanesDetectApert_2Steps(self.Poly, LOPolys, LnPtemp, LOSurfs, self.Optics[0].BaryS, Ps, nPs, e1=e1s, e2=e2s, Test=True) - elif self.OpticsType=='Lens': - MinX1, MinX2, MaxX1, MaxX2, e1, e2 = _tfg_c.Calc_ViewConePointsMinMax_PlanesDetectLens(LOPolys[0], self._Optics_Lens_ConeTip, Ps, nPs, e1=e1s, e2=e2s, Test=True) - self._ConeWidth_k = k - self._ConeWidth_X1 = np.array([MinX1,MaxX1]) - self._ConeWidth_X2 = np.array([MinX2,MaxX2]) - self._ConeWidth = np.min(np.array([np.diff(self._ConeWidth_X1,axis=0),np.diff(self._ConeWidth_X2,axis=0)]),axis=0).flatten() - - def _set_Sino(self,RefPt=None): - self._check_inputs(Sino_RefPt=Sino_RefPt) - self._Ves._set_Sino(RefPt) - self._set_SinoSpan(RefPt) - - def _isOnGoodSide(self, Pts, NbPoly=None, Log='all'): - """ Check whether each point is on the inside or the outside of each Detect and Apert (with respect to nIn) """ - return _tfg_c._Detect_isOnGoodSide(Pts, self.BaryS, self.nIn, [oo.BaryS for oo in self.Optics], [oo.nIn for oo in self.Optics], NbPoly=NbPoly, Log=Log) - - def _isInsideConeWidthLim(self, Pts): - """ Check whether each point lies inside the enveloppe of the viewing cone """ - return _tfg_c._Detect_isInsideConeWidthLim(Pts, self.LOS[self._LOSRef]['LOS'].D, self.LOS[self._LOSRef]['LOS'].u, self._ConeWidth_k, self._ConeWidth_X1, self._ConeWidth_X2) - - def _set_ConePoly(self, CalcCone=True, DRY=tfd.DetConeDRY, DXTheta=None, DZ=tfd.DetConeDZ, NPsi=20, Nk=60, Test=True): - """ If CalcCone is True, compute the projections of the VOS, also called viewing cones elsewhere in the documentation - - To compute the VOS, tofu tests all points inside a 3D grid to see if each point is visible from the detector through the apertures or not. - The meshed space is determined by the volume spanned by a LOS sampling of the VOS. - Then, a contour function is used to find the polygons limiting the cross-section and horizontal projections of the VOS. - Once computed, the viewing cones are assigned to attributes of the Detect instance. - - In the particular case (1) when the LOS of the detector lies entirely inside one cross-section (e.g.: tomography diagnostics), tofu also computes the integral in the direction of the ignorable coordinate of the solid angle on a regular mesh (for faster computation of the geometry assuming toroidaly invariant basis functions). - This regular mesh is defined in 2D, by the distance between a mesh point and the detector (k) and by the poloidal angle between the LOS and the line going from the detector to the mesh point (psi) - - Parameters - ---------- - DRY : float - Resolution of the grid in the R (for 'Tor' vessel types) or Y (for 'Lin' vessel types) direction, in meters - DXTheta : float - Resolution of the grid in the toroidal (for 'Tor' vessel types, in radians) or X (for 'Lin' vessel types, in meters) direction - DZ : float - Resolution of the grid in the Z direction, in meters - NPsi : int - Number of points of the regular mesh in psi direction (angle), in case (1) - Nk : int - Number of points of the regular mesh in k direction (distance), in case (1) - Test : bool - Flag indicating whether the inputs should be tested for conformity - - """ - - if CalcCone and not (self.LOS=='Impossible' or self.LOS is None): - print " "+self.Id.Name+" : Computing ConePoly..." - DPoly, DBaryS, DnIn = self.Poly, self.BaryS, self.nIn - LOPolys = [oo.Poly for oo in self.Optics] - LOnIns = [oo.nIn for oo in self.Optics] - LSurfs = [oo.Surf for oo in self.Optics] - LOBaryS = [oo.BaryS for oo in self.Optics] - LOSD, LOSu = self.LOS[self._LOSRef]['LOS'].D, self.LOS[self._LOSRef]['LOS'].u - LOSPIn, LOSPOut = self.LOS[self._LOSRef]['LOS'].PIn, self.LOS[self._LOSRef]['LOS'].POut - - self._SAngCross_Reg, self._SAngCross_Reg_Int, self._SAngCross_Reg_K, self._SAngCross_Reg_Psi, self._SAngCross_Points, self._SAngCross_Max, self._SAngCross_Int, self._SAngHor_Points, self._SAngHor_Max, self._SAngHor_Int, self._Cone_PolyCross, self._Cone_PolyHor, self._Cone_PolyCrossbis, self._Cone_PolyHorbis, self._Cone_Poly_DX, self._Cone_Poly_DY, self._Cone_Poly_DR, self._Cone_Poly_DTheta, self._Cone_Poly_DZ \ - = _tfg_c._Detect_set_ConePoly(DPoly, DBaryS, DnIn, LOPolys, LOnIns, LSurfs, LOBaryS, self._SAngPlane, LOSD, LOSu, LOSPIn, LOSPOut, self._Span_k, - Span_R=self._Span_R, Span_Theta=self._Span_Theta, Span_X=self._Span_X, Span_Y=self._Span_Y, Span_Z=self._Span_Z, - ConeWidth_k=self._ConeWidth_k, ConeWidth_X1=self._ConeWidth_X1, ConeWidth_X2=self._ConeWidth_X2, Lens_ConeTip=self._Optics_Lens_ConeTip, Lens_ConeHalfAng=self._Optics_Lens_ConeHalfAng, - RadD=self.Rad, RadL=self.Optics[0].Rad, F1=self.Optics[0].F1, VPoly=self.Ves.Poly, VVin=self.Ves.Vin, DLong=self.Ves.DLong, - VType=self.Ves.Type, OpType=self.OpticsType, NPsi=NPsi, Nk=Nk, thet=np.linspace(0.,2.*np.pi,DPoly.shape[1]), - DXTheta=DXTheta, DRY=DRY, DZ=DZ, Test=True) - - - def _get_KPsiCrossInt(self,PtsRZ): - """ Computes k and psi for a set of points in cross-section (R,Z) or (Y,Z) coordinates """ - return _tfg_c._Detect_get_KPsiCrossInt(PtsRZ, SAngCross_Reg=self._SAngCross_Reg, LOSPOut=self.LOS['Cart']['LOS'].POut, DBaryS=self.BaryS, VType=self.Ves.Type) - - - -
[docs] def refine_ConePoly(self, dMax=tfd.DetConeRefdMax, Proj='Cross', indPoly=0, Verb=True, Test=True): - """ Reduce the number of points of the selected Cone_Poly projection using the provided maximum distance and checking for convexity - - Provide a built-in method to simplify the 2 projections of the viewing cone (VOS). - In its raw form, the projection of the VOS is a polygon with potentially a high number of points (computed using matplotlib._cntr() function). - A re-sampled version of this polygon is computed by taking its convex hull and checking, for each edge, how far it is from the original edge. - Each edge (2 points) of the convex hull is then compared to the set of original edges it encloses. - If the maximum distance between this convex hull-derived edge and the original set of edges is smaller than dMax, then the convex hull-derived egde is used, otherwise the original edges are preserved. - The method does not return a value, instead it assigns the new polygon to a dedicated attribute of the object, thus ensuring that both the original and the re-sampled projections of the VOS are available. - - Parameters - ---------- - dMax : float - Threshold absolute distance that limits the acceptable discrepancy between the original polygon and its convex hull (checked for each edge of the convex hull) - Proj : str - Flag indicating to which projection of the VOS the method should be applied - indPoly : int - Index of the polygon to be treated (i.e.: in case one projection of the VOS results in a list of several polygons instead of just one polygon as is usually the case) - Verb : bool - Flag indicating whether a one-line comment should be printed at the end of the calculation giving the number of points of the new polygon vs the number of points of the original polygon - Test : bool - Flag indicating whether the inputs should be tested for conformity - - """ - assert Proj in ['Cross','Hor'], "Arg Proj must be in ['Cross','Hor'] !" - assert type(indPoly) is int and indPoly<=max(len(self._Cone_PolyCrossbis),len(self._Cone_PolyHorbis)), "Arg indPoly must be a valid int index !" - Poly = np.copy(self._Cone_PolyCross[indPoly]) if Proj=='Cross' else np.copy(self._Cone_PolyHor[indPoly]) - PP = _tfg_c.Refine_ConePoly_All(Poly, dMax=dMax) - if Proj=='Cross': - self._Cone_PolyCrossbis[indPoly], self._Cone_PolyCross_dMax = PP, dMax - else: - self._Cone_PolyHorbis[indPoly], self._Cone_PolyHor_dMax = PP, dMax - if Verb: - print " "+self.Id.Name+".refine_ConePoly('"+Proj+"') : from ", Poly.shape[1], "to", PP.shape[1], "points"
- -
[docs] def isInside(self, Points, In='(X,Y,Z)', Test=True): - """ Return an array of indices indicating whether each point lies both in the cross-section and horizontal porojections of the viewing cone - - Like for the :class:`~tofu.geom.Ves` object, points can be provided in 2D or 3D coordinates (specified by 'In'), and an array of booleans is returned. - - Parameters - ---------- - Points : np.ndarray - (2,N) or (3,N) array of coordinates of the N points to be tested - In : str - Flag indicating in which coordinate system the Points are provided, must be in ['(R,Z)','(Y,Z)','(X,Y)','(X,Y,Z)','(R,phi,Z)'] - * '(R,Z)': All points are assumed to lie in the horizontal projection, for 'Tor' vessel type only - * '(Y,Z)': All points are assumed to lie in the horizontal projection, for 'Lin' vessel type only - * '(X,Y)': All points are assumed to lie in the cross-section projection - Test : bool - Flag indicating whether the inputs should be tested for conformity - - Returns - ------- - ind : np.ndarray - (N,) array of booleans with True if a point lies inside both projections of the viewing cone - - """ - assert not self.LOS=='Impossible !', "The detected volume is zero !" - TorAngRef = np.arctan2(self.LOS[self._LOSRef]['PRef'][1],self.LOS[self._LOSRef]['PRef'][0]) if self.Ves.Type=='Tor' else None - return _tfg_c._Detect_isInside(self._Cone_PolyCrossbis, self._Cone_PolyHorbis, Points, In=In, VType=self.Ves.Type, TorAngRef=TorAngRef, Test=Test)
- - -
[docs] def calc_SAngVect(self, Pts, In='(X,Y,Z)', Colis=tfd.DetCalcSAngVectColis, Test=True): - """ Return the Solid Angle of the Detect-Apert system as seen from the specified points, including collisions detection or not - - Compute the solid angle and the directing vector subtended by the Detect-Optics system as seen from the desired points (provided in the specified coordinates). - This can be useful for visualizing the solid angle distribution or for computing synthetic signal from simulated emissivity in a 3D numerical integration manner. - The automtic detection of collisions with the edges of the :class:`~tofu.geom.Ves` object can be switched off (not recommended). - - Parameters - ---------- - Pts : np.ndarray - (2,N) or (3,N) array of coordinates of the provided N points - In : str - Flag indicating in which coordinate system the Pts are provided, must be in ['(R,Z)','(X,Y,Z)','(R,phi,Z)'] - Colis : bool - Flag indicating whether collision detection should be activated - Test : bool - Flag indicating whether the inputs should be tested for conformity - - Returns - ------- - SAng : np.ndarray - (N,) array of floats, the computed solid angles - - """ - if Test: - assert isinstance(Pts,np.ndarray) and Pts.ndim==2 and Pts.shape[0] in [2,3], "Arg Pts must be a 2D np.ndarray !" - CrossRef = np.arctan2(self.LOS[self._LOSRef]['PRef'][1],self.LOS[self._LOSRef]['PRef'][0]) if self.Ves.Type=='Tor' else self.LOS[self._LOSRef]['PRef'][0] - Pts = _tfg_gg.CoordShift(Pts, In=In, Out='(X,Y,Z)', CrossRef=CrossRef) - LOPolys = [oo.Poly for oo in self.Optics] - LOnIns = [oo.nIn for oo in self.Optics] - LOBaryS = [oo.BaryS for oo in self.Optics] - return _tfg_c._Detect_SAngVect_Points(Pts, DPoly=self.Poly, DBaryS=self.BaryS, DnIn=self.nIn, LOBaryS=LOBaryS, LOnIns=LOnIns, LOPolys=LOPolys, SAngPlane=self._SAngPlane, Lens_ConeTip=self._Optics_Lens_ConeTip, Lens_ConeHalfAng=self._Optics_Lens_ConeHalfAng, RadL=self.Optics[0].Rad, RadD=self.Rad, F1=self.Optics[0].F1, thet=np.linspace(0.,2.*np.pi,self.NP), OpType=self.OpticsType, VPoly=self.Ves.Poly, VVin=self.Ves.Vin, DLong=self.Ves.DLong, VType=self.Ves.Type, Cone_PolyCrossbis=self._Cone_PolyCrossbis, Cone_PolyHorbis=self._Cone_PolyHorbis, TorAngRef=CrossRef, Colis=Colis, Test=Test)
- - - def _get_SAngIntMax(self, Proj='Cross', SAng='Int'): - """ Get the Int or Max of the SAng in a cross-section or horizontal projection """ - CrossRef = np.arctan2(self.LOS[self._LOSRef]['PRef'][1],self.LOS[self._LOSRef]['PRef'][0]) if self.Ves.Type=='Tor' else self.LOS[self._LOSRef]['PRef'][0] - return _tfg_c._Detect_get_SAngIntMax(SAngCross_Reg=self._SAngCross_Reg, SAngCross_Points=self._SAngCross_Points, SAngCross_Reg_K=self._SAngCross_Reg_K, SAngCross_Reg_Psi=self._SAngCross_Reg_Psi, SAngCross_Reg_Int=self._SAngCross_Reg_Int, SAngCross_Int=self._SAngCross_Int, SAngCross_Max=self._SAngCross_Max, SAngHor_Points=self._SAngHor_Points, SAngHor_Int=self._SAngHor_Int, SAngHor_Max=self._SAngHor_Max, Cone_PolyCrossbis=self._Cone_PolyCrossbis, Cone_PolyHorbis=self._Cone_PolyHorbis, TorAngRef=CrossRef, DBaryS=self.BaryS, LOSPOut=self.LOS[self._LOSRef]['LOS'].POut, Proj=Proj, SAng=SAng, VType=self.Ves.Type) - - - -
[docs] def set_SigPrecomp(self, CalcPreComp=True, dX12=None, dX12Mode=None, ds=None, dsMode=None, MarginS=None, Colis=None): - """ Precompute a 3D grid for fast integration of a 3D emissivity for a synthetic diagnostic approach - - In order to accelerate the computation of synthetic signal from simulated emissivity, it is possible to pre-compute a discretisation of the VOS (mesh points + solid angle) and store it as an attribute of the Detect object. - While such pre-computation does speed-up significantly the numerical integration, it also burdens the object with heavy attributes that can make it too big to save. - Hence, the saving method has a special argument that allows to specify that these pre-computed attributes should not be saved but should instead be re-computed automatically when loading the file. - The parameters dX12, dX12Mode, ds and dsMode give the user control over how fine the discretization of the VOS should be, which affects both the accuracy of the numerical integration and the size of the resulting mesh. - - Parameters - ---------- - CalcPreComp : bool - Flag indicating whether the pre-computation should be run - dX12 : list - Array of the 2 resolutions to be used to define the grid in a plane perpendicular to the LOS - dX12Mode : str - Flag specifying whether the values in dX12 are absolute distances or relative values (i.e. fraction of the total width [0;1]) - ds : float - Float indicating the resolution in the longitudinal direction - dsMode : str - Flag specifying whether ds is an absolute distance or relative (i.e. fraction of the total length [0;1]) - MarginS : float - Float specifying - Colis : bool - Flag indicating whether collision detection should be used - - """ - if CalcPreComp and not (self.LOS=='Impossible !' or self.LOS is None): - print " "+self.Id.Name+" : Pre-computing 3D matrix for synthetic diag..." - - LOPolys = [oo.Poly for oo in self.Optics] - LOBaryS = [oo.BaryS for oo in self.Optics] - LOnIns = [oo.nIn for oo in self.Optics] - LOSD = self.LOS[self._LOSRef]['LOS'].D - LOSu = self.LOS[self._LOSRef]['LOS'].u - thet = np.linspace(0.,2.*np.pi,self.Poly.shape[1]) - CrossRef = np.arctan2(self.LOS[self._LOSRef]['PRef'][1],self.LOS[self._LOSRef]['PRef'][0]) if self.Ves.Type=='Tor' else self.LOS[self._LOSRef]['PRef'][0] - - if self._SynthDiag_Done: - dX12 = tfd.DetSynthdX12 if dX12 is None else self._SynthDiag_dX12 - dX12Mode = tfd.DetSynthdX12Mode if dX12Mode is None else self._SynthDiag_dX12Mode - ds = tfd.DetSynthds if ds is None else self._SynthDiag_ds - dsMode = tfd.DetSynthdsMode if dsMode is None else self._SynthDiag_dsMode - MarginS = tfd.DetSynthMarginS if MarginS is None else self._SynthDiag_MarginS - Colis = tfd.DetCalcSAngVectColis if Colis is None else self._SynthDiag_Colis - else: - dX12 = tfd.DetSynthdX12 if dX12 is None else dX12 - dX12Mode = tfd.DetSynthdX12Mode if dX12Mode is None else dX12Mode - ds = tfd.DetSynthds if ds is None else ds - dsMode = tfd.DetSynthdsMode if dsMode is None else dsMode - MarginS = tfd.DetSynthMarginS if MarginS is None else MarginS - Colis = tfd.DetCalcSAngVectColis if Colis is None else Colis - - Out = _tfg_c._Detect_set_SigPrecomp(self.Poly, self.BaryS, self.nIn, LOPolys, LOBaryS, LOnIns, self._SAngPlane, LOSD=LOSD, LOSu=LOSu, Span_k=self._Span_k, ConeWidth_k=self._ConeWidth_k, ConeWidth_X1=self._ConeWidth_X1, - ConeWidth_X2=self._ConeWidth_X2, Cone_PolyCrossbis=self._Cone_PolyCrossbis, Cone_PolyHorbis=self._Cone_PolyHorbis, - Lens_ConeTip=self._Optics_Lens_ConeTip, Lens_ConeHalfAng=self._Optics_Lens_ConeHalfAng, RadL=self.Optics[0].Rad, RadD=self.Rad, F1=self.Optics[0].F1, thet=thet, - VPoly=self.Ves.Poly, VVin=self.Ves.Vin, DLong=self.Ves.DLong, CrossRef=CrossRef, dX12=dX12, dX12Mode=dX12Mode, ds=ds, dsMode=dsMode, MarginS=MarginS, VType=self.Ves.Type, OpType=self.OpticsType, Colis=Colis) - self._SynthDiag_Points, self._SynthDiag_SAng, self._SynthDiag_Vect, self._SynthDiag_dV = Out[0], Out[1], Out[2], Out[3] - self._SynthDiag_ds, self._SynthDiag_dsMode, self._SynthDiag_MarginS, self._SynthDiag_dX12, self._SynthDiag_dX12Mode, self._SynthDiag_Colis = Out[4], Out[5], Out[6], Out[7], Out[8], Out[9] - self._SynthDiag_Done = True
- - def _reset_SynthDiag(self): - self._SynthDiag_Points, self._SynthDiag_SAng, self._SynthDiag_Vect, self._SynthDiag_dV = None, None, None, None - -
[docs] def calc_Sig(self, ff, extargs={}, Method='Vol', Mode='simps', PreComp=True, - epsrel=tfd.DetSynthEpsrel, dX12=tfd.DetSynthdX12, dX12Mode=tfd.DetSynthdX12Mode, ds=tfd.DetSynthds, dsMode=tfd.DetSynthdsMode, MarginS=tfd.DetSynthMarginS, Colis=tfd.DetCalcSAngVectColis, Test=True): - """ Return the signal computed from an input emissivity function, using a 3D or LOS method - - The synthetic signal resulting from a simulated emissivity can be computed automatically in several ways. - The user can choose between a VOS and a LOS approach (volume integration or line integration with etendue). - In each case the user can choose between the numerical integration method (from scipy.integrate + np.sum()). - It is possible to specify that, for a VOS approach, you want to use the pre-conputed mesh for faster computation (see :meth:`~tofu.geom.Detect.set_SigPrecomp`). - For a VOS approach, the user can specify how fine the discretization should be. - The collision detection with the edges of the :class:`~tofu.geom.Ves` object can be switched off (not recommended). - - Parameters - ---------- - ff : function - Input emissiviy function, should take one input as follows: - * ff(Pts), where Points is a np.ndarray of shape=(3,N), with the (X,Y,Z) coordinates of any N number of points - Method : str - Flag indicating whether the spatial integration should be done with a volume ('Vol') or a LOS ('LOS') approach - Mode : str - Flag indicating the numerical integration method in ['quad','simps','trapz','nptrapz','sum'] - PreComp : bool - Flag indicating whether the pre-computed grid should be used - epsrel : float - Float specifying the tolerated relative error on the numerical integration, used for 'quad' - dX12 : list - Array of the 2 resolutions to be used to define the grid in a plane perpendicular to the LOS - dX12Mode : str - Flag specifying whether the values in dX12 are absolute distances or relative values (i.e. fraction of the total width [0;1]) - ds : float - Float indicating the resolution in the longitudinal direction - dsMode : str - Flag specifying whether ds is an absolute distance or relative (i.e. fraction of the total length [0;1]) - Colis : bool - Flag indicating whether collision detection should be used - Test : bool - Flag indicating whether the inputs should be tested for conformity - - Returns - -------- - Sig : float - The computed signal - - """ - # * ff(Pts, Vect), where Vect is a np.ndarray of shape=(3,N) with the (X,Y,Z) coordinates of a vector indicating the direction in which photons are emitted - if PreComp and not Method=='LOS': - assert not self._SynthDiag_ds is None, "The precomputed matrix shall be computed before using it..... " - - LOPolys = [oo.Poly for oo in self.Optics] - LOBaryS = [oo.BaryS for oo in self.Optics] - LOnIn = [oo.nIn for oo in self.Optics] - LOSD = self.LOS[self._LOSRef]['LOS'].D - LOSu = self.LOS[self._LOSRef]['LOS'].u - LOSkPIn = self.LOS[self._LOSRef]['LOS'].kPIn - LOSkPOut = self.LOS[self._LOSRef]['LOS'].kPOut - LOSEtend = self.LOS[self._LOSRef]['Etend'] - thet = np.linspace(0.,2.*np.pi,self.Poly.shape[1]) - CrossRef = np.arctan2(self.LOS[self._LOSRef]['PRef'][1],self.LOS[self._LOSRef]['PRef'][0]) if self.Ves.Type=='Tor' else self.LOS[self._LOSRef]['PRef'][0] - - Sig = _tfg_c._Detect_SigSynthDiag(ff, extargs=extargs, Method=Method, Mode=Mode, PreComp=PreComp, - DPoly=self.Poly, DBaryS=self.BaryS, DnIn=self.nIn, LOPolys=LOPolys, LOBaryS=LOBaryS, LOnIn=LOnIn, Lens_ConeTip=self._Optics_Lens_ConeTip, Lens_ConeHalfAng=self._Optics_Lens_ConeHalfAng, - RadL=self.Optics[0].Rad, RadD=self.Rad, F1=self.Optics[0].F1, thet=thet, OpType=self.OpticsType, - LOSD=LOSD, LOSu=LOSu, LOSkPIn=LOSkPIn, LOSkPOut=LOSkPOut, LOSEtend=LOSEtend, Span_k=self._Span_k, ConeWidth_X1=self._ConeWidth_X1, ConeWidth_X2=self._ConeWidth_X2, SAngPlane=self._SAngPlane, CrossRef=CrossRef, - Cone_PolyCrossbis=self._Cone_PolyCrossbis, Cone_PolyHorbis=self._Cone_PolyHorbis, VPoly=self.Ves.Poly, VVin=self.Ves.Vin, VType=self.Ves.Type, - SynthDiag_Points=self._SynthDiag_Points, SynthDiag_SAng=self._SynthDiag_SAng, SynthDiag_Vect=self._SynthDiag_Vect, SynthDiag_dV=self._SynthDiag_dV, - SynthDiag_dX12=self._SynthDiag_dX12, SynthDiag_dX12Mode=self._SynthDiag_dX12Mode, SynthDiag_ds=self._SynthDiag_ds, - SynthDiag_dsMode=self._SynthDiag_dsMode, SynthDiag_MarginS=self._SynthDiag_MarginS, SynthDiag_Colis=self._SynthDiag_Colis, - epsrel=epsrel, dX12=dX12, dX12Mode=dX12Mode, ds=ds, dsMode=dsMode, MarginS=MarginS, Colis=Colis, Test=Test) - return Sig
- - def _debug_Etendue_BenchmarkRatioMode(self, RelErr=tfd.DetEtendepsrel, Ratio=[0.01,0.05,0.2,0.5], Modes=['simps','trapz','quad'], dX12=[0.002,0.002], dX12Mode='abs', Colis=tfd.DetCalcEtendColis): - """ Return the etendue computed 3 different numerical integration methods, with or without collisions, with more or less margin for the perpendicular plane size (Ratio) - - USed for debugging, compute the etendue with various values of the Ratio (extra margin for the integration intervals), to check it does not affect the computed value - - Parameters - ---------- - RelErr : float - Float specifying the tolerated relative error on the numerical integration, used for 'quad' - Ratio : list - Array of values in [0,1] specifying margin to be used to define the edges of the perpendicular plane - Colis : bool - Flag indicating whether collision detection should be used - - Returns - ------- - EtendSimps : np.ndarray - (NLos,NRatio) array of the computed etendues with numerical integration 'simps', where NLos is the number of LOS of Detect and NRatio=len(Ratio) - EtendTrapz : np.ndarray - (NLos,NRatio) array of the computed etendues with numerical integration 'trapz', where NLos is the number of LOS of Detect and NRatio=len(Ratio) - EtendQuad : np.ndarray - (NLos,NRatio) array of the computed etendues with numerical integration 'quad', where NLos is the number of LOS of Detect and NRatio=len(Ratio) - Keys : list - List of the available LOS - - """ - if not self.LOS=='Impossible !': - Keys = self.LOS.keys() - NLOS, NR = len(Keys), len(Ratio) - Etends = {} - for kk in Modes: - Etends[kk] = np.nan*np.ones((NLOS,NR)) - for jj in range(0,NLOS): - PRef = self.LOS[Keys[jj]]['PRef'] - LOSu = self.LOS[Keys[jj]]['LOS'].u - e1, e2 = _tfg_gg.Calc_DefaultCheck_e1e2_PLane_1D(PRef, LOSu) - PRef = PRef.reshape((3,1)) - LOSu = LOSu.reshape((3,1)) - e1, e2 = e1.reshape((3,1)), e2.reshape((3,1)) - LOPolys = [oo.Poly for oo in self.Optics] - LOBaryS = [oo.BaryS for oo in self.Optics] - LOnIn = [oo.nIn for oo in self.Optics] - LOSurfs = [oo.Surf for oo in self.Optics] - for ii in range(0,len(Ratio)): - print " ...Computing Etendue with integration method", kk, " for LOS ", Keys[jj], " and Ratio=", Ratio[ii] - Etends[kk][jj,ii] = _tfg_c.Calc_Etendue_PlaneLOS(PRef, LOSu, self.Poly, self.BaryS, self.nIn, LOPolys, LOnIn, LOSurfs, LOBaryS, self._SAngPlane, self.Ves.Poly, self.Ves.Vin, DLong=self.Ves.DLong, - Lens_ConeTip = self._Optics_Lens_ConeTip, Lens_ConeHalfAng=self._Optics_Lens_ConeHalfAng, RadL=self.Optics[0].Rad, RadD=self.Rad, F1=self.Optics[0].F1, - OpType=self.OpticsType, VType=self.Ves.Type, Mode=kk, e1=e1, e2=e2, epsrel=RelErr, Ratio=Ratio[ii], dX12=dX12, dX12Mode=dX12Mode, Colis=Colis, Test=True)[0][0] - return Etends, Ratio, RelErr, dX12, dX12Mode, Colis - - -
[docs] def calc_Etendue_AlongLOS(self, Length='', NP=tfd.DetEtendOnLOSNP, Modes=['trapz','quad'], RelErr=tfd.DetEtendepsrel, dX12=tfd.DetSynthdX12, dX12Mode=tfd.DetSynthdX12Mode, Ratio=tfd.DetEtendRatio, - Colis=tfd.DetSAngColis, LOSRef=None, Test=True): - """ Return the etendue computed at different points along the LOS, with various numerical methods, with or without collision detection - - Computing the etendue along the LOS of a Detect object can be useful for checking whether the etendue is constant (as it should be if the LOS approximation is to be used). - Cases with non-constant etendue include in particular partially obstructed VOS in the divertor region of Tokamaks. - Also useful for debugging: if the etendue is not constant but the VOS is not obstructed, something might be wrong with the computation of the etendue or with the model (e.g.: for Lens optics). - Indeed, the model implemented for a Lens is ideal, but a close look at the etendue shows that the model is not perfect (but sufficiently accurate for most uses though). - - Parameters - ---------- - Length : str - Flag indicating whether to use the full length of the VOS (including partially obstructed parts: ''), or just the length of the LOS unil its exit point ('LOS'). - NP : int - Number of points (uniformly distributed along the LOS) where the etendue should be computed - Modes : list or str - Flag or list of flags indicating which numerical integration methods shoud be used in ['quad','simps','trapz'] - RelErr : float - For 'quad', a positive float defining the relative tolerance allowed - dX12 : list - For 'simps' or 'trapz', a list of 2 floats defining the resolution of the sampling in X1 and X2 - dX12Mode : str - For 'simps' or'trapz', 'rel' or 'abs', if 'rel' the resolution dX12 is in dimensionless units in [0;1] (hence a value of 0.1 means 10 discretisation points between the extremes), if 'abs' dX12 is in meters - Ratio : float - A float specifying the relative margin to be taken for integration boundaries - Colis : bool - Flag indicating whether collision detection should be used - LOSRef : None or str - Flag indicating which LOS should be used - Test : bool - Flag indicating whether the inputs should be tested for conformity - - Returns - ------- - Etend : np.ndarray - Computed etendues - Pts : np.ndarray - (3,NP) array specifying the 3D (X,Y,Z) coordinates of the points along the LOS where the etendue was computed - kPts : np.ndarray - (NP,) array of the distance-coordinate k along the LOS - LOSRef : str - The LOS that was used - - """ - if Test: - assert Modes in ['quad','simps','trapz'] or (type(Modes) is list and all([mode in ['quad','simps','trapz'] for mode in Modes])), "Arg Modes must be a list of Modes to be used ('quad', 'simps' or 'trapz') !" - if type(Modes) is str: - Modes = [Modes] - NMod = len(Modes) - - if not self.LOS=='Impossible !': - LOSRef = self._LOSRef if LOSRef is None else LOSRef - RelErr = self.LOS[LOSRef]['Etend_RelErr'] if 'quad' in Modes and RelErr is None else RelErr - dX12 = self.LOS[LOSRef]['Etend_dX12'] if (not (Modes=='quad' or Modes==['quad'])) and dX12 is None else dX12 - dX12Mode = self.LOS[LOSRef]['Etend_dX12Mode'] if (not (Modes=='quad' or Modes==['quad'])) and dX12Mode is None else dX12Mode - Ratio = self.LOS[LOSRef]['Etend_Ratio'] if Ratio is None else Ratio - Etends = {} - - PRef = self.LOS[LOSRef]['PRef'] - LOSu = self.LOS[LOSRef]['LOS'].u - e1, e2 = _tfg_gg.Calc_DefaultCheck_e1e2_PLane_1D(PRef, LOSu) - LOPolys = [oo.Poly for oo in self.Optics] - LOBaryS = [oo.BaryS for oo in self.Optics] - LOnIn = [oo.nIn for oo in self.Optics] - LOSurfs = [oo.Surf for oo in self.Optics] - - k1 = self.LOS[LOSRef]['LOS'].kPIn if Length=='LOS' else self._Span_k[0] - k2 = self.LOS[LOSRef]['LOS'].kPOut if Length=='LOS' else self._Span_k[1] - k = np.linspace(k1,k2,NP) - P1 = self.LOS[LOSRef]['LOS'].D - Ps = np.array([P1[0] + k*LOSu[0], P1[1] + k*LOSu[1], P1[2] + k*LOSu[2]]) - nPs = np.tile(LOSu,(NP,1)).T - e1, e2 = np.tile(e1,(NP,1)).T, np.tile(e2,(NP,1)).T - for ii in range(0,NMod): - print " ...Computing Etendues of "+ self.Id.Name +" for ",NP," planes with integration method ",Modes[ii] - Etends[Modes[ii]] = _tfg_c.Calc_Etendue_PlaneLOS(Ps, nPs, self.Poly, self.BaryS, self.nIn, LOPolys, LOnIn, LOSurfs, LOBaryS, self._SAngPlane, - self.Ves.Poly, self.Ves.Vin, DLong=self.Ves.DLong, Lens_ConeTip=self._Optics_Lens_ConeTip, Lens_ConeHalfAng=self._Optics_Lens_ConeHalfAng, RadL=self.Optics[0].Rad, RadD=self.Rad, F1=self.Optics[0].F1, - OpType=self.OpticsType, VType=self.Ves.Type, Mode=Modes[ii], e1=e1, e2=e2, epsrel=RelErr, Ratio=Ratio, dX12=dX12, dX12Mode=dX12Mode, Colis=Colis, Test=True)[0] - return Etends, Ps, k, LOSRef
- - -
[docs] def calc_SAngNb(self, Pts=None, Proj='Cross', Slice='Int', DRY=None, DXTheta=None, DZ=None, Colis=tfd.DetSAngColis): - """ Compute the solid angle subtended by the Detect+Optics system as seen for desired points, in a slice or integrated manner - - Mostly useful in the :class:`GDetect` object when there are several detectors. - Computes, for each point in the desired projection, the total solid angle subtended by all the detectors (or its integral) and the number of detectors that 'see' each point. - - Parameters - ---------- - Pts : None / np.ndarray - (3,N) array of cartesian (X,Y,Z) coordinates of the provided N points, if None a default set of points is computed according to DRY, DXTheta and DZ - Proj : str - Flag indicating to which projection of the VOS the method should be applied - Slice : str - Flag indicating whether to compute the solid angle ('Slice'), the maximum solid angle along the ignorable coordinate ('Max'), or the integral over the ignorable coordinate ('Int') - DRY : None / float - Resolution (in horizontal direction of the cross-section) of the mesh to be constructed if the points are not provided - DXTheta : None / float - Resolution (in ignorable coordinate direction) of the mesh to be constructed if the points are not provided - DZ : None / float - Resolution (in vertical direction) of the mesh to be constructed if the points are not provided - Colis : bool - Flag indicating whether collision detection should be used - - Returns - ------- - SA : np.ndarray - Array of (ND,NP) solid angle values, where ND is the number of detectors and NP the number of points - Nb : np.ndarray - Array of (ND,NP) booleans, True if a point is seen by a detector - Pts : np.ndarray - The computed points (in case they were not provided) - - """ - # Return pre-computed data if matches - if all([ss is None for ss in [Pts,DRY,DXTheta,DZ]]) and Slice in ['Int','Max']: - if Proj=='Cross': - SA = self._SAngCross_Int if Slice=='Int' else self._SAngCross_Max - Pts = self._SAngCross_Points - elif Proj=='Hor': - SA = self._SAngHor_Int if Slice=='Int' else self._SAngHor_Max - Pts = self._SAngHor_Points - else: - # Get the mesh if Pts not provided - if Pts is None: - LOS = self.LOS[self._LOSRef]['LOS'] - SingPts = np.vstack((LOS.PIn, LOS.PIn+0.002*LOS.u, 0.5*(LOS.POut+LOS.PIn), LOS.POut-0.002*LOS.u , LOS.POut)).T - if self.Ves.Type=='Tor': - X1, XIgn, Z, NX1, NIgn, NZ, Pts, out = _tfg_c._get_CrossHorMesh(SingPoints=SingPts, LSpan_R=[self._Span_R], LSpan_Theta=[self._Span_Theta], LSpan_Z=[self._Span_Z], DR=DRY, DTheta=DXTheta, DZ=DZ, - VType=self.Ves.Type, Proj=Proj, ReturnPts=True) - elif self.Ves.Type=='Lin': - XIgn, X1, Z, NIgn, NX1, NZ, Pts, out = _tfg_c._get_CrossHorMesh(SingPoints=SingPts, LSpan_X=[self._Span_X], LSpan_Y=[self._Span_Y], LSpan_Z=[self._Span_Z], DX=DXTheta, DY=DRY, DZ=DZ, - VType=self.Ves.Type, Proj=Proj, ReturnPts=True) - # Get the Solid angle (itself, or Int or Max) - if Slice in ['Int','Max']: - FF = self._get_SAngIntMax(Proj=Proj, SAng=Slice) - SA = FF(Pts, In=out) - else: - if Proj=='Hor': - Span = self._Span_Z - else: - Span = self._Span_Theta if self.Ves.Type=='Tor' else self._Span_X - assert Slice>=Span[0] and Slice<=Span[1], "Arg Slice is outside of the interval were non-zeros values can be found !" - Ptsint = _tfg_gg.CoordShift(Pts, In=out, Out='(X,Y,Z)', CrossRef=Slice) - SA = self.calc_SAngVect(Ptsint, In='(X,Y,Z)', Colis=Colis, Test=True)[0] - return SA, SA>0., Pts
- - - def _calc_Res(self, Pts=None, CrossMesh=[0.01,0.01], CrossMeshMode='abs', Mode='Iso', Amp=1., Deg=0, steps=0.001, Thres=0.05, ThresMode='rel', ThresMin=0.01, - IntResCross=[0.1,0.1], IntResCrossMode='rel', IntResLong=0.05, IntResLongMode='rel', - Eq=None, PlotDetail=False, Cdict=dict(tfd.DetConed), Ntt=100, SaveName=None, SavePath='./', save=False, Test=True): - """ Compute the resolution and given input points or grid knots, with specified method and accuracy, the result can be automatically saved (useful for long computations) - - The definition that tofu proposes for the spatial resolution of a tomography diagnostic is as follows: - (describe after publication) - - Parameters - ---------- - Pts : None or iterable - CrossMesh : None or iterable - CrossMeshMode : str - Mode : str - Amp : float - Deg : int - steps : float - Thres : float - ThresMode : str - ThresMin : float - IntResCross : iterable - IntResCrossMode : str - IntResLong : float - IntResLongMode : str - Eq : None or callable - PlotDetail : bool - Cdict : dict - Ntt : int - SaveName : None or str - SavePath : str - save : bool - Test : bool - - Returns - ------- - Res : np.ndarray - Pts : np.ndarray - - """ - - Res, Pts, LDetLim, Mode, steps, Thres, ThresMode, ThresMin, IntResCross, IntResCrossMode, IntResLong, IntResLongMode \ - = _Calc_Resolution(self, Pts=Pts, CrossMesh=CrossMesh, CrossMeshMode=CrossMeshMode, Mode=Mode, Amp=Amp, Deg=Deg, steps=steps, Thres=Thres, ThresMode=ThresMode, ThresMin=ThresMin, - IntResCross=IntResCross, IntResCrossMode=IntResCrossMode, IntResLong=IntResLong, IntResLongMode=IntResLongMode, - Eq=Eq, PlotDetail=PlotDetail, Cdict=Cdict, Ntt=Ntt, SaveName=SaveName, SavePath=SavePath, save=save, Test=Test) - return Res, Pts - - def _set_Res(self, CrossMesh=[0.05,0.02], CrossMeshMode='rel', Mode='Iso', Amp=1., Deg=0, steps=0.001, Thres=0.05, ThresMode='rel', ThresMin=0.01, - IntResCross=[0.1,0.1], IntResCrossMode='rel', IntResLong=0.05, IntResLongMode='rel', Eq=None, EqName=None, Ntt=100, save=False, Test=True): - """ Compute the resolution of the Detect instance on a mesh grid of the Cross section, with specified parameters (see :meth:`~self.calc_Res` for details) - - Parameters - ---------- - EqName : str - Flag name used to identify the equilibrium reconstruction that was used, if any - save : bool - if True the Detect instance saves itself automatically once the computation is finished (useful for long computations) - """ - - Res, Pts, LDetLim, Mode, steps, Thres, ThresMode, ThresMin, IntResCross, IntResCrossMode, IntResLong, IntResLongMode \ - = _Calc_Resolution(self, Pts=None, CrossMesh=CrossMesh, CrossMeshMode=CrossMeshMode, Mode=Mode, Amp=Amp, Deg=Deg, steps=steps, Thres=Thres, ThresMode=ThresMode, ThresMin=ThresMin, - IntResCross=IntResCross, IntResCrossMode=IntResCrossMode, IntResLong=IntResLong, IntResLongMode=IntResLongMode, Eq=Eq, Ntt=Ntt, PlotDetail=False, save=False, Test=Test) - - self._Res_Mode, self._Res_Amp, self._Res_Deg = Mode, Amp, Deg - self._Res_Pts, self._Res_Res, self._Res_CrossMesh, self._Res_CrossMeshMode = Pts, Res, CrossMesh, CrossMeshMode - self._Res_steps, self._Res_Thres, self._Res_ThresMode, self._Res_ThresMin = steps, Thres, ThresMode, ThresMin - self._Res_IntResCross, self._Res_IntResCrossMode, self._Res_IntResLong, self._Res_IntResLongMode, self._Res_IntNtt = IntResCross, IntResCrossMode, IntResLong, IntResLongMode, Ntt - self._Res_EqName = EqName - self._Res_Done = True - if save: - self.save() - - def _reset_Res(self): - self._Res_Mode, self._Res_Amp, self._Res_Deg = None, None, None - self._Res_Pts, self._Res_Res, self._Res_CrossMesh, self._Res_CrossMeshMode = None, None, None, None - self._Res_steps, self._Res_Thres, self._Res_ThresMode, self._Res_ThresMin = None, None, None, None - self._Res_IntResCross, self._Res_IntResCrossMode, self._Res_IntResLong, self._Res_IntResLongMode, self._Res_IntNtt = None, None, None, None, None - self._Res_EqName = None - self._Res_Done = False - - -
[docs] def plot(self, Lax=None, Proj='All', Elt='PVC', EltLOS='LDIORP', EltOptics='P', EltVes='', Leg=None, LOSRef=None, - Pdict=tfd.ApPd, Vdict=tfd.ApVd, Cdict=tfd.DetConed, LVIn=tfd.ApLVin, - LOSdict=tfd.LOSdict, Opticsdict=tfd.Apertdict, Vesdict=tfd.Vesdict, - LegDict=tfd.TorLegd, draw=True, a4=False, Test=True): - """ Plot the Detect instance in a projection or in 3D, its polygon, perpendicular vector, projected viewing cones and optionally its :class:`~tofu.geom.LOS`, :class:`~tofu.geom.Apert`, and :class:`~tofu.geom.Ves` objects - - The Detect instance can be plotted in a cross-section or horizontal projection, or in 3D. - Several of its attributes can be plotted too using the usual 'Elt' keyword argument. - Dedicated 'Elt' keyword arguments are also usable to specify the elements to be plotted for sub-classes like :class:`~tofu.geom.LOS`, :class:`~tofu.geom.Apert`, and :class:`~tofu.geom.Ves`. - Dedicated dictionary help specify how each element sshould be plotted. - - Parameters - ---------- - Lax : None, plt.Axes or list - Axes or list of axes to be used for plotting, if None a new figure and appropriate axes are created - Proj : str - Flag indicating whether to plot the cross-section ('Cross'), the horizontal projection ('Hor'), both ('All') or a 3D representation ('3D') - Elt : str - Flag indicating which elements of the Detect instance to plot, each capital letter stands for an element - * 'P': polygon - * 'V': perpendicular vector - * 'C': viewing cone - EltLOS : None or str - Flag indicating which elements of the LOS to plot, will be fed to LOS.plot(), if None uses the 'Elt' arg of LOSdict instead - EltOptics : None or str - Flag indicating which elements of the Aperts to plot, will be fed to Apert.plot(), if None uses the 'Elt' arg of Apertdict instead - EltVes : None or str - Flag indicating which elements of the Ves to plot, will be fed to :meth:`~tofu.geom.Ves.plot`, if None uses the 'Elt' arg of Vesdict instead - Leg : str - Legend to be used for the detector, if '' the Detect.iD.Name is used - LOSRef : None or str - Flag indicating which LOS should be represented, if None Detect._LOSRef is used - Pdict : dict - Dictionary of properties for the Polygon - Vdict : dict - Dictionary of properties for the Vector - Cdict : dict - Dictionary of properties for the Cone - LVIn : float - Length of the Vector - LOSdict : dict - Dictionary of properties for the LOS if EltLOS is not '', fed to LOS.plot() - Apertdict : dict - Dictionary of properties for the Apert if EltOptics is not '', fed to Apert.plot() - Vesdict : dict - Dictionary of properties for the Ves if EltVes is not '', fed to :meth:`~tofu.geom.Ves.plot` - LegDict : dict - Dictionary of properties for the legend, fed to plt.legend() - draw : bool - Flag indicating whether to draw the figure - a4 : bool - Flag indicating whether the default figure should be of size a4 paper - Test : bool - Flag indicating whether the inputs should be tested for conformity - - Returns - ------- - Lax plt.Axes or list - Axes or list of axes used for plotting - - """ - return _tfg_p.GLDetect_plot(self, Lax=Lax, Proj=Proj, Elt=Elt, EltOptics=EltOptics, EltLOS=EltLOS, EltVes=EltVes, Leg=Leg, LOSRef=LOSRef, - Pdict=Pdict, Vdict=Vdict, Cdict=Cdict, LVIn=LVIn, - LOSdict=LOSdict, Opticsdict=Opticsdict, Vesdict=Vesdict, LegDict=LegDict, draw=draw, Test=Test)
- -
[docs] def plot_SAngNb(self, Lax=None, Proj='Cross', Slice='Int', Pts=None, plotfunc='scatter', DRY=None, DXTheta=None, DZ=None, - Elt='P', EltVes='P', EltLOS='', EltOptics='P', - Pdict=tfd.ApPd, Vdict=tfd.ApVd, Cdict=tfd.DetConed, LVIn=tfd.ApLVin, - LOSdict=tfd.LOSdict, Opticsdict=tfd.Apertdict, Vesdict=tfd.Vesdict, - CDictSA=None, CDictNb=None, Colis=tfd.DetSAngColis, a4=False, draw=True, Test=True): - """ Plot the solid angle projections (integrated 'Int' or maximum 'Max') as well as the number of detectors visible from each point in the plasma - - Mostly useful with the :class:`~tofu.geom.GDetect` object, used to visualize the goemetrical coverage in terms of total solid angle and number of detectors 'seeing' each point for a set of detectors (see :meth:`~tofu.geom.Detect.calc_SAngNb` method for details). - - Parameters - ---------- - Lax : None or list or plt.Axes - Axes or list of Axes to be used for plotting, if None a new figure and appropriate axes are created - Proj : str - Flag indicating whether to plot the cross-section ('Cross') or the horizontal projection ('Hor') - Mode : str, None or float - Flag indicating whether to plot: - * 'Int': the integrated value along the projected coordinates - * 'Max': the maximum value along the projected coordinates - * float: the projected coordinate at which to plot the slice (Theta or X if Proj='Cross', Z if Proj='Hor') - * None: the slice is done in the middle of the viewing volume - plotfunc : str - Flag indicating which plotting method to use ('scatter', 'contour', 'contourf' or 'imshow') - DCross : float - Resolution along the 1st cross-section coordinate (R for Type='Tor', Y for Type='Lin') - DXTheta : float - Resolution along the ignorable coordinate (Theta for Type='Tor', X for Type='Lin') - DZ : float - Vertical resolution (for both Types) - CDictSA : dict - Properties of the solid angle plot, to be fed to the function chosen by plotfunc - CDictNb : dict - Properties of the Nb plot, to be fed to the chsoen plotting routine - Colis : bool - Flag indicating whether collision detection should be used - a4 : bool - Flag indicating whether to use a4 dimensions to create a new figure if Lax=None - draw : bool - Flag indicating whether to draw the figure - Test : bool - Flag indicating whether the inputs should be tested for conformity - - Returns - ------- - Lax : plt.Axes or list - List of the axes used for plotting - - """ - SA, Nb, Pts = self.calc_SAngNb(Pts=Pts, Proj=Proj, Slice=Slice, DRY=DRY, DXTheta=DXTheta, DZ=DZ, Colis=Colis) - Lax = _tfg_p._GLDetect_plot_SAngNb(Leg=self.Id.Name, SA=SA, Nb=Nb, Pts=Pts, Lax=Lax, Proj=Proj, Slice=Slice, plotfunc=plotfunc, CDictSA=CDictSA, CDictNb=CDictNb, Colis=Colis, - DRY=DRY, DXTheta=DXTheta, VType=self.Ves.Type, a4=a4, draw=False, Test=Test) - if any([not ss=='' for ss in [Elt,EltVes, EltLOS, EltOptics]]): - Lax[0] = self.plot(Proj=Proj, Lax=Lax[0], Elt=Elt, EltVes=EltVes, EltLOS=EltLOS, EltOptics=EltOptics, Pdict=Pdict, Vdict=Vdict, Cdict=Cdict, LVIn=LVIn, - LOSdict=LOSdict, Opticsdict=Opticsdict, Vesdict=Vesdict, LegDict=None, a4=a4, draw=False, Test=Test) - Lax[1] = self.plot(Proj=Proj, Lax=Lax[1], Elt=Elt, EltVes=EltVes, EltLOS=EltLOS, EltOptics=EltOptics, Pdict=Pdict, Vdict=Vdict, Cdict=Cdict, LVIn=LVIn, - LOSdict=LOSdict, Opticsdict=Opticsdict, Vesdict=Vesdict, LegDict=None, a4=a4, draw=False, Test=Test) - if draw: - Lax[0].figure.canvas.draw() - return Lax
- - def _debug_plot_SAng_OnPlanePerp(self, ax=None, Pos=tfd.DetSAngPlRa, dX12=tfd.DetSAngPldX12, dX12Mode=tfd.DetSAngPldX12Mode, Ratio=tfd.DetSAngPlRatio, SurfDict=tfd.DetSAngPld, LegDict=tfd.TorLegd, - Colis=tfd.DetSAngColis, LOSRef=None, draw=True, a4=False, Test=True): - """ Plot the solid angle subtended by the Detect-Apert system as seen from points on a plane perpendicular to the LOS - - Used for debugging or illustrative purposes. - Plot a surface plot of the solid angle subtended by the Detect+Optics system as seen for all points standing on a plane perpendicular to the LOS (the integral of which is the etendue). - - Parameters - ---------- - ax : None or plt.Axes - Axes to be used for plotting, if None a new figure and appropriate axes are created - Pos : float - Relative position between LOS.PIn and LOS.POut where the plane os to be placed, in ]0;1[ - dX12 : list - List of 2 floats defining the resolution of the sampling in X1 and X2 - dX12Mode : str - Flag indicating whether the resolution dX12 is in dimensionless units (in [0;1], hence a value of 0.1 means 10 discretisation points between the extremes), if 'abs' dX12 is in meters - Ratio : float - A float specifying the relative margin to be taken for integration boundaries - SurfDict : dict - Dictionary of properties to be used for plotting the surface plot (fed to :meth:`~matplotlib.pyplot.plot_surface`) - LegDict : None or dict - If None, no legend is plotted, else LegDict is fed to :meth:'~matplotlib.pyplot.Axes.legend' - Colis : bool - Flag indicating whether collision detection should be used - draw : bool - Flag indicating whether to draw the figure - a4 : bool - Flag indicating whether the created figure should have a4 dimensions (useful for printing) - Test : bool - Flag indicating whether the inputs should be tested for conformity - - Returns - ------- - ax : plt.Axes - The axes used for plotting - - """ - if Test: - assert type(Pos) is float, "Arg Pos must be a float specifying the relative distance on the LOS at which the plane is to be placed !" - if LOSRef is None: - LOSRef = self._LOSRef - Ps = (self.LOS[LOSRef]['LOS'].PIn + Pos*(self.LOS[LOSRef]['LOS'].POut - self.LOS[LOSRef]['LOS'].PIn)).reshape((3,1)) - nPs = self.LOS[LOSRef]['LOS'].u.reshape((3,1)) - LOPolys = [oo.Poly for oo in self.Optics] - LOBaryS = [oo.BaryS for oo in self.Optics] - LOnIns = [oo.nIn for oo in self.Optics] - LOSurfs = [oo.Surf for oo in self.Optics] - Etend, e1, e2, err, SA, X1, X2, NumX1, NumX2 = _tfg_c.Calc_Etendue_PlaneLOS(Ps, nPs, self.Poly, self.BaryS, self.nIn, LOPolys, LOnIns, LOSurfs, LOBaryS, self._SAngPlane, self.Ves.Poly, self.Ves.Vin, DLong=self.Ves.DLong, - Lens_ConeTip=self._Optics_Lens_ConeTip, Lens_ConeHalfAng=self._Optics_Lens_ConeHalfAng, RadL=self.Optics[0].Rad, RadD=self.Rad, F1=self.Optics[0].F1, - OpType=self.OpticsType, VType=self.Ves.Type, Mode='trapz', dX12=dX12, dX12Mode=dX12Mode, Ratio=Ratio, Colis=Colis, Details=True, Test=True) - - #SA, X1, X2, numX1, numX2 = _tfg_c.Calc_SAngOnPlane(self, P, self.LOS[LOSRef]['LOS'].u, dX12=dX12, dX12Mode=dX12Mode, e1=None,e2=None, Ratio=Ratio, Colis=Colis, Test=True) - SA = SA.reshape((NumX1[0],NumX2[0])) - X1, X2 = np.tile(X1.flatten(),(NumX2[0],1)).T, np.tile(X2.flatten(),(NumX1[0],1)) - Name = self.Id.NameLTX + " Pos={0} (Ratio={1})".format(Pos,Ratio) - ax = _tfg_p.Plot_SAng_Plane(SA, X1, X2, Name=Name, ax=ax, SurfDict=SurfDict, LegDict=LegDict, draw=False, a4=a4) - if draw: - ax.figure.canvas.draw() - return ax - - -
[docs] def plot_Etend_AlongLOS(self, ax=None, NP=tfd.DetEtendOnLOSNP, kMode='rel', Modes=['trapz'], Length='', RelErr=tfd.DetEtendepsrel, dX12=tfd.DetSynthdX12, dX12Mode=tfd.DetSynthdX12Mode, Ratio=tfd.DetEtendRatio, LOSRef=None, - LOSPts=True, Ldict=dict(tfd.DetEtendOnLOSLd), LegDict=tfd.TorLegd, Colis=tfd.DetSAngColis, draw=True, a4=True, Test=True): - """ Plot the etendue of the selected LOS along it, with or without collision detection - - The number of points along the LOS where the etendue is computed can be specified via arguments, as well as the numerical integration method. - Arguments Length, NP, Modes, RelErr, dX12, dX12Mode, Ratio, Colis, LOSRef are fed to :meth:`~tofu.geom.Detect.calc_Etendue_AlongLOS` - - Parameters - ---------- - ax : None or plt.Axes - Axes to be used for plotting, if None a new figure and appropriate axes are created - kMode : str - Flag indicating whether the distance on the line should be plotted as abolute distance ('abs') or relative to the total length ('rel') - Ldict : dict - Dictionary of properties for plotting the result - LegDict : None / dict - If None, no legend is plotted, else LegDict is fed to :meth:'~matplotlib.pyplot.Axes.legend' - draw : bool - Flag indicating whether to draw the figure - a4 : bool - Flag indicating whether the created figure should have a4 dimensions (useful for printing) - Test : bool - Flag indicating whether the inputs should be tested for conformity - - Returns - ------- - ax : plt.Axes - The axes used for plotting - - """ - Etends, Pts, kPts, LOSRef = self.calc_Etendue_AlongLOS(Length=Length, NP=NP, Modes=Modes, RelErr=RelErr, dX12=dX12, dX12Mode=dX12Mode, Ratio=Ratio, Colis=Colis, LOSRef=LOSRef, Test=True) - ax = _tfg_p.Plot_Etendue_AlongLOS(kPts, Etends, kMode, self.LOS[LOSRef]['LOS'].Id.NameLTX, ax=ax, Colis=Colis, - Etend=self.LOS[LOSRef]['Etend'], kPIn=self.LOS[LOSRef]['LOS'].kPIn, kPOut=self.LOS[LOSRef]['LOS'].kPOut, y0=0., - RelErr=RelErr, dX12=dX12, dX12Mode=dX12Mode, Ratio=Ratio, - Ldict=Ldict, LegDict=LegDict, draw=draw, a4=a4, Test=Test) - return ax
- -
[docs] def plot_Sinogram(self, ax=None, Proj='Cross', Elt='DLV', Ang='theta', AngUnit='rad', Sketch=True, Ddict=tfd.DetImpd, Ldict=tfd.LOSMImpd, Vdict=tfd.TorPFilld, LegDict=tfd.TorLegd, LOSRef=None, draw=True, a4=False, Test=True): - """ Plot the the Detect VOS in projection space, optionally also the associated :class:`~tofu.geom.Ves` object and reference LOS - - In projection space, a VOS is a patch (as opposed to a LOS which is a point). - The patch is estimated by plotting a large number of LOS sampling the VOS and taking the convex hull of the resulting points on projection space. - Notice that this method results in irrelevant patches for VOS lying at the edges of the projection space. - See :meth:`~tofu.geom.LOS.plot_Sinogram` for details. - - Parameters - ---------- - ax : None / plt.Axes - Axes on which to plot the Etendue, if None a default axes is created - Proj : str - Flag indicating whether to plot the traditional sinogram in a cross-section ('Cross') or a 3D sinogram ('3d'), cannot be '3d' if 'D' in Elt. - Elt : str - Flags indicating whether to plot the VOS of the Detect ('D' in Elt => only Proj='Cross'), the LOS ('L' in Elt) and the :class:`~tofu.geom.Ves` ('V' in Elt) - Ang : str - Flag indicating which angle to use for the plot, with respect to the considered line () or to the impact parameter line () - AngUnit : str - Flag indicating whether the angle should be measured in 'rad' or 'deg' - Sketch : bool - Flag indicating whether a small sketch illustrating the definitions of angles and impact parameter should be included - Ddict : dict - Plotting properties of the VOS of the Detect, fed to plt.plot() - Ldict : dict - Plotting properties of the LOS, fed to plt.plot() - Vdict : dict - Plotting properties of the Ves, fed to plt.plot() - LegDict : None / dict - Plotting properties of the legend, if None no legend is plotted - LOSRef : None / str - Flag indicating which LOS to plot, if None self._LOSRef is used - draw : bool - Flag indicating whether to draw the figure - a4 : bool - Flag indicating whether the created figure should have a4 dimensions (useful for printing) - Test : bool - Flag indicating whether the inputs should be tested for conformity - - Returns - ------- - ax : plt.Axes - The axes used for plotting - - """ - ax = _tfg_p.GLDetect_plot_Sinogram(self, Proj=Proj, ax=ax, Elt=Elt, Sketch=Sketch, Ang=Ang, AngUnit=AngUnit, Ddict=Ddict, Ldict=Ldict, Vdict=Vdict, LegDict=LegDict, LOSRef=LOSRef, draw=draw, a4=a4, Test=Test) - return ax
- - - - def _plot_Res(self, ax=None, plotfunc='scatter', NC=20, CDict=tfd.DetConed, draw=True, a4=False, Test=True): - """ Plot the resolution as defined by tofu (see :meth:`~tofu.geom.Detect._calc_Res` for details) - - Parameters - ---------- - ax : None / plt.Axes - Axes on which to plot the Etendue, if None a default axes is created - plotfunc : str - Flag indicating which plotting method to use in ['scatter','contour','contourf','imshow'] - NC : int - Number of contours to be plotted if plotfunc in ['contour','contourf'] - CDict : dict - Dictionary of properties for plotting, fed to the plotting routine - draw : bool - Flag indicating whether to draw the figure - a4 : bool - Flag indicating whether the created figure should have a4 dimensions (useful for printing) - Test : bool - Flag indicating whether the inputs should be tested for conformity - - Returns - ------- - ax : plt.Axes - - """ - assert self._Res_Done, "Cannot plot the resolution before it has been computed on a mesh grid with self.set_Res() !" - ax = _tfg_p._Resolution_Plot(self._Res_Pts, self._Res_Res, self, [self.Id.Name], ax=ax, plotfunc=plotfunc, NC=NC, CDict=dict(CDict), - ind=None, Val=None, draw=draw, a4=a4, Test=Test) - return ax - - - -
[docs] def save(self,SaveName=None,Path=None,Mode='npz', compressed=False, SynthDiag=False): - """ Save the object in folder Name, under file name SaveName, using specified mode - - Most tofu objects can be saved automatically as numpy arrays (.npz, recommended) at the default location (recommended) by simply calling self.save() - In the case of Detect and GDetect instances, there is an additional keyword argument 'SynthDiag' which allows to **not** save the pre-computed 3D mesh of the VOS for synthetic diagnostic. - Indeed, this pre-computed data is often large and results in big files. Not saving it results in significantly smaller files, and it can be re-computed when loading the instance. - - Parameters - ---------- - SaveName : None / str - The name to be used for the saved file, if None (recommended) uses self.Id.SaveName - Path : None / str - Path specifying where to save the file, if None (recommended) uses self.Id.SavePath - Mode : str - Flag specifying whether to save the object as a numpy array file ('.npz', recommended) or an object using cPickle (not recommended, heavier and may cause retro-compatibility issues) - compressed : bool - Flag, used when Mode='npz', indicating whether to use np.savez or np.savez_compressed (slower saving and loading but smaller files) - SynthDiag : bool - Flag indicating whether the pre-computed mesh for synthetic diagnostics calculations shall be saved too (can be heavy, if False, it will be re-computed when opening the saved object) - - """ - if not SynthDiag: - self._reset_SynthDiag() - tfpf.Save_Generic(self, SaveName=SaveName, Path=Path, Mode=Mode, compressed=compressed)
- - - - - - -def _Detect_set_Defaults(Poly=None, Type=None, Exp=None, Diag=None, shot=None, Ves=None, Optics=None): - if not Optics is None: - if type(Optics) is list: - Diag = Diag if not Diag is None else Optics[0].Id.Diag - Exp = Exp if not Exp is None else Optics[0].Id.Exp - Ves = Optics[0].Ves if Ves is None else Ves - else: - Diag = Diag if not Diag is None else Optics.Id.Diag - Exp = Exp if not Exp is None else Optics.Id.Exp - Ves = Optics.Ves if Ves is None else Ves - if type(Optics) is Lens: - Type = Type if not Type is None else 'Circ' - elif not Ves is None: - Exp = Exp if not Exp is None else Ves.Id.Exp - if type(Poly) is dict and not Optics is None: - if type(Optics) is Lens: - Poly['O'] = Optics.O-Optics.F1*Optics.nIn - Poly['nIn'] = Optics.nIn - return Poly, Type, Exp, Diag, shot, Ves - - - - - - -def _Detect_check_inputs(Id=None, Poly=None, Type=None, Optics=None, Vess=None, Sino_RefPt=None, Exp=None, Diag=None, shot=None, CalcEtend=None, CalcSpanImp=None, CalcCone=None, CalcPreComp=None, Calc=None, Verb=None, - Etend_RelErr=None, Etend_dX12=None, Etend_dX12Mode=None, Etend_Ratio=None, Colis=None, LOSRef=None, Etend_Method=None, - MarginRMin=None, NEdge=None, NRad=None, Nk=None, - Cone_DRY=None, Cone_DXTheta=None, Cone_DZ=None, Cone_NPsi=None, Cone_Nk=None, - arrayorder=None, Clock=None, SavePath=None, dtime=None, dtimeIn=None): - - if not Id is None: - assert type(Id) in [str,tfpf.ID], "Arg Id must be a str or a tfpf.ID object !" - if not Poly is None: - assert type(Poly) is dict or (hasattr(Poly,'__getitem__') and np.asarray(Poly).ndim==2 and 3 in np.asarray(Poly).shape), "Arg Poly must be a dict or an iterable with 3D cartesian coordinates of points !" - if type(Poly) is dict: - assert all([aa in Poly.keys() for aa in ['Rad']]), "Arg Poly must be a dict with keys ['Rad'] !" - assert type(Poly['Rad']) in [float,np.float64], "Arg Poly['Rad'] must be a float !" - if not Optics is None: - assert type(Optics) in [list,Apert,Lens], "Arg Optics must be a list, Apert or Lens" - if type(Optics) is list: - assert all([type(oo) is Apert for oo in Optics]), "Arg Optics must be a list of Apert !" - if type(Optics) is Lens: - assert type(Poly) is dict and 'Rad' in Poly.keys(), "When Optics is a Lens, Poly must be a dict with field 'Rad' !" - if not Exp is None: - if type(Optics) is list: - assert Exp==Optics[0].Id.Exp, "Arg Exp must be the same as the Optics[0].Id.Exp !" - else: - assert Exp==Optics.Id.Exp, "Arg Exp must be the same as the Optics.Id.Exp !" - if not Diag is None: - if type(Optics) is list: - assert Diag==Optics[0].Id.Diag, "Arg Exp must be the same as the Optics[0].Id.Diag !" - else: - assert Diag==Optics.Id.Diag, "Arg Diag must be the same as the Optics.Id.Diag !" - if not Vess is None: - assert type(Vess) is Ves, "Arg Ves must be a Ves instance !" - if not Exp is None: - assert Exp==Vess.Id.Exp, "Arg Exp must be the same as the Ves.Id.Exp !" - if not arrayorder is None: - assert arrayorder in ['C','F'], "Arg arrayorder must be in ['C','F'] !" - bools = [CalcEtend,CalcSpanImp,CalcCone,CalcPreComp,Calc,Verb,Colis,Clock,dtimeIn] - if any([not aa is None for aa in bools]): - assert all([aa is None or type(aa) is bool for aa in bools]), " Args [CalcEtend,CalcSpanImp,CalcCone,CalcPreComp,Calc,Verb,Colis,Clock,dtimeIn] must all be bool !" - if not Exp is None: - assert Exp in tfd.AllowedExp, "Arg Exp must be in "+str(tfd.AllowedExp)+" !" - assert Type is None or Type=='Circ', "Arg Type must be Circ or None for Detect objects !" - Iter2 = [Sino_RefPt,Etend_dX12] - if any([not aa is None for aa in Iter2]): - assert all([aa is None or (hasattr(aa,'__iter__') and np.asarray(aa).shape==(2,)) for aa in Iter2]), "Args [Sino_RefPt,Etend_dX12] must be an iterable with len()=2 !" - strs = [Etend_dX12Mode,LOSRef,Etend_Method,Diag,SavePath] - if any([not aa is None for aa in strs]): - assert all([aa is None or type(aa) is str for aa in strs]), "Args [dX12Mode,LOSRef,Method,Diag,SavePath] must all be str !" - floats = [Etend_RelErr,Etend_Ratio,MarginRMin,Cone_DRY,Cone_DXTheta,Cone_DZ] - if any([not aa is None for aa in floats]): - assert all([aa is None or type(aa) in [float,np.float64] for aa in floats]), "Args [RelErr,dX12,Ratio,MarginRMin] must all be floats !" - ints = [shot,NEdge,NRad,Nk,Cone_NPsi,Cone_Nk] - if any([not aa is None for aa in ints]): - assert all([aa is None or type(aa) is int for aa in ints]), "Args [shot,NEdge,NRad] must be int !" - if not dtime is None: - assert type(dtime) is dtm.datetime, "Arg dtime must be a dtm.datetime !" - - - - - - - - - - - - - - -
[docs]class GDetect(object): - """ An object grouping a list of :class:`~tofu.geom.Detect` objects with some common features (e.g.: all belong to the same camera) and the same :class:`~tofu.geom.Ves` object, provides methods for common computing and plotting - - A GDetect object is a convenient tool for managing groups of detectors, applying common treatment, plotting... - It is typically suited for a camera (e.g.: a group of detectors sharing a common aperture) - - Parameters - ---------- - Id : str or tfpf.ID - A name string or a pre-built tfpf.ID class to be used to identify this particular instance, if a string is provided, it is fed to :class:`~tofu.pathfile.ID` - LDetect : list or Detect - List of Detect instances with the same :class:`~tofu.geom.Ves` instance - Type : None - Not used in the current verion of tofu - Exp : None or str - Experiment to which the Lens belongs, should be identical to Ves.Id.Exp if Ves is provided, if None and Ves is provided, Ves.Id.Exp is used - Diag : None or str - Diagnostic to which the Lens belongs - shot : None or int - Shot number from which this Lens is usable (in case its position was changed from a previous configuration) - SavePath : None / str - If provided, forces the default saving path of the object to the provided value - Sino_RefPt : None or iterable - If provided, forces the common :attr:`~tofu.geom.Detect.Sino_RefPt` to the provided value for all :class:`~tofu.geom.Detect` instances - arrayorder : str - Flag indicating whether the attributes of type=np.ndarray (e.g.: Poly) should be made C-contiguous ('C') or Fortran-contiguous ('F') - dtime : None or dtm.datetime - A time reference to be used to identify this particular instance (used for debugging mostly) - dtimeIn : bool - Flag indicating whether dtime should be included in the SaveName (used for debugging mostly) - - """ - def __init__(self, Id, LDetect, Type=None, Exp=None, Diag=None, shot=None, Sino_RefPt=None, LOSRef=None, arrayorder='C', Clock=False, dtime=None, dtimeIn=False, SavePath=None): - - self._Done = False - tfpf._check_NotNone({'Clock':Clock,'arrayorder':arrayorder}) - self._check_inputs(Clock=Clock, arrayorder=arrayorder) - self._arrayorder = arrayorder - self._Clock = Clock - - self._check_inputs(LDetect=LDetect, Exp=Exp, Diag=Diag) - LDetect, Exp, Diag, Sino_RefPt, LOSRef = _GDetect_set_Defaults(LDetect=LDetect, Exp=Exp, Diag=Diag, Sino_RefPt=Sino_RefPt, LOSRef=LOSRef) - self._LOSRef = LOSRef - - self._set_Id(Id, Type=Type, Exp=Exp, Diag=Diag, shot=shot, dtime=dtime, dtimeIn=dtimeIn, SavePath=SavePath) - self._set_LDetect(LDetect) - self._reset_Res() - self._Done = True - - @property - def Id(self): - """ the associated tfpf.ID object """ - return self._Id - @property - def LDetect(self): - """ Return the list of :class:`~tofu.geom.Detect` instances the GDetect object comprises """ - return self._LDetect - @property - def nDetect(self): - """ Return the number of :class:`~tofu.geom.Detect` instances the GDetect object comprises """ - return self._nDetect - @property - def Optics(self): - """ Return the list of optics the GDetect object comprises (either :class:`~tofu.geom.Lens` or :class:`~tofu.geom.Apert`) """ - return self._Optics - @property - def Ves(self): - """ Return the :class:`~tofu.geom.Ves` instance associated to the GDetect object """ - return self._Ves - @property - def Sino_RefPt(self): - """ Return the coordinates (R,Z) or (Y,Z) for Ves of Type 'Tor' or (Y,Z) for Ves of Type 'Lin' of the reference point used to compute the sinogram """ - return self._Sino_RefPt - - - - def _check_inputs(self, Id=None, LDetect=None, Type=None, Sino_RefPt=None, LOSRef=None, Exp=None, Diag=None, shot=None, - arrayorder=None, Clock=None, SavePath=None, dtime=None, dtimeIn=None): - _GDetect_check_inputs(Id=Id, LDetect=LDetect, Type=Type, Sino_RefPt=Sino_RefPt, LOSRef=LOSRef, Exp=Exp, Diag=Diag, shot=shot, - arrayorder=arrayorder, Clock=Clock, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - - def _set_Id(self, Val, Type=None, Exp=None, Diag=None, shot=None, dtime=None, dtimeIn=False, SavePath=None): - if self._Done: - Out = tfpf._get_FromItself(self.Id, {'Type':Type, 'Exp':Exp, 'shot':shot, 'Diag':Diag, 'dtime':dtime, '_dtimeIn':dtimeIn, 'SavePath':SavePath}) - Type, Exp, shot, Diag, dtime, dtimeIn, SavePath = Out['Type'], Out['Exp'], Out['shot'], Out['Diag'], Out['dtime'], Out['dtimeIn'], Out['SavePath'] - tfpf._check_NotNone({'Id':Val}) - self._check_inputs(Id=Val) - if type(Val) is str: - tfpf._check_NotNone({'Exp':Exp, 'shot':shot, 'Diag':Diag, 'dtimeIn':dtimeIn}) - self._check_inputs(Type=Type, Exp=Exp, shot=shot, Diag=Diag, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - Val = tfpf.ID('GDetect', Val, Type=Type, Exp=Exp, Diag=Diag, shot=shot, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - self._Id = Val - - def _set_LDetect(self, LDetect): - self._check_inputs(LDetect=LDetect) - self._LDetect = LDetect - self._nDetect = len(LDetect) - self._Optics = _get_OpticsFromLDetect(LDetect) - - LObj = [dd.Id for dd in LDetect] + [aa.Id for aa in self._Optics] - if not LDetect[0].Ves is None: - LObj.append(LDetect[0].Ves.Id) - self.Id.set_LObj(LObj) - self._Ves = LDetect[0].Ves - self._Sino_RefPt = LDetect[0].Sino_RefPt - - def _calc_All(self, Sino_RefPt=None, CalcEtend=True, CalcSpanImp=True, CalcCone=True, CalcPreComp=True, - Etend_Method=tfd.DetEtendMethod, Etend_RelErr=tfd.DetEtendepsrel, Etend_dX12=tfd.DetEtenddX12, Etend_dX12Mode=tfd.DetEtenddX12Mode, Etend_Ratio=tfd.DetEtendRatio, Colis=tfd.DetCalcEtendColis, LOSRef=None, - Cone_DRY=tfd.DetConeDRY, Cone_DXTheta=None, Cone_DZ=tfd.DetConeDZ, Cone_NPsi=20, Cone_Nk=60, Verb=True): - LOSRef = self._LOSRef if LOSRef is None else LOSRef - for ii in range(0,self.nDetect): - self._LDetect[ii]._calc_All(Sino_RefPt=Sino_RefPt, CalcEtend=CalcEtend, CalcSpanImp=CalcSpanImp, CalcCone=CalcCone, CalcPreComp=CalcPreComp, - Etend_Method=Etend_Method, Etend_RelErr=Etend_RelErr, Etend_dX12=Etend_dX12, Etend_dX12Mode=Etend_dX12Mode, Etend_Ratio=Etend_Ratio, Colis=Colis, LOSRef=LOSRef, - Cone_DRY=Cone_DRY, Cone_DXTheta=Cone_DXTheta, Cone_DZ=Cone_DZ, Cone_NPsi=Cone_NPsi, Cone_Nk=Cone_Nk, Verb=Verb) - - def _set_Sino(self, RefPt=None): - self._check_inputs(RefPt=RefPt) - self._Ves._set_Sino(RefPt) - for ii in range(0,self.nDetect): - self._LDetect[ii]._set_Sino(RefPt) - self._Sino_RefPt = RefPt - -
[docs] def select(self, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In', Out=bool): - """ Return the indices or instances of all instances matching the specified criterion. - - The selection can be done according to 2 different mechanism (1) and (2). - - For mechanism (1): the user provides the value (Val) that the specified criterion (Crit) should take for a :class:`tofu.geom.Detect` to be selected. - The criteria are typically attributes of the self.Id attribute (i.e.: name of the instance, or user-defined attributes like the camera head...) - - For mechanism (2), used if Val=None: the user provides a str expression (or a list of such) to be fed to eval(), used to check on quantitative criteria, placed before the criterion value (e.g.: 'not ' or '<='). - Another str or list of str expressions can be provided that will be placed after the criterion value. - - Other parameters are used to specify logical operators for the selection (match any or all the criterion...) and the type of output. - See :meth:`~tofu.geom.GLOS.select` for examples - - Parameters - ---------- - Crit : str - Flag indicating which criterion to use for discrimination - Can be set to any attribute of the tofu.pathfile.ID class (e.g.: 'Name','SaveName','SavePath'...) or any key of ID.USRdict (e.g.: 'Exp'...) - Val : list, str or None - The value to match for the chosen criterion, can be a list of different values - Used for selection mechanism (1) - PreExp : list, str or None - A str of list of str expressions to be fed to eval(), used to check on quantitative criteria, placed before the criterion value (e.g.: 'not ') - Used for selection mechanism (2) - PostExp : list, str or None - A str of list of str expressions to be fed to eval(), used to check on quantitative criteria, placed after the criterion value (e.g.: '>=5.') - Used for selection mechanism (2) - Log : str - Flag indicating whether the criterion shall match all provided values or one of them ('any' or 'all') - InOut : str - Flag indicating whether the returned indices are the ones matching the criterion ('In') or the ones not matching it ('Out') - Out : type / str - Flag indicating in which form shall the result be returned, as an array of integer indices (int), an array of booleans (bool), a list of names ('Names') or a list of instances ('Detect') - - Returns - ------- - ind : list / np.ndarray - The computed output (array of index, list of names or instances depending on parameter 'Out') - - """ - if not Out=='Detect': - return tfpf.SelectFromListId([ll.Id for ll in self.LDetect], Val=Val, Crit=Crit, PreExp=PreExp, PostExp=PostExp, Log=Log, InOut=InOut, Out=Out) - else: - ind = tfpf.SelectFromListId([ll.Id for ll in self.LDetect], Val=Val, Crit=Crit, PreExp=PreExp, PostExp=PostExp, Log=Log, InOut=InOut, Out=int) - return [self.LDetect[ii] for ii in ind]
- - -
[docs] def isInside(self, Points, In='(X,Y,Z)', Test=True): - """ Return an array of indices indicating whether each point lies both in the cross-section and horizontal porojections of the viewing cone of each :class:`~tofu.geom.Detect` - - see :meth:`~tofu.geom.Detect.isInside` for details - - Parameters - ---------- - Points : np.ndarray - (2,N) or (3,N) array of coordinates of the N points to be tested - In : str - Flag indicating in which coordinate system the Points are provided, must be in ['(R,Z)','(Y,Z)','(X,Y)','(X,Y,Z)','(R,phi,Z)'] - * '(R,Z)': All points are assumed to lie in the horizontal projection, for 'Tor' vessel type only - * '(Y,Z)': All points are assumed to lie in the horizontal projection, for 'Lin' vessel type only - * '(X,Y)': All points are assumed to lie in the cross-section projection - Test : bool - Flag indicating whether the inputs should be tested for conformity - - Returns - ------- - ind : np.ndarray - (ND,N) array of booleans with True if a point lies inside both projections of the viewing cone, where ND is the number of Detect instances - - """ - assert isinstance(Points,np.ndarray), "Arg Points must be a np.ndarray !" - return np.vstack([dd.isInside(Points, In=In, Test=Test) for dd in self.LDetect])
- -
[docs] def get_GLOS(self, Name=None, LOSRef=None): - """ Return the :class:`~tofu.geom.GLOS` instance that can be built by grouping the :class:`~tofu.geom.LOS` of each :class:`~tofu.geom.Detect` instance - - Can be useful for handling a GLOS instead of a GDetect (heavier) instance - - Parameters - ---------- - Name : None / str - Name to be given to the GLOS instance, if None a name is built from the name of the GDetect object by appending '_GLOS' - LOSRef : None / str - Key indicating which LOS to be used, if None the default LOSRef is used - - Returns - ------- - glos : :class:`~tofu.geom.GLOS` - The constructed :class:`~tofu.geom.GLOS` instance - - """ - LOSRef = self._LOSRef if LOSRef is None else LOSRef - LLOS = [dd.LOS[LOSRef]['LOS'] for dd in self.LDetect if not dd.LOS in ['Impossible !',None]] - if Name is None: - Name = self.Id.Name+'_GLOS' - return GLOS(Name,LLOS)
- -
[docs] def set_SigPrecomp(self, CalcPreComp=True, dX12=tfd.DetSynthdX12, dX12Mode=tfd.DetSynthdX12Mode, ds=tfd.DetSynthds, dsMode=tfd.DetSynthdsMode, MarginS=tfd.DetSynthMarginS, Colis=tfd.DetCalcSAngVectColis): - """ Applies :meth:`~tofu.geom.Detect.set_SigPrecomp` to all :class:`~tofu.geom.Detect` instances """ - for ii in range(0,self.nDetect): - self._LDetect[ii].set_SigPrecomp(CalcPreComp=CalcPreComp, dX12=dX12, dX12Mode=dX12Mode, ds=ds, dsMode=dsMode, MarginS=MarginS, Colis=Colis)
- -
[docs] def calc_SAngVect(self, Pts, In='(X,Y,Z)', Colis=tfd.DetCalcSAngVectColis, Test=True): - """ Applies :meth:`~tofu.geom.Detect.calc_SAngVect` to all :class:`~tofu.geom.Detect` instances - - Return the result as two 2D arrays where the first dimension is the number of :class:`~tofu.geom.Detect` instances - see :meth:`~tofu.geom.Detect.calc_SAngVect` for details - - """ - SAng, Vect = np.zeros((self.nDetect,Pts.shape[1])), [0 for ii in range(0,self.nDetect)] - for ii in range(0,self.nDetect): - SAng[ii,:], Vect[ii] = self.LDetect[ii].calc_SAngVect(Pts, In=In, Colis=Colis, Test=Test) - return SAng, Vect
- - def calc_SAngNb(self, Pts=None, Proj='Cross', Slice='Int', DRY=None, DXTheta=None, DZ=None, Colis=tfd.DetSAngColis, - ind=None, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In'): - SA, Nb, Pts = _GDetect_Calc_SAngNb(self, Pts=Pts, Proj=Proj, Slice=Slice, DRY=DRY, DXTheta=DXTheta, DZ=DZ, Colis=Colis, - ind=ind, Val=Val, Crit=Crit, PreExp=PreExp, PostExp=PostExp, Log=Log, InOut=InOut) - """ Applies :meth:`~tofu.geom.Detect.calc_SAngNb` to all :class:`~tofu.geom.Detect` instances - - See :meth:`~tofu.geom.Detect.calc_SAngNb` for details - Arguments ind, Val, Crit, PreExp, PostExp, Log and InOut are fed to :meth:`~tofu.geom.GDetect.select` - - """ - return SA, Nb, Pts - -
[docs] def calc_Sig(self, ff, extargs={}, Method='Vol', Mode='simps', PreComp=True, - epsrel=tfd.DetSynthEpsrel, dX12=tfd.DetSynthdX12, dX12Mode=tfd.DetSynthdX12Mode, ds=tfd.DetSynthds, dsMode=tfd.DetSynthdsMode, MarginS=tfd.DetSynthMarginS, Colis=tfd.DetCalcSAngVectColis, Test=True, - ind=None, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In'): - """ Applies :meth:`~tofu.geom.Detect.calc_Sig` to all :class:`~tofu.geom.Detect` instances - - See :meth:`~tofu.geom.Detect.calc_Sig` for details - Arguments ind, Val, Crit, PreExp, PostExp, Log and InOut are fed to :meth:`~tofu.geom.GDetect.select` - - """ - GD, Leg, LOSRef = _tfg_p._get_LD_Leg_LOSRef(self, LOSRef=self._LOSRef, ind=ind, Val=Val, Crit=Crit, PreExp=PreExp, PostExp=PostExp, Log=Log, InOut=InOut) - Sig = [dd.calc_Sig(ff, extargs=extargs, Method=Method, Mode=Mode, PreComp=PreComp, epsrel=epsrel, dX12=dX12, dX12Mode=dX12Mode, ds=ds, dsMode=dsMode, MarginS=MarginS, Colis=Colis,Test=Test) for dd in GD] - return np.vstack(Sig).T, GD
- - - def _calc_Res(self, Pts=None, CrossMesh=[0.01,0.01], CrossMeshMode='abs', Mode='Iso', Amp=1., Deg=0, steps=0.001, Thres=0.05, ThresMode='rel', ThresMin=0.01, - IntResCross=[0.1,0.1], IntResCrossMode='rel', IntResLong=0.05, IntResLongMode='rel', - Eq=None, PlotDetail=False, Cdict=dict(tfd.DetConed), Ntt=100, SaveName=None, SavePath='./', save=False, Test=True): - """ Applies :meth:`~tofu.geom.Detect._calc_Res` to all :class:`~tofu.geom.Detect` instances - - See :meth:`~tofu.geom.Detect._calc_Res` for details - - """ - - Res, Pts, LDetLim, Mode, steps, Thres, ThresMode, ThresMin, IntResCross, IntResCrossMode, IntResLong, IntResLongMode \ - = _Calc_Resolution(self, Pts=Pts, CrossMesh=CrossMesh, CrossMeshMode=CrossMeshMode, Mode=Mode, Amp=Amp, Deg=Deg, steps=steps, Thres=Thres, ThresMode=ThresMode, ThresMin=ThresMin, - IntResCross=IntResCross, IntResCrossMode=IntResCrossMode, IntResLong=IntResLong, IntResLongMode=IntResLongMode, - Eq=Eq, PlotDetail=PlotDetail, Cdict=Cdict, Ntt=Ntt, SaveName=SaveName, SavePath=SavePath, save=save, Test=Test) - return Res, Pts, LDetLim, Mode, steps, Thres, ThresMode, ThresMin, IntResCross, IntResCrossMode, IntResLong, IntResLongMode - - - - def _set_Res(self, CrossMesh=[0.05,0.02], CrossMeshMode='rel', Mode='Iso', Amp=1., Deg=0, steps=0.001, Thres=0.05, ThresMode='rel', ThresMin=0.01, - IntResCross=[0.1,0.1], IntResCrossMode='rel', IntResLong=0.05, IntResLongMode='rel', Eq=None, Ntt=100, EqName=None, save=False, Test=True): - """ Compute the resolution of the Detect instance on a mesh grid of the Cross section, with specified parameters - - See :meth:`~tofu.geom.Detect._set_Res` for details - - """ - Res, Pts, LDetLim, Mode, steps, Thres, ThresMode, ThresMin, IntResCross, IntResCrossMode, IntResLong, IntResLongMode \ - = _Calc_Resolution(self, Pts=None, CrossMesh=CrossMesh, CrossMeshMode=CrossMeshMode, Mode=Mode, Amp=Amp, Deg=Deg, steps=steps, Thres=Thres, ThresMode=ThresMode, ThresMin=ThresMin, - IntResCross=IntResCross, IntResCrossMode=IntResCrossMode, IntResLong=IntResLong, IntResLongMode=IntResLongMode, Eq=Eq, Ntt=Ntt, PlotDetail=False, save=False, Test=Test) - - self._Res_Mode, self._Res_Amp, self._Res_Deg = Mode, Amp, Deg - self._Res_Pts, self._Res_Res, self._Res_DetLim, self._Res_CrossMesh, self._Res_CrossMeshMode = Pts, Res, LDetLim, CrossMesh, CrossMeshMode - self._Res_steps, self._Res_Thres, self._Res_ThresMode, self._Res_ThresMin = steps, Thres, ThresMode, ThresMin - self._Res_IntResCross, self._Res_IntResCrossMode, self._Res_IntResLong, self._Res_IntResLongMode = IntResCross, IntResCrossMode, IntResLong, IntResLongMode - self._Res_EqName = EqName - self._Res_Done = True - if save: - self.save() - - def _reset_Res(self): - self._Res_Mode, self._Res_Amp, self._Res_Deg = None, None, None - self._Res_Pts, self._Res_Res, self._Res_DetLim, self._Res_CrossMesh, self._Res_CrossMeshMode = None, None, None, None, None - self._Res_steps, self._Res_Thres, self._Res_ThresMode, self._Res_ThresMin = None, None, None, None - self._Res_IntResCross, self._Res_IntResCrossMode, self._Res_IntResLong, self._Res_IntResLongMode = None, None, None, None - self._Res_EqName = None - self._Res_Done = False - - -
[docs] def plot(self, Lax=None, Proj='All', Elt='PVC', EltLOS='LDIORP', EltOptics='P', EltVes='', Leg=None, LOSRef=None, - Pdict=tfd.ApPd, Vdict=tfd.ApVd, Cdict=tfd.DetConed, LVIn=tfd.ApLVin, - LOSdict=tfd.LOSdict, Opticsdict=tfd.Apertdict, Vesdict=tfd.Vesdict, - LegDict=tfd.TorLegd, draw=True, a4=False, Test=True, - ind=None, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In'): - """ Plot all or a subset of the Detect instances in a projection or in 3D - - See :meth:`~tofu.geom.Detect.plot` for details - Arguments ind, Val, Crit, PreExp, PostExp, Log and InOut are fed to :meth:`~tofu.geom.GDetect.select` - - Parameters - ---------- - Lax : None, plt.Axes or list - Axes or list of axes to be used for plotting, if None a new figure and appropriate axes are created - Proj : str - Flag indicating whether to plot the cross-section ('Cross'), the horizontal projection ('Hor'), both ('All') or a 3D representation ('3D') - Elt : str - Flag indicating which elements of the Detect instance to plot, each capital letter stands for an element - * 'P': polygon - * 'V': perpendicular vector - * 'C': viewing cone - EltLOS : None or str - Flag indicating which elements of the LOS to plot, will be fed to LOS.plot(), if None uses the 'Elt' arg of LOSdict instead - EltOptics : None or str - Flag indicating which elements of the Aperts to plot, will be fed to Apert.plot(), if None uses the 'Elt' arg of Apertdict instead - EltVes : None or str - Flag indicating which elements of the :class:`~tofu.geom.Ves` to plot, will be fed to :meth:`~tofu.geom.Ves.plot`, if None uses the 'Elt' arg of Vesdict instead - Leg : str - Legend to be used for the detector, if '' the Detect.iD.Name is used - LOSRef : None or str - Flag indicating which LOS should be represented, if None Detect._LOSRef is used - Pdict : dict - Dictionary of properties for the Polygon - Vdict : dict - Dictionary of properties for the Vector - Cdict : dict - Dictionary of properties for the Cone - LVIn : float - Length of the Vector - LOSdict : dict - Dictionary of properties for the LOS if EltLOS is not '', fed to LOS.plot() - Apertdict : dict - Dictionary of properties for the Apert if EltOptics is not '', fed to Apert.plot() - Vesdict : dict - Dictionary of properties for the :class:`~tofu.geom.Ves` if EltVes is not '', fed to :meth:`~tofu.geom.Ves.plot` - LegDict : dict - Dictionary of properties for the legend, fed to plt.legend() - draw : bool - Flag indicating whether to draw the figure - a4 : bool - Flag indicating whether the default figure should be of size a4 paper - Test : bool - Flag indicating whether the inputs should be tested for conformity - - Returns - ------- - Lax plt.Axes or list - Axes or list of axes used for plotting - - """ - return _tfg_p.GLDetect_plot(self, Lax=Lax, Proj=Proj, Elt=Elt, EltOptics=EltOptics, EltLOS=EltLOS, EltVes=EltVes, Leg=Leg, LOSRef=LOSRef, - Pdict=Pdict, Vdict=Vdict, Cdict=Cdict, LVIn=LVIn, - LOSdict=LOSdict, Opticsdict=Opticsdict, Vesdict=Vesdict, LegDict=LegDict, draw=draw, Test=Test, - ind=ind, Val=Val, Crit=Crit, PreExp=PreExp, PostExp=PostExp, Log=Log, InOut=InOut)
- - -
[docs] def plot_SAngNb(self, Lax=None, Proj='Cross', Slice='Int', Pts=None, plotfunc='scatter', DRY=None, DXTheta=None, DZ=None, - Elt='P', EltVes='P', EltLOS='', EltOptics='P', - Pdict=tfd.ApPd, Vdict=tfd.ApVd, Cdict=tfd.DetConed, LVIn=tfd.ApLVin, - LOSdict=tfd.LOSdict, Opticsdict=tfd.Apertdict, Vesdict=tfd.Vesdict, - CDictSA=None, CDictNb=None, Colis=tfd.DetSAngColis, a4=False, draw=True, Test=True, - ind=None, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In'): - """ Plot the solid angle projections (integrated 'Int' or maximum 'Max') as well as the number of detectors visible from each point in the plasma - - See :meth:`~tofu.geom.Detect.plot_SAngNb` for details - Arguments ind, Val, Crit, PreExp, PostExp, Log and InOut are fed to :meth:`~tofu.geom.GDetect.select` - - Parameters - ---------- - Lax : None or list or plt.Axes - Axes or list of Axes to be used for plotting, if None a new figure and appropriate axes are created - Proj : str - Flag indicating whether to plot the cross-section ('Cross') or the horizontal projection ('Hor') - Mode : str, None or float - Flag indicating whether to plot: - * 'Int': the integrated value along the projected coordinates - * 'Max': the maximum value along the projected coordinates - * float: the projected coordinate at which to plot the slice (Theta or X if Proj='Cross', Z if Proj='Hor') - * None: the slice is done in the middle of the viewing volume - plotfunc : str - Flag indicating which plotting method to use ('scatter', 'contour', 'contourf' or 'imshow') - DCross : float - Resolution along the 1st cross-section coordinate (R for Type='Tor', Y for Type='Lin') - DXTheta : float - Resolution along the ignorable coordinate (Theta for Type='Tor', X for Type='Lin') - DZ : float - Vertical resolution (for both Types) - CDictSA : dict - Properties of the solid angle plot, to be fed to the function chosen by plotfunc - CDictNb : dict - Properties of the Nb plot, to be fed to ... - Colis : bool - Flag indicating whether collision detection should be used - a4 : bool - Flag indicating whether to use a4 dimensions to create a new figure if Lax=None - draw : bool - Flag indicating whether to draw the figure - Test : bool - Flag indicating whether the inputs should be tested for conformity - - Returns - ------- - Lax plt.Axes or list List of the axes used for plotting - - """ - SA, Nb, Pts = self.calc_SAngNb(Pts=Pts, Proj=Proj, Slice=Slice, DRY=DRY, DXTheta=DXTheta, DZ=DZ, Colis=Colis, ind=ind, Val=Val, Crit=Crit, PreExp=PreExp, PostExp=PostExp, Log=Log, InOut=InOut) - Lax = _tfg_p._GLDetect_plot_SAngNb(Leg=self.Id.Name, SA=SA, Nb=Nb, Pts=Pts, Lax=Lax, Proj=Proj, Slice=Slice, plotfunc=plotfunc, CDictSA=CDictSA, CDictNb=CDictNb, Colis=Colis, - DRY=DRY, DXTheta=DXTheta, VType=self.Ves.Type, a4=a4, draw=False, Test=Test) - if any([not ss=='' for ss in [Elt,EltVes, EltLOS, EltOptics]]): - Lax[0] = self.plot(Proj=Proj, Lax=Lax[0], Elt=Elt, EltVes=EltVes, EltLOS=EltLOS, EltOptics=EltOptics, Pdict=Pdict, Vdict=Vdict, Cdict=Cdict, LVIn=LVIn, - LOSdict=LOSdict, Opticsdict=Opticsdict, Vesdict=Vesdict, LegDict=None, a4=a4, draw=False, Test=Test, - ind=ind, Val=Val, Crit=Crit, PreExp=PreExp, PostExp=PostExp, Log=Log, InOut=InOut) - Lax[1] = self.plot(Proj=Proj, Lax=Lax[1], Elt=Elt, EltVes=EltVes, EltLOS=EltLOS, EltOptics=EltOptics, Pdict=Pdict, Vdict=Vdict, Cdict=Cdict, LVIn=LVIn, - LOSdict=LOSdict, Opticsdict=Opticsdict, Vesdict=Vesdict, LegDict=None, a4=a4, draw=False, Test=Test, - ind=ind, Val=Val, Crit=Crit, PreExp=PreExp, PostExp=PostExp, Log=Log, InOut=InOut) - if draw: - Lax[0].figure.canvas.draw() - return Lax
- - -
[docs] def plot_Etend_AlongLOS(self, ax=None, NP=tfd.DetEtendOnLOSNP, kMode='rel', Modes=['trapz'], RelErr=None, dX12=None, dX12Mode=None, Ratio=None, LOSRef=None, - LOSPts=True, Ldict=tfd.DetEtendOnLOSLd, LegDict=tfd.TorLegd, Colis=tfd.DetSAngColis, draw=True, a4=True, Test=True, - ind=None, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In'): - """ Plot the etendue of the selected LOS along it, with or without collision detection - - The number of points along the LOS where the etendue is computed can be specified via arguments, as well as the numerical integration method. - See :meth:`~tofu.geom.Detect.plot_Etendue_AlongLOS` for details - Arguments Length, NP, Modes, RelErr, dX12, dX12Mode, Ratio, Colis, LOSRef are fed to :meth:`~tofu.geom.Detect.calc_Etendue_AlongLOS` - Arguments ind, Val, Crit, PreExp, PostExp, Log and InOut are fed to :meth:`~tofu.geom.GDetect.select` - - Parameters - ---------- - ax : None or plt.Axes - Axes to be used for plotting, if None a new figure and appropriate axes are created - NP : int - Number of points along the LOS at which the Etendue should be computed - kMode : str - Flag indicating whether the distance on the line should be plotted as abolute distance ('abs') or relative to the total length ('rel') - Modes : str or list - Flag or list of flags indicating which integration method should be used - Colis : bool - Flag indicating whether collision detection should be used - LOSRef : None or str - Flag indicating which LOS should be used - Ldict : dict - Dictionary of properties for plotting the result - LegDict : None / dict - If None, no legend is plotted, else LegDict is fed to :meth:'~matplotlib.pyplot.Axes.legend' - draw : bool - Flag indicating whether to draw the figure - a4 : bool - Flag indicating whether the created figure should have a4 dimensions (useful for printing) - Test : bool - Flag indicating whether the inputs should be tested for conformity - - Returns - ------- - ax : plt.Axes - The axes used for plotting - - """ - if ind is None: - ind = self.select(Val=Val,Crit=Crit,InOut=InOut,Out=int) - elif ind.dtype.name=='bool': - ind = ind.nonzero()[0] - LD = [self.LDetect[ii] for ii in ind] - nD = len(LD) - LOSRef = self._LOSRef if LOSRef is None else LOSRef - for ii in range(0,nD): - ax = LD[ii].plot_Etend_AlongLOS(ax=ax, NP=NP, kMode=kMode, Modes=Modes, RelErr=RelErr, dX12=dX12, dX12Mode=dX12Mode, Ratio=Ratio, LOSRef=LOSRef, - LOSPts=LOSPts, Ldict=Ldict, LegDict=None, Colis=Colis, draw=False, a4=a4, Test=Test) - if LegDict is not None: - ax.legend(**LegDict) - if draw: - ax.figure.canvas.draw() - return ax
- -
[docs] def plot_Sinogram(self, ax=None, Proj='Cross', Elt='DLV', Ang='theta', AngUnit='rad', Sketch=True, Ddict=tfd.DetImpd, Ldict=tfd.LOSMImpd, Vdict=tfd.TorPFilld, LegDict=tfd.TorLegd, LOSRef=None, draw=True, a4=False, Test=True, - ind=None, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In'): - """ Plot the VOS of all or of a subset of the :class:`~tofu.geom.Detect` instances in projection space, optionally also the associated :class:`~tofu.geom.Ves` object and reference :class:`~tofu.geom.LOS` - - See :meth:`~tofu.geom.Detect.plot_Sinogram` for details - Arguments ind, Val, Crit, PreExp, PostExp, Log and InOut are fed to :meth:`~tofu.geom.GDetect.select` - - """ - ax = _tfg_p.GLDetect_plot_Sinogram(self, Proj=Proj, ax=ax, Elt=Elt, Sketch=Sketch, Ang=Ang, AngUnit=AngUnit, Ddict=Ddict, Ldict=Ldict, Vdict=Vdict, LegDict=LegDict, LOSRef=LOSRef, draw=draw, a4=a4, Test=Test, - ind=ind, Val=Val, Crit=Crit, PreExp=PreExp, PostExp=PostExp, Log=Log, InOut=InOut) - return ax
- -
[docs] def plot_Etendues(self, Mode='Etend', Elt='', ax=None, Adict=tfd.GDetEtendMdA, Rdict=tfd.GDetEtendMdR, Edict=tfd.GDetEtendMdS, LegDict=tfd.TorLegd, draw=True, a4=False, Test=True, - ind=None, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In'): - """ Plot the etendues of all or a subset of the :class:`~tofu.geom.Detect` instances for the chosen :class:`~tofu.geom.LOS` - - A given Detect+Optics system has a VOS, under proper conditions, this VOS can be approximated by a LOS, but the choice of the LOS is not unique, there is an infinite number of possible LOS in a single VOS. - The LOS automatically computed by tofu os the 'natural' option : goes from the midlle of the Detect area throught the middle of the optics. - Then tofu automatically computes the associated etendue. - This methods plots all the etendues of all the chosen :class:`~tofu.geom.Detect` instances for the chosen :class:`~tofu.geom.LOS`, which is by default the 'natural' LOS computed by tofu - - Parameters - ---------- - Mode : str - Flasg indicating whether to plot the etendue ('Etend') or a geometrical calibration factor ('Calib') computed as the 4pi/etendue - Elt : str - Flag indicating whether to plot, in addition to the etendue, also the direct ('A') and reverse ('R') 0-order approximation of the etendue - ax : None or plt.Axes - Axes to be used for plotting, if None a new figure and appropriate axes are created - Adict : dict - Dictionary of properties for plotting the direct 0-order approximation of the etendue (if 'A' in Elt), fed to :meth:`~matplotlib.pyplot.Axes.plot` - Rdict : dict - Dictionary of properties for plotting the reverse 0-order approximation of the etendue (if 'R' in Elt), fed to :meth:`~matplotlib.pyplot.Axes.plot` - Edict : dict - Dictionary of properties for plotting the etendue, fed to :meth:`~matplotlib.pyplot.Axes.plot` - LegDict : dict - If None, no legend is plotted, else LegDict is fed to :meth:'~matplotlib.pyplot.Axes.legend' - draw : bool - Flag indicating whether to draw the figure - a4 : bool - Flag indicating whether the created figure should have a4 dimensions (useful for printing) - Test : bool - Flag indicating whether the inputs should be tested for conformity - - Returns - ------- - ax : plt.Axes - The axes used for plotting - - """ - ax = _tfg_p.Plot_Etendues_GDetect(self, ax=ax, Mode=Mode, Elt=Elt, Adict=Adict, Rdict=Rdict, Edict=Edict, LegDict=LegDict, draw=draw, a4=a4, Test=Test, - ind=ind, Val=Val, Crit=Crit, PreExp=PreExp, PostExp=PostExp, Log=Log, InOut=InOut) - return ax
- - -
[docs] def plot_Sig(self, ffSig, extargs={}, Method='Vol', Mode='simps', ax=None, Leg='', Sdict=tfd.GDetSigd, LegDict=tfd.TorLegd, draw=True, a4=False, Test=True, - PreComp=True, epsrel=tfd.DetSynthEpsrel, dX12=tfd.DetSynthdX12, dX12Mode=tfd.DetSynthdX12Mode, ds=tfd.DetSynthds, dsMode=tfd.DetSynthdsMode, MarginS=tfd.DetSynthMarginS, Colis=tfd.DetCalcSAngVectColis, - ind=None, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In'): - """ Plot the ignal computed for each or a subset of the :class:`~tofu.geom.Detect` instances - - If the signal is not directly provided as an array, it is computed from a function. - If ffSig is a callable function, arguments ffSig, extargs, Method, Mode, PreComp, epsrel, dX12, dX12Mode, ds, dsMode, MarginS, Colis and Test are fed to :meth:`~tofu.geom.GDetect.calc_Sig` - Arguments ind, Val, Crit, PreExp, PostExp, Log and InOut are fed to :meth:`~tofu.geom.GDetect.select` - - Parameters - ---------- - ffSig np.ndarray or callable - Either a np.ndarray containing the signal to be plotted (of shape (ND,) or (N,ND) where ND is the number of detectors to be plotted) or a callable to be fed to for computing the signal - ax : None or plt.Axes - Axes to be used for plotting, if None a new figure and appropriate axes are created - Sdict : dict - Dictionary of properties for plotting the signal, fed to :meth:`~matplotlib.pyplot.Axes.plot` - Leg : str - Label to be used for the plot - LegDict : dict - If None, no legend is plotted, else LegDict is fed to :meth:'~matplotlib.pyplot.Axes.legend' - draw : bool - Flag indicating whether to draw the figure - a4 : bool - Flag indicating whether the created figure should have a4 dimensions (useful for printing) - Test : bool - Flag indicating whether the inputs should be tested for conformity - - Returns - ------- - ax : plt.Axes - The axes used for plotting - - """ - assert type(ffSig) is np.ndarray or hasattr(ffSig,'__call__'), "Arg ffSig must be either pre-computed np.ndarray of signals or a callable function for computing it (fed to GDetect.calc_Sig()) !" - if type(ffSig) is not np.ndarray: - ffSig, GD = self.calc_Sig(ffSig, extargs=extargs, Method=Method, Mode=Mode, PreComp=PreComp, epsrel=epsrel, dX12=dX12, dX12Mode=dX12Mode, ds=ds, dsMode=dsMode, MarginS=MarginS, Colis=Colis, Test=Test) - else: - GD, Leg, LOSRef = _tfg_p._get_LD_Leg_LOSRef(self, Leg=Leg, LOSRef=LOSRef, ind=ind, Val=Val, Crit=Crit, PreExp=PreExp, PostExp=PostExp, Log=Log, InOut=InOut) - assert (ffSig.ndim==1 and ffSig.size==len(GD)) or (ffSig.ndim==2 and ffSig.shape[1]==len(GD)), "Arg ffSig does not have the good shape !" - ax = _tfg_p.Plot_Sig_GDetect(GD, ffSig, ax=ax, Leg=Leg, Sdict=Sdict, LegDict=LegDict, draw=draw, a4=a4, Test=Test) - return ax
- - - def _plot_Res(self, ax=None, plotfunc='scatter', NC=20, CDict=None, draw=True, a4=False, Test=True): - """ see :meth:`~tofu.geom.Detect._plot_Res` for details - - """ - assert self._Res_Done, "Cannot plot the resolution before it has been computed on a mesh grid with self.set_Res() !" - ax = _tfg_p._Resolution_Plot(self._Res_Pts, self._Res_Res, self, self._Res_DetLim, ax=ax, plotfunc=plotfunc, NC=NC, CDict=CDict, draw=draw, a4=a4, Test=Test) - return ax - - -
[docs] def save(self,SaveName=None,Path=None,Mode='npz', compressed=False, SynthDiag=False): - """ Save the object in folder Name, under file name SaveName, using specified mode - - Most tofu objects can be saved automatically as numpy arrays (.npz, recommended) at the default location (recommended) by simply calling self.save() - In the case of Detect and GDetect instances, there is an additional keyword argument 'SynthDiag' which allows to **not** save the pre-computed 3D mesh of the VOS for synthetic diagnostic. - Indeed, this pre-computed data is often large and results in big files. Not saving it results in significantly smaller files, and it can be re-computed when loading the instance. - - Parameters - ---------- - SaveName : None / str - The name to be used for the saved file, if None (recommended) uses self.Id.SaveName - Path : None / str - Path specifying where to save the file, if None (recommended) uses self.Id.SavePath - Mode : str - Flag specifying whether to save the object as a numpy array file ('.npz', recommended) or an object using cPickle (not recommended, heavier and may cause retro-compatibility issues) - compressed : bool - Flag, used when Mode='npz', indicating whether to use np.savez or np.savez_compressed (slower saving and loading but smaller files) - SynthDiag : bool - Flag indicating whether the pre-computed mesh for synthetic diagnostics calculations shall be saved too (can be heavy, if False, it will be re-computed when opening the saved object) - - """ - if not SynthDiag: - for ii in range(0,self.nDetect): - self.LDetect[ii]._reset_SynthDiag() - tfpf.Save_Generic(self, SaveName=SaveName, Path=Path, Mode=Mode, compressed=compressed)
- - - - - -def _get_OpticsFromLDetect(LD): - LO = [] - for ii in range(0,len(LD)): - if ii==0: - LO += LD[ii].Optics - else: - for jj in range(0,len(LD[ii].Optics)): - if not any([tfpf.CheckSameObj(aa, LD[ii].Optics[jj], ['Poly','Name','SaveName','Type']) for aa in LO]): - LO.append(LD[ii].Optics[jj]) - return LO - - -def _GDetect_set_Defaults(LDetect=None, Exp=None, Diag=None, Sino_RefPt=None, LOSRef=None): - if not LDetect is None: - if type(LDetect) is list: - Diag = Diag if not Diag is None else LDetect[0].Id.Diag - Exp = Exp if not Exp is None else LDetect[0].Id.Exp - Sino_RefPt = Sino_RefPt if not Sino_RefPt is None else LDetect[0].Sino_RefPt - LOSRef = LOSRef if not LOSRef is None else LDetect[0]._LOSRef - else: - Diag = Diag if not Diag is None else LDetect.Id.Diag - Exp = Exp if not Exp is None else LDetect.Id.Exp - Sino_RefPt = Sino_RefPt if not Sino_RefPt is None else LDetect.Sino_RefPt - LOSRef = LOSRef if not LOSRef is None else LDetect._LOSRef - LDetect = [LDetect] - return LDetect, Exp, Diag, Sino_RefPt, LOSRef - - - - - -def _GDetect_check_inputs(Id=None, LDetect=None, Type=None, Optics=None, Vess=None, Sino_RefPt=None, Exp=None, Diag=None, shot=None, CalcEtend=None, CalcSpanImp=None, CalcCone=None, CalcPreComp=None, Calc=None, Verb=None, - Etend_RelErr=None, Etend_dX12=None, Etend_dX12Mode=None, Etend_Ratio=None, Colis=None, LOSRef=None, Etend_Method=None, - MarginRMin=None, NEdge=None, NRad=None, Nk=None, - Cone_DRY=None, Cone_DXTheta=None, Cone_DZ=None, Cone_NPsi=None, Cone_Nk=None, - arrayorder=None, Clock=None, SavePath=None, dtime=None, dtimeIn=None): - - if not Id is None: - assert type(Id) in [str,tfpf.ID], "Arg Id must be a str or a tfpf.ID object !" - if not LDetect is None: - assert type(LDetect) is list and all([type(dd) is Detect for dd in LDetect]), "Arg LDetect must be a list of Detect instances !" - assert all([tfpf.CheckSameObj(LDetect[0].Ves,dd.Ves, ['Poly','Name','SaveName']) for dd in LDetect]), "All Detect objects must have the same :class:`~tofu.geom.Ves` object !" - assert all([np.all(dd.Sino_RefPt==LDetect[0].Sino_RefPt) for dd in LDetect]) - assert all([dd.Id.Exp==LDetect[0].Id.Exp for dd in LDetect]), "All Detect instances in LDetect must belong to the same Exp !" - assert all([dd.Id.Diag==LDetect[0].Id.Diag for dd in LDetect]), "All Detect instances in LDetect must belong to the same Diag !" - if not Exp is None: - assert Exp==LDetect[0].Id.Exp, "Arg Exp must be identical to the LDetect Exp !" - if not Diag is None: - assert Diag==LDetect[0].Id.Diag, "Arg Diag must be identical to the LDetect Diag !" - if not arrayorder is None: - assert arrayorder in ['C','F'], "Arg arrayorder must be in ['C','F'] !" - bools = [Clock,dtimeIn] - if any([not aa is None for aa in bools]): - assert all([aa is None or type(aa) is bool for aa in bools]), " Args [CalcEtend,CalcSpanImp,CalcCone,CalcPreComp,Calc,Verb,Colis,Clock,dtimeIn] must all be bool !" - if not Exp is None: - assert Exp in tfd.AllowedExp, "Arg Exp must be in "+str(tfd.AllowedExp)+" !" - assert Type is None, "Arg Type must be None for GDetect objects !" - Iter2 = [Sino_RefPt] - if any([not aa is None for aa in Iter2]): - assert all([aa is None or (hasattr(aa,'__iter__') and np.asarray(aa).shape==(2,)) for aa in Iter2]), "Args [Sino_RefPt] must be an iterable with len()=2 !" - strs = [Diag,SavePath] - if any([not aa is None for aa in strs]): - assert all([aa is None or type(aa) is str for aa in strs]), "Args [dX12Mode,LOSRef,Method,Diag,SavePath] must all be str !" - ints = [shot] - if any([not aa is None for aa in ints]): - assert all([aa is None or type(aa) is int for aa in ints]), "Args [shot,NEdge,NRad] must be int !" - if not dtime is None: - assert type(dtime) is dtm.datetime, "Arg dtime must be a dtm.datetime !" - - - - -def _GDetect_Calc_SAngNb(GD, Pts=None, Proj='Cross', Slice='Int', DRY=None, DXTheta=None, DZ=None, Colis=tfd.DetSAngColis, - ind=None, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In'): - if ind is None: - ind = GD.select(Val=Val,Crit=Crit,InOut=InOut,Out=int) - elif ind.dtype.name=='bool': - ind = ind.nonzero()[0] - LD = [GD.LDetect[ii] for ii in ind] - nD = len(LD) - if DRY is None: - DRY = min([dd._Cone_Poly_DR for dd in LD]) if GD.Ves.Type=='Tor' else min([dd._Cone_Poly_DY for dd in LD]) - if DXTheta is None: - DXTheta = min([dd._Cone_Poly_DTheta for dd in LD]) if GD.Ves.Type=='Tor' else min([dd._Cone_Poly_DX for dd in LD]) - if DZ is None: - DZ = min([dd._Cone_Poly_DZ for dd in LD]) - # Get the mesh if Pts not provided - if Pts is None: - LLOS = GD.get_GLOS().LLOS - LLOS = [LLOS[ii] for ii in ind] - SingPts = np.vstack(tuple([np.vstack((ll.PIn, ll.PIn+0.002*ll.u, 0.5*(ll.POut+ll.PIn), ll.POut-0.002*ll.u , ll.POut)) for ll in LLOS])).T - LSpan_Z = [dd._Span_Z for dd in LD] - if GD.Ves.Type=='Tor': - LSpan_R = [dd._Span_R for dd in LD] - LSpan_Theta = [dd._Span_Theta for dd in LD] - LSpan_Z = [dd._Span_Z for dd in LD] - X1, XIgn, Z, NX1, NIgn, NZ, Pts, out = _tfg_c._get_CrossHorMesh(SingPoints=SingPts, LSpan_R=LSpan_R, LSpan_Theta=LSpan_Theta, LSpan_Z=LSpan_Z, DR=DRY, DTheta=DXTheta, DZ=DZ, - VType=GD.Ves.Type, Proj=Proj, ReturnPts=True) - elif GD.Ves.Type=='Lin': - LSpan_X = [dd._Span_X for dd in LD] - LSpan_Y = [dd._Span_Y for dd in LD] - XIgn, X1, Z, NIgn, NX1, NZ, Pts, out = _tfg_c._get_CrossHorMesh(SingPoints=SingPts, LSpan_X=LSpan_X, LSpan_Y=LSpan_Y, LSpan_Z=LSpan_Z, DX=DXTheta, DY=DRY, DZ=DZ, VType=GD.Ves.Type, Proj=Proj, ReturnPts=True) - - # Get the Solid angle (itself, or Int or Max) - SA = np.zeros((nD,Pts.shape[1])) - if Slice in ['Int','Max']: - for ii in range(0,nD): - FF = LD[ii]._get_SAngIntMax(Proj=Proj, SAng=Slice) - SA[ii,:] = FF(Pts, In=out) - if np.any(SA[ii,:]<0.): - print " SAngNb : ", LD[ii].Id.Name, " has negative SAng values !" - else: - if Proj=='Hor': - Span = [min([oo[0] for oo in LSpan_Z]), max([oo[1] for oo in LSpan_Z])] - else: - Span = [min([oo[0] for oo in LSpan_Theta]), max([oo[1] for oo in LSpan_Theta])] if GD.Ves.Type=='Tor' else [min([oo[0] for oo in LSpan_X]), max([oo[1] for oo in LSpan_X])] - assert Slice>=Span[0] and Slice<=Span[1], "Arg Slice is outside of the interval were non-zeros values can be found !" - Ptsint = _tfg_gg.CoordShift(Pts, In=out, Out='(X,Y,Z)', CrossRef=Slice) - for ii in range(0,nD): - SA[ii,:] = LD[ii].calc_SAngVect(Ptsint, In='(X,Y,Z)', Colis=Colis, Test=True)[0] - if np.any(SA[ii,:]<0.): - print " SAngNb : ", LD[ii].Id.Name, " has negative SAng values !" - Nb = np.sum(SA>0.,axis=0) - SA = np.sum(SA,axis=0) - return SA, Nb, Pts - - - - - - - - - - - - - - - - - - - - - - - - - - - - -""" -############################################################################### -############################################################################### - Special high-level functions -############################################################################### -""" - - - -def _Calc_Resolution(GLD, Pts=None, CrossMesh=[0.01,0.01], CrossMeshMode='abs', Mode='Iso', Amp=1., Deg=0, steps=0.001, Thres=0.05, ThresMode='rel', ThresMin=0.01, - IntResCross=[0.1,0.1], IntResCrossMode='rel', IntResLong=0.05, IntResLongMode='rel', - Eq=None, PlotDetail=False, Cdict=dict(tfd.DetConed), Ntt=100, - ind=None, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In', SaveName=None, SavePath='./', save=False, Test=True): - if Test: - assert type(GLD) in [list,Detect,GDetect], "Arg GLD must be a Detect or list of such or a GDetect instance !" - assert Pts is None or (hasattr(Pts,'__iter__') and np.asarray(Pts).ndim in [1,2]), "Arg Pts must be an iterable with Points coordinates !" - assert len(CrossMesh)==2, "Arg CrossMesh must be a len()==2 iterable with the desired mesh resolution in the two directions !" - assert CrossMeshMode in ['abs','rel'], "Arg CrossMeshMode must be in ['abs','rel'] !" - assert Mode in ['Iso','HorVert','Equi'], "Arg Mode must be in ['Iso','HorVert','Equi'] !" - assert type(Amp) is float, "Arg Amp must be a float (amplitude of the emissivity) !" - assert type(Deg) is int, "Arg Deg must be a int (degree of the bivariate b-splines) !" - assert type(steps) is float or (hasattr(steps,'__iter__') and len(steps)==2), "Arg steps must be a float or an iterable of 2 floats (incremental increase of emissivity size, in absolute value, meters or rad) !" - assert type(Thres) is float or hasattr(Thres,'__iter__'), "Arg Thres must be a float or an iterable (fraction of the initial signal above which a change can be considered visible) !" - assert len(IntResCross)==2, "Arg IntResCross must be an iterable of len()==2 with absolute resolution to be used for signal integration ([DRY,DZ]) !" - assert type(IntResLong) is float, "Arg IntResLong must be a float with the absolute resolution to be used for signal integration (DXTheta) !" - assert Eq is None or hasattr(Eq,'__call__'), "Arg Eq must be None or a callable function (delivering etheta tangent to flux surface for each point in cross-section) !" - - # Convert to list of Detect, with common legend if GDetect - GLD, Leg, LOSRef = _tfg_p._get_LD_Leg_LOSRef(GLD, Leg=None, LOSRef=None, ind=ind, Val=Val, Crit=Crit, PreExp=PreExp, PostExp=PostExp, Log=Log, InOut=InOut) - ND = len(GLD) - Ves = GLD[0].Ves - if hasattr(Thres,'__iter__'): - Thres = np.asarray(Thres) - assert Thres.ndim==1 and Thres.size==len(GLD), "If an iterable, arg Thres must be the same len() as the input list of Detect !" - - DXTheta = np.array([dd._Span_Theta for dd in GLD]) if Ves.Type=='Tor' else np.array([dd._Span_X for dd in GLD]) - DXTheta = [np.nanmin(DXTheta[:,0]), np.nanmax(DXTheta[:,1])] - - # Build name if save - if save: - if SaveName is None: - Thresstr = "Thres{0:02.0f}-{1:02.0f}".format(100.*ThresMin,100.*Thres) - Thresstr = Thresstr+"Rel" if ThresMode.lower()=='rel' else Thresstr+"Abs" - Stepstr = "Step{0:03.1f}mm".format(1000.*steps) - Intstr = "IntCross{0:02.0f}-{1:02.0f}mm".format(1000.*IntResCross[0],1000.*IntResCross[1]) if IntResCrossMode.lower()=='abs' else "IntCross{0:4.2f}-{1:4.2f}".format(IntResCross[0],IntResCross[1]) - Intstr = Intstr+"_IntLong{0:02.0f}mm".format(1000.*IntResLong) if IntResLongMode.lower()=='abs' else Intstr+"_IntLong{0:4.2f}".format(IntResLong) - SaveName = 'Res_'+GLD[0].Id.Exp+'_Diag'+GLD[0].Id.Diag+'_'+Mode+'_'+Thresstr+'_'+Stepstr+'_'+Intstr - print SaveName - - # Prepare mesh - if Pts is None: - Pts, X1, X2, NumX1, NumX2 = Ves.get_MeshCrossSection(CrossMesh=CrossMesh, CrossMeshMode=CrossMeshMode, Test=True) - else: - Pts = np.asarray(Pts) - Pts = Pts if Pts.ndim==2 else Pts.reshape((Pts.size,1)) - assert Pts.shape[0]==2, "Arg Pts must be provided in (R,Z) or (Y,Z) coordinates (for Ves.Type=Tor or Ves.Type=Lin) !" - In = '(R,Z)' if Ves.Type=='Tor' else '(Y,Z)' - - ind = np.vstack([dd.isInside(Pts, In=In) for dd in GLD]) - - # Prepare THR fraction - Thres = Thres*np.ones((ND,),dtype=float) if type(Thres) is float else Thres - if ThresMode=='abs': - THR = np.copy(Thres) - else: - # Restrict to points initially detected by at least one detector - Pts = Pts[:,np.any(ind,axis=0)] - ind = ind[:,np.any(ind,axis=0)] - NP = Pts.shape[1] - - LDetLim = [] - if Mode=='Iso': - tt = np.linspace(0.,2.*np.pi,Ntt) - Res = np.nan*np.ones((NP,)) - for ii in range(0,NP): - print " Resolution : Point", ii+1, "/", NP - size = 0. - InitSigs = np.zeros((ND,),dtype=float) - if np.any(ind[:,ii]): - Ind = ind[:,ii].nonzero()[0] - pp, Emiss, dV = _Resolution_PpsEmissdV_Iso(Pts[:,ii], DXTheta, size=size, Deg=Deg, Amp=Amp, IntResCross=IntResCross, IntResCrossMode=IntResCrossMode, - IntResLong=IntResLong, IntResLongMode=IntResLongMode, VType=Ves.Type) - InitSigs[ind[:,ii]] = np.asarray([np.sum(Emiss * dV * GLD[jj].calc_SAngVect(pp, In='(X,Y,Z)', Colis=True)[0]) for jj in Ind]) - if not np.any(InitSigs[ind[:,ii]]>0.): - continue - if ThresMode=='rel': - THR = np.min(Thres)*np.nanmin(InitSigs[ind[:,ii]])*np.ones((ND,)) - THR[ind[:,ii]] = Thres[ind[:,ii]]*InitSigs[ind[:,ii]] - if not ThresMin is None: - THRmin = ThresMin*np.nanmax(InitSigs[ind[:,ii]]) - THR[THR<THRmin] = THRmin - - Lsigs = [np.copy(InitSigs)] - Lsize = [size] - while not np.any(np.abs(Lsigs[-1]-InitSigs)>THR): - Lsize.append(Lsize[-1]+steps) - pp, Emiss, dV = _Resolution_PpsEmissdV_Iso(Pts[:,ii], DXTheta, size=Lsize[-1], Deg=Deg, Amp=Amp, IntResCross=IntResCross, IntResCrossMode=IntResCrossMode, - IntResLong=IntResLong, IntResLongMode=IntResLongMode, VType=Ves.Type) - Lsigs.append(np.asarray([np.sum(Emiss * dV * dd.calc_SAngVect(pp, In='(X,Y,Z)', Colis=True)[0]) for dd in GLD])) - - if len(Lsize) == 2: - #print " ...Refining..." - Lsigs = [np.copy(InitSigs)] - Lsize = [0.] - stepsbis = steps/5. - while not np.any(np.abs(Lsigs[-1]-InitSigs)>THR): - Lsize.append(Lsize[-1]+stepsbis) - pp, Emiss, dV = _Resolution_PpsEmissdV_Iso(Pts[:,ii], DXTheta, size=Lsize[-1], Deg=Deg, Amp=Amp, IntResCross=IntResCross, IntResCrossMode=IntResCrossMode, - IntResLong=IntResLong, IntResLongMode=IntResLongMode, VType=Ves.Type) - Lsigs.append(np.asarray([np.sum(Emiss * dV * dd.calc_SAngVect(pp, In='(X,Y,Z)', Colis=True)[0]) for dd in GLD])) - - # Identify the Detect that passed the threshold and interpolate an accurate value of Res from Lsize - indDet = (np.abs(Lsigs[-1]-InitSigs)>THR).nonzero()[0][0] - ss = [Lsigs[-2][indDet],Lsigs[-1][indDet]] - crit = InitSigs[indDet]+THR[indDet] if Lsigs[-1][indDet] > InitSigs[indDet]+THR[indDet] else InitSigs[indDet]-THR[indDet] - Res[ii] = (np.diff(Lsize[-2:]))/np.diff(ss) * (crit-Lsigs[-2][indDet]) + Lsize[-2] - LDetLim.append(GLD[indDet].Id.Name) - - if PlotDetail: - print 'InitSigs[ind[:,ii]]', InitSigs[ind[:,ii]] - print 'THR[ind[:,ii]]', THR[ind[:,ii]] - ax1, ax2, ax3 = _tfg_p._Resolution_PlotDetails(GLD, ND, Pts[:,ii], np.array(Lsize), np.vstack(Lsigs), InitSigs, len(Lsigs), indDet, Ind, Res[ii], Ves, THR, tt=tt, Cdict=dict(Cdict), draw=True) - #print " ", GLD[indDet].Id.Name, Res[ii] - - if save: - np.savez(SavePath+SaveName+'.npz', Res=Res, LDetLim=LDetLim, Pts=Pts, Mode=Mode, steps=steps, Thres=Thres, ThresMode=ThresMode, ThresMin=ThresMin, - IntResCross=IntResCross, IntResCrossMode=IntResCrossMode, IntResLong=IntResLong, IntResLongMode=IntResLongMode) - return Res, Pts, LDetLim, Mode, steps, Thres, ThresMode, ThresMin, IntResCross, IntResCrossMode, IntResLong, IntResLongMode - else: - Res0, Res1 = np.nan*np.ones((NP,)), np.nan*np.ones((NP,)) - for ii in range(0,NP): - ind = [dd.isInside(Pts[:,ii:ii+1], In=In) for dd in GLD] - if save: - np.savez(SavePath+SaveName+'.npz', Res0=Res0, Res1=Res1, LDetLim=LDetLim, Pts=Pts, Mode=Mode, steps=steps, Thres=Thres, ThresMode=ThresMode, ThresMin=ThresMin, - IntResCross=IntResCross, IntResCrossMode=IntResCrossMode, IntResLong=IntResLong, IntResLongMode=IntResLongMode) - return [Res0,Res1], Pts, LDetLim, Mode, steps, Thres, ThresMode, ThresMin, IntResCross, IntResCrossMode, IntResLong, IntResLongMode - - - -def _Resolution_PpsEmissdV_Iso(Pt, DXTheta, size=0., Deg=0, Amp=1., IntResCross=[0.1,0.1], IntResCrossMode='rel', IntResLong=0.05, IntResLongMode='rel', VType='Tor'): - Nxtheta = int(np.diff(DXTheta)/IntResLong) if IntResLongMode=='abs' else int(1./IntResLong) - xtheta = np.linspace(DXTheta[0],DXTheta[1],Nxtheta) - if size==0.: - pp = np.array([Pt[0]*np.cos(xtheta), Pt[0]*np.sin(xtheta), Pt[1]*np.ones((Nxtheta,))]) if VType=='Tor' else np.array([xtheta, Pt[0]*np.ones((Nxtheta,)), Pt[1]*np.ones((Nxtheta,))]) - Emiss = Amp * np.ones((pp.shape[1],)) - dV = IntResLong - else: - # Get Number of points, make sure it is odd (to get the center) - NRY = max(3,int(np.ceil(size/IntResCross[0]))) if IntResCrossMode=='abs' else int(1./IntResCross[0]) - NZ = max(3,int(np.ceil(size/IntResCross[1]))) if IntResCrossMode=='abs' else int(1./IntResCross[1]) - NRY = NRY+1 if NRY%2==0 else NRY - NZ = NZ+1 if NZ%2==0 else NZ - - RY = np.linspace(Pt[0]-0.5*size,Pt[0]+0.5*size,NRY) - Z = np.linspace(Pt[1]-0.5*size,Pt[1]+0.5*size,NZ) - RRYY = np.tile(RY,(NZ,1)).flatten() - ZZ = np.tile(Z,(NRY,1)).T.flatten() - - r = np.hypot(RRYY-Pt[0], ZZ-Pt[1]) - ind = r<=size/2. - - ds = IntResCross[1]*((RRYY+IntResCross[0]/2.)**2 - (RRYY-IntResCross[0]/2.)**2)/2. if VType=='Tor' else IntResCross[0]*IntResCross[1]*np.ones((RRYY.size,)) - dS = np.sum(ds[ind]) - - if VType=='Tor': - RRRYYY = np.tile(RRYY[ind],(Nxtheta,1)).flatten() - ZZZ = np.tile(ZZ[ind],(Nxtheta,1)).flatten() - TTT = np.tile(xtheta,(ind.sum(),1)).T.flatten() - pp = np.array([RRRYYY*np.cos(TTT), RRRYYY*np.sin(TTT), ZZZ]) - else: - pp = np.array([np.tile(xtheta,(ind.sum(),1)).T.flatten(), np.tile(RRYY[ind],(Nxtheta,1)).flatten(), np.tile(ZZ[ind],(Nxtheta,1)).flatten()]) - dV = IntResLong*np.tile(ds[ind],(Nxtheta,1)).flatten() - if Deg==0: - Emiss = Amp/dS * np.ones((ind.sum()*Nxtheta,)) - - return pp, Emiss, dV - - - - -def _Plot_Resolution(GLD, ax=None, Pts=None, Res=[0.01,0.01], ResMode='abs', Mode='Iso', Amp=1., Deg=0, steps=0.001, Thres=0.05, ThresMode='rel', ThresMin=None, - IntResCross=[0.1,0.1], IntResCrossMode='rel', IntResLong=0.05, IntResLongMode='rel', - Eq=None, Cdict=dict(tfd.DetConed), tt=np.linspace(0.,2.*np.pi,100), - plotfunc='scatter', NC=20, CDictRes=None, - ind=None, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In', Test=True): - - Res, LDetLim, Pts = _Calc_Resolution(GLD, Pts=Pts, Res=Res, ResMode=ResMode, Mode=Mode, Amp=Amp, Deg=Deg, steps=steps, Thres=Thres, ThresMode=ThresMode, ThresMin=ThresMin, - IntResCross=IntResCross, IntResCrossMode=IntResCrossMode, IntResLong=IntResLong, IntResLongMode=IntResLongMode, - Eq=Eq, PlotDetail=False, Cdict=Cdict, tt=tt, - ind=ind, Val=Val, Crit=Crit, PreExp=PreExp, PostExp=PostExp, Log=Log, InOut=InOut, Test=Test) - ax = _tfg_p._Resolution_Plot(Pts, Res, GLD, LDetLim, ax=ax, plotfunc=plotfunc, NC=NC, CDictRes=CDictRes, - ind=ind, Val=Val, Crit=Crit, PreExp=PreExp, PostExp=PostExp, Log=Log, InOut=InOut, Test=Test) - return ax - - - - -
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/build/html/_modules/tofu/pathfile.html b/doc/build/html/_modules/tofu/pathfile.html deleted file mode 100644 index fd6d62b43..000000000 --- a/doc/build/html/_modules/tofu/pathfile.html +++ /dev/null @@ -1,1519 +0,0 @@ - - - - - - - - tofu.pathfile — tofu v1.1 - - - - - - - - - - - - - - - -
-
-
-
- -

Source code for tofu.pathfile

-# -*- coding: utf-8 -*-
-"""
-Created on Wed Jul 30 14:37:31 2014
-
-@author: didiervezinet
-"""
-
-import os                   # For accessing cuurent working direcVesy
-import cPickle as pck       # For saving / loading objects
-import numpy as np
-import datetime as dtm
-import getpass
-import inspect
-import warnings
-
-# ToFu specific
-from tofu.defaults import dtmFormat as TFDdtmFormat
-
-
-__author__ = "Didier Vezinet"
-__all__ = ["Find_Rootpath","get_DefaultPaths","get_Default_dtimeFmt","_get_PathFileExt_FromName","convert_units","get_PolyFromPolyFileObj",
-           "ID",
-           "CheckSameObj","Save_Generic","Open"]
-
-
-"""
-###############################################################################
-###############################################################################
-###############################################################################
-                Path Handling
-###############################################################################
-###############################################################################
-"""
-
-
-
[docs]def Find_Rootpath(Path=os.getcwd(),substr='/tofu'): - """ - Return the absolute path of the root directory of ToFu, searching for a pattern in the provided input path - - Parameters - ---------- - Path : str - An absolute path in which a pattern is to be looked for - substr : str - The pattern to look for - - Returns - ------- - root : str - The absolute path containing the pattern - - """ - indstr = Path.find(substr) - if indstr==-1: - substr = substr.lower() - indstr = Path.find(substr) - root = Path[:indstr] + substr - return root
- - - -
[docs]def get_DefaultPaths(RootPath=None, Plugin=None, lSubs=[], PathInp=None, PathObj=None, PathOut=None): - """ - Return the default paths for input loading, object and output saving depending on the root path used - """ - assert RootPath is None or type(RootPath) is str, "Arg RootPath must be a str !" - assert Plugin is None or type(Plugin) is str, "Arg Plugin must be a str !" - assert all([ss is None or type(ss) is str for ss in [PathInp, PathObj, PathOut]]), "Args PathInp, PathObj, PathOut must be None or str !" - assert type(lSubs) is list and all([type(ss) is str for ss in lSubs]) - - if RootPath is None: - RootPath = Find_Rootpath() - for pp, ss in [(PathInp,'Inputs'), (PathObj,'Objects'), (PathOut,'Outputs')]: - if pp is None: - pp = str(RootPath) - if not Plugin is None: - pp = pp + '/' + Plugin - for sub in lSubs: - pp = pp + '/' + sub - pp = pp + '/' + ss - - return PathInp+'/', PathObj+'/', PathOut+'/'
- - -
[docs]def get_Default_dtimeFmt(dtime=None, dtFormat=TFDdtmFormat): - """ - Return the default datetime value and format - """ - if dtime is None: - dtime = dtm.datetime.now() - elif type(dtime) is str: - dtime = dtm.strptime(dtime,dtFormat) - return dtime, dtFormat
- - -def _get_PathFileExt_FromName(Name=None, Path=os.getcwd(), Lstr=[]): # Used in tofu.plugin.ITER.Ves.create() - """ Retrieve PathFileExt from a Name, in Path if absolute path not specified in Name, with possible TFMod and ext options """ - if not Name is None and '/' in Name: - PathFileExt = Name - else: - LF = os.listdir(Path) - if type(Name) is str: - Lstr.append(Name) - elif type(Name) is list: - Lstr = Lstr+Name - if not Lstr==[]: - LF = [ff for ff in LF if all([ss in ff for ss in Lstr])] - assert len(LF)==1, "Several or no possibility for "+str(Name)+" in "+Path+" with "+str(Lstr)+" LF = "+str(LF) - PathFileExt = Path + LF[0] - return PathFileExt - - - -def _set_arrayorder(obj, arrayorder): - assert arrayorder in ['C','F'], "Arg arrayorder must be in ['C','F']" - Lattr = dir(obj) - for aa in Lattr: - bb = getattr(obj,aa) - if type(bb) is np.array and bb.ndim>1: - try: - if arrayorder=='C': - setattr(obj,aa,np.ascontiguousarray(bb)) - else: - setattr(obj,aa,np.asfortranarray(bb)) - except Exception: - pass - obj._arrayorder = arrayorder - - -
[docs]def convert_units(P, In='cm', Out='m'): - """ - Quickly convert distance units between meters, centimeters and millimeters - """ - c = {'m':{'mm':1000.,'cm':100.,'m':1.}, - 'cm':{'mm':10.,'cm':1.,'m':0.01}, - 'mm':{'mm':1.,'cm':0.1,'m':0.001}} - return c[In][Out]*P
- - - -
[docs]def get_PolyFromPolyFileObj(PolyFileObj, SavePathInp=None, units='m', comments='#', skiprows=0, shape0=2): - """ Return a polygon as a np.ndarray, extracted from a txt file or from a ToFu object, with appropriate units - - Useful for :meth:`tofu.plugins.AUG.Ves._create()` - - Parameters - ---------- - PolyFileObj : str / :mod:`tofu.geom` object / np.ndarray - The source where the polygon is to be found, either: - - str: the name of a file containing the coorindates of a polygon to be loaded with :meth:`numpy.loadtxt()` - - A :mod:`tofu.geom` object: with attribute 'Poly' - - np.ndarray: an 2-dimensional array containing the 2D cartesian coordinates of a polygon - SavePathInp : str / None - The absolute path where the input file is stored - units : str - Flag indicating in which units the polygon coordinates is expressed in the input file / object / array (will be converted to meters) - comments : str - Parameter to be fed to :meth:`numpy.loadtxt()` if PolyFileObj is a file name - skiprows : int - Parameter to be fed to :meth:`numpy.loadtxt()` if PolyFileObj is a file name - shape0 : int - Specifies whether the loaded array is a (2,N) or (3,N) array (transposed it if necessary) - - Returns - ------- - Poly : np.ndarray - (2,N) np.ndarray containing the 2D cartesian coordinates of the polygon, where N is the number of points - addInfo : dict - Dictionaryb containing information on the origin of the polygon, for the record (e.g.: the name and absolute path of the file from which it was extracted) - - """ - assert type(PolyFileObj) in [list,str] or hasattr(PolyFileObj,"Poly") or np.asarray(PolyFileObj).ndim==2, "Arg PolyFileObj must be str (PathFileExt), a ToFu object with attribute Poly or an iterable convertible to 2d np.ndarray !" - - # Load PolyFileObj if file and check shape - addInfo = {} - if type(PolyFileObj) in [list,str]: - PathFileExt = _get_PathFileExt_FromName(PolyFileObj, Path=SavePathInp, Lstr=[]) - # Include PathFileExt in ID for tracability - addInfo = {'Input':PathFileExt} - PolyFileObj = np.loadtxt(PathFileExt, dtype=float, comments=comments, delimiter=None, converters=None, skiprows=skiprows, usecols=None, unpack=False, ndmin=2) - elif hasattr(PolyFileObj,"Poly"): - addInfo = {'Input':PolyFileObj.Id.SaveName} - PolyFileObj = PolyFileObj.Poly - - Poly = np.asarray(PolyFileObj) - assert Poly.ndim==2 and 2 in Poly.shape and max(Poly.shape)>=3 and not np.any(np.isnan(Poly)), "Arg np.asarray(PolyFileObj) must be a (2,N) or (N,2) np.ndarray with non NaNs !" - Poly = Poly if Poly.shape[0]==shape0 else Poly.T - Poly = convert_units(Poly, In=units, Out='m') - return Poly, addInfo
- - - - - - -""" -############################################################################### -############################################################################### -############################################################################### - Generic input checking and retrieving -############################################################################### -############################################################################### -""" - - -def _check_NotNone(Dict): - for aa in Dict.keys(): - assert not Dict[aa] is None, "Arg "+aa+" must not be None !" - - -def _get_FromItself(obj, Dict): - for aa in Dict.keys(): - if Dict[aa] is None: - try: - Dict[aa] = getattr(obj,aa) - except: - pass - return Dict - - - - -""" -############################################################################### -############################################################################### -############################################################################### - ID Class and naming -############################################################################### -############################################################################### -""" - - -
[docs]class ID(object): - """ A class used by all ToFu objects as an attribute, storing all relevant data for the identification of created instances and providing default path and names for saving objects - - Each detector created in ToFu should be identifiable thanks to user-friendly criteria, like its name, the diagnostic and experiment it is attached to, the shot number from from it was physically installed on the experiement... - Users can also freely add some information they consider relevant, such as some characteristics of the detector (size, manufacturer, date of last calibration...) - - Parameters - ---------- - Cls : str - Flag indicating which class is the object fro which the ID instance is being created, available class flags are: - - From :mod:`tofu.geom`: 'Ves', 'Struct', 'LOS', 'GLOS', 'Apert', 'Lens', 'Detect' and 'GDetect' - - From :mod:`tofu.mesh`: 'Mesh1D', 'Mesh2D', 'LBF1D' and 'LBF2D' (to be finished) - - From :mod:`tofu.`: (to be completed) - Name : str - Name to be assigned to the created instance, should be a str without ' ' or '_' (spaces and underscores will be automatically removed if present) - Type : None / str - If provided (necessary for some objects, but not for all), specifies the Type of object (i.e.: 'Tor' or 'Lin' for a Ves instance) - Deg : None / int - If provided (necessary only for objects of class 'LBF1D' and 'LBF2D'), specifies the degree of the b-splines constituting the :mod:`tofu.mesh` object - Exp : None / str - A short 3-4 letters max flag specifying the experiment to which the created instance belongs (e.g.: 'AUG', 'ITER', 'TCV', 'JET'...) - Diag : None / str - A short flag indicating which diagnostic the the created instance belongs to (e.g.: 'SXR', 'HXR', 'Bolo'...) - shot : None / int - A shot number from which the created instance can be considered valid (useful for tracking geometry changes in the case of Ves and Detect objects) - SaveName : None / str - If provided, overrides the automatically generated name for saving the created instance (not recommended) - SavePath : None / str - If provided, overrides the automatically generated path for saving the created instance - USRdict : None / dict - If provided, a user-defined dictionary containing information about the instance considered relevant (e.g.: thickness of the diode, date of installation...) - LObj : None / dict / list - If provided, either - - list: list of other ID instances of objects on which the created object depends (this list will then be sorted by class and formatted into a dictionary storign key attributes) - - dict: a ready-made such dictionary - dtime : None / dtm.datetime - If provided, a time reference to be used to identify this particular instance (used for debugging mostly) - dtFormat : None / str - If provided, the format in which dtime should be written in the automatically generated saving name for the created instance - dtimeIn : bool - Flag indicating whether the dtm.datetime should be included in the automatically generated saving name for the created instance - - Returns - ------- - Id ID instance - The created ID instance, with all necessary computed attributes and methods - - """ - - def __init__(self, Cls, Name, Type=None, Deg=None, Exp=None, Diag=None, shot=None, SaveName=None, SavePath=None, USRdict=None, LObj=None, dtime=None, dtFormat=TFDdtmFormat, dtimeIn=False): - assert type(Exp) is str, "Arg Exp must be a str !" - assert type(Cls) is str, "Arg Cls must be a str !" - assert shot is None or type(shot) is int, "Arg shot must be a int !" - assert Diag is None or type(Diag) is str, "Arg Diag must be a str !" - assert Type is None or type(Type) is str, "Arg Type must be a str !" - - self._Exp = Exp - self._Cls = Cls - self._Type = Type - self._Deg = Deg - self._Diag = Diag - self._shot = shot - self._set_dtime(dtime=dtime, dtFormat=dtFormat, dtimeIn=dtimeIn) - self.set_Name(Name, SaveName=SaveName) - self.set_SavePath(SavePath=SavePath) - self._LObj = {} - self.set_LObj(LObj) - self.set_USRdict(USRdict) - - def _set_dtime(self,dtime=None, dtFormat=TFDdtmFormat, dtimeIn=False): - assert dtime is None or isinstance(dtime,dtm.datetime), "Arg dtime must be a dtm.datetime instance !" - if dtime is None: - dtime = dtm.datetime.now() - self._dtime = dtime - self._dtFormat = dtFormat - self._dtimeIn = dtimeIn - -
[docs] def set_Name(self, Name, SaveName=None, dtimeIn=None): - """ Set the Name of the created instance, automatically updating the SaveName - - When the name is changed (reminding it should not include space (' ') or underscore ('_') characters), the name used for saving the object is automatically changed - - Parameters - ---------- - Name : str - Name to be assigned to the created instance, should be a str without ' ' or '_' (spaces and underscores will be automatically removed if present) - SaveName : None / str - If provided, overrides the automatically generated name for saving the created instance (not recommended) - dtimeIn : None / bool - If provided, modifies the value of dtimeIn provided upon creation of the ID object - - """ - assert type(Name) is str, "ID.Name must be assigned to a str !" - self._Name = Name - self.set_SaveName(SaveName=SaveName, dtimeIn=dtimeIn)
- -
[docs] def set_SaveName(self,SaveName=None, dtimeIn=None): - """ Enables either to automatically compute a ToFu-consistent saving name for the created instance, or to override that default saving name with the user-provided SaveName - - When creating an object of any class, an ID object is assigned to it that automatically computes a saving name in case the user wants to save the object. - This automatically generated saving name includes not only the name given to the instance but also useful classifying info such as the class of the object, its Type, experiment, diagnostic... - It is not recommended to override this automatically generated saving name (because some routines rely on it for fast identification of saved files), but it is made possible for flexibility. - - Parameters - ---------- - SaveName : None / str - If provided, a str that overrides the automatically generated saving name - dtimeIn : None / bool - If provided, modifies the value of dtimeIn provided upon creation of the ID object - - """ - assert SaveName is None or type(SaveName) is str, "ID.SaveName must be assigned to a str !" - dtimeIn = self._dtimeIn if dtimeIn is None else dtimeIn - if SaveName is None: - self._SaveName = SaveName_Conv(self._Exp, self.Cls, self._Type, self._Deg, self._Diag, self._Name, shot=self._shot, dtime=self._dtime, Format=self._dtFormat, dtimeIn=dtimeIn) - else: - self._SaveName = SaveName
- -
[docs] def set_SavePath(self,SavePath=None): - """ Enables to automatically generate a saving path for the created object, or to override that default path with the user-provided SavePath - - Similarily to SaveName, ToFu automatically generates a saving path for any created object. - This saving path can be overriden if desired. - This is less crucial than SaveName, changing the SavePath has little consequences as long as you remember what you are doing. - - Parameters - ---------- - SavePath : None / str - If provided, a str that overrides the automatically generated saving path - - """ - assert SavePath is None or type(SavePath) is str, "ID.SavePath must be assigned to a str !" - if SavePath is None: - SavePath = Find_Rootpath()+'/Objects_'+self.Exp+'/' if not self.Cls in ['PreData','Sol2D'] else Find_Rootpath()+'/Outputs_'+self.Exp+'/' - self._SavePath = SavePath.replace('//','/')
- -
[docs] def set_LObj(self,LObj=None): - """ Set the LObj attribute to store the list of ID of other objects the created instance depends on - - A Detect object depends on a vessel and some optics (e.g.: a list of apertures). - It is necessary that the link between the created Detect object and the already-existing Ves and Apert objects be stored somewhere, so that even after saving and closing the session, this correspondence can be retrieved and the Detect object can be re-loaded with links to the proper Ves and Apert objects, themselves beoing possibly saved elsewhere (so their respective SavePath must also be stored). - The LObj parameter does this: it stores all information necessary about each of the other objects the created instance depends on, mostly by storing their ID attributes as dictionaries. - - Parameters - ---------- - LObj : None / dict / list - If provided, either - - list: list of other ID instances of objects on which the created object depends (this list will then be sorted by class and formatted into a dictionary storign key attributes) - - dict: a ready-made such dictionary - - """ - assert LObj is None or type(LObj) is dict or (type(LObj) is list and all([isinstance(oo,ID) for oo in LObj])), "Arg LObj must be a list of ID instances !" - if type(LObj) is list: - LCls = [oo.Cls for oo in LObj] - ClsU = list(set(LCls)) - for Cls in ClsU: - self._LObj[Cls] = {'Exp':[oo.Exp for oo in LObj if oo.Cls==Cls], 'Name':[oo.Name for oo in LObj if oo.Cls==Cls], 'SaveName':[oo.SaveName for oo in LObj if oo.Cls==Cls], - 'SavePath':[oo.SavePath for oo in LObj if oo.Cls==Cls], 'Type':[oo.Type for oo in LObj if oo.Cls==Cls], 'Diag':[oo.Diag for oo in LObj if oo.Cls==Cls], - 'shot':[oo.shot for oo in LObj if oo.Cls==Cls], - 'dtFormat':[oo._dtFormat for oo in LObj if oo.Cls==Cls], 'dtime':[oo.dtime.strftime(oo._dtFormat) for oo in LObj if oo.Cls==Cls], - 'USRdict':[oo._USRdict for oo in LObj if oo.Cls==Cls], 'LObj':[oo._LObj for oo in LObj if oo.Cls==Cls]} - elif type(LObj) is dict: - self._LObj = LObj
- - def get_LObjasLId(self,Cls=None): - if Cls is None: - Cls = sorted([self._LObj.keys()]) - Cls = [Cls] if type(Cls) is str else Cls - DId = {} - for ii in range(0,len(Cls)): - lid = [] - keys = self._LObj[Cls[ii]].keys() - for jj in range(0,len(self._LObj[Cls[ii]]['Exp'])): - dd = {} - for kk in keys: - dd[kk] = self._LObj[Cls[ii]][kk][jj] - name = dd['Name'] - del dd['Name'], dd['dtime'] - lid.append(ID(Cls[ii], name, **dd)) - DId[Cls[ii]] = lid - return DId - - -
[docs] def set_USRdict(self,USRdict=None): - """ Set the USRdict to enable the user to store arbitrary information about the instance created - - It may sometimes be useful to store unforeseen arbitrary info about some objects created, like the manufacturing date of a diode, the material used for a filter... - The USRdict attribute is a user-defined dictionary for this purpose. - - Parameters - ---------- - USRdict : None / dict - If provided, a user-defined dictionary containing information about the instance considered relevant (e.g.: thickness of the diode, date of installation...) - - """ - assert USRdict is None or type(USRdict) is dict, "Arg USRdict must be a dictionnary !" - USRdict = {} if USRdict is None else USRdict - self._USRdict = USRdict
- - @property - def Cls(self): - return self._Cls - @property - def Name(self): - return self._Name - @Name.setter - def Name(self,Val): - self.set_Name(Val) - @property - def NameLTX(self): - return r"$"+self.Name.replace('_','\_')+r"$" - @property - def Diag(self): - return self._Diag - @property - def shot(self): - return self._shot - @property - def Type(self): - return self._Type - @property - def SaveName(self): - return self._SaveName - @SaveName.setter - def SaveName(self,Val): - self.set_SaveName(Val) - @property - def SavePath(self): - return self._SavePath - @SavePath.setter - def SavePath(self,Val): - self.set_SavePath(Val) - @property - def dtime(self): - return self._dtime - @property - def Exp(self): - return self._Exp - @property - def LObj(self): - return self._LObj - @property - def USRdict(self): - return self._USRdict - @USRdict.setter - def USRdict(self, Val): - self.set_USRdict(Val) - - def todict(self): - return _Id_todict(self)
- - -def SaveName_Conv(Exp, Cls, Type, Deg, Diag, Name, shot=None, dtime=None, Format="D%Y%m%d_T%H%M%S", dtimeIn=False): - """ Create a default name for saving the object, including key info for fast identification of the object class, type, experiement... - - When create a ToFu object, this function called by the ID class to generate a default name for saving the object. - This automatically generated name includes all key info about the object, in addition to its user-defined name. - It is recommended to use this default name. - - Parameters - ---------- - Exp : None / str - A short 3-4 letters max flag specifying the experiment to which the created instance belongs (e.g.: 'AUG', 'ITER', 'TCV', 'JET'...) - Cls : None / str - Flag indicating which class is the object fro which the ID instance is being created, available class flags are: - - From :mod:`tofu.geom`: 'Ves', 'Struct', 'LOS', 'GLOS', 'Apert', 'Lens', 'Detect' and 'GDetect' - - From :mod:`tofu.mesh`: 'Mesh1D', 'Mesh2D', 'LBF1D' and 'LBF2D' (to be finished) - - From :mod:`tofu.`: (to be completed) - Type : None / str - If provided (necessary for some objects, but not for all), specifies the Type of object (i.e.: 'Tor' or 'Lin' for a Ves instance) - Deg : None / int - If provided (necessary only for objects of class 'LBF1D' and 'LBF2D'), specifies the degree of the b-splines constituting the :mod:`tofu.mesh` object - Diag : None / str - A short flag indicating which diagnostic the the created instance belongs to (e.g.: 'SXR', 'HXR', 'Bolo'...) - Name : str - Name to be assigned to the created instance, should be a str without ' ' or '_' (spaces and underscores will be automatically removed if present) - shot : None / int - A shot number from which the created instance can be considered valid (useful for tracking geometry changes in the case of Ves and Detect objects) - dtime : None / dtm.datetime - If provided, a time reference to be used to identify this particular instance (used for debugging mostly) - Format : None / str - If provided, the format in which dtime should be written in the automatically generated saving name for the created instance - dtimeIn : bool - Flag indicating whether the dtm.datetime should be included in the automatically generated saving name for the created instance - - Returns - ------- - SVN : str - The automatically generated saving name - - """ - if Cls in ['Ves','Struct','LOS','GLOS','Lens','Apert','Detect','GDetect']: - Mod = 'TFG' - elif Cls in ['Mesh1D','Mesh2D','Mesh3D','LBF1D','LBF2D','LBF3D']: - Mod = 'TFM' - elif Cls in ['Eq2D']: - Mod = 'TFEq' - elif Cls in ['GMat2D','GMat3D']: - Mod = 'TFMC' - elif Cls in ['Corresp','PreData']: - Mod = 'TFT' - elif Cls=='Sol2D': - Mod = 'TFI' - if not isinstance(dtime,dtm.datetime): - dtime = dtm.datetime.now() - ClsType = Cls if Type is None else Cls+Type - if Cls=='PreData': - Elts = [(ClsType,''),(Exp,''),(Deg,'D'),(Diag,'Dg'),(shot,'sh'),(Name,'')] - else: - Elts = [(ClsType,''),(Exp,''),(Deg,'D'),(Diag,'Dg'),(Name,''),(shot,'sh')] - SVN = Mod - for ii in range(0,len(Elts)): - SVN = SVN + '_' + Elts[ii][1] + str(Elts[ii][0]).replace('_','') if not Elts[ii][0] is None else SVN - if dtimeIn: - SVN = SVN+'_'+dtime.strftime(Format) - SVN = SVN.replace('__','_') - if Cls in ['PreData','Sol2D']: - SVN = SVN + '_U' + getpass.getuser() - return SVN - - -# Checking several instances are the same object -
[docs]def CheckSameObj(obj0, obj1, LFields=None): - """ Check two variable refer to the same instance of a ToFu class by checking some key attributes - - Sometimes two different variables can refer to the same instance (for example if an object was created and assigned to obj0, then later saved and loaded and assigned to obj1). - Occasionally it may be useful to check whether two variables really represent the same instance, according to important criteria from the point of view of ToFu. - - Parameters - ---------- - obj0 : tofu object - A variable refering to a ToFu object of any class - obj1 : tofu object - A variable refering to a ToFu object of any class (but the same class as obj0) - LFields : None / str / list - The criteria against which the two objects are evaluated, if not None, must be str matching an attribute of the ID class or an attribute of the object class itself (or a list of such) - - None: True is returned - - str or list: tests whether the attributes have the same value or not and only returns True if all do - - Returns - ------- - A : bool - - """ - assert LFields is None or type(LFields) is str or (type(LFields) is list and all([type(ss) is str for ss in LFields])), "Arg LFields must be a str or a list of str !" - if LFields is None: - return True - if not type(LFields) is list: - LFields = [LFields] - ind = [False for ii in range(0,len(LFields))] - for ii in range(0,len(LFields)): - assert LFields[ii] in dir(obj0.Id)+dir(obj0), LFields[ii]+" not in "+obj0.Id.Name+" !" - assert LFields[ii] in dir(obj1.Id)+dir(obj1), LFields[ii]+" not in "+obj1.Id.Name+" !" - if LFields[ii] in dir(obj0): - ind[ii] = np.all(getattr(obj0,LFields[ii])==getattr(obj1,LFields[ii])) - else: - ind[ii] = getattr(obj0.Id,LFields[ii])==getattr(obj1.Id,LFields[ii]) - A = all(ind) - return A
- - -def SelectFromIdLObj(IdLObjCls, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In', Out=bool): - """ To do (deprecated ?) - """ - assert type(Crit) is str or (type(Crit) is list and all([type(cc) is str for cc in Crit])), "Arg Crit must be a str or list of str !" - assert all([rr is None or type(rr) is str or (type(rr) is list and all([type(ee) is str for ee in rr])) for rr in [PreExp,PostExp]]), "Args PreExp and PostExp must be a str or list of str !" - assert Log in ['any','all'], "Arg Log must be in ['and','or'] !" - assert InOut in ['In','Out'], "Arg InOut must be in ['In','Out'] !" - NObj = len(IdLObjCls['Name']) - if Val is None and PreExp is None and PostExp is None: - ind = np.ones((1,NObj),dtype=bool) - elif not Val is None: - if type(Val) is str: - Val=[Val] - N = len(Val) - ind = np.zeros((N,NObj),dtype=bool) - if Crit in dir(ID): - for ii in range(0,N): - ind[ii,:] = np.asarray([idd==Val[ii] for idd in IdLObjCls[Crit]],dtype=bool) - else: - for ii in range(0,N): - ind[ii,:] = np.asarray([idd[Crit]==Val[ii] for idd in IdLObjCls['USRdict']],dtype=bool) - else: - if type(PreExp) is str: - PreExp = [PreExp] - if type(PostExp) is str: - PostExp = [PostExp] - if PreExp is None: - PreExp = ["" for ss in PostExp] - if PostExp is None: - PostExp = ["" for ss in PreExp] - assert len(PreExp)==len(PostExp), "Arg Exp must be a list of same length as Crit !" - N = len(PreExp) - ind = np.zeros((N,NObj),dtype=bool) - if Crit in dir(ID): - for ii in range(0,N): - ind[ii,:] = np.asarray([eval(PreExp[ii]+" idd "+PostExp[ii]) for idd in IdLObjCls[Crit]],dtype=bool) - else: - for ii in range(0,N): - ind[ii,:] = np.asarray([eval(PreExp[ii]+" idd[Crit] "+PostExp[ii]) for idd in IdLObjCls['USRdict']],dtype=bool) - ind = np.any(ind,axis=0) if Log=='any' else np.all(ind,axis=0) - if InOut=='Out': - ind = ~ind - if Out==bool: - return ind - elif Out==int: - return ind.nonzero()[0] - else: - if Out in dir(ID): - return [IdLObjCls[Out][ii] for ii in ind.nonzero()[0]] - else: - return [IdLObjCls['USRdict'][ii][Out] for ii in ind.nonzero()[0]] - - - -def SelectFromListId(LId, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In', Out=bool): - """ Select the ID instances in the provided list that match the criteria and return their index or other attributes - - Return - - Parameters - ---------- - LId : list - - Val : None / str / list - - Crit : str - - PreExp : None / str - - PostExp : None / str - - Log : str - - InOut : str - - Out : type / str - - - Returns - ------- - ind : np.ndarray / list - - - """ - assert type(Crit) is str or (type(Crit) is list and all([type(cc) is str for cc in Crit])), "Arg Crit must be a str or list of str !" - assert all([rr is None or type(rr) is str or (type(rr) is list and all([type(ee) is str for ee in rr])) for rr in [PreExp,PostExp]]), "Args PreExp and PostExp must be a str or list of str !" - assert Log in ['any','all'], "Arg Log must be in ['any','all'] !" - assert InOut in ['In','Out'], "Arg InOut must be in ['In','Out'] !" - if Val is None and PreExp is None and PostExp is None: - ind = np.ones((1,len(LId)),dtype=bool) - elif not Val is None: - if type(Val) is str: - Val=[Val] - N = len(Val) - ind = np.zeros((N,len(LId)),dtype=bool) - if Crit in dir(ID): - for ii in range(0,N): - ind[ii,:] = np.asarray([getattr(iid,Crit)==Val[ii] for iid in LId],dtype=bool) - else: - for ii in range(0,N): - ind[ii,:] = np.asarray([iid.USRdict[Crit]==Val[ii] for iid in LId],dtype=bool) - else: - if type(PreExp) is str: - PreExp = [PreExp] - if type(PostExp) is str: - PostExp = [PostExp] - if PreExp is None: - PreExp = ["" for ss in PostExp] - if PostExp is None: - PostExp = ["" for ss in PreExp] - assert len(PreExp)==len(PostExp), "Arg Exp must be a list of same length as Crit !" - N = len(PreExp) - ind = np.zeros((N,len(LId)),dtype=bool) - if Crit in dir(ID): - for ii in range(0,N): - ind[ii,:] = np.asarray([eval(PreExp[ii]+" getattr(iid,Crit) "+PostExp[ii]) for iid in LId],dtype=bool) - else: - for ii in range(0,N): - ind[ii,:] = np.asarray([eval(PreExp[ii]+" iid.USRdict[Crit] "+PostExp[ii]) for iid in LId],dtype=bool) - ind = np.any(ind,axis=0) if Log=='any' else np.all(ind,axis=0) - if InOut=='Out': - ind = ~ind - if Out==int: - ind = ind.nonzero()[0] - elif Out is not bool and hasattr(ID,Out): - ind = [getattr(LId[ii],Out) for ii in ind.nonzero()[0]] - elif Out is not bool and Out in LId[0].USRdict.keys(): - ind = [LId[ii].USRdict[Out] for ii in ind.nonzero()[0]] - return ind - - - -def _Id_todict(Id): - IdTxt = {'Cls':Id.Cls, 'Name':Id.Name, 'SaveName':Id.SaveName, 'SavePath':Id.SavePath, 'Diag':Id.Diag, 'Type':Id.Type, 'shot':Id.shot, 'Exp':Id.Exp} - Iddtime = {'dtime':Id.dtime, 'dtFormat':Id._dtFormat, 'dtimeIn':Id._dtimeIn} - IdLobjUsr = {'LObj':Id.LObj, 'USRdict':Id.USRdict} - return [IdTxt,Iddtime,IdLobjUsr] - - - - -def _Id_recreateFromdict(IdS): - Id = ID(Cls=IdS[0]['Cls'], Type=IdS[0]['Type'], Exp=IdS[0]['Exp'], Diag=IdS[0]['Diag'], shot=IdS[0]['shot'], Name=IdS[0]['Name'], SaveName=IdS[0]['SaveName'], SavePath=IdS[0]['SavePath'], - dtime=IdS[1]['dtime'], dtFormat=IdS[1]['dtFormat'], dtimeIn=IdS[1]['dtimeIn'], - LObj=IdS[2]['LObj'], USRdict=IdS[2]['USRdict']) - return Id - - - - - -""" -############################################################################### -############################################################################### -############################################################################### - Saving and loading ToFu objects with numpy and cPickle -############################################################################### -############################################################################### -""" - - -########################### -# IDentify a Sol2D file -########################### - -def FindSolFile(shot=0, t=0, Dt=None, Mesh='Rough1', Deg=2, Deriv='D2N2', Sep=True, Pos=True, OutPath='/afs/ipp-garching.mpg.de/home/d/didiv/Python/tofu/src/Outputs_AUG/'): - """ Identify the good Sol2D saved file in a given folder (OutPath), based on key ToFu criteria - - When trying to load a Sol2D object (i.e.: solution of a tomographic inversion), it may be handy to provide the key parameters (shot, time, mesh name, degree of basis functions, regularisation functional) instead of copy-pasting the full file name. - This function identifies, within the relevant repository (OutPath), the files matching the provided criteria. - This function only works of the automatically generated default SaveName was preserved for the Sol2D objects. - - Parameters - ---------- - shot : int - A shot number - t : None / int / float - A time value that must be contained in the time interval of the Sol2D file, must be provided if Dt is None - Dt : None / iterable - A time interval that the Sol2D file has to match, must be provided if t is None - Mesh : str - The name of the mesh that was used to compute the inversion - Deg : int - The of the b-splines (LBF2D object) that were used to discretize the solution - Deriv : str - The flag indicating the regularization functional that was used for the inversion - Sep : bool - The flag value that was used for indicating whether the boundary constraint at the separatrix should be considered - Pos : bool - The flag value that was used for indicating whether the positivity constraint was considered - Outpath : str - The absolute path of the repository where to look - - Returns - ------- - out : None / str - The matching file name, if any - - """ - assert None in [t,Dt] and not (t is None and Dt is None), "Arg t or Dt must be None, but not both !" - LF = [ff for ff in os.listdir(OutPath) if 'TFI_Sol2D_AUG_SXR' in ff] - LF = [ff for ff in LF if all([ss in ff for ss in ['_'+str(shot)+'_', '_'+Mesh+'_D'+str(Deg), '_Deriv'+Deriv+'_Sep'+str(Sep)+'_Pos'+str(Pos)]])] - if len(LF)==0: - print "No matching Sol2D file in ", OutPath - out = None - LDTstr = [ff[ff.index('_Dt')+3:ff.index('s_')] for ff in LF] - LDTstr = [(ss[:7],ss[8:]) for ss in LDTstr] - if t is None: - LF = [LF[ii] for ii in range(0,len(LF)) if LDTstr[ii][0]+'-'+LDTstr[ii][1]=='{0:07.4f}-{1:07.4f}'.format(Dt[0],Dt[1])] - elif Dt is None: - LF = [LF[ii] for ii in range(0,len(LF)) if t>=float(LDTstr[ii][0]) and t<=float(LDTstr[ii][1])] - if len(LF)==0: - print "No matching Sol2D file in ", OutPath - out = None - elif len(LF)>1: - print "Several matching Sol2D files in ", OutPath - print LF - out = None - else: - out = LF[0] - return out - - - -def _get_ClsFromName(PathFileExt): - assert type(PathFileExt) is str, "Arg PathFileExt must be a str !" - LCls = ['Ves','LOS','GLOS','Apert','Lens','Detect','GDetect','Mesh1D','Mesh2D','BF1D','BF2D','PreData','Sol2D'] - Found = False - for nn in LCls: - if '_'+nn+'_' in PathFileExt: - Found = True - break - assert Found, "Class could not be identified in "+PathFileExt - return nn - - - -########################### -# Saving -########################### - - -
[docs]def Save_Generic(obj, SaveName=None, Path=None, Mode='npz', compressed=False): - """ Save a ToFu object under file name SaveName, in folder Path, using specified mode - - ToFu provides built-in saving and loading functions for ToFu objects. - They can be saved at their default SavePath under their default SaveName or user-defined values can be forced if necessary. - Saving can be done in two ways : - - by direct object saving using cPickle (straightforward but heavy) - - by mapping the key object attributes to a dictionary and using :meth:`numpy.savez_compressed()` (faster and lighter, recommended) - - ToFu now automatically saves information on smaller objects on which the object of interest depends (like apertures for detectors), so that all info is stored in a single file. - In particular, provided the Ves object is saved separately, a whole camera can be saved in a single file (i.e.: all detectors and apertures). - - Parameters - ---------- - SaveName : str - The name to be used to for the saved file, if None (recommended) uses obj.Id.SaveName - Path : str - Path specifying where to save the file, if None (recommended) uses obj.Id.SavePath - Mode : str - Flag specifying whether to save the object as a numpy array file ('.npz', recommended) or an object using cPickle (not recommended, may cause retro-compatibility issues with later versions) - compressed : bool - Flag, used when Mode='npz', indicating whether to use np.savez or np.savez_compressed (slower saving and loading but smaller files) - - """ - if Path is None: - Path = obj.Id.SavePath - else: - assert type(Path) is str, "Arg Path must be a str !" - obj._Id.SavePath = Path - if SaveName is None: - SaveName = obj.Id.SaveName - else: - assert type(SaveName) is str, "Arg SaveName must be a str !" - obj.Id.SaveName = SaveName - Ext = '.npz' if 'npz' in Mode else '.pck' - pathfileext = Path+SaveName+Ext - if '.npz' in Ext: - _save_np(obj, pathfileext, compressed=compressed) - else: - _save_object(obj, pathfileext) - print("Saved in : "+pathfileext)
- - -def _save_object(obj,pathfileext): - if 'TFM' in pathfileext: - obj.LFunc = None - with open(pathfileext, 'wb') as output: - pck.dump(obj, output, -1) - - - -def _convert_Detect2Ldict(obj): - # Store LOS data - llos = obj.LOS.keys() - LOSprops = {'Keys':llos, 'Id':[obj.LOS[kk]['LOS'].Id.todict() for kk in llos], 'Du':[(obj.LOS[kk]['LOS'].D,obj.LOS[kk]['LOS'].u) for kk in llos]} - lprops = obj.LOS[kk].keys() - for pp in lprops: - if not pp=='LOS': - LOSprops[pp] = [obj.LOS[kk][pp] for kk in llos] - - # Get all attributes - lAttr = dir(obj) - Sino, Span, Cone, SAng, SynthDiag, Res = {}, {}, {}, {}, {}, {} - - # Store Sino data - for pp in lAttr: - #print inspect.ismethod(getattr(obj,pp)), type(getattr(obj,pp)), pp - if not inspect.ismethod(getattr(obj,pp)): - if '_Sino' in pp: - Sino[pp] = getattr(obj,pp) - elif '_Span' in pp: - Span[pp] = getattr(obj,pp) - elif '_Cone' in pp: - Cone[pp] = getattr(obj,pp) - elif '_SAng' in pp: - SAng[pp] = getattr(obj,pp) - elif '_SynthDiag' in pp: - SynthDiag[pp] = getattr(obj,pp) - elif '_Res' in pp: - Res[pp] = getattr(obj,pp) - - - # Store Optics key parameters (for re-creating if not saved independantly) - Optics = [] - if len(obj.Optics)>0: - if obj.OpticsType=='Apert': - for aa in obj.Optics: - Optics.append({'Id':aa.Id.todict(), 'Poly':aa.Poly, 'arrayorder':aa._arrayorder, 'Clock':aa._Clock}) - elif obj.OpticsType=='Lens': - ln = obj.Optics[0] - Optics.append({'Id':ln.Id.todict(), 'O':ln.O, 'nIn':ln.nIn, 'Rad':ln.Rad, 'F1':ln.F1, 'F2':ln.F2, 'R1':ln.R1, 'R2':ln.R2, 'dd':ln.dd, 'Type':ln.Type, 'arrayorder':ln._arrayorder, 'Clock':ln._Clock}) - - return LOSprops, Sino, Span, Cone, SAng, SynthDiag, Res, Optics - - - -def _convert_PreData2Ldict(obj): - Init = {'data':obj._dataRef, 't':obj._tRef, 'Chans':obj._ChansRef, 'DtRef':obj._DtRef} - PhysNoiseParam = None if obj._PhysNoise is None else obj._PhysNoise['Param'].update(obj._NoiseModel['Par']) - Update = {'Dt':obj.Dt, 'Resamp_t':obj._Resamp_t, 'Resamp_f':obj._Resamp_f, 'Resamp_Method':obj._Resamp_Method, 'Resamp_interpkind':obj._Resamp_interpkind, - 'indOut':obj._indOut, 'indCorr':obj._indCorr, 'interp_lt':obj._interp_lt, 'interp_lNames':obj._interp_lNames, 'Subtract_tsub':obj._Subtract_tsub, - 'FFTPar':obj._FFTPar, 'PhysNoiseParam':PhysNoiseParam} - return Init, Update - - - -def _save_np(obj, pathfileext, compressed=False): - - func = np.savez_compressed if compressed else np.savez - - Idsave = obj.Id.todict() - - # tofu.geom - if obj.Id.Cls=='Ves': - func(pathfileext, Idsave=Idsave, arrayorder=obj._arrayorder, Clock=obj._Clock, Poly=obj.Poly, DLong=obj.DLong, Sino_RefPt=obj.Sino_RefPt, Sino_NP=obj.Sino_NP) - - if obj.Id.Cls=='Struct': - func(pathfileext, Idsave=Idsave, arrayorder=obj._arrayorder, Clock=obj._Clock, Poly=obj.Poly, DLong=obj.DLong) - - elif obj.Id.Cls=='LOS': - func(pathfileext, Idsave=Idsave, Du=obj.Du, Sino_RefPt=obj.Sino_RefPt, arrayorder=obj._arrayorder, Clock=obj._Clock) - - elif obj.Id.Cls=='GLOS': - LIdLOS = [ll.Id.todict() for ll in obj.LLOS] - LDs, Lus = np.array([ll.D for ll in obj.LLOS]).T, np.array([ll.u for ll in obj.LLOS]).T - func(pathfileext, Idsave=Idsave, LIdLOS=LIdLOS, LDs=LDs, Lus=Lus, Sino_RefPt=obj.Sino_RefPt, arrayorder=obj._arrayorder, Clock=obj._Clock) - - elif obj.Id.Cls=='Lens': - func(pathfileext, Idsave=Idsave, arrayorder=obj._arrayorder, Clock=obj._Clock, O=obj.O, nIn=obj.nIn, Rad=[obj.Rad], F1=[obj.F1], F2=[obj.F2], R1=[obj.R1], R2=[obj.R2], dd=[obj.dd]) - - elif obj.Id.Cls=='Apert': - func(pathfileext, Idsave=Idsave, arrayorder=obj._arrayorder, Clock=obj._Clock, Poly=obj.Poly) - - elif obj.Id.Cls=='Detect': - LOSprops, Sino, Span, Cone, SAng, SynthDiag, Res, Optics = _convert_Detect2Ldict(obj) - func(pathfileext, Idsave=Idsave, Poly=obj.Poly, Rad=obj.Rad, BaryS=obj.BaryS, nIn=obj.nIn, arrayorder=obj._arrayorder, Clock=obj._Clock, Sino_RefPt=obj.Sino_RefPt, LOSNP=[obj._LOS_NP], - LOSprops=[LOSprops], Sino=[Sino], Span=[Span], Cone=[Cone], SAng=[SAng], SynthDiag=[SynthDiag], Res=[Res], Optics=[Optics]) - - elif obj.Id.Cls=='GDetect': - LDetsave, LDetSynthRes = [], [] - for ii in range(0,obj.nDetect): - ddIdsave = obj.LDetect[ii].Id.todict() - LOSprops, Sino, Span, Cone, SAng, SynthDiag, Res, Optics = _convert_Detect2Ldict(obj.LDetect[ii]) - dd = dict(Idsave=ddIdsave, Poly=obj.LDetect[ii].Poly, Rad=obj.LDetect[ii].Rad, BaryS=obj.LDetect[ii].BaryS, nIn=obj.LDetect[ii].nIn, arrayorder=obj._arrayorder, Clock=obj._Clock, Sino_RefPt=obj.Sino_RefPt, - LOSNP=[obj.LDetect[ii]._LOS_NP], LOSprops=[LOSprops], Sino=[Sino], Span=[Span], Cone=[Cone], SAng=[SAng], Optics=[Optics]) - LDetsave.append(dd) - LDetSynthRes.append({'SynthDiag':[SynthDiag],'Res':[Res]}) - Res, lAttr = {}, dir(obj) - for pp in lAttr: - if not inspect.ismethod(getattr(obj,pp)) and '_Res' in pp: - Res[pp] = getattr(obj,pp) - func(pathfileext, Idsave=Idsave, arrayorder=obj._arrayorder, Clock=obj._Clock, Sino_RefPt=obj.Sino_RefPt, LOSRef=obj._LOSRef, Res=[Res], LDetsave=LDetsave, LDetSynthRes=LDetSynthRes) - - # tofu.Eq - elif obj.Id.Cls=='Eq2D': - np.savez(pathfileext, Idsave=Idsave, **obj._Tab) - - # tofu.mesh - elif obj.Id.Cls=='Mesh1D': - func(pathfileext, Idsave=Idsave, Knots=obj.Knots) - - elif obj.Id.Cls=='Mesh2D': - SubMinds = [{'Name':kk, 'ind':obj._SubMesh[kk]['ind']} for kk in obj._SubMesh.keys()] - func(pathfileext, Idsave=Idsave, Knots=[obj.MeshX1.Knots,obj.MeshX2.Knots], SubMinds=SubMinds, IndBg=obj._get_CentBckg()[1]) - - elif obj.Id.Cls=='BF2D': - Id = np.array(['BF2D',obj.Id.Name,obj.Id.SaveName,obj.Id.SavePath,obj.Id._dtFormat,obj.Id._Diag,str(obj.Id._shot), [obj.Id.Type], obj.Id.Exp],dtype=str) - IdMesh = np.array(['Mesh2D',obj.Mesh.Id.Name,obj.Mesh.Id.SaveName,obj.Mesh.Id.SavePath,obj.Mesh.Id._dtFormat],dtype=str) - dtime, dtimeMesh = np.array([obj.Id._dtime],dtype=object), np.array([obj.Mesh.Id._dtime],dtype=object) - USR = np.asarray(obj.Id.USRdict) - func(pathfileext, Id=Id, IdMesh=IdMesh, dtime=dtime, IdUSR=USR, dtimeMesh=dtimeMesh, KnotsR=obj.Mesh.MeshR.Knots, KnotsZ=obj.Mesh.MeshZ.Knots, Deg=np.array([obj.Deg],dtype=int), Ind=obj.Mesh._get_CentBckg()[1]) - - # tofu.matcomp - elif obj.Id.Cls=='GMat2D': - Id = np.array(['GMat2D',obj.Id.Name,obj.Id.SaveName,obj.Id.SavePath,obj.Id._dtFormat,obj.Id._Diag,str(obj.Id._shot), [obj.Id.Type], obj.Id.Exp],dtype=str) - dtime = np.array([obj.Id._dtime],dtype=object) - USR = np.asarray(obj.Id.USRdict) - IdObj, IdObjUSR = save_np_IdObj(obj.Id) - CompParamVal = np.array([obj._Mat_epsrel, obj._Mat_SubP, obj._Mat_SubTheta, obj._indMat_SubP, obj._MatLOS_epsrel, obj._MatLOS_SubP, int(obj._Mat_Fast)]) - CompParamStr = np.array([obj._Mat_Mode, obj._Mat_SubMode, obj._Mat_SubThetaMode, obj._MatLOS_Mode, obj._MatLOS_SubMode]) - func(pathfileext, Id=Id, dtime=dtime, IdUSR=USR, Ves=IdObj[2], VesUSR=IdObjUSR[2], LDetect=IdObj[1], BF2=IdObj[0], BF2USR=IdObjUSR[0], LDetectUSR=IdObjUSR[1], CompParamVal=CompParamVal, - CompParamStr=CompParamStr, indMat=obj._indMat, Matdata=obj._Mat_csr.data, Matind=obj._Mat_csr.indices, Matindpr=obj._Mat_csr.indptr, Matshape=obj._Mat_csr.shape, - MatLOSdata=obj._MatLOS_csr.data, MatLOSind=obj._MatLOS_csr.indices, MatLOSindpr=obj._MatLOS_csr.indptr, MatLOSshape=obj._MatLOS_csr.shape, - BF2Par=np.array([obj._BF2_Deg,obj._BF2_NFunc,obj._BF2_NCents]), LD_nD=obj._LD_nDetect) - - # tofu.treat - elif obj.Id.Cls=='PreData': - Init, Update = _convert_PreData2Ldict(obj) - func(pathfileext, Idsave=Idsave, Init=[Init], Update=[Update]) - - #Id = np.array(['PreData',obj.Id.Name,obj.Id.SaveName,obj.Id.SavePath,obj.Id._dtFormat,obj.Id._Diag,str(obj.Id._shot), [obj.Id.Type], obj.Id.Exp],dtype=str) - #dtime = np.array([obj.Id._dtime],dtype=object) - #USR = np.asarray(obj.Id.USRdict) - #IdObj, IdObjUSR = save_np_IdObj(obj.Id) - #StrPar = np.asarray([obj._Exp, obj._interpkind]) - #func(pathfileext, Id=Id, dtime=dtime, IdUSR=USR, LDetect=IdObj[0], LDetectUSR=IdObjUSR[0], - # DLPar=obj._DLPar, shot=obj._shot, StrPar=StrPar, Dt=obj._Dt, DtMarg=obj._DtMargin, MovMeanfreq=obj._MovMeanfreq, Resamp=obj._Resamp, - # indOut=obj._indOut, indCorr=obj._indCorr, PhysNoise=obj._PhysNoise, NoiseMod=obj._NoiseModel, interp_lt=obj._interp_lt, interp_lN=obj._interp_lNames) - - # tofu.inv - elif obj.Id.Cls=='Sol2D': - Id = np.array(['Sol2D',obj.Id.Name,obj.Id.SaveName,obj.Id.SavePath,obj.Id._dtFormat,obj.Id._Diag,str(obj.Id._shot), [obj.Id.Type], obj.Id.Exp],dtype=str) - dtime = np.array([obj.Id._dtime],dtype=object) - USR = np.asarray(obj.Id.USRdict) - IdObj, IdObjUSR = save_np_IdObj(obj.Id) - try: - timing = obj._timing - except Exception: - timing = obj._t2 - func(pathfileext, Id=Id, dtime=dtime, IdUSR=USR, PreData=IdObj[2], PreDataUSR=IdObjUSR[2], GMat2D=IdObj[1], GMatUSR=IdObjUSR[1], BF2D=IdObj[0], BF2DUSR=IdObjUSR[0], - InvParam=obj.InvParam, shot=obj.shot, LNames=obj._LNames, Run=obj._run, - LOS=obj._LOS, data=obj._data, t=obj._t, Coefs=obj._Coefs, sigma=obj._sigma, Mu=obj._Mu, Chi2N=obj._Chi2N, R = obj._R, Nit=obj._Nit, Spec=obj._Spec, t2=timing, PostTreat=obj._PostTreat) - - -def save_np_IdObj(Id): - """ (to do) """ - LObj, LObjUSR = [], [] - Keys = sorted(Id.LObj.keys()) - for ii in range(0,len(Keys)): - kk = sorted(Id.LObj[Keys[ii]].keys()) - Larr, LarrUSR = [], [] - for jj in range(0,len(kk)): - if kk[jj]=='USRdict': - LarrUSR.append(np.asarray([Id.LObj[Keys[ii]][kk[jj]]],dtype=object)) - else: - Larr.append(np.asarray([Id.LObj[Keys[ii]][kk[jj]]],dtype=str)) - LObj.append( np.concatenate(tuple(Larr),axis=0) ) - LObjUSR.append( np.concatenate(tuple(LarrUSR),axis=0) ) - return LObj, LObjUSR - - - -########################### -# Opening -########################### - - -
[docs]def Open(pathfileext=None, shot=None, t=None, Dt=None, Mesh=None, Deg=None, Deriv=None, Sep=True, Pos=True, OutPath=None, ReplacePath=None, Ves=None, out='full', Verb=False): - """ Open a ToFu object saved file - - This generic open function identifies the required loading routine by detecting how the object was saved from the file name extension. - Also, it uses :meth:`~tofu.pathfile.FindSolFile()` to identify the relevant file in case key criteria such as shot, Deg... are provided instead of the file name itself. - Finally, once all the relevant data is loaded from the file, a ToFu object is re-created, if necessary by implicitly loading all other objects it may depend on (i.e.: vessel, apertures...) - - If pathfileext is not provided (None), then the following keyword arguments are fed to :meth:`~tofu.pathfile.FindSolFile()`: shot, t, Dt, Mesh, Deg, Deriv, Sep, Pos - - Parameters - ---------- - pathfileext : None / str - If provided, the name of the file to load - OutPath : None / str - If provided, the absolute path where the file is to be found - ReplacePath : str - If provided, ? (to finish) - Ves : None / - If provided, the :class:`tofu.geom.Ves` object that shall be used to reconstruct the object (if not provided, the appropriate vessel will be loaded). - out : str - Flag indicating whether the object should be loaded completely ('full'), in a light dismissing the heaviest attributes ('light') or whether only the Id or a list of Id should be returned ('Id'), valid only for '.npz' - Verb : bool - Flag indicating whether to pring intermediate comments on the loading procedure - - Returns - ------- - obj ToFu object - The loaded and re-created ToFu object - - """ - assert None in [pathfileext,shot] and not (pathfileext is None and shot is None), "Arg pathfileext or shot must be None, but not both !" - if pathfileext is None: - File = FindSolFile(shot=shot, t=t, Dt=Dt, Mesh=Mesh, Deg=Deg, Deriv=Deriv, Sep=Sep, Pos=Pos, OutPath=OutPath) - if File is None: - return File - pathfileext = OutPath+File - assert '.npz' in pathfileext or '.pck' in pathfileext, "Arg pathfileext must contain '.npz' or .pck !" - - if '.npz' in pathfileext: - obj = _open_np(pathfileext, Ves=Ves, ReplacePath=ReplacePath, out=out, Verb=Verb) - else: - obj = _open_object(pathfileext) - print("Loaded : "+pathfileext) - return obj
- - - -def _open_object(pathfileext): - with Open(pathfileext, 'rb') as input: - obj = pck.load(input) - if 'TFM' in pathfileext: - obj.set_BasisFunc(obj.Deg) - return obj - - -def open_np_IdObj(LCls=None,LIdArr=None,LIdUSR=None): - LIdObj = [] - if not LIdArr is None: - assert type(LIdArr) is list and type(LCls) is list, "Args LCls and LIdArr must be lists !" - NObj = len(LIdArr) - for ii in range(0,NObj): - no = LIdArr[ii].shape[1] - for jj in range(0,no): - if not LIdUSR is None and not LIdUSR[ii][0][jj] is None: - LIdObj.append(ID(LCls[ii],str(LIdArr[ii][1,jj]),SaveName=str(LIdArr[ii][2,jj]), SavePath=str(LIdArr[ii][3,jj]), Exp=str(LIdArr[ii][0,jj]), dtime=dtm.datetime.strptime(str(LIdArr[ii][5,jj]),str(LIdArr[ii][4,jj])), dtFormat=str(LIdArr[ii][4,jj]), USRdict=LIdUSR[ii][0][jj])) - else: - LIdObj.append(ID(LCls[ii],str(LIdArr[ii][1,jj]),SaveName=str(LIdArr[ii][2,jj]), SavePath=str(LIdArr[ii][3,jj]), Exp=str(LIdArr[ii][0,jj]), dtime=dtm.datetime.strptime(str(LIdArr[ii][5,jj]),str(LIdArr[ii][4,jj])), dtFormat=str(LIdArr[ii][4,jj]))) - return LIdObj - - -def _tryloadVes(Id, Ves=None): - if not Ves is None: - if type(Ves) is TFG.Ves and Id.LObj['Ves']['SavePath'][0]==Ves.Id.SavePath and Id.LObj['Ves']['SaveName'][0]==Ves.Id.SaveName: - return Ves - else: - try: - PathFileExt = Id.LObj['Ves']['SavePath'][0]+Id.LObj['Ves']['SaveName'][0]+'.npz' - Ves = Open(PathFileExt) - except: - warnings.warn(Id.Name +" : associated Ves object could not be loaded from "+PathFileExt) - return Ves - -def _tryLoadOpticsElseCreate(Id, Opt=None, Ves=None, Verb=False): - import tofu.geom as TFG - if 'Apert' in Id.LObj.keys(): - Optics = [] - for ii in range(0,len(Id.LObj['Apert']['SaveName'])): - try: - PathFileExt = Id.LObj['Apert']['SavePath'][ii]+Id.LObj['Apert']['SaveName'][ii]+'.npz' - aa = Open(PathFileExt, Ves=Ves) - Optics.append(aa) - except Exception: - if not Opt is None: - assert type(Ves) is TFG.Ves, "Arg Ves must be a TFG.Ves instance !" - if Verb: - print(Id.Name +" : no saved Apert => creating the associated Apert object !") - ind = [jj for jj in range(0,len(Opt)) if Opt[jj]['Id'][0]['SaveName']==Id.LObj['Apert']['SaveName'][ii] and Opt[jj]['Id'][0]['SavePath']==Id.LObj['Apert']['SavePath'][ii]] - assert len(ind)==1, "Several possible solutions !" - ind = ind[0] - iid = _Id_recreateFromdict(Opt[ind]['Id']) - aa = TFG.Apert(iid, Opt[ind]['Poly'], Ves=Ves, arrayorder=Opt[ind]['arrayorder'], Clock=Opt[ind]['Clock']) - Optics.append(aa) - else: - warnings.warn(Id.Name +" : associated Apert object could not be loaded from "+PathFileExt) - elif 'Lens' in Id.LObj.keys(): - try: - PathFileExt = Id.LObj['Lens']['SavePath'][0]+Id.LObj['Lens']['SaveName'][0]+'.npz' - Optics = Open(PathFileExt, Ves=Ves) - except Exception: - if not Opt is None: - assert type(Ves) is TFG.Ves, "Arg Ves must be a TFG.Ves instance !" - if Verb: - print(Id.Name +" : no saved Lens => creating the associated Lens object !") - iid = _Id_recreateFromdict(Opt[0]['Id']) - aa = TFG.Lens(iid, Opt[0]['O'], Opt[0]['nIn'], Opt[0]['Rad'], Opt[0]['F1'], F2=Opt[0]['F2'], R1=Opt[0]['R1'], R2=Opt[0]['R2'], dd=Opt[0]['dd'], Type=Opt[0]['Type'], Ves=Ves, - arrayorder=Opt[0]['arrayorder'], Clock=Opt[0]['Clock']) - Optics = aa - else: - warnings.warn(Id.Name +" : associated Lens object could not be loaded from "+PathFileExt) - return Optics - - - -def _resetDetectAttr(obj, Out): - import tofu.geom as TFG - # Re-creating LOS - LOS = {} - kkeys = Out['LOSprops'].keys() - for ii in range(0,len(Out['LOSprops']['Keys'])): - idlos = _Id_recreateFromdict(Out['LOSprops']['Id'][ii]) - los = TFG.LOS(idlos, Out['LOSprops']['Du'][ii], Ves=obj.Ves, Sino_RefPt=obj.Sino_RefPt) - LOS[Out['LOSprops']['Keys'][ii]] = {'LOS':los} - for jj in range(0,len(kkeys)): - if not kkeys[jj] in ['Keys','Id','Du']: - LOS[Out['LOSprops']['Keys'][ii]][kkeys[jj]] = Out['LOSprops'][kkeys[jj]][ii] - obj._LOS = LOS - - # Re-assigning tabulated data - fields = ['Sino', 'Span', 'Cone', 'SAng', 'SynthDiag', 'Res'] - for ff in fields: - for kk in Out[ff].keys(): - setattr(obj,kk,Out[ff][kk]) - return obj - - - - -def _get_light_SynthDiag_Res(): - SynthDiag = {'_SynthDiag_Done':False, '_SynthDiag_ds':None, '_SynthDiag_dsMode':None, '_SynthDiag_MarginS':None, '_SynthDiag_dX12':None, '_SynthDiag_dX12Mode':None, '_SynthDiag_Colis':None, - '_SynthDiag_Points':None, '_SynthDiag_SAng':None, '_SynthDiag_Vect':None, '_SynthDiag_dV':None} - Res = {'_Res_Mode':None, '_Res_Amp':None, '_Res_Deg':None, - '_Res_Pts':None, '_Res_Res':None, '_Res_CrossMesh':None, '_Res_CrossMeshMode':None, - '_Res_steps':None, '_Res_Thres':None, '_Res_ThresMode':None, '_Res_ThresMin':None, - '_Res_IntResCross':None, '_Res_IntResCrossMode':None, '_Res_IntResLong':None, '_Res_IntResLongMode':None, '_Res_IntNtt':None, - '_Res_EqName': None, - '_Res_Done': False} - - return SynthDiag, Res - - - - -def _open_np(pathfileext, Ves=None, ReplacePath=None, out='full', Verb=False): - - if 'TFG' in pathfileext: - import tofu.geom as TFG - elif 'TFEq' in pathfileext: - import tofu.Eq as tfEq - elif 'TFM' in pathfileext: - import tofu.mesh as TFM - elif 'TFMC' in pathfileext: - import tofu.matcomp as TFMC - elif 'TFT' in pathfileext: - import tofu.treat as tft - elif 'TFI' in pathfileext: - import tofu.inv as TFI - - Out = np.load(pathfileext,mmap_mode=None) - Id = _Id_recreateFromdict(Out['Idsave']) - if out=='Id': - return Id - - if Id.Cls == 'Ves': - obj = TFG.Ves(Id, Out['Poly'], Type=Id.Type, Exp=Id.Exp, DLong=Out['DLong'].tolist(), Clock=bool(Out['Clock']), arrayorder=str(Out['arrayorder']), Sino_RefPt=Out['Sino_RefPt'], Sino_NP=int(Out['Sino_NP']), - SavePath=Id.SavePath, dtime=Id.dtime, dtimeIn=Id._dtimeIn) - - elif Id.Cls == 'Struct': - Ves = _tryloadVes(Id) - obj = TFG.Struct(Id, Out['Poly'], Type=Id.Type, Exp=Id.Exp, DLong=Out['DLong'].tolist(), Ves=Ves, Clock=bool(Out['Clock']), arrayorder=str(Out['arrayorder']), - SavePath=Id.SavePath, dtime=Id.dtime, dtimeIn=Id._dtimeIn) - - elif Id.Cls == 'LOS': - Ves = _tryloadVes(Id) - obj = TFG.LOS(Id, tuple(Out['Du']), Type=Id.Type, Ves=Ves, Sino_RefPt=Out['Sino_RefPt'], arrayorder=str(Out['arrayorder']), Clock=bool(Out['Clock']), Exp=Id.Exp, Diag=Id.Diag, shot=Id.shot, - SavePath=Id.SavePath, dtime=Id.dtime, dtimeIn=Id._dtimeIn) - elif Id.Cls == 'GLOS': - Ves = _tryloadVes(Id) - LLOS, IdLOS = [], Id.LObj['LOS'] - for ii in range(0,len(IdLOS['Name'])): - Idl = _Id_recreateFromdict(Out['LIdLOS'][ii]) - ll = TFG.LOS(Idl, Du=(Out['LDs'][:,ii],Out['Lus'][:,ii]), Ves=Ves, Sino_RefPt=Out['Sino_RefPt'], arrayorder=str(Out['arrayorder'])) - LLOS.append(ll) - obj = TFG.GLOS(Id, LLOS, Ves=Ves, Type=Id.Type, Exp=Id.Exp, Diag=Id.Diag, shot=Id.shot, Sino_RefPt=Out['Sino_RefPt'], SavePath=Id.SavePath, arrayorder=str(Out['arrayorder']), Clock=bool(Out['Clock']), - dtime=Id.dtime, dtimeIn=Id._dtimeIn) - - elif Id.Cls == 'Lens': - Ves = _tryloadVes(Id, Ves=Ves) - obj = TFG.Lens(Id, Out['O'], Out['nIn'], Out['Rad'][0], Out['F1'][0], F2=Out['F2'][0], Type=Id.Type, R1=Out['R1'][0], R2=Out['R2'][0], dd=Out['dd'][0], Ves=Ves, - Exp=Id.Exp, Clock=bool(Out['Clock']), Diag=Id.Diag, shot=Id.shot, arrayorder=str(Out['arrayorder']), SavePath=Id.SavePath, dtime=Id.dtime, dtimeIn=Id._dtimeIn) - - elif Id.Cls == 'Apert': - Ves = _tryloadVes(Id, Ves=Ves) - obj = TFG.Apert(Id, Out['Poly'], Clock=bool(Out['Clock']), arrayorder=str(Out['arrayorder']), Ves=Ves, Exp=Id.Exp, Diag=Id.Diag, shot=Id.shot, dtime=Id.dtime, dtimeIn=Id._dtimeIn) - - elif Id.Cls == 'Detect': - Ves = _tryloadVes(Id, Ves=Ves) - LOSprops, Sino, Span, Cone, SAng, Opt = Out['LOSprops'][0], Out['Sino'][0], Out['Span'][0], Out['Cone'][0], Out['SAng'][0], Out['Optics'][0] - (SynthDiag,Res) = (Out['SynthDiag'][0],Out['Res'][0]) if out=='full' else _get_light_SynthDiag_Res() - Optics = _tryLoadOpticsElseCreate(Id, Opt=Opt, Ves=Ves, Verb=Verb) - - Poly = Out['Poly'] if type(Optics) is list else dict(Rad=float(Out['Rad']),O=Out['BaryS'],nIn=Out['nIn']) - obj = TFG.Detect(Id, Poly, Optics=Optics, Ves=Ves, Sino_RefPt=Sino['_Sino_RefPt'], CalcEtend=False, CalcSpanImp=False, CalcCone=False, CalcPreComp=False, Calc=True, Verb=Verb, - arrayorder=str(Out['arrayorder']), Clock=bool(Out['Clock'])) - obj = _resetDetectAttr(obj, {'LOSprops':LOSprops, 'Sino':Sino, 'Span':Span, 'Cone':Cone, 'SAng':SAng, 'SynthDiag':SynthDiag, 'Res':Res, 'Optics':Opt}) - obj._LOS_NP = Out['LOSNP'] - if obj._SynthDiag_Done and obj._SynthDiag_Points is None: - obj.set_SigPrecomp() - - elif Id.Cls == 'GDetect': - LDetsave = list(Out['LDetsave']) - LDet = [] - Ves = _tryloadVes(Id, Ves=Ves) - if out=='light': - SynthDiag, Res = _get_light_SynthDiag_Res() - else: - LDetSynthRes = Out['LDetSynthRes'] - for ii in range(0,len(LDetsave)): - ddIdsave = _Id_recreateFromdict(LDetsave[ii]['Idsave']) - LOSprops, Sino, Span, Cone, SAng, Opt = LDetsave[ii]['LOSprops'][0], LDetsave[ii]['Sino'][0], LDetsave[ii]['Span'][0], LDetsave[ii]['Cone'][0], LDetsave[ii]['SAng'][0], LDetsave[ii]['Optics'][0] - if out=='full': - SynthDiag, Res = LDetSynthRes[ii]['SynthDiag'][0], LDetSynthRes[ii]['Res'][0] - Optics = _tryLoadOpticsElseCreate(ddIdsave, Opt=Opt, Ves=Ves, Verb=Verb) - Poly = LDetsave[ii]['Poly'] if type(Optics) is list else dict(Rad=float(LDetsave[ii]['Rad']),O=LDetsave[ii]['BaryS'],nIn=LDetsave[ii]['nIn']) - dd = TFG.Detect(ddIdsave, Poly, Optics=Optics, Ves=Ves, Sino_RefPt=Out['Sino_RefPt'], CalcEtend=False, CalcSpanImp=False, CalcCone=False, CalcPreComp=False, Calc=True, Verb=Verb, - arrayorder=str(Out['arrayorder']), Clock=bool(Out['Clock'])) - dd = _resetDetectAttr(dd, {'LOSprops':LOSprops, 'Sino':Sino, 'Span':Span, 'Cone':Cone, 'SAng':SAng, 'SynthDiag':SynthDiag, 'Res':Res, 'Optics':Opt}) - dd._LOS_NP = LDetsave[ii]['LOSNP'] - if dd._SynthDiag_Done and dd._SynthDiag_Points is None: - dd.set_SigPrecomp() - LDet.append(dd) - obj = TFG.GDetect(Id, LDet, Type=Id.Type, Exp=Id.Exp, Diag=Id.Diag, shot=Id.shot, dtime=Id.dtime, dtimeIn=Id._dtimeIn, Sino_RefPt=Out['Sino_RefPt'], LOSRef=str(Out['LOSRef']), - arrayorder=str(Out['arrayorder']), Clock=bool(Out['Clock']), SavePath=Id.SavePath) - Res = Out['Res'][0] if out=='full' else Res - for kk in Res.keys(): - setattr(obj,kk,Res[kk]) - - elif Id.Cls=='Eq2D': - Sep = [np.array(ss) for ss in Out['Sep'].tolist()] - obj = tfEq.Eq2D(Id, Out['PtsCross'], t=Out['t'], MagAx=Out['MagAx'], Sep=Sep, rho_p=Out['rho_p'].tolist(), rho_t=Out['rho_t'].tolist(), surf=Out['surf'].tolist(), vol=Out['vol'].tolist(), - q=Out['q'].tolist(), jp=Out['jp'].tolist(), pf=Out['pf'].tolist(), tf=Out['tf'].tolist(), theta=Out['theta'].tolist(), thetastar=Out['thetastar'].tolist(), - BTX=Out['BTX'].tolist(), BRY=Out['BRY'].tolist(), BZ=Out['BZ'].tolist(), Ref=str(Out['Ref'])) - - elif Id.Cls=='Mesh1D': - obj = TFM.Mesh1D(Id, Out['Knots']) - - elif Id.Cls=='Mesh2D': - obj = TFM.Mesh2D(Id, [Out['Knots'][0],Out['Knots'][1]]) - obj = TFM.Mesh2D(Id, Knots=obj, ind=Out['IndBg']) - for ii in range(0,len(Out['SubMinds'])): - obj.add_SubMesh(Name=Out['SubMinds'][ii]['Name'], ind=Out['SubMinds'][ii]['ind']) - - elif Id.Cls=='Metric1D': - obj = TFM.Metric1D(Id) - - elif Id.Cls=='Metric2D': - obj = TFM.Metric2D(Id) - - - elif Id.Cls in 'BF2D': - IdMesh = ID(str(Out['IdMesh'][0]), str(Out['IdMesh'][1]), SaveName=str(Out['IdMesh'][2]), SavePath=str(Out['IdMesh'][3]), dtime=Out['dtimeMesh'][0], dtFormat=str(Out['IdMesh'][4])) - M2 = TFM.Mesh2D(IdMesh, Knots=[Out['KnotsR'],Out['KnotsZ']]) - M2bis = TFM.Mesh2D(IdMesh,Knots=M2,Ind=Out['Ind']) - obj = TFM.BF2D(Id, M2bis, int(Out['Deg'][0])) - elif Id.Cls=='GMat2D': - import ToFu_MatComp as TFMC - import scipy.sparse as scpsp - Id.set_LObj(open_np_IdObj(['Ves','BF2D','Detect'], [Out['Ves'],Out['BF2'],Out['LDetect']], [Out['VesUSR'],Out['BF2USR'],Out['LDetectUSR']])) - Mat = scpsp.csr_matrix((Out['Matdata'], Out['Matind'], Out['Matindpr']), shape=Out['Matshape']) - MatLOS = scpsp.csr_matrix((Out['MatLOSdata'], Out['MatLOSind'], Out['MatLOSindpr']), shape=Out['MatLOSshape']) - obj = TFMC.GMat2D(Id, None, None, Mat=None, indMat=None, MatLOS=None, Calcind=False, Calc=False, CalcLOS=False) - obj._init_CompParam(Mode=str(Out['CompParamStr'][0]), epsrel=Out['CompParamVal'][0], SubP=Out['CompParamVal'][1], SubMode=str(Out['CompParamStr'][1]), SubTheta=Out['CompParamVal'][2], SubThetaMode=str(Out['CompParamStr'][2]), Fast=bool(Out['CompParamVal'][-1]), SubPind=Out['CompParamVal'][3], ModeLOS=str(Out['CompParamStr'][3]), epsrelLOS=Out['CompParamVal'][4], SubPLOS=Out['CompParamVal'][5], SubModeLOS=str(Out['CompParamStr'][4])) - obj._BF2 = None - obj._BF2_Deg = int(Out['BF2Par'][0]) - obj._BF2_NCents = int(Out['BF2Par'][2]) - obj._BF2_NFunc = int(Out['BF2Par'][1]) - obj._Ves = None - obj._LD = None - obj._LD_nDetect = int(Out['LD_nD']) - obj._set_indMat(indMat=Out['indMat'], Verb=False) - obj._set_MatLOS(MatLOS=MatLOS, Verb=False) - obj._set_Mat(Mat=Mat, Verb=False) - - - - elif Id.Cls=='PreData': - LIdDet = Id.get_LObjasLId('Detect') if 'Detect' in Id.LObj.keys() else None - Init, Update = Out['Init'][0], Out['Update'][0] - obj = tft.PreData(Init['data'], Id=Id, t=Init['t'], Chans=Init['Chans'], DtRef=Init['DtRef'], LIdDet=LIdDet) - obj.set_Dt(Update['Dt'], Calc=False) - obj.set_Resamp(t=Update['Resamp_t'], f=Update['Resamp_f'], Method=Update['Resamp_Method'], interpkind=Update['Resamp_interpkind'], Calc=False) - obj.Out_add(indOut=Update['indOut'], Calc=False) - obj.Corr_add(indCorr=Update['indCorr'], Calc=False) - obj.interp(lt=Update['interp_lt'], lNames=Update['interp_lNames'], Calc=False) - obj.substract_Dt(tsub=Update['Subtract_tsub'], Calc=False) - obj.set_fft(Calc=True, **Update['FFTPar']) - if not Update['PhysNoiseParam'] is None: - Method = 'svd' if 'Modes' in Update['PhysNoiseParam'].keys() else 'fft' - obj.set_PhysNoise(**Update['PhysNoiseParam'].update({'Method':Method})) - - - #Id.set_LObj(open_np_IdObj(['Detect'],[Out['LDetect']], [Out['LDetectUSR']])) - #obj = TFT.PreData(Id=Id, shot=int(Out['shot']), DLPar=Out['DLPar'].item(), Exp=str(Out['StrPar'][0]), Dt=list(Out['Dt']), DtMargin=float(Out['DtMarg']), MovMeanfreq=float(Out['MovMeanfreq']), Resamp=bool(Out['Resamp']), - # interpkind=str(Out['StrPar'][1]), indOut=Out['indOut'], indCorr=Out['indCorr'], lt=Out['interp_lt'], lNames=Out['interp_lN'].tolist(), Test=True) - #if not Out['PhysNoise'].item() is None: - # obj.set_PhysNoise(Deg=int(Out['NoiseMod'].item()['Deg']), Nbin=int(Out['NoiseMod'].item()['Nbin']), LimRatio=float(Out['NoiseMod'].item()['LimRatio']), **Out['PhysNoise'].item()['Param']) - - - elif Id.Cls=='Sol2D': - Id.set_LObj(open_np_IdObj(['PreData','GMat2D','BF2D'],[Out['PreData'], Out['GMat2D'], Out['BF2D']], [Out['PreDataUSR'],Out['GMatUSR'],Out['BF2DUSR']])) - GMSaveName = Id.LObj['GMat2D']['SaveName'][0] - try: - GMat = Open(Id.LObj['GMat2D']['SavePath'][0]+GMSaveName+'.npz') - except Exception: - GMSaveName = GMSaveName[:GMSaveName.index('All_')+4]+'sh'+GMSaveName[GMSaveName.index('All_')+4:] - GMat = Open(Id.LObj['GMat2D']['SavePath'][0]+GMSaveName+'.npz') - obj = TFI.Sol2D(Id, PreData=None, GMat=GMat, InvParam=Out['InvParam'].item(), SVesePreData=False, SVeseGMat=True, SVeseBF=True) - obj._PreData = None - obj._GMat = obj.GMat.get_SubGMat2D(Val=list(Out['LNames']), Crit='Name',InOut='In') - obj._shot = int(Out['shot']) - try: - obj._LNames = Out['LNames'].tolist() - except Exception: - obj._LNames = obj.PreData.In_list() - obj._run = bool(Out['Run']) - if bool(Out['Run']): - obj._LOS = bool(Out['LOS']) - obj._t, obj._data = Out['t'], Out['data'] - obj._Coefs, obj._sigma = Out['Coefs'], Out['sigma'] - obj._Mu, obj._Chi2N, obj._R, obj._Nit = Out['Mu'], Out['Chi2N'], Out['R'], Out['Nit'] - obj._Spec = list(Out['Spec']) - obj._timing = Out['t2'] - obj._PostTreat = list(Out['PostTreat']) - return obj - - - - -
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/build/html/_modules/tofu/plugins/AUG/SXR/data/_core.html b/doc/build/html/_modules/tofu/plugins/AUG/SXR/data/_core.html deleted file mode 100644 index 901e2492f..000000000 --- a/doc/build/html/_modules/tofu/plugins/AUG/SXR/data/_core.html +++ /dev/null @@ -1,580 +0,0 @@ - - - - - - - - tofu.plugins.AUG.SXR.data._core — tofu v1.1 - - - - - - - - - - - - - - - -
-
-
-
- -

Source code for tofu.plugins.AUG.SXR.data._core

-# -*- coding: utf-8 -*-
-"""
-Provide basic python routines for load AUG SXR data in a ToFu-compatible format
-
-@author: didiervezinet
-"""
-
-from __future__ import print_function
-import sys
-
-import os
-import itertools as itt
-import string
-import numpy as np
-import warnings
-# import scipy.interpolate as scpinterp
-
-import matplotlib.pyplot as plt
-import datetime as dtm
-
-# ToFu specific
-import tofu.defaults as tfd
-import tofu.pathfile as tfpf
-import tofu.helper as tfh
-import tofu.treat as tft
-from ... import _path as _tfaug_path
-from .. import _helper as tfaugSXRh
-from .. import geom as tfaugsxrg
-
-# AUG specific
-import dd
-
-__author__ = "Didier Vezinet"
-__all__ = ["load"]
-
-
-
-
-############################################################################
-############################################################################
-############################################################################
-#       Default path for PreData saving
-############################################################################
-
-
-def _get_defaultsSavePathsdtime(SavePathObj=None, SavePathInp=None, dtime=None, dtFormat=tfd.dtmFormat, Type='Object'):
-    assert SavePathObj is None or type(SavePathObj) is str, "Arg SavePathObj must be a str !"
-    assert SavePathInp is None or type(SavePathInp) is str, "Arg SavePathInp must be a str !"
-    assert dtime is None or type(dtime) is str or isinstance(dtime,dtm.datetime), "Arg dtime must be a str or a dtm.datetime instance !"
-    assert type(dtFormat) is str, "Arg dtFormat must be a str !"
-    RP = tfpf.Find_Rootpath()
-    if SavePathInp is None:
-        SavePathInp = RP+'/Inputs_'+Exp+'/'
-    if SavePathObj is None:
-        SavePathObj = RP+'/Objects_'+Exp+'/' if Type=='Object' else RP+'/Outputs_'+Exp+'/'
-    if dtime is None:
-        dtime = dtm.datetime.now()
-    elif type(dtime) is str:
-        dtime = dtm.strptime(dtime,dtFormat)
-    return SavePathObj, SavePathInp, dtime
-
-
-
-
-
-
-
-############################################################################
-############################################################################
-############################################################################
-#       Data loading
-############################################################################
-
-
-
[docs]def load(shot=None, Names=None, Mode='SSX', Dt=None, Join=True, tRef='fmin', Method='interp', NoGeom=True, Tofu=True, - - Verb=True, Test=True): # Add kwdarg tRef to decide which time base to use - """ Load SXR data from the AUG database and returns it either as numpy arrays or a ToFu-compatible object with appropriate methods - - - Part of the difficulty is that all channels do not have the same sampling frequency and time vector. - Hence, there is an option to uniformize the time base. - - - Parameters - ---------- - shot : int - Shot number for which the SXR data should be loaded - Names : None / str / list - If provided, data is loaded only for the specified channel(s) - Mode : str - Flag indicating whether data should be loaded from a down-sampled database ('SSX', , faster loading) or from the complete database ( depending on the channel) - Dt : None / iterable - If provided, a len()=2 iterable giving the time interval of interest (recommended to avoid very large data files) - Join : bool - Flag, useful when Mode='SX', indicating whether the different time bases of the channels shall be uniformized - tRef : None / str / np.ndarray - Flag or time vector, useful when Mode='SX' and Join=True, indicating which time basis should be used as a reference - - 'fmin': the time vector of the channel presenting the smallest sampling frequency is used as a reference - - 'fmax': the time vector of the channel presenting the highest sampling frequency is used as a reference - - any channel name: the time vector of the specifiec channel is used as a reference - - np.ndarray: the provided time vector is used as a reference - Method : str - Flag, usefule when Mode='SX' and Join=True, indicating how the - NoGeom : bool - Flag indicating whether the data should be stripped of its geometrical calibration factor (thus being expressed in W instead of W/m2), to allow for: - - Application of a tofu-computed etendue in case of a LOS approach - - Direct use of the signal in case of a VOS approach - Tofu : bool - Flag indicating whether the loaded data should be returned as (SXR, t, Names) where the first two are np.ndarrays and Names is a list or as a tofu.data.PreData object - Verb : bool - Flag indicating whether extra comments should be printed to give feedback on the progress of the routine - Test : bool - Flag indicating whether the inputs should be tested for conformity - - - Returns - ------- - out : tuple / tofu.data.PreData - - - """ - if Test: - assert type(shot) is int, "Arg shot must be a int !" - assert Names is None or type(Names) is str or (hasattr(Names,'__iter__') and all([type(ss) is str for ss in Names])), "Arg Names must be a str or an iterable of str (channel names) !" - assert Mode in ['SSX','SX'], "Arg Mode must be in ['SSX','SX'] !" - assert type(Join) is bool, "Arg Join must be a bool !" - assert Dt is None or (hasattr(Dt,'__iter__') and len(Dt)==2 and all([type(dt) in [float,int,np.float64] for dt in Dt]) and Dt[0]<Dt[1]), "Arg Dt be an iterable of len()==2 with increasing values !" - assert tRef is None or type(tRef) is str or (type(tRef) is np.ndarray and tRef.ndim==1), "Arg tRef must be a str or a 1D np.ndarray !" - assert not (type(tRef) is np.ndarray and Dt is not None), "Conflicting time interval between Dt and tRef !" - assert Method in ['interp'], "Arg Method must be in ['interp'] !" - assert type(NoGeom) is bool, "Arg NoGeom must be a bool !" - assert type(Tofu) is bool, "Arg ToFu must be a bool !" - assert type(Verb) is bool, "Arg Verb must be a bool !" - - # Pre-formatting input - if Mode=='SSX' and not NoGeom: - Names = [Names] if type(Names) is str else Names - Names = sorted(tfaugSXRh._CamHeads().keys()) if Names is None else sorted(Names) - else: - Dict = tfaugSXRh._WhichSX(shot=shot, Names=Names, Verb=Verb) - Names = sorted(Dict.keys()) - NN = len(Names) - assert NN>0, "None of the desired channels available for {0}".format(shot) - - if type(tRef) is np.ndarray: - Dt = [np.nanmin(tRef), np.nanmax(tRef)] - Dtlarge = [Dt[0]-0.1*np.diff(Dt), Dt[1]+0.1*np.diff(Dt)] if not Dt is None else None - - # Loading - - # Use diagnostic SSX (down-sampled data) - if Mode=='SSX': - try: - SXR, t, Names = _load_SSX(shot, Names, NN, Dt) - - except Exception: - print(" Could not load SSX for ", shot) - SXR, t, Names = np.empty((0,0)), np.empty((0,0)), [] - - assert len(Names)==SXR.shape[1], " There seems to be a mistake in the number of channels !" - indt = (t>=Dt[0]) & (t<=Dt[1]) - t = t[(t>=Dt[0]) & (t<=Dt[1])] - - # Use diagnostic SX. - elif Mode=='SX': - - Ldiags = [Dict[nn]['Diag'] for nn in Names] - ind = [Ldiags[ii] is None for ii in range(0,NN)] - if any(ind): - print(" Could not find "+str([Names[ii] for ii in range(0,NN) if ind[ii]])+" in the SX shotfiles for {0}".format(shot)) - - Names = [Names[ii] for ii in range(0,NN) if not ind[ii]] - Ldiags = [Ldiags[ii] for ii in range(0,NN) if not ind[ii]] - NN = len(Names) - - Ldiagsu = sorted(list(set(Ldiags))) - SXR, t = [None for ii in range(0,NN)], [None for ii in range(0,NN)] - dtl = Dtlarge if Join else Dt # To have margin (for boundary effects) for unifying the time basis - if Verb: - print("---------------------------------------------------------", end="\n") - for ii in range(0,len(Ldiagsu)): - try: - SXR, t = _load_SX(shot, Ldiagsu[ii], Names, NN, Ldiags, dtl, SXR, t) - - except Exception: - print(" Could not load "+Ldiagsu[ii]+" for "+str(shot)) - - ind = [ii for ii in range(0,NN) if not SXR[ii] is None] - t = [t[ii] for ii in ind] - Names = [Names[ii] for ii in ind] - SXR = [SXR[ii] for ii in ind] - NN = len(Names) - if Join: - if Verb: - print("---------------------------------------------------------", end="\n") - print(" Unifying the time bases") - tRef = _get_tRef(Names, t, tRef) - tRef = tRef[(tRef>=Dt[0]) & (tRef<=Dt[1])] - SXR, t = _Unify(SXR, t, tRef, Method=Method) - elif Tofu: - Tofu = False - warnings.warn("ToFu output can only be issued if Join=True !") - - if NoGeom and NN>0: - FourPiOnEt = np.asarray([Dict[nn]['MULTIA02'] for nn in Names]) - if type(SXR) is list: - SXR = [SXR[ii]/FourPiOnEt[ii] for ii in range(0,NN)] - else: - SXR = SXR.dot(np.diag(1./FourPiOnEt)) - - if not Tofu: - out = (SXR, t, Names) - else: - out = _create_PreData(shot, SXR, t, Names, Mode, Dt, tRef, Method, NoGeom) - - return out
- - - - - - - - - -def _load_SSX(shot, Names, NN, Dt): - sh = dd.shotfile('SSX',shot) - sxr, t = [None for ii in range(0,NN)], [None for ii in range(0,NN)] - for ii in range(0,NN): - try: - load = sh(Names[ii]) - time = load.time - indin = np.ones((time.size,),dtype=bool) - if not Dt is None: - indin = (time>=Dt[0]) & (time<=Dt[1]) - if not np.any(indin): - indin[np.argsort(np.abs(time-np.mean(Dt)))[0:3]] = True - t[ii] = time[indin] - sxr[ii] = load.data[indin] - except Exception: - print(" Could not load SSX "+Names[ii]+" for "+str(shot)) - sh.close() - ind = [ii for ii in range(0,NN) if not t[ii] is None] - t = [t[ii] for ii in ind] - assert all([np.all(tt==t[0]) for tt in t]), " SSX do not have same time base for all channels in "+str(shot) - t = t[0] - Names = [Names[ii] for ii in ind] - SXR = np.asarray([sxr[ii] for ii in ind]).T - return SXR, t, Names - - - -def _load_SX(shot, diag, Names, NN, Ldiags, Dt, SXR, t, Verb=True): - inds = [jj for jj in range(0,NN) if Ldiags[jj]==diag] - sh = dd.shotfile(diag, shot) - for jj in range(0,len(inds)): - try: - load = sh(Names[inds[jj]]) - if Verb: - print(Names[inds[jj]], end=" ") - sys.stdout.flush() - time = load.time - if not Dt is None: - indin = (time>=Dt[0]) & (time<=Dt[1]) - if not np.any(indin): - indin[np.argsort(np.abs(time-np.mean(Dt)))[0:3]] = True - t[inds[jj]] = time[indin] - SXR[inds[jj]] = load.data[indin] - except Exception: - if Verb: - print("",end="\n") - print(" Could not load "+diag+" "+Names[inds[jj]]+" for {0}".format(shot), end='\n') - if Verb: - print("",end="\n") - sh.close() - return SXR, t - - - - - - - -############################################################################ -############################################################################ -############################################################################ -# Secondary routines -############################################################################ - -def _get_tRef(Names, t, tRef): - if type(tRef) is np.ndarray: - assert tRef==np.unique(tRef), "Arg tRef must be a vector of increasing values !" - else: - assert tRef in Names or tRef in ['fmin','fmax'], "Arg tRef must be a channel name or in ['fmin','fmax'] !" - if tRef in Names: - tRef = t[Names.index(tRef)] - else: - lf = [1./np.mean(np.diff(tt)) for tt in t] - tRef = t[int(np.argmin(lf))] if tRef=='fmin' else t[int(np.argmax(lf))] - return tRef - - - -def _Unify(SXR, t, tRef, Method='interp'): - SXRref = np.nan*np.ones((tRef.size,len(SXR))) - if Method=='interp': - for ii in range(0,len(SXR)): - SXRref[:,ii] = np.interp(tRef, t[ii], SXR[ii]) - return SXRref, tRef - - - - -############################################################################ -############################################################################ -############################################################################ -# --------- Objects creation ------- -############################################################################ - - -def _create_PreData(shot, SXR, t, Names, Mode, Dt, tRef, Method, NoGeom, - Name=None, SavePath=None, Root=_tfaug_path._Root, save=True, - SXInfo=True, Filt=True, TorPos=True, NamesOut=[], - CorrDef=True, NamesCorr=[], - Test=True): - """ - Get the data from AUG shotfile for chosen shot and time interval, resampled with chosen frequency and using chosen diagnostic and return it as a TFT.PreData object - - Paramaters - ---------- - Name str, user-defined name to be given to the dataset for customization, advised to leave None (default) which automatically include useful information - shot int, shot number to be used for shotfile loading - Dt list, bounds of the time interval to which data should be restricted in seconds (default : [0,10]) - MovMeanFreq float, frequency to used for resampling of the data in Hz (default 200.e3) - Diag str, diagnostic name to be used for shotfile loading, for SXR on AUG one can choose between 'SSX' and 'SX' (default) - Exp str, experiment name used shotfile loading (default: 'AUG') - NamesOut list, names of the SXR channels to be left out of the data because they are thought to be corrupted or useless (default : []) - OutChanDef bool, flag indicating whereas the default selection of corrupted channels shall be used (default : True) - SXInfo bool, flag indicating whereas the default selection of corrupted channels shall use info available from SXinfo (default : True) - Filt bool, flag indicating whether the default selection of corrupted channels shall use info regarding the filter type of each diode (default : True) - TorPos bool, flag indicating whether the default selection of corrupted channels shall use info regarding the toroidal position of each channel (default : True) - Resamp bool, flag indicating whether data shall be resampled (default : True) - interpkind str, type of interpolation to be used for the resampling (default : 'linear') - CorrDef bool, flag indicating whereas the default selection of channels needing correction shall be used (default : True) - NamesCorr list, names of the SXR channels that are thought to be needing automated correction by retrofit (default : []) - SavePathObj str, absolute path of the AUG ToFu objects (TFG.Tor and TFG.GDetect) to be used (default : None => automatic) - SavePathInp str, absolute path of the ... - dtimeObj dtm.datetime object indicating the kind of kind of SXR diagnostic geometry that should be used (default : None => automatic) - dtFormat str, format to be used in the file names for the dtime indication (default : "D%Y%m%d_T%H%M%S") - Test bool, flag indicating whether inputs shall be tested for consistency - - Returns - ------- - Pre : TFT.PreData - Object containing the prepared data, additional treatments can be done using the object methods (channel selection, noise estimation...) - - """ - if Test: - assert type(SXR) is np.ndarray, "Arg SXR must be a np.ndarray !" - assert type(t) is np.ndarray and t.ndim==1 and t.size==SXR.shape[0], "Arg t must be a time vector with size=SXR.shape[0] !" - assert all([type(ss) is bool for ss in [SXInfo,Filt,TorPos]]), "Args [OutChanDef,SXInfo,Filt,TorPos] must be bools !" - assert NamesOut is None or (type(NamesOut) is list and all([type(nn) is str for nn in NamesOut])), "Arg NamesOut must be a list of Names !" - - - # Get pathfileext of geometry files to pass to PreData in case of data plotting with geometry - CamHs = tfaugSXRh._CamHeads() - CamHs = sorted(list(set([CamHs[nn] for nn in Names]))) - LIdDet = tfaugsxrg.load(Cams=CamHs, shot=shot, out='Id') - if len(CamHs)>1: - LIdDet = list(itt.chain.from_iterable([idg.get_LObjasLId(Cls='Detect')['Detect'] for idg in LIdDet])) - else: - LIdDet = LIdDet[0].get_LObjasLId(Cls='Detect')['Detect'] - LIdDet = [idd for idd in LIdDet if idd.Name in Names] - - # Path for saving PreData object - if SavePath is None: - SavePath = Root+'/tofu/plugins/AUG/SXR/data/Outputs/' - - # Loading data in tft.PreData object - USRdict = {'Mode':Mode, 'Dt':Dt, 'tRef':tRef, 'Method':Method, 'NoGeom':NoGeom} - - # Creating the PreData object - Pre = tft.PreData(SXR, t=t, Chans=Names, Id=Name, Exp='AUG', shot=shot, Diag='SXR', SavePath=SavePath, LIdDet=LIdDet, DtRef=Dt) - Pre.Id.set_USRdict(USRdict) - - # Getting Default corrupted channels out - if any([SXInfo,Filt,TorPos]): - LOut = {'Cam':[], 'CamHead':[], 'Name':[]} - Lout = _GetDefOutChannels(shot, Pre.Id.LObj['Detect'], LOut, SXInfo=SXInfo, Filt=Filt, TorPos=TorPos) - NamesOut = NamesOut+Lout['Name']+LOut['Cam']+LOut['CamHead'] - Pre.Out_add(Val=sorted(list(set(NamesOut))), LCrit=['Name','Cam','CamHead']) - - - # Getting defaults Corr channels - Corr = {'Cam':[], 'CamHead':[], 'Name':[]} - if CorrDef: - Corr = _GetCorrChannels(shot, Corr) - NamesCorr = NamesCorr+Corr['Name']+Corr['Cam']+Corr['CamHead'] - Pre.Corr_add(Val=sorted(list(set(NamesCorr))), LCrit=['Name','Cam','CamHead']) - - return Pre - - - - - - - - - -def _GetDefOutChannels(shot, LObjDet, LOut={'Cam':[],'CamHead':[],'Name':[]}, SXInfo=True, Filt=True, TorPos=True): - if TorPos: - LOut['Cam'] += ['F'] - if Filt: - Filt = [(usr['FiltMat'],usr['FiltThick']) for usr in LObjDet['USRdict']] - Filtu = list(set(Filt)) - FiltRef = [Filt.count(ff) for ff in Filtu] - FiltRef = Filtu[FiltRef.index(max(FiltRef))] - LOut['Name'] = [LObjDet['Name'][ii] for ii in range(0,len(LObjDet['Name'])) if not (LObjDet['USRdict'][ii]['FiltMat'],LObjDet['USRdict'][ii]['FiltThick'])==FiltRef] - # The rest is taken from SXinfo (update regularly) - if SXInfo: - if shot >= 31679: - LOut['Name'] += ['F_019', 'J_057','J_058','J_059','J_060', 'J_079','J_082'] - if shot >= 25987: - LOut['Name'] += ['K_020','K_049','K_058'] - if shot >= 26663: - LOut['Name'] += ['K_057'] - if shot >= 27489 and shot <= 31621: - LOut['Name'] += ['I_061'] - if shot >= 30506 and shot <= 31549: - LOut['Name'] += ['I_060'] - if shot >= 25823 and shot <= 25890: - LOut['Cam'] += ['L'] - if shot >= 30161 and shot <= 30425: - LOut['Cam'] += ['H'] - return LOut - - - - - -def _GetCorrChannels(shot, Corr={'Name':[],'Cam':[],'CamHead':[]}): - if shot >= 30446: - Corr['CamHead'] += ['H2'] - if shot == 25854: - Corr['CamHead'] += ['J2'] - if shot >= 31802: - Corr['Cam'] += 'L' - Corr['Cam'] += 'M' - return Corr - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/build/html/_modules/tofu/plugins/AUG/SXR/geom/_core.html b/doc/build/html/_modules/tofu/plugins/AUG/SXR/geom/_core.html deleted file mode 100644 index 5ac7667ee..000000000 --- a/doc/build/html/_modules/tofu/plugins/AUG/SXR/geom/_core.html +++ /dev/null @@ -1,751 +0,0 @@ - - - - - - - - tofu.plugins.AUG.SXR.geom._core — tofu v1.1 - - - - - - - - - - - - - - - -
-
-
-
- -

Source code for tofu.plugins.AUG.SXR.geom._core

-# -*- coding: utf-8 -*-
-"""
-Provides the basic ToFu geometry handling for the SXR diagnostic of AUG
-"""
-
-
-
-import itertools as itt
-import os
-import numpy as np
-import math
-import datetime as dtm
-import warnings
-
-
-# ToFu specific
-import tofu.defaults as tfd
-import tofu.pathfile as tfpf
-import tofu.helper as tfh
-import tofu.geom as tfg
-from ... import Ves as tfaugVes
-from ... import _path as _tfaug_path
-from .. import _helper as tfaugSXRh
-
-
-# AUG specific
-import dd
-
-__author__ =    "D. Vezinet"
-__all__ = ["create","load","get_GeomFromShot"]
-
-
-_addpath = '/tofu/plugins/AUG/SXR/geom'
-
-
-#########################################################
-#########################################################
-### Storing changes in geometry in a dictionary #########
-#########################################################
-
-
-def _compareDictChan(Dict1, Dict2):
-    Crit = ['FiltThick','RPINHOLE','ZPINHOLE','REND','ZEND','Tor_Pos','CAMANGLE','P_Length','P_Width','Foc_Len','D_Length','D_Width','D_Gap','MULTIA02']
-    Lim = [5.e-6, 0.5e-3, 0.5e-3, 0.5e-3, 0.5e-3, 0.5, 0.5, 0.1, 0.01, 0.1, 0.1, 0.01, 0.001, 1.e6]
-    CritCh = []
-    Change = {}
-
-    Names1 = sorted(Dict1.keys())
-    Names2 = sorted(Dict2.keys())
-    Names = sorted(list(set(Names1+Names2)))
-
-    for nn in Names:
-        Change[nn] = {}
-
-        if not nn in Names1:
-            Change[nn] = Dict2[nn]
-
-        elif not nn in Names2:
-            Change[nn] = Dict1[nn]
-
-        else:
-            for ii in range(0,len(Crit)):
-                diff = math.fabs(float(Dict1[nn][Crit[ii]]-Dict2[nn][Crit[ii]]))
-                if diff > Lim[ii]:
-                    Change[nn][Crit[ii]] = diff
-
-        if len(Change[nn].keys())==0:
-            del Change[nn]
-
-    return Change
-
-
-
-def _get_GeomFromShot_CSX(shot, Nums, CamH, Chan='CamHeads', Verb=True):
-    assert Chan in ['All','CamHeads'] or (type(Chan) is list and all([type(cc) is str for cc in Chan])), "Arg Chan must be in ['All','CamHeads'] or a list of channel names !"
-
-    DictChan = {}
-    sh = dd.shotfile('CSX',shot)
-
-    # Which channels shall be used for the testing
-    if Chan=='All':
-        Dir = sh.getObjectNames()
-    elif Chan=='CamHeads':  # One per camera head
-        Dir = ['CF_020','CG_020','CH_020','CH_052','CH_087','CI_016','CI_052','CI_091','CJ_017','CJ_052','CJ_087','CK_020','CK_055','CL_020','CM_020']
-    else:   # Custom
-        for ii in range(0,len(Chan)):
-            if not Chan[ii][0]=='C':
-                Chan[ii] = 'C'+Chan[ii]
-        Dir = Chan
-    Dir = [Dir[ii] for ii in range(0,len(Dir)) if all([ss in Dir[ii] for ss in ['C','_']]) and all([nn in Nums for nn in Dir[ii][-3:]])]
-
-    # Do the testing
-    LNames = []
-    for ii in range(0,len(Dir)):
-        try:
-            Name = Dir[ii][1:]
-            load = sh('C'+Name)
-            Diag = str(load['SX_DIAG'].data[0]+load['SX_DIAG'].data[1]+load['SX_DIAG'].data[2])
-            if not Diag=='000' and Name in CamH.keys():
-                tfaugSXRh._get_DictChanFromload(DictChan, Name, load, CamH, Diag)
-                if Verb:
-                    print("        Done for "+Name)
-        except Exception:
-            pass
-    sh.close()
-    return DictChan
-
-
-def _get_GeomFromShot_CSXscan( Lshots=range(22000,40000,1), Chan='CamHeads', Verb=True ):
-
-    CamH = tfaugSXRh._CamHeads()
-
-    DictShot = {}
-    DictChan0 = {}
-    DictChan1 = {}
-    init = True
-    Nums = map(str,range(0,10))
-    Change = {}
-
-    Inshots = [True for ss in Lshots]
-    for ii in range(0,len(Lshots)):
-        shot = int(Lshots[ii])
-        success = False
-        while not success:
-            try:
-                if init:
-                    DictChan0 = _get_GeomFromShot_CSX(shot, Nums, CamH, Chan=Chan, Verb=Verb)
-                    init = False
-                    if Verb:
-                        print("")
-                        print("    Initiated with shot {0}".format(shot))
-                    minshot = int(shot)
-                    Lshots[ii] = int(shot)
-                elif shot>minshot:
-                    DictChan1 = _get_GeomFromShot_CSX(shot, Nums, CamH, Chan=Chan, Verb=Verb)
-                    change = _compareDictChan(DictChan0, DictChan1)
-                    if len(change.keys())>0:
-                        Change[shot] = change
-                        DictChan0 = dict(DictChan1)
-                        if Verb:
-                            print("    Change detected for shot {0}".format(shot))
-                    minshot = int(shot)
-                    Lshots[ii] = int(shot)
-                else:
-                    Inshots[ii] = False
-                success = True
-            except Exception:
-                if ii==len(Lshots)-1:
-                    shot = shot-1
-                else:
-                    shot = shot+1
-    Lshots = [Lshots[ii] for ii in range(0,len(Lshots)) if Inshots[ii]]
-    return Change, Lshots
-
-
-
-def get_GeomFromShot( shot_init=22006, shot_end=33730, Ds=1000, Chan='CamHeads', Verb=True, save=True ):
-    """ Scan the database using diagnostic 'CSX' to identify the shots where changes were made to the SXR diagnostic
-
-    The geometry of a diagnostic changes from year to year due to improvements, adjustments...
-    It is necessary to know from which shot a new geometry is valid.
-    This function uses the 'CSX' data to scan the stored geometry (and other parameters) of all channels of the SXR diagnostic on a large span of shots to identify the first shots presenting changes.
-    Beware... it is long (typically several hours for a scann of all channels on a span of several thousands of shots).
-
-    Parameters
-    ----------
-    shot_init :     int
-        The first shot of the interval to be scanned
-    shot_end :      int
-        The last shot of the interval to be scanned
-    Ds :            10*int
-        The step by which the shot numbers will be increased for scanning (initial value, an algorithm then reduces it by dividing by 10 successively to focus on the identified changes)
-    Verb :          bool
-        Flag indicating whether some extra comments should be printed
-    save :          bool
-        Flag indicating whether the result should be saved
-
-    Returns
-    -------
-    Change :        dict
-        A dictionary of changes, where the keys are the shot numbers identified as first to change and where the values are themselves dictionaries of the changes implemented
-    Array :        np.ndarray
-        (2,N) np.ndarray where the first line is the list of shots tested in the last iteration and the second line is 0 or 1 (1 if changes are observed between the corresponding shot and its predecessor)
-
-    """
-
-    Lshots = sorted(list(set(range(shot_init, shot_end+1, Ds)+[shot_end])))
-    ds = int(Ds)
-    while not ds<1:
-        if Verb:
-            print("")
-            print("    In: ", Lshots)
-        Change, Lshots = _get_GeomFromShot_CSXscan( Lshots, Chan=Chan, Verb=Verb )
-        Lshots = sorted(list(set(Lshots)))
-        Lch = Change.keys()
-
-        Array = np.asarray([Lshots, [ii in Lch for ii in Lshots]])
-        if Verb:
-            print("    Out: ", Array)
-
-        ds = ds/10
-        if ds>=1:
-            Lshots = sorted(list(set(itt.chain.from_iterable([range(Lshots[ii-1],Lshots[ii]+1,ds)+[Lshots[ii]] for ii in range(1,len(Lshots)) if Array[1,ii]]))))
-
-    if save:
-        Chanstr = Chan if type(Chan) is str else 'Custom'
-        Name = 'Changes_'+Chanstr+'_shot{0}-{1}_Ds{2}'.format(shot_init,shot_end,Ds)
-        np.savez(_tfaug_path._Root+'/tofu/plugins/AUG/SXR/geom/'+Name+'.npz', Change=[Change], Array=Array)
-
-    return Change, Array
-
-
-
-
-
-
-#########################################################
-#########################################################
-### Using the dictionary to determine relevant shots ####
-#########################################################
-
-
-
-def _get_GeomFromShot_New(shot, chfile='Changes_CamHeads_shot22006-33730_Ds1000.npz', chpath=_tfaug_path._Root):
-    """ Return the last reference geometry shot depending on the input shot and on the Change dictionary selected
-
-    Parameters
-    ----------
-    shot :      int
-        Shot for which the user wants to know which geometry to use
-    chfile :    str
-        Name of the Changes dictionary to be used
-
-    Returns
-    -------
-    Rshot:      int
-        Reference geometry shot corresponding to the input shot
-
-    """
-
-    shot_init = int(chfile[chfile.index('_shot')+5:chfile.index('-')])
-    shot_end = int(chfile[chfile.index('-')+1:chfile.index('-')+6])
-    assert shot >= shot_init and shot <= shot_end, "Geometry not computed yet !"
-
-    # Loading the Changes dictionary
-    Change = np.load(chpath+_addpath+'/'+chfile)['Change'][0]
-    lshots = np.unique(Change.keys())
-    assert shot >= np.min(lshots) and shot <= np.max(lshots), "Geometry not computed yet (stored shots in Changes) !"
-    Rshot = int(np.max(lshots[lshots<=shot]))
-
-    return Rshot
-
-
-def _get_RectifiedFromShot(shot):
-    """ Get the real lower shot number from CSX
-
-    Check whether the desired shot number is available in the database of CSX diagnostic, if not return the first following one which is
-
-    Parameters
-    -----------
-    shot :      int
-        Desired shot number to be checked
-
-    Returns
-    -------
-    shotbis :   int
-        Closest valid shot number
-
-    """
-    Done = False
-    shotbis = int(shot)
-    while not Done:
-        try:
-            sh = dd.shotfile('CSX',shotbis)
-            Done = True
-        except Exception:
-            shotbis = shotbis + 1
-    sh.close()
-    return shotbis
-
-
-def _get_Tiles_FromShot(shot):
-    """ Return the list of camera heads that should be affected by view-limiting tiles depending on the shot number
-
-    In theory, the limiting tiles were removed after #31802, but in practice the gap was probably just widened (but how much ?)
-
-    Parameters
-    ----------
-    shot :  int
-        The shot number for which to return the list
-
-    Returns
-    -------
-    Tiles :     list
-        The list of camera heads with limiting tiles
-
-    """
-    Tiles = ['F','G']
-    if shot<31802:
-        Tiles = Tiles + ['L','M']
-    return Tiles
-
-
-
-
-# Old, mot used any more (keep for backward compatibility and double checks)
-def _get_GeomFromShot(shot):     # Deprecated
-    """ Deprecated """
-    assert shot>=24190, "Geometry not computed yet !"
-    if shot >= 24190 and shot < 24492:     # Lower bound not adjusted to minimum !
-        shot, LCamH = 24190, "All"
-    elif shot >= 24492 and shot < 25962:
-        shot, LCamH = 24492, "All"
-    elif shot >= 25962 and shot < 27439:
-        shot, LCamH = 25962, "All"
-    elif shot >= 27439 and shot < 31802:
-        shot, LCamH = 27439, "All"
-    elif shot >= 31802:   #Upper bound to be updated !
-        shot, LCamH = 31802, ['L','M']
-    return shot, LCamH
-
-
-
-
-
-
-#########################################################
-#########################################################
-### Helper routines to find out which cameras have already been created ####
-#########################################################
-
-
-
-
-
-
-
-def _listavailCams(Exp='AUG', Diag='SXR', SavePathObj=None, Root=_tfaug_path._Root, shotstr='_sh'):
-    """ Return a dictionary listing, for each camera head (keys), the shot numbers for which it was already created
-
-    A GDetect object is created for each camera head, and several versions of it exist depending on the shot number because of geometry changes in time
-    This routine tells you, for each camera head, for which shots it was already created
-
-    Parameters
-    ----------
-    Exp :           str
-        The experiment, here always 'AUG'
-    Diag :          str
-        The diagnostic, here always 'SXR'
-    SavePathObj :   None / str
-        The path where to look for already created GDetect objects, if None takes default
-    Root : str
-        The root path to which '/tofu/plugins/AUG/SXR/geom/Objects/' will be appended to build a default path if SavePathObj is None
-    shotstr :       str
-        The string pattern used to identify the shot number in the file names
-
-    Returns
-    -------
-    DC :    dict
-        The dictionary containing all relevant info
-
-    """
-
-    if SavePathObj is None:
-        SavePathObj = Root + _addpath+ '/Objects/'
-
-    kstr = 'TFG_GDetect_'+Exp+'_Dg'+Diag+'_'
-    LC = os.listdir(SavePathObj)
-    LC = [cc for cc in LC if all([ss in cc for ss in [kstr,shotstr,'.npz']])]
-    DC = {}
-    for ii in range(0,len(LC)):
-        ind = LC[ii].index(shotstr)
-        shot = int(LC[ii][ind+len(shotstr):ind+len(shotstr)+5])
-        ind = LC[ii].index(kstr)
-        strtemp = LC[ii][ind+len(kstr):]
-        indbis = strtemp.index('_')
-        CamH = strtemp[:indbis]
-        if not CamH in DC.keys():
-            DC[CamH] = []
-        DC[CamH].append(shot)
-
-    return DC
-
-
-
-
-
-
-
-#########################################################
-#########################################################
-######## Create cameras (apertures + detectors) #########
-#########################################################
-
-
-def _getLApert( Dict, dd, Ves, shot, SavePathObj, dtime, dtFormat, Exp='AUG', Tiles=['F','G','L','M']):
-    """ Return the list of apertures associated to a specific SXR channel
-
-    In AUG, each camera head is associated to a single aperture (data stored in CSX)
-    However, for some camera heads, a fraction of the VOS might be obstructed by
-
-    Parameters
-    ----------
-    Dict :          dict
-        Dictionary with all info from CSX, issued by :meth:`~tofu.plugins.AUG.SXR._helper._WhichSX()`
-    dd :            str
-        Key to Dict, should be a channel name
-    Ves :           :class:`tofu.geom.Ves`
-        The Ves instance with which to build the Apert objects
-    shot :          int
-        The shot number with which to build the Apert objects
-    SavePathObj :   None / str
-        The SavePath where the Apert objects should be saved (None recommended for default)
-    dtime :         dtm.datetime
-        A dtm.datetime object for identifying the create Apert objects (mostly for debugging)
-    dtFormat :      str
-        A str flag indicating the format with which dtime should be written in the automatically generated SaveName (if necessary)
-    Exp :           str
-        The experiment flag on which the Apert objects are created, should be the same as for Ves
-    Tiles :      bool
-        Flag indicating the list of caamera heads for which an additional aperture should be built from tiles (can be de-activated simply by removing the concerned camera head from the list)
-
-    Returns
-    ------
-    LApert :        list
-        List of apertures, created using the data available in CSX via Dict
-
-    """
-
-    A = np.array([Dict[dd]['RPINHOLE'], Dict[dd]['ZPINHOLE']])
-    B = np.array([Dict[dd]['REND'], Dict[dd]['ZEND']])
-    phi = Dict[dd]['Tor_Pos']*np.pi/180.
-    theta = Dict[dd]['CAMANGLE']*np.pi/180.
-
-    PolyApert, M = tfh.PolyFromLine(A, B, A, theta, phi, float(Dict[dd]['P_Length']*1.e-3), float(Dict[dd]['P_Width']*1.e-3))
-    assert np.hypot(np.hypot(M[0],M[1])-A[0], M[2]-A[1]) < 1.e-10, "Something wrong with Apert poly !"
-    IdApert0 = tfpf.ID('Apert', Dict[dd]['CamHead'], shot=shot, Diag='SXR', SaveName=None, SavePath=SavePathObj, dtime=dtime, Exp=Exp, LObj=None, dtFormat=dtFormat,
-                       USRdict={'Cam':Dict[dd]['Cam'], 'CamHead':Dict[dd]['CamHead'], 'FiltMat':Dict[dd]['FiltMat'], 'FiltThick':Dict[dd]['FiltThick']})
-    Apert0 = tfg.Apert(IdApert0, PolyApert, Ves=Ves)
-    LApert, LIdApert = [Apert0], [IdApert0]
-
-    # Add extra apertures (space between tiles) for the relevant cameras
-    if Dict[dd]['CamHead'] in Tiles:
-        if Dict[dd]['Cam']=='F':
-            d = 0.034
-            LTor, L2 = 0.012, 0.12
-            Ang = -(np.pi/2-theta)
-        elif Dict[dd]['Cam']=='G':
-            d = 0.034
-            LTor, L2 = 0.0117, 0.12
-            Ang = -(np.pi/2-theta)
-        elif Dict[dd]['Cam']=='L':
-            d  = 0.040
-            LTor, L2 = 0.0064, 0.2
-            Ang = -36.9*np.pi/180.
-        else:
-            d  = 0.036
-            LTor, L2 = 0.0054, 0.15
-            Ang = 16.75*np.pi/180.
-        C = tfh.RZ2XYZ_1D(A,phi) + d*Apert0.nIn
-        e2 = np.cross(np.array([-np.sin(phi),np.cos(phi),0]),Apert0.nIn)
-        e2 = e2/np.linalg.norm(e2)
-        nP = Apert0.nIn*np.cos(Ang) + e2*np.sin(Ang)
-        PolyApert = tfh.RectFromPlaneCenter(C, nP, np.array([-np.sin(phi),np.cos(phi),0]), LTor, L2, Test=True)
-        LIdApert.append(tfpf.ID('Apert', Dict[dd]['CamHead']+"_Tiles", shot=shot, Diag='SXR', SaveName=None, SavePath=SavePathObj, dtime=dtime, Exp=Exp, LObj=None, dtFormat=dtFormat,
-                                USRdict={'Cam':Dict[dd]['Cam'],'CamHead':Dict[dd]['CamHead'],'FiltMat':None,'FiltThick':None}))
-        Apert1 = tfg.Apert(LIdApert[-1], PolyApert, Ves=Ves)
-        LApert.append(Apert1)
-    return LApert
-
-
-
-
-
[docs]def create(shot=0, VesName='V1', SavePathObj=None, Root=_tfaug_path._Root, forceshot=False, overwrite=False, save=True, dtime=None, dtFormat=tfd.dtmFormat, - CalcEtend=True, CalcSpanImp=True, CalcCone=True, CalcPreComp=True, Calc=True, Verb=True, - Etend_Method='quad', Etend_RelErr=1.e-3, Etend_dX12=[0.01,0.01], Etend_dX12Mode='rel', Etend_Ratio=0.02, Colis=True, LOSRef='Cart', - Cone_DRY=0.0025, Cone_DXTheta=np.pi/1024., Cone_DZ=0.0025, Cone_NPsi=20, Cone_Nk=60): - """ Create, save and return all the GDetect objects relevant for the input shot, unless already created for a relevant reference shot - - Create the :class:`tofu.geom.GDetect` objects (i.e.: the cameras, which are groups of detectors) from geometry taken from CSX disgnostic for the proposed shot or earlier (looks for the oldest version of the matching geometry) and stores them in the SavePathObj. - - All extra arguments are fed to :class:`~tofu.geom.Detect` - - Parameters - ---------- - shot : int - Shot number for which to build the geometry - VesName : str - Name of the tfg.Ves object to be fed as an input to the :class:`tofu.geom.GDetect` objects - SavePathObj : None / str - Absolute path where the created :class:`tofu.geom.GDetect` objects should be saved (if save=True), if None the default is used - Root : str - If SavePathObj=None, a default value is created by appending '/tofu/plugins/AUG/SXR/geom/Objects/' to Root - forceshot : bool - Flag indicating whether the shot number shall be downgraded to the oldest shot with the same geometry (False) or whether the provided shot number shall be enforced (True, for all camera heads) - overwrite : bool - Flag indicating whether new :class:`tofu.geom.GDetect` objects shall be computed (and possibly saved) when similar ones already exist (True) - save : bool - Flag indicating whether to save the created :class:`tofu.geom.GDetect` objects (in SavePathObj) - dtime : None / dtm.datetime - If provided (i.e.: not None), used as a label of the created :class:`tofu.geom.GDetect` objects (mostly used for debugging) - dtFormat : str - The time format to be used for labelling the created :class:`tofu.geom.GDetect` objects (mostly used for debugging) - - Returns - ------- - LGD : list - A list of all the created tfg.GDetect objects - - """ - - # Pre-formatting inputs - if SavePathObj is None: - SavePathObj = Root + _addpath + '/Objects/' - - # LMNoTile = _get_LMTilesFromShot(shot) # Deprecated, replace by proper scanning / refit of several successive shots - if not forceshot: - #shot, LCamH = _get_GeomFromShot(shot) - shot = _get_GeomFromShot_New(shot) - #else: - # LCamH = "All" - #if not LCamH=="All": - # assert LCamH in CamHeads or all([cc in CamHeads for cc in LCamH]) - #else: - # LCamH = CamHeads - shot = _get_RectifiedFromShot(shot) - - Dict = tfaugSXRh._WhichSX(shot=shot) - Ves = tfaugVes.load(VesName) - - Tiles = _get_Tiles_FromShot(shot) - - # Computing and saving - UnCamH = sorted(list(set([Dict[dd]['CamHead'] for dd in Dict.keys()]))) - ListGDPre = _listavailCams(Exp='AUG', Diag='SXR', SavePathObj=SavePathObj, Root=Root, shotstr='_sh') - LGD = [] - for ii in range(0,len(UnCamH)): - cond0 = overwrite - cond1 = not UnCamH[ii] in ListGDPre.keys() or not shot in ListGDPre[UnCamH[ii]] - if any([cond0, cond1]): - lds = sorted([dd for dd in Dict.keys() if Dict[dd]['CamHead']==UnCamH[ii]]) - LApert = _getLApert(Dict, lds[0], Ves, shot, SavePathObj, dtime, dtFormat, Tiles=Tiles, Exp='AUG') - LD = [] - for dd in lds: - Id = tfpf.ID('Detect', dd, shot=shot, Diag='SXR', SaveName=None, SavePath=SavePathObj, dtime=dtime, Exp='AUG', LObj=None, dtFormat=dtFormat, - USRdict={'Cam':Dict[dd]['Cam'], 'CamHead':Dict[dd]['CamHead'], 'Diag':Dict[dd]['Diag'], 'Sig':Dict[dd]['Sig'], 'Num':Dict[dd]['Num'], 'FiltMat':Dict[dd]['FiltMat'], 'FiltThick':Dict[dd]['FiltThick'], - 'Sampl':Dict[dd]['Sampling'], 'Address':Dict[dd]['Address']}) - - A = np.array([Dict[dd]['RPINHOLE'], Dict[dd]['ZPINHOLE']]) - B = np.array([Dict[dd]['REND'], Dict[dd]['ZEND']]) - phi = Dict[dd]['Tor_Pos']*np.pi/180. - theta = Dict[dd]['CAMANGLE']*np.pi/180. - - RIn = np.hypot(LApert[0].BaryS[0]+LApert[0].nIn[0],LApert[0].BaryS[1]+LApert[0].nIn[1]) - np.hypot(LApert[0].BaryS[0],LApert[0].BaryS[1]) - Sgn = np.sign(RIn*np.cos(theta) + LApert[0].nIn[2]*np.sin(theta)) - P = A - Sgn*1.e-3*Dict[dd]['Foc_Len']*np.array([np.cos(theta), np.sin(theta)]) - DTor, DPol, DGap = float(1.e-3*Dict[dd]['D_Length']), float(1.e-3*Dict[dd]['D_Width']), float(1.e-3*Dict[dd]['D_Gap']) - Poly, M = tfh.PolyFromLine(A, B, P, theta, phi, DTor, DPol) - DD = np.hypot(np.hypot(M[0],M[1])-P[0], M[2]-P[1]) - nn = DD/(DGap+DPol) - assert np.abs(nn-np.round(nn))<0.017, "Inconsistent location of center for "+dd+", abs(nn-round(nn)) = "+str(np.abs(nn-np.round(nn)))+" with nn = "+str(nn) - - Det = tfg.Detect(Id, Poly, Optics=LApert, Ves=Ves, Sino_RefPt=None, - CalcEtend=CalcEtend, CalcSpanImp=CalcSpanImp, CalcCone=CalcCone, CalcPreComp=CalcPreComp, Calc=Calc, Verb=Verb, - Etend_Method=Etend_Method, Etend_RelErr=Etend_RelErr, Etend_dX12=Etend_dX12, Etend_dX12Mode=Etend_dX12Mode, Etend_Ratio=Etend_Ratio, Colis=Colis, LOSRef=LOSRef, - Cone_DRY=Cone_DRY, Cone_DXTheta=Cone_DXTheta, Cone_DZ=Cone_DZ, Cone_NPsi=Cone_NPsi, Cone_Nk=Cone_Nk, - arrayorder='C', Clock=False, Type=None, Exp='AUG', Diag='SXR', shot=shot, dtime=None, dtimeIn=False, SavePath=SavePathObj) - - LD.append(Det) - - GD = tfg.GDetect(UnCamH[ii], LDetect=LD, Type=None, Exp='AUG', Diag='SXR', shot=shot, Sino_RefPt=None, LOSRef='Cart', arrayorder='C', Clock=False, dtime=None, dtimeIn=False, SavePath=SavePathObj) - - if save: - GD.save(SynthDiag=True) - LGD.append(GD) - return LGD
- - - - - - - - - - - - - -######################################################### -######################################################### -############ Loading tools ############################## -######################################################### - - -
[docs]def load(Cams=None, shot=None, SavePathObj=None, Root=_tfaug_path._Root, sort=False, out='full', Test=True): - """ Load and return the desired :class:`~tofu.geom.GDetect` objects (i.e.: camera heads) - - Directly fecthes and loads the desired :class:`~tofu.geom.GDetect` objects. - - Parameters - ---------- - Cams : str / list - A name or a list of names of the camera heads to be loaded (available are ['F','G','H1','H2','H3','I1','I2','I3','J1','J2','J3','K1','K2','L','M']) - shot : int / float / np.float - A shot number indicating which version of the geometry should be loaded (the ) - SavePathObj : None / str - Absolute path where the created :class:`tofu.geom.GDetect` objects should be saved (if save=True), if None the default is used - Root : str - If SavePathObj=None, a default value is created by appending '/tofu/plugins/AUG/SXR/geom/Objects/' to Root - sort : bool - Flag indicating whether the loaded :class:`tofu.geom.GDetect` objects shall be returned sorted by alphabetical order of the names (True) or in the same order as asked in Cams (False) - out : str - Flag indicating whether the object should be loaded completely ('full'), in a light dismissing the heaviest attributes ('light') or whether only the Id or a list of Id should be returned ('Id'), valid only for '.npz' - Test : bool - Flag indicating whether the inputs should be tested for conformity - - Returns: - -------- - LGD : list / :class:`tofu.geom.GDetect` - The loaded :class:`tofu.geom.GDetect`, returned as a single object if Cams was provided as a single name, as a list otherwise - - """ - - if Test: - assert Cams is None or type(Cams) is str or (type(Cams) is list and all([type(cc) is str for cc in Cams])), "Arg Cams must be a str or a list of such !" - assert shot is None or type(shot) in [int,float,np.float], "Arg shot must be a int !" - - # Pre-formatting inputs - Flagstr = False - if type(Cams) is str: - Cams = [Cams] - Flagstr = True - if SavePathObj is None: - SavePathObj = Root + _addpath + '/Objects/' - - # List available cameras heads, sort and select the relevant files - DC = _listavailCams(Exp='AUG', Diag='SXR', SavePathObj=SavePathObj, Root=Root, shotstr='_sh') - Cams = sorted(DC.keys()) if Cams is None else Cams - assert all([cc in DC.keys() for cc in Cams]), "Some Cams asked for are not available in "+SavePathObj - Cams = sorted(Cams) if sort else Cams - - # Loading - LGD = [] - for ii in range(0,len(Cams)): - sh = DC[Cams[ii]] if shot is None else [sh for sh in DC[Cams[ii]] if sh<shot] - if len(sh)==0: - warnings.warn(" Camera "+Cams[ii]+" could not be loaded because it was only computed for later shots !") - else: - sh = max(sh) - ff = 'TFG_GDetect_AUG_DgSXR_'+Cams[ii]+'_sh'+str(sh)+'.npz' - gd = tfpf.Open(SavePathObj + ff, out=out) - LGD.append( gd ) - if len(LGD)>0: - LGD = LGD[0] if Flagstr else LGD - return LGD
- - - - - -
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/build/html/_modules/tofu/plugins/AUG/Ves/_core.html b/doc/build/html/_modules/tofu/plugins/AUG/Ves/_core.html deleted file mode 100644 index 631b70d6f..000000000 --- a/doc/build/html/_modules/tofu/plugins/AUG/Ves/_core.html +++ /dev/null @@ -1,260 +0,0 @@ - - - - - - - - tofu.plugins.AUG.Ves._core — tofu v1.1 - - - - - - - - - - - - - - - -
-
-
-
- -

Source code for tofu.plugins.AUG.Ves._core

-# -*- coding: utf-8 -*-
-#! /usr/bin/python
-
-"""
-Provide all necessary modules for dealing with AUG-specific data (geometry, diag and signal names...)
-"""
-
-
-import os
-import datetime as dtm
-
-# ToFu specific
-import tofu.defaults as tfd
-import tofu.pathfile as tfpf
-import tofu.geom as tfg
-from .. import _path as _tfaug_path
-
-
-
-__author__ = "Didier Vezinet"
-__all__ = ["_create","load"]
-
-
-
-############################################################################
-############################################################################
-#       Pre-set default SavePathIn, SavePathObj and SavePathOut
-############################################################################
-
-
-
-
-
-############################################################################
-############################################################################
-############################################################################
-#                   Ves creation and loading
-############################################################################
-
-
-def _create(Name='V1', Ves=None, shot=0, SavePathInp=None, SavePathObj=None, Root=_tfaug_path._Root, save=True,
-           skiprows=0, comments='#', units="m",
-           dtime=None, dtFormat=tfd.dtmFormat, dtimeIn=False, Test=True):
-    """ Create and save a Ves object from givn input file or Ves object
-
-    A Ves object can be created from an input file, a np.ndarray or another :class:`~tofu.geom.Ves` object
-
-    Parameters
-    ----------
-    Name :          str
-        The name to be given to the created Ves instance
-    Ves :           None / str / :class:`tofu.geom.Ves` / np.ndarray
-        The source where the polygon is to be found, either:
-            - str: the name of a file containing the coordinates of a polygon to be loaded with :meth:`numpy.loadtxt()`
-            - A :class:`tofu.geom.Ves` object: to re-use its Poly attribute and build one with different name
-            - np.ndarray: an 2-dimensional array containing the 2D cartesian coordinates of a polygon
-    shot :          int
-        A shot number, to be used as a reference point in time, marking from when the provided geometry is valid
-    SavePathInp :   None / str
-        If provided, forces the routine to search for the input file at SavePathInp, if not provided SavePathInp is automatically set to default (i.e. tofu/plugin/Ves/Inputs/)
-    SavePathObj :   None / str
-        If provided, forces the routine to save the created instance at SavePathObj, if not provided SavePathObj is automatically set to default (i.e. tofu/plugin/Ves/Objects/)
-    Root :          str
-        If SavePathObj=None, a default value is created by appending '/tofu/plugins/AUG/Ves/Objects/' to Root
-    save :          bool
-        Flag indicating whether the created Ves instance shall be saved automatically (in SavePathObj)
-    skiprows :      int
-        Parameter fed to np.loadtxt() for reading the polygon from a txt file
-    comments :      str
-        Parameter fed to np.loadtxt() for reading the polygon from a txt file
-    units :         str
-        Flag indicating in which units the input polygon is provided (in ['m','cm','mm'])
-    dtime :         None / dtm.datetime
-        A datetime instance used for labelling the created instance (mostly used for debugging)
-    dtFormat :      str
-        The format of the labelling (mostly used for debugging)
-    dtimeIn :       bool
-        Flag indicating whether to include the label in the file name (mostly used for debugging)
-
-    Returns
-    -------
-    Ves :           tfg.Ves
-        The created tfg.Ves instance
-
-    """
-
-    if Test:
-        assert type(Name) is str, "Arg Name must be a str !"
-        assert Ves is None or type(Ves) in [tfg.Ves,str,np.ndarray], "Arg Ves must be a :class:`~tofu.geom.Ves` instance, a file name or a np.ndarray !"
-        assert type(shot) is int, "Arg shot must be a int !"
-        assert all([ss is None or type(ss) is str for ss in [SavePathInp,SavePathObj]]), "Args [SavePathInp,SavePathObj] must be str !"
-        assert type(save) is bool, "Arg save must be a bool !"
-        assert type(units) is str and units in ['m','cm','mm'], "Arg units must be in ['m','cm','mm'] !"
-        assert dtime is None or type(dtime) is dtm.datetime, "Arg dtime must be a dtm.datetime !"
-        assert type(dtFormat) is str, "Arg dtFormat must be a str !"
-        assert type(dtimeIn) is bool, "Arg dtimeIn must be a bool !"
-
-    if SavePathInp is None:
-        SavePathInp = Root + '/tofu/plugins/AUG/Ves/Inputs/'
-    if SavePathObj is None:
-        SavePathObj = Root + '/tofu/plugins/AUG/Ves/Objects/'
-
-
-    # Get default paths and dtime
-    dtime, dtFormat = tfpf.get_Default_dtimeFmt(dtime=dtime, dtFormat=dtFormat)
-
-    # Get default Ves
-    Ves = SavePathInp+'AUG_Ves.txt' if Ves is None else Ves
-
-    # Create ID object for Ves
-    Ves, addInfo = tfpf.get_PolyFromPolyFileObj(Ves, SavePathInp, units=units, comments=comments, skiprows=skiprows)
-    Ves = tfg.Ves(Name, Ves, Type='Tor', Sino_RefPt=None, Sino_NP=tfd.TorNP, Clock=False, arrayorder='C', Exp=_Exp, shot=shot, dtime=dtime, dtimeIn=dtimeIn, SavePath=SavePathObj)
-
-    # Add info about input to Id
-    for dd in addInfo.keys():
-        Ves.Id._USRdict[dd] = addInfo[dd]
-
-    if save:
-        Ves.save()
-    return Ves
-
-
-
-
[docs]def load(Name='V1', SavePathObj=None, Root=_tfaug_path._Root, Test=True): - """ Load and return the selected Ves object (selected by name or file name) - - Several Ves object might exist for the same experiment depending changes to the experiment in time for example - This function loads the one specified by its name. - - Parameters - ---------- - Name : str / list - Name of the file to be loaded, or a subset of this name or a list of subsets, the file with a name matching all the subsets will be loaded. An error is issued in case of ambiguity - SavePathObj : str - Absolute path where the objects can be found, if None sets to default - Root : str - If SavePathObj=None, a default value is created by appending '/tofu/plugins/AUG/Ves/Objects/' to Root - Test : bool - Flag indicating whether the inputs should be tested for conformity - - Returns - ------- - Ves : :class:`tofu.geom.Ves` - The loaded Ves object - - """ - - if Test: - assert type(Name) is str or (type(Name) is list and all([type(ss) is str for ss in Name])), "Arg Name must be a str or a list of str !" - assert SavePathObj is None or type(SavePathObj) is str, "Arg SavePathObj must be a str !" - - if SavePathObj is None: - SavePathObj = Root + '/tofu/plugins/AUG/Ves/Objects/' - - Name = [Name] if type(Name) is str else Name - lobj = os.listdir(SavePathObj) - lobj = [ff for ff in lobj if all([ss in ff for ss in Name])] - assert len(lobj)==1, "Several possible matching files for "+str(Name)+" in "+SavePathObj - - Ves = tfpf.Open(SavePathObj+lobj[0]) - return Ves
- - - - - - - - - -
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/build/html/_modules/tofu/plugins/ITER/Bolo/geom/_core.html b/doc/build/html/_modules/tofu/plugins/ITER/Bolo/geom/_core.html deleted file mode 100644 index 373a63c31..000000000 --- a/doc/build/html/_modules/tofu/plugins/ITER/Bolo/geom/_core.html +++ /dev/null @@ -1,389 +0,0 @@ - - - - - - - - tofu.plugins.ITER.Bolo.geom._core — tofu v1.1 - - - - - - - - - - - - - - - -
-
-
-
- -

Source code for tofu.plugins.ITER.Bolo.geom._core

-# -*- coding: utf-8 -*-
-"""
-Created on Wed Mar  5 10:42:24 2014
-
-@author: didiervezinet
-"""
-
-import os
-import numpy as np
-import datetime as dtm
-import warnings
-
-
-# ToFu-specific
-import tofu.defaults as tfd
-import tofu.pathfile as tfpf
-import tofu.geom as tfg
-from ... import _path as _tfiter_path
-from ... import Ves as tfiterVes
-
-
-__author__ = "Didier Vezinet"
-__all__ = ["create_Apert","create_Detect","create_GDetect", "load"]
-
-
-Exp = 'ITER'
-
-SavePathObj = '/afs/ipp-garching.mpg.de/home/g/gav/ToFu_ITER/Objects_ITER/'
-SavePathInp = '/afs/ipp-garching.mpg.de/home/g/gav/ToFu_ITER/Inputs_ITER/'
-
-
-
-############################################################################
-############################################################################
-############################################################################
-# --------- Objects creation -------
-############################################################################
-
-
-
[docs]def create_Apert(Name, Ves, Poly, shot=0, SavePathVes=SavePathObj, SavePathObj=SavePathObj, SavePathInp=SavePathInp, comments='#', skiprows=0, units='m', save=True): - """ - Create a Apert object (i.e.: aperture) with specified Name from either a file (.dat,.txt,.csv) or directly from a (2,N) or (N,2) numpy array - Object is created, Saved in SavePathObj and returned - If an input file is specified and the file name does not include an absolute path, the path specified in SavePathInp is used - - Parameters - ---------- - Name : str - Name of the object to be created - Ves : str / :class:`tofu.geom.Ves` - Ves object to which the aperture is associated, a file name can also be used if the Ves object was previously Saved - Poly : str / np.ndarray - Numpy array or input file name (fed to numpy.loadtxt) used to specify the polygon to be used (should be (2,N) or (N,2) for N points) - shot : int - Shot number from which the provided geometry is valid (useful for geometry changes bewteen campaigns) - SavePathVes : None / str - (optional) if Ves is a str (i.e.: file name) or a list (i.e.: list of strings contained in the file name), specifies the path at which the file is to be found - SavePathObj : None / str - (optional) Absolute path where the created object will be saved - SavePathInp : None / str - (optional) Absolute path where the input file is to be found - comments : str - (optional) str specifying the flag for comments in the Poly file (if Poly is a file name), fed to numpy.loadtxt - skiprows : int - (optional) number of rows to be skipped in the Poly file (if Poly is a file name), fed to numpy.loadtxt - units : str - Flag indicating in which units the input polygon is provided (in ['m','cm','mm']) - save : bool - (optional) Flag indicating whether the created object should be Saved - Test : bool - Flag indicating whether the inputs should be tested for conformity - - Returns - ------- - Apert : :class:`tofu.geom.Apert` - The created Apert object - - """ - if Test: - assert type(Name) is str, "Arg Name must be a str !" - assert type(Ves) in [tfg.Ves,str], "Ves must be specified (tfg.Ves or file name) !" - assert type(Poly) in [str,list,np.ndarray], "Poly must be specified (np.ndarray or file name) !" - assert type(shot) is int, "Arg shot must be a int !" - assert all([ss is None or type(ss) is str for ss in [SavePathVes,SavePathInp,SavePathObj]]), "Args [SavePathInp,SavePathObj] must be str !" - assert type(save) is bool, "Arg save must be a bool !" - assert type(units) is str and units in ['m','cm','mm'], "Arg units must be in ['m','cm','mm'] !" - - # Get default path for loading inputs and saving object - #SavePathObj, SavePathInp = _get_defaultsSavePathsdtime(SavePathObj=SavePathObj, SavePathInp=SavePathInp, Type='Object') - if SavePathInp is None: - SavePathInp = Root + '/tofu/plugins/'+_Exp+'/Bolo/geom/Inputs/' - if SavePathObj is None: - SavePathObj = Root + '/tofu/plugins/'+_Exp+'/Bolo/geom/Objects/' - - # Loading the Ves object - if type(Ves) in [str.list]: - Ves = tfiterVes.load(Name=Ves, SavePathObj=SavePathVes) - - # Get polygon and info - Poly, addInfo = tfpf.get_PolyFromPolyFileObj(Poly, SavePathInp, units=units, comments=comments, skiprows=skiprows, shape0=3) - - # Create Apert object - Apert = tfg.Apert(Name, Poly, Ves=Ves, Exp='ITER', Diag='Bolo', shot=shot, arrayorder='C', Clock=False, SavePath=SavePathObj) - - # Add info about input to Id - for dd in addInfo.keys(): - Apert.Id._USRdict[dd] = addInfo[dd] - - if save: - Apert.save() - return Apert
- - - - - - -
[docs]def create_Detect(Name, Ves, Poly, LApert, shot=0, SavePathVes=SavePathObj, SavePathObj=SavePathObj, SavePathInp=SavePathInp, comments='#', skiprows=0, - Cone_DRY=0.0025, Cone_DXTheta=np.pi/1024., Cone_DZ=0.0025, Cone_NPsi=20, Cone_Nk=60, - Synth_dX12=[0.005, 0.005], Synth_dX12Mode='abs', Synth_ds=0.005, Synth_dsMode='abs', Synth_Colis=True, - Calc=True, CalcEtend=True, CalcSpanImp=True, CalcCone=True, CalcPreComp=True, save=True, save_SynthDiag=False): - """ - Create a :class:`tofu.geom.Detect` object (i.e.: detector) with specified Name from either a file (.dat,.txt,.csv) or directly from a (2,N) or (N,2) numpy array - Object is created, optionally Saved in SavePathObj and returned - If an input file is specified and the file name does not include an absolute path, the path specified in SavePathInp is used - - Parameters - ---------- - Name : str - Name of the object to be created - Ves : :class:`tofu.geom.Ves` or str - Ves object to which the aperture is associated, a file name can also be used if the Ves object was previously Saved - Poly : str or np.ndarray - Numpy array or input file name (fed to numpy.loadtxt) used to specify the polygon to be used (should be (2,N) or (N,2) for N points) - LApert : list - List of Apert objects to be associated to the detector - SavePathVes : None / str - (optional) if Ves is a str (i.e.: file name) or a list (i.e.: list of strings contained in the file name), specifies the path at which the file is to be found - SavePathObj : str - (optional) Absolute path where the created object will be Saved - SavePathInp : str - (optional) Absolute path where the input file is to be found - comments : str - (optional) str specifying the flag for comments in the Poly file (if Poly is a file name), fed to numpy.loadtxt - skiprows : int - (optional) number of rows to be skipped in the Poly file (if Poly is a file name), fed to numpy.loadtxt - save : bool - (optional) Flag indicating whether the created object should be Saved - save_SynthDiag : bool - (optional) Flag indicating whether the pre-computed synthetic diagnostic mesh should also be saved (larger files) or whether it should be recomputed upon loading - - To compute the VOS, tofu tests all points inside a 3D grid to see if each point is visible from the detector through the apertures or not - Cone_DR : float - Resolution of the grid in the R direction, in meters - Cone_DTheta : float - Resolution of the grid in the toroidal direction, in radians - Cone_DZ : float - Resolution of the grid in the Z direction, in meters - - In the particular case when the LOS of the detector lies entirely inside one poloidal cross-section (e.g.: tomography diagnostics), - tofu also computes the integral in the toroidal direction of the solid angle on a regular mesh (for faster computation of the geometry assuming toroidaly invariant basis functions) - This regular mesh is defined in 2D, by the distance between a mesh point and the detector (k) and by the poloidal angle between the LOS and the line going from the detector to the mesh point (psi) - Cone_NPsi : 20 - Number of points of the regular mesh in psi direction (angle) - Cone_Nk : 60 - Number of points of the regular mesh in k direction (distance) - - To compute synthetic signal faster for any simulated emissivity, tofu can pre-compute a 3D mesh of the VOS and store it, with the associates solid angles - This 3D mesh is computed with respect to the LOS. One coordinate (s) is the distance along the LOS, the two others (1 and 2) are the distances in directions perpendicular to the LOS - Synth_dX12 : list - Resolution of the mesh in the two directions perpendicular to the LOS - Synth_dX12Mode : str - Flag indicating whether dX12 is an absolute value ('abs', in meters) or a fraction of the maximum local with of the VOS ('rel') - Synth_ds : float - Resolution of the mesh in the direction parallel to the LOS - Synth_dsMode : str - Flag indicating whether ds is an absolute value ('abs', in meters) or a fraction of the maximum local with of the VOS ('rel') - Synth_Colis : bool - Flag indicating whether the collision detection should be activated - - Returns - ------- - Detect : TFG.Detect - The created TFG.Detect object - - """ - if Test: - assert type(Name) is str, "Arg Name must be a str !" - assert type(Ves) in [tfg.Ves,str], "Ves must be specified (tfg.Ves or file name) !" - assert type(Poly) in [str,list,np.ndarray], "Poly must be specified (np.ndarray or file name) !" - assert type(LApert) is list and all([type(ss) in [TFG.Apert,str] for ss in LApert]), "Arg LApert must be a list of apertures, specified by file name or directly TFG.Apert !" - assert type(shot) is int, "Arg shot must be a int !" - assert all([ss is None or type(ss) is str for ss in [SavePathVes,SavePathInp,SavePathObj]]), "Args [SavePathInp,SavePathObj] must be str !" - assert type(save) is bool, "Arg save must be a bool !" - assert type(units) is str and units in ['m','cm','mm'], "Arg units must be in ['m','cm','mm'] !" - - - # Get default path for loading inputs and saving object - #SavePathObj, SavePathInp = _get_defaultsSavePathsdtime(SavePathObj=SavePathObj, SavePathInp=SavePathInp, Type='Object') - if SavePathInp is None: - SavePathInp = Root + '/tofu/plugins/'+_Exp+'/Bolo/geom/Inputs/' - if SavePathObj is None: - SavePathObj = Root + '/tofu/plugins/'+_Exp+'/Bolo/geom/Objects/' - - # Loading the Ves object - if type(Ves) in [str.list]: - Ves = tfiterVes.load(Name=Ves, SavePathObj=SavePathVes) - - # Loading apertures - for ii in range(0,len(LApert)): - if type(LApert[ii]) is str: - PathFileExt = tfpf._get_PathFileExt_FromName(LApert[ii], Path=SavePathObj, Lstr=['TFG_Apert','ITER','Bolo',LApert[ii],'.npz']) - LApert[ii] = tfpf.Open(PathFileExt) - - # Get polygon and info - Poly, addInfo = tfpf.get_PolyFromPolyFileObj(Poly, SavePathInp, units=units, comments=comments, skiprows=skiprows, shape0=3) - - # Create Detect - Detect = TFG.Detect(Id, Poly, Ves=Ves, LApert=LApert, Exp='ITER', Diag='Bolo', shot=shot, - Cone_DRY=Cone_DRY, Cone_DXTheta=Cone_DXTheta, Cone_DZ=Cone_DZ, Cone_NPsi=Cone_NPsi, Cone_Nk=Cone_Nk, - Calc=True, CalcEtend=True, CalcSpanImp=True, CalcCone=CalcCone, CalcPreComp=False, SavePath=SavePathObj) - - # Now compute the pre-computed mesh for synthetic signal, with default or specified parameters - if CalcPreComp: - LPar = {'dX12':Synth_dX12, 'dX12Mode':Synth_dX12Mode, 'ds':Synth_ds, 'dsMode':Synth_dsMode, 'Colis':Synth_Colis} - Detect.set_SigPrecomp(**params) - - if save: - Detect.save() - return Detect
- - - - - - - -
[docs]def create_GDetect(Name, LDetect, SavePathObj=SavePathObj, save=True, save_SynthDiag=False): - """ - Create a :class:`tofu.geom.GDetect` object (i.e.: group of detectors, or camera) with specified Name from a list of Detect objects - Object is created, optionally Saved in SavePathObj and returned - - Parameters - ---------- - Name : str - Name of the object to be created - LDetect : list - List of already-created Detect objects - SavePathObj : str - (optional) Absolute path where the created object will be Saved - save : bool - (optional) Flag indicating whether the created object should be Saved - save_SynthDiag : bool - (optional) Flag indicating whether the pre-computed synthetic diagnostic mesh should also be saved (larger files) or whether it should be recomputed upon loading - - Returns - ------- - GD : :class:`tofu.geom.GDetect` - The created object - - """ - - if SavePathObj is None: - SavePathObj = shot=LDetect[0].Id.SavePath - - GD = tfg.GDetect(Name, LDetect, Exp='ITER', Diag='Bolo', shot=LDetect[0].Id.shot, SavePath=SavePathObj) - if save: - GD.save(SynthDiag=save_SynthDiag) - return GD
- - - -
[docs]def load(Name, Cls='GDetect', SavePathObj=SavePathObj): - """ Load the desired object, identified by name and saving path - - Searches in SavePathObj a ToFu object of the specified class (Cls) saved under the specified name (Name). - If a single match is found, the object is loaded and returned, otherwise an error is raised - - Parameters - ---------- - Name : str - Name of the object - Cls : str - Class of the object, in ['Ves','Apert','Detect','GDetect'] - SavePathObj : str - Path under which the object is to be found - - """ - - LD = os.listdir(SavePathObj) - LD = [ff for ff in LD if all([ss in ff for ss in ['TFG_','ITER','Bolo',Cls,Name,'.npz']])] - assert len(LD)==1, "Several or no matching file for "+Name+" of class "+Cls+" in "+SavePathObj - - obj = tfpf.open(SavePathObj+LD[0]) - return obj
- - - - -
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/build/html/_modules/tofu/plugins/ITER/Struct/_core.html b/doc/build/html/_modules/tofu/plugins/ITER/Struct/_core.html deleted file mode 100644 index e8f5cbb83..000000000 --- a/doc/build/html/_modules/tofu/plugins/ITER/Struct/_core.html +++ /dev/null @@ -1,238 +0,0 @@ - - - - - - - - tofu.plugins.ITER.Struct._core — tofu v1.1 - - - - - - - - - - - - - - - -
-
-
-
- -

Source code for tofu.plugins.ITER.Struct._core

-# -*- coding: utf-8 -*-
-"""
-Created on Wed Mar  5 10:42:24 2014
-
-@author: didiervezinet
-"""
-
-
-import os
-import numpy as np
-import datetime as dtm
-import warnings
-
-# ToFu-specific
-import tofu.defaults as tfd
-import tofu.pathfile as tfpf
-import tofu.geom as tfg
-from .. import _path as _tfiter_path
-from .. import Ves as tfiterVes
-
-
-__author__ = "Didier Vezinet"
-__all__ = ["plot"]
-
-
-
-_Exp = 'ITER'
-
-SavePathInp = '/afs/ipp-garching.mpg.de/home/d/didiv/Python/tofu/tofu/plugins/ITER/Struct/Inputs/'
-SavePathObj = '/afs/ipp-garching.mpg.de/home/d/didiv/Python/tofu/tofu/plugins/ITER/Struct/Objects/'
-
-
-
-############################################################################
-############################################################################
-############################################################################
-#                   Struct creation and plotting
-############################################################################
-
-
-
-
[docs]def plot(Elt='BPV', EltStruct='P', EltVes='P', Lax=None, Proj="Cross", shot=0, SavePathInp=SavePathInp, SavePathObj=SavePathObj, - Ves=None, NameVes=None, SavePathVes=None, - skiprows=0, comments='#', units='mm', - dtime=None, dtFormat=tfd.dtmFormat, dtimeIn=False, Test=True): - """ Create and plot the required Struct object on the required axes - - The coordinates of the polygons of the Struct objects are taken from SavePathInp - - Parameters - ---------- - Elt : str - Flag indicating which elements to plot, one capital letter per element - - 'B' : the Beams - - 'P' : the ports - - 'V' : the associated Ves object - Lax : None / plt.Axes / list - If provided, the axes or list of axes on which the poloidal and / or horizontal projections of the structure elements shall be plotted - shot : int - A shot number, to be used as a reference point in time, marking from when the provided geometry is valid - SavePathInp : None / str - If provided, forces the routine to search for the input file at SavePathInp, if not provided SavePathInp is automatically set to default (i.e. tofu/plugin/Ves/Inputs/) - SavePathObj : None / str - (optional) Absolute path where the created object will be saved - Ves : None / :class:`tofu.geom.Ves` - If provided, associates the Struct objects with this Ves object, otherwise a default Ves is loaded from SavePathVes if provided - NameVes : str - Use if Ves is not provided, fed to tofu.plugins.ITER.Ves.load() for loading a default Ves - SavePathVes : None / str - If provided, path from which a default Ves object can be loaded - skiprows : int - Parameter fed to np.loadtxt() for reading the polygon from a txt file - comments : str - Parameter fed to np.loadtxt() for reading the polygon from a txt file - units : str - Flag indicating in which units the input polygon is provided (in ['m','cm','mm']) - dtime : None / dtm.datetime - A datetime instance used for labelling the created instance (mostly used for debugging) - dtFormat : str - The format of the labelling (mostly used for debugging) - dtimeIn : bool - Flag indicating whether to include the label in the file name (mostly used for debugging) - Test : bool - Flag indicating whether the inpurts should be checked for conformity - - Returns - ------- - LS : list - The list of all created :class:`tofu.geom.Struct` instances - - """ - - if Test: - assert type(Elt) is str, "Arg Elt must be a str !" - assert type(shot) is int, "Arg shot must be a int !" - assert all([ss is None or type(ss) is str for ss in [SavePathInp]]), "Args [SavePathInp] must be str !" - assert type(units) is str and units in ['m','cm','mm'], "Arg units must be in ['m','cm','mm'] !" - assert dtime is None or type(dtime) is dtm.datetime, "Arg dtime must be a dtm.datetime !" - assert type(dtFormat) is str, "Arg dtFormat must be a str !" - assert type(dtimeIn) is bool, "Arg dtimeIn must be a bool !" - - # Get default path for loading inputs and saving object - if SavePathInp is None: - SavePathInp = Root + '/tofu/plugins/'+_Exp+'/Struct/Inputs/' - - # Load Ves if necessary - if Ves is None: - Ves = tfiterVes.load(Name=NameVes, SavePathObj=SavePathVes) - - # Get polygons and info - LS = [] - ld = os.listdir(SavePathInp) - if 'P' in Elt: - L = sorted([ll for ll in ld if all([ss in ll for ss in ['PoloidalCurvesCoordinates_','.csv']]) and not any([ss in ll for ss in ['_Poloidal','_BM']])]) - NB = len(L) - for ii in range(0,NB): - ind1 = L[ii].index('PoloidalCurvesCoordinates_')+len('PoloidalCurvesCoordinates_') - ind2 = L[ii].index('.csv') - name = L[ii][ind1:ind2] - Poly, addInfo = tfpf.get_PolyFromPolyFileObj(L[ii], SavePathInp=SavePathInp, units=units, comments='#', skiprows=0, shape0=2) - ss = tfg.Struct(name, Poly, Type='Tor', Ves=Ves, Exp='ITER', shot=shot, SavePath=SavePathObj) - for dd in addInfo.keys(): - ss.Id._USRdict[dd] = addInfo[dd] - LS.append(ss) - if 'B' in Elt: - L = sorted([ll for ll in ld if all([ss in ll for ss in ['PoloidalCurvesCoordinates_','_BM','.csv']]) and not any([ss in ll for ss in ['_Poloidal']])]) - NB = len(L) - for ii in range(0,NB): - ind1 = L[ii].index('_BM')+1 - ind2 = L[ii].index('.csv') - name = L[ii][ind1:ind2] - Poly, addInfo = tfpf.get_PolyFromPolyFileObj(L[ii], SavePathInp=SavePathInp, units=units, comments='#', skiprows=0, shape0=2) - ss = tfg.Struct(name, Poly, Type='Tor', Ves=Ves, Exp='ITER', shot=shot, SavePath=SavePathObj) - for dd in addInfo.keys(): - ss.Id._USRdict[dd] = addInfo[dd] - LS.append(ss) - - # Plot - if 'V' in Elt: - Lax = Ves.plot(Lax=Lax, Proj=Proj, Elt=EltVes) - for ii in range(0,len(LS)): - Lax = LS[ii].plot(Lax=Lax, Proj=Proj, Elt=EltStruct) - - return Lax, LS
- - - - -
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/build/html/_modules/tofu/plugins/ITER/Ves/_core.html b/doc/build/html/_modules/tofu/plugins/ITER/Ves/_core.html deleted file mode 100644 index 91b4a4bee..000000000 --- a/doc/build/html/_modules/tofu/plugins/ITER/Ves/_core.html +++ /dev/null @@ -1,296 +0,0 @@ - - - - - - - - tofu.plugins.ITER.Ves._core — tofu v1.1 - - - - - - - - - - - - - - - -
-
-
-
- -

Source code for tofu.plugins.ITER.Ves._core

-# -*- coding: utf-8 -*-
-"""
-Created on Wed Mar  5 10:42:24 2014
-
-@author: didiervezinet
-"""
-
-
-import os
-import numpy as np
-import datetime as dtm
-import warnings
-
-# ToFu-specific
-import tofu.defaults as tfd
-import tofu.pathfile as tfpf
-import tofu.geom as tfg
-from .. import _path as _tfiter_path
-
-
-__author__ = "Didier Vezinet"
-__all__ = ["create","load"]
-
-
-
-_Exp = 'ITER'
-
-DefName, DefFile, Defskiprows = 'ITER_D_2N9J75 v1.7-1', ['PoloidalCurvesCoordinates','ITER','2N9J75','csv'], 4
-
-
-
-############################################################################
-############################################################################
-############################################################################
-# --------- Miscellaneous -------
-############################################################################
-
-
-def _get_defaultsSavePathsdtime(SavePathObj=None, SavePathInp=None, Type='Object'):  # Deprecated ?
-    """ Get default path for loading input and saving output """
-    assert SavePathObj is None or type(SavePathObj) is str, "Arg SavePathObj must be a str !"
-    assert SavePathInp is None or type(SavePathInp) is str, "Arg SavePathInp must be a str !"
-    RP = TFPF.Find_Rootpath(Path=cwd,substr='/ToFu_ITER')
-    if SavePathInp is None:
-        SavePathInp = RP+'/Inputs_'+Exp+'/'
-    if SavePathObj is None:
-        SavePathObj = RP+'/Objects_'+Exp+'/' if Type=='Object' else RP+'/Outputs_'+Exp+'/'
-    return SavePathObj, SavePathInp
-
-
-
-
-############################################################################
-############################################################################
-############################################################################
-#                   Ves creation
-############################################################################
-
-
-
-
[docs]def create(Name=DefName, Poly=DefFile, shot=0, - SavePathInp=None, SavePathObj=None, Root=_tfiter_path._Root, save=True, - skiprows=Defskiprows, comments='#', units='mm', - dtime=None, dtFormat=tfd.dtmFormat, dtimeIn=False, Test=True): - """ Create and save a Ves object from givn input file or Ves object - - A Ves object can be created from an input file, a np.ndarray or another :class:`~tofu.geom.Ves` object - - Parameters - ---------- - Name : str - The name to be given to the created Ves instance - Poly : None / str / :class:`tofu.geom.Ves` / np.ndarray - The source where the polygon is to be found, either: - - str: the name of a file containing the coordinates of a polygon to be loaded with :meth:`numpy.loadtxt()` - - A :class:`tofu.geom.Ves` object: to re-use its Poly attribute and build one with different name - - np.ndarray: an 2-dimensional array containing the 2D cartesian coordinates of a polygon - shot : int - A shot number, to be used as a reference point in time, marking from when the provided geometry is valid - SavePathInp : None / str - If provided, forces the routine to search for the input file at SavePathInp, if not provided SavePathInp is automatically set to default (i.e. tofu/plugin/Ves/Inputs/) - SavePathObj : None / str - If provided, forces the routine to save the created instance at SavePathObj, if not provided SavePathObj is automatically set to default (i.e. tofu/plugin/Ves/Objects/) - Root : str - If SavePathObj=None, a default value is created by appending '/tofu/plugins/ITER/Ves/Objects/' to Root - save : bool - Flag indicating whether the created Ves instance shall be saved automatically (in SavePathObj) - skiprows : int - Parameter fed to np.loadtxt() for reading the polygon from a txt file - comments : str - Parameter fed to np.loadtxt() for reading the polygon from a txt file - units : str - Flag indicating in which units the input polygon is provided (in ['m','cm','mm']) - dtime : None / dtm.datetime - A datetime instance used for labelling the created instance (mostly used for debugging) - dtFormat : str - The format of the labelling (mostly used for debugging) - dtimeIn : bool - Flag indicating whether to include the label in the file name (mostly used for debugging) - Test : bool - Flag indicating whether the inpurts should be checked for conformity - - Returns - ------- - Ves : :class:`tofu.geom.Ves` - The created tfg.Ves instance - - """ - - if Test: - assert type(Name) is str, "Arg Name must be a str !" - assert Poly is None or type(Poly) in [tfg.Ves,str,list,np.ndarray], "Arg Poly must be a :class:`~tofu.geom.Ves` instance, a file name or a np.ndarray !" - assert type(shot) is int, "Arg shot must be a int !" - assert all([ss is None or type(ss) is str for ss in [SavePathInp,SavePathObj]]), "Args [SavePathInp,SavePathObj] must be str !" - assert type(save) is bool, "Arg save must be a bool !" - assert type(units) is str and units in ['m','cm','mm'], "Arg units must be in ['m','cm','mm'] !" - assert dtime is None or type(dtime) is dtm.datetime, "Arg dtime must be a dtm.datetime !" - assert type(dtFormat) is str, "Arg dtFormat must be a str !" - assert type(dtimeIn) is bool, "Arg dtimeIn must be a bool !" - - # Get default path for loading inputs and saving object - #SavePathObj, SavePathInp = _get_defaultsSavePathsdtime(SavePathObj=SavePathObj, SavePathInp=SavePathInp, Type='Object') - if SavePathInp is None: - SavePathInp = Root + '/tofu/plugins/'+_Exp+'/Ves/Inputs/' - if SavePathObj is None: - SavePathObj = Root + '/tofu/plugins/'+_Exp+'/Ves/Objects/' - - # Get polygon and info - Poly, addInfo = tfpf.get_PolyFromPolyFileObj(Poly, SavePathInp, units=units, comments=comments, skiprows=skiprows) - - # Create Ves object - Ves = tfg.Ves(Name, Poly, Type='Tor', Sino_RefPt=None, Sino_NP=tfd.TorNP, Clock=False, arrayorder='C', Exp=_Exp, shot=shot, dtime=dtime, dtimeIn=dtimeIn, SavePath=SavePathObj) - - # Add info about input to Id - for dd in addInfo.keys(): - Ves.Id._USRdict[dd] = addInfo[dd] - - if save: - Ves.save() - return Ves
- - - - - - - - -############################################################################ -############################################################################ -############################################################################ -# Ves loading -############################################################################ - - - - -
[docs]def load(Name=None, SavePathObj=None, Root=_tfiter_path._Root, Test=True): - """ Load and return the selected Ves object (selected by name or file name) - - Several Ves object might exist for the same experiment depending changes to the experiment in time for example - This function loads the one specified by its name. - - Parameters - ---------- - Name : str / list - Name of the file to be loaded, or a subset of this name or a list of subsets, the file with a name matching all the subsets will be loaded. An error is issued in case of ambiguity (no or several matches) - SavePathObj : None / str - Absolute path where the objects can be found, if None sets to default - Root : str - If SavePathObj=None, a default value is created by appending '/tofu/plugins/AUG/Ves/Objects/' to Root - Test : bool - Flag indicating whether the inputs should be tested for conformity - - Returns - ------- - Ves : :class:`tofu.geom.Ves` - The loaded Ves object - - """ - - if Test: - assert Name is None or type(Name) is str or (type(Name) is list and all([type(ss) is str for ss in Name])), "Arg Name must be a str or a list of str !" - assert SavePathObj is None or type(SavePathObj) is str, "Arg SavePathObj must be a str !" - - if SavePathObj is None: - SavePathObj = Root + '/tofu/plugins/'+_Exp+'/Ves/Objects/' - - if Name is None: - Name = ['2N9J75','v1.7-1'] - - Name = [Name] if type(Name) is str else Name - lobj = os.listdir(SavePathObj) - lobj = [ff for ff in lobj if all([ss in ff for ss in Name])] - assert len(lobj)==1, "Several possible matching files for "+str(Name)+" in "+SavePathObj - - Ves = tfpf.Open(SavePathObj+lobj[0]) - return Ves
- - - - - - - - -
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/build/html/_modules/tofu/treat/_core.html b/doc/build/html/_modules/tofu/treat/_core.html deleted file mode 100644 index c42c70f0a..000000000 --- a/doc/build/html/_modules/tofu/treat/_core.html +++ /dev/null @@ -1,796 +0,0 @@ - - - - - - - - tofu.treat._core — tofu v1.1 - - - - - - - - - - - - - - - -
-
-
-
- -

Source code for tofu.treat._core

-# -*- coding: utf-8 -*-
-"""
-Provide data handling class and methods (storing, processing, plotting...)
-"""
-
-import numpy as np
-import matplotlib.pyplot as plt
-
-
-# ToFu-specific
-import tofu.pathfile as tfpf
-from . import _compute as _tft_c
-from . import _plot as _tft_p
-
-
-__author__ = "Didier Vezinet"
-__all__ = ["PreData"]
-
-
-
-
[docs]class PreData(object): - """ A class defining a data-handling object, data is stored as read-only attribute, copies of it can be modified, methods for plotting, saving... - - The name of the class refers to Pre-treatment Data (i.e.: in the context of tomography, data that is pre-treated before being fed to an inversion algorithm). - ToFu provide a generic data-handling class, which comes a robust data storing policy: the input data is stored in a read-only attribute and the data-processing methods are used on a copy (e.g.: for computing the SVD, Fourier transform, shorten the time interval of interest, eliminate some channels...). - Furthermore, methods for interactive plotting are provided as well as a saving method - - Parameters: - ----------- - - - - Returns: - -------- - obj : PreData - The created instance - - """ - - - - - def __init__(self, data, t=None, Chans=None, Id=None, Exp='AUG', shot=None, Diag='SXR', dtime=None, dtimeIn=False, SavePath=None, - LIdDet=None, DtRef=None, - MovMeanfreq=100, Resamp=True, interpkind='linear', indOut=None, indCorr=None, - - DF=None, Harm=True, DFEx=None, HarmEx=True, lt=[], lNames=[], - Calc=True): - - self._Done = False - - self._set_Id(Id, Exp=Exp, shot=shot, Diag=Diag, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn, Dt=Dt, t=t) - self.set_data(data, t=t, Chans=Chans, DtRef=DtRef, LIdDet=LIdDet) - - self.set_timeResamp(MovMeanfreq, Resamp=Resamp, interpkind=interpkind, Test=Test, Calc=False) - - self.Out_add(indOut=indOut, Calc=False) - self.Corr_add(indCorr=indCorr, Calc=False) - self.substract_Dt(DtRef, Calc=False) - self.set_fft(DF=DF, Harm=Harm, DFEx=DFEx, HarmEx=HarmEx, Calc=False) - self.interp(lt=lt, lNames=lNames, Calc=False) - if Calc: - self._doAll() - self._PhysNoise = None - self._NoiseModel = None - - - - - self._Done = True - - - @property - def Id(self): - return self._Id - @property - def Exp(self): - return self.Id.Exp - @property - def shot(self): - return self.Id.shot - @property - def data(self): - return self._data - @property - def t(self): - return self._t - @property - def Dt(self): - return self._Dt - @property - def Chans(self): - return self._Chans - - @property - def svd(self): - return self._svd - @property - def FFT(self): - return self._FFT - - - def _check_inputs(self, Id=None, Exp=None, shot=None, SavePath=None): - _PreData_check_inputs(Id=Id, Exp=Exp, shot=shot, SavePath=SavePath) - - def _set_Id(self, Val, Exp=None, Diag=None, shot=None, dtime=None, dtimeIn=False, SavePath=None, t=None, Dt=None): - if self._Done: - Out = tfpf._get_FromItself(self.Id,{'Exp':Exp, 'Diag':Diag, 'shot':shot, 'dtime':dtime, '_dtimeIn':dtimeIn, 'SavePath':SavePath}) - Exp, Diag, shot, dtime, dtimeIn, SavePath = Out['Exp'], Out['Diag'], Out['shot'], Out['dtime'], Out['dtimeIn'], Out['SavePath'] - if Val is None: - Val = _tft_c.get_DefName(t=t, Dt=Dt) - tfpf._check_NotNone({'Id':Val}) - self._check_inputs(Id=Val) - if type(Val) is str: - tfpf._check_NotNone({'Exp':Exp, 'Diag':Diag, 'shot':shot, 'dtimeIn':dtimeIn}) - self._check_inputs(Exp=Exp, Diag=Diag, shot=shot, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - Val = tfpf.ID('PreData', Val, Type=Type, Exp=Exp, shot=shot, SavePath=SavePath, dtime=dtime, dtimeIn=dtimeIn) - self._Id = Val - - def _set_data(self, data, t, Chans, DtRef=None, LIdDet=None): - self._check_inputs(data=data, t=t, Chans=Chans, DtRef=DtRef, LIdDet=LIdDet) - - OutRef, Out, Outind = _tft_c._PreData_set_data(data, t, Chans, DtRef=DtRef, LIdDet=LIdDet) - self._dataRef, self._tRef, self._ChanRef, self._NChanRef, self._LIdDetRef, self._DtRef = OutRef - self._data, self._t, self._Chans, self._NChans, self._LIdDet, self._Dt = Out - self._indOut, self._indCorr = Outind - - if not self._LIdDetRef is None: - self.Id.set_LObj(self._LIdDetRef) - - -
[docs] def set_Dt(self, Dt=None, Calc=True): - """ Set the time interval to which the data should be limited (does not affect the reference data) - - While the original data set and time base are always preserved in the background, you can change your mind and focus on a smaller interval included in the original one. - This can be convenient for applying data treatment (SVD, fft...) to parts of the signal lifetime only. - - Parameters - ---------- - Dt : None / list - The time interval of interest, as a list of len()=2 in increasing values - Calc : bool - Flag indicating whether the calculation should be triggered immediately - - """ - self._check_inputs(Dt=Dt) - # assert Dt is None or (hasattr(Dt,'__getitem__') and len(Dt)==2), "Arg Dt must be a len==2 list, tuple or np.ndarray !" - self._Dt = Dt - if Calc: - self._doAll()
- - - -
[docs] def set_Resamp(self, t=None, f=None, Method='movavrg', interpkind='linear', Calc=True): - """ Re-sample the data and time vector - - Use a new time vector that can either be: - - provided directly (if t is not None) - - computed from an input sampling frequency (if f is not None) - If but t and f are provided, t is used as the time vector and f is only used for the moving average - - Then, the data is re-computed on this new time vector using either interpolation ('interp') or moving average ('movavrg') - - Parameters - ---------- - t : None / np.ndarray - - f : None / int / float - - Method : str - - Resamp : bool - - interpkind : str - - Calc : bool - Flag indicating whether the calculation should be triggered immediately - - """ - self._check_inputs(t=t, f=f, Method=Method, Resamp=Resamp, interpkind=interpkind, Calc=Calc) - - self._Resamp_t = t - self._Resamp_f = f - self._Resamp_Method = Method - self._Resamp_interpkind = interpkind - if Calc: - self._doAll()
- - - - -
[docs] def select(self, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', InOut='In', Out=bool, ToIn=False): - """ Return a sub-set of the data (channels-wise selection) - - Return an array of indices of channels selected according to the chosen criteria with chosen values - Use either Val or (PreExp and PostExp) - - Parameters - ---------- - Val : list or str - List of values that the chosen criteria must match (converted to one-item list if str) - Crit : str - Criterion used to select some channels, must be among their tfpf.ID class attributes (e.g.: 'Name', 'SaveName'...) or IFTF.ID.USRdict ('Cam',...) - PreExp : list or str - List of str expressions to be fed to eval(PreExp[ii]+" Detect.Crit "+PostExp[ii]) or eval(PreExp[ii]+" Detect.USRdict.Crit "+PostExp[ii]) - PostExp : list or str - List of str expressions to be fed to eval(PreExp[ii]+" Detect.Crit "+PostExp[ii]) or eval(PreExp[ii]+" Detect.USRdict.Crit "+PostExp[ii]) - Log : str - Flag ('or' or 'and') indicating whether to select the channels matching all criteria or any - InOut : str - Flag ('In' or 'Out') indicating whether to select all channels matching the criterion, or all except those - Out : type or str - Flag (bool, int or an attribute of tfpf.ID or tfpf.ID.USRdict) indicating whether to return an array of boolean indices or int indices, or a list of the chosen attributes (e.g.: 'Name') - ToIn : bool - Flag indicating whether indices should be returned with respect to the channels that are considered as included only (see obj.In_list() to see these channels) - - Returns - ------- - ind : np.ndarray - Indices of the selected channels, as a bool or int array - - - Examples - -------- - >> ind = TFT.PreData.select(Val=['H','J'], Crit='Cam', Log='any', InOut='In', Out=bool) - Will return a bool array of the indices of all channels for which 'Cam' is 'H' or 'J' - >> ind = PreData.select(Crit='Name', PreExp=["'F' in ", "'6' in "], Log='and', InOut='In', Out=int) - Will return an int array of indices of all channels for which 'F' and '6' are both included in the name - >> ind = PreData.select(Crit='CamHead', PreExp=["'F' in ", "'2' in "], Log='any', InOut='Out', Out='Name') - Will return the names (as a list) of all channels except those that have a camera head name that includes a 'F' or a '2' (i.e.: except camera heads 'F' and 'H2', 'I2', 'J2', 'K2') - - """ - - if ToIn: - LD = {} - for kk in self.Id.LObj['Detect'].keys(): - LD[kk] = [self.Id.LObj['Detect'][kk][ii] for ii in (~self._indOut).nonzero()[0]] - return tfpf.SelectFromIdLObj(LD, Val=Val, Crit=Crit, PreExp=PreExp, PostExp=PostExp, Log=Log, InOut=InOut, Out=Out) - else: - return tfpf.SelectFromIdLObj(self.Id.LObj['Detect'], Val=Val, Crit=Crit, PreExp=PreExp, PostExp=PostExp, Log=Log, InOut=InOut, Out=Out)
- - - - -
[docs] def Out_add(self, Val=[], LCrit=['Name','Cam','CamHead'], indOut=None, Calc=True): - """ Add desired channels to the list of channels to be excluded - - It is possible to store a list a list of channels that are thought to be corrupted or more generally that, after closer inspection, are considered not fit. - This list is then automatically passed on to further ToFu objects (e.g.: for inversions), so that the corresponding data is excluded from all further processes. - PreData provides methods to append channel names to this list (in fact you can even exclude whole cameras). - - Parameters - ---------- - Val : list - Fed to self.select(), list of values for criteria in LCrit that should be used to exclude channels (e.g.: list of channel names of camera names) - LCrit : list - Fed to self.select(), list of criteria against which to select the channels matching the values in Val (should be attributes of :class:`tofu.pathfile.ID` or of its USRdict attribute) - indOut : None / np.ndarray - Alternatively, you can directly pass a (N,) bool array whereN matches the number of channels and True means that a channel should be excluded, thus setting self._indOut - Calc : bool - Flag indicating whether the calculation should be triggered immediately - - """ - if not indOut is None: - assert isinstance(indOut,np.ndarray) and indOut.dtype.name=='bool' and indOut.ndim==1 and indOut.size==self._NChanRef, "Arg indOut must be a (N,) np.ndarray of bool !" - self._indOut = indOut - elif not LVal==[]: - ind = np.zeros((len(LCrit),self._NChanRef),dtype=bool) - for ii in range(0,len(LCrit)): - ind[ii,:] = self.select(Val=Val, Crit=LCrit[ii], InOut='In', Out=bool) - self._indOut = self._indOut | np.any(ind,axis=0) - if Calc & (not Val==[] or not indOut is None): - self._doAll()
- -
[docs] def In_add(self, LVal=[], LCrit=['Name','Cam','CamHead'], Calc=True): - """ Add channels to the list of channels to be re-included as valid channels - - Provides a mechanism opposite to :meth:`~tofu.treat.PreData.Out_add()`. - We you change your mind about a series of channel and think they should be re-included as valid, pass them to this method using the same arguments as self.Out_add() - - Parameters - ---------- - Val : list - Fed to self.select(), list of values for criteria in LCrit that should be used to exclude channels (e.g.: list of channel names of camera names) - LCrit : list - Fed to self.select(), list of criteria against which to select the channels matching the values in Val (should be attributes of :class:`tofu.pathfile.ID` or of its USRdict attribute) - indOut : None / np.ndarray - Alternatively, you can directly pass a (N,) bool array whereN matches the number of channels and True means that a channel should be excluded, thus setting self._indOut - Calc : bool - Flag indicating whether the calculation should be triggered immediately - - """ - if not LVal==[]: - ind = np.ones((len(LCrit),self._NChanRef),dtype=bool) - for ii in range(0,len(LCrit)): - ind[ii,:] = self.select(Val=LVal, Crit=LCrit[ii], InOut='Out', Out=bool) - self._indOut = self._indOut & np.all(ind,axis=0) - if Calc: - self._doAll()
- -
[docs] def Out_list(self, Out='Name'): - """ Return the list of excluded channel names (considered corrupted) - - This lists the channels indicated by self._indOut, populated using self.Out_add() and de-populated using self.In_add(). - The output can be returned as a list of channel Names - - Parameters - ---------- - Out : str - Flag indicating in which form to return the output (fed to :meth:`~tofu.treat.PreData.select()`) - - Returns - ------- - L : list - List of excluded channels in the required form - - """ - L = self.select(Out=Out) - L = [L[ii] for ii in range(0,len(L)) if self._indOut[ii]] - return L
- -
[docs] def In_list(self, Out='Name'): - """ Return the list of included channel names (considered valid) - - The equivalent of :meth:`~tofu.treat.PreData.Out_list()`, but this time returning the complementary list - - Parameters - ---------- - Out : str - Flag indicating in which form to return the output (fed to :meth:`~tofu.treat.PreData.select()`) - - Returns - ------- - L : list - List of excluded channels in the required form - - """ - L = self.select(Out=Out) - L = [L[ii] for ii in range(0,len(L)) if not self._indOut[ii]] - return L
- -
[docs] def interp(self, lt=[], lNames=[], Calc=True): - """ Perform linear interpolation of data at chosen times for chosen channels - - As opposed to self.set_t(), this method shall be used to interpolate data of a small number of channels at a small sumber of time points. - Use this to correct a small number of time points that are clearly corrupted when you think the rest shall be preserved. - - !!! This is done with respect to the reference time vector and dataset, to avoid propagating errors through later data treatment (use self.plot(V='Ref') to plot the reference data set) !!! - - Parameters - ---------- - lt : list - Times at which linear interpolation should be performed - lNames : list - Channels for which interpolation should be performed, one element per corresponding time point, elements can be: - - list of str: list of channel names that should be interpolated for the corresponding time point - - str: single channel name that should be interpolated for the corresponding time point - - 'All': all channels should be interpolated for the corresponding time point - Calc : bool - Flag indicating whether data should be updated immediately - - Examples - -------- - >> obj.interp(lt=[2.55, 5.10, 6.84], lNames=[['H_021','J_014'], 'F_10', 'All'], Calc=True) - Will perform interpolation for 2 channels for the first time point, for one channel for the second, and for all channels for the last time point - - """ - self._interp_lt, self._interp_lNames, self._interp_UNames = _tft_c._PreData_interp(lt=lt, lNames=lNames) - if Calc: - self._doAll()
- -
[docs] def substract_Dt(self, tsub=None, Calc=True): - """ Allows subtraction of data at one time step from all data - - Can be convenient for plotting background-subtracted signal (background meaning signal before a reference time step). - - Parameters - ---------- - tsub : int / float / iterable - A time value, or a time interval indicating which part of the signal is to be considered as reference and subtracted from the rest - - int / float : - Calc : bool - Flag indicating whether data should be updated immediately - - """ - assert tsub is None or type(tsub) in [int,float,list,tuple,np.ndarray], "Arg tsub must be a time value (int,float) or a time interval (list,tuple,np.ndarray) !" - if not type(tsub) is float and not tsub is None: - assert len(tsub)==2 and tsub[1]>tsub[0] and np.diff(tsub)>np.mean(np.diff(self.t)), "Arg tsub must be an increasing time interval larger than the signal time reolsution !" - self._Subtract_tsub = tsub - if Calc: - self._doAll()
- - -
[docs] def set_fft(self, DF=None, Harm=True, DFEx=None, HarmEx=True, Calc=True): - """ Return the FFT-filtered signal (and the rest) in the chosen frequency window (in Hz) and in all the higher harmonics (optional) - - Can also exclude a given interval and its higher harmonics from the filtering (optional) - - Parameters - ---------- - DF : iterable - Iterable of len()=2, containing the lower and upper bounds of the frequency interval (Hz) to be used for filtering - Harm : bool - If True all the higher harmonics of the interval DF will also be included - DFEx : list - List or tuple of len()=2, containing the lower and upper bounds of the frequency interval to be excluded from filtering (in case it overlaps with some high harmonics of DF) - HarmEx : bool - If True all the higher harmonics of the interval DFEx will also be excluded - - """ - self._FFTPar = {'DF':DF, 'Harm':Harm, 'DFEx':DFEx, 'HarmEx':HarmEx} - if Calc: - self._doAll()
- - - def _doAll(self): - """ Centralizes all the computations, run everytime something is updated (time interval, valid channels, resampling, subtraction, fft...) """ - - # Get the list of channels considered valid - self._Chans = self.In_list() - self._NChans = np.sum(~self._indOut) - - data = self._dataRef[:,~self._indOut] - - # Interp of individual corrupted time points (must be done on reference data and time vector to be robust) - unames = [nn for nn in self._interp_UNames if not nn=='All'] - inds = [self.select(Val=nn, Crit='Name', Out=bool)[~self._indOut].nonzero()[0] for nn in unames] - data = _tft_c._PreData_doAll_interp(data, self._tRef, self._interp_lt, self._interp_lNames, unames, inds) - - # Time re-sampling - data, t = _tft_c._PreData_doAll_Resamp(self._DtRef, self._tRef, data, self._Resamp_t, self._Resamp_f, self._Resamp_Method, self._Resamp_interpkind) - - # Subtracting reference time - data = _tft_c._PreData_doAll_Subtract(data, t, self._Subtract_tsub) - - # Performing fft - data = _tft_c._PreData_doAll_FFT(data, t, self._FFTPar) - - # Focus on time interval (only for visualization) - indt = (t>=self._Dt[0]) & (t<=self._Dt[1]) if not self._Dt is None else np.ones((t.size,),dtype=bool) - self._data, self._t = data[indt,:], t[indt] - - -
[docs] def Corr_add(self, Val=[], LCrit=['Name','Cam','CamHead'], indCorr=None, Calc=True): - """ Add channels to the list of channels that are thought to need correction - - When a channel is suspected to need correction (mismatching retrofit due for example to wrong calibration), it can be included in a dedicated correction list. - Channels in this list can then be discarded for the inversion, a correction coefficient can be computed from the retrofit, and the inversion can be re-done using this correction coefficient. - This list works like the list of excluded / corrupted channels self.Out_list() - - Parameters - ---------- - Val : list - Fed to self.select(), list of values for criteria in LCrit that should be used to exclude channels (e.g.: list of channel names of camera names) - LCrit : list - Fed to self.select(), list of criteria against which to select the channels matching the values in Val (should be attributes of :class:`tofu.pathfile.ID` or of its USRdict attribute) - indCorr : None / np.ndarray - Alternatively, you can directly pass a (N,) bool array whereN matches the number of channels and True means that a channel should be excluded, thus setting self._indCorr - Calc : bool - Flag indicating whether the calculation should be triggered immediately - - """ - if not indCorr is None: - assert isinstance(indCorr,np.ndarray) and indCorr.dtype.name=='bool' and indCorr.ndim==1 and indCorr.size==self._NChanRef, "Arg indCorr must be a (N,) np.ndarray of bool !" - self._indCorr = indCorr - elif not LVal==[]: - ind = np.zeros((len(LCrit),self._NChanRef),dtype=bool) - for ii in range(0,len(LCrit)): - ind[ii,:] = self.select(Val=LVal, Crit=LCrit[ii], InOut='In', Out=bool) - self._indCorr = self._indCorr | np.any(ind,axis=0)
- - -
[docs] def Corr_remove(self, Val=[], LCrit=['Name','Cam','CamHead'], Calc=True): - """ Add channels to the list of channels to be re-inserted as valid channels - - Works like self.In_add() (i.e.: opposite of self.Corr_add()) - - Parameters - ---------- - Val : list - Fed to self.select(), list of values for criteria in LCrit that should be used to exclude channels (e.g.: list of channel names of camera names) - LCrit : list - Fed to self.select(), list of criteria against which to select the channels matching the values in Val (should be attributes of :class:`tofu.pathfile.ID` or of its USRdict attribute) - indCorr : None / np.ndarray - Alternatively, you can directly pass a (N,) bool array whereN matches the number of channels and True means that a channel should be excluded, thus setting self._indCorr - Calc : bool - Flag indicating whether the calculation should be triggered immediately - - """ - if not LVal==[]: - ind = np.ones((len(LCrit),self._NChanRef),dtype=bool) - for ii in range(0,len(LCrit)): - ind[ii,:] = self.select(Val=LVal, Crit=LCrit[ii], InOut='Out', Out=bool) - self._indCorr = self._indCorr & np.all(ind,axis=0)
- -
[docs] def Corr_list(self, Out='Name'): - """ Return the list of channel names needing correction - - This lists the channels indicated by self._indOut, populated using self.Out_add() and de-populated using self.In_add(). - The output can be returned as a list of channel Names - - Parameters - ---------- - Out : str - Flag indicating in which form to return the output (fed to :meth:`~tofu.treat.PreData.select()`) - - Returns - ------- - L : list - List of excluded channels in the required form - - """ - L = self.select(Out=Out) - L = [L[ii] for ii in range(0,len(L)) if self._indCorr[ii]] - return L
- -
[docs] def set_PhysNoise(self, Mode='svd', Phys=range(0,8), DF=[10.e3,11.e3], DFEx=None, Harm=True, HarmEx=True, Deg=0, Nbin=3, LimRatio=0.05, Plot=False): - """ Use a svd or a fft to estimate the physical part of the signal and the part which can be assimilated to noise, then uses specified degree for polynomial noise model - - This method provides an easy way to compute the noise level on each channel. - It can be done in 2 different ways: - - 'svd': you have to provide the mode numbers that you think can be considered as physical, the signal will be re-constructed from these and the rest discarded as noise - - 'fft': you have to provide the frequency window that you think is physical (optionaly the higher harmonics can be included), the signal is re-constructed via inverse fourier and the rest discarded as noise - - To help you decide which mode numbers of frequency interval to use, you can preliminarily use self.plot_svd() and self.plot_fft() to visualize the decompositions. - - Note : this is only used to compute a noise estimate, stored separately, the total original signal is preserved - - Parameters - ---------- - Mode : str - Flag indicating with which method should the noise be estimated ('svd' or 'fft') - Phys list - Modes to be extracted from the svd (default: first 8 modes), use method .plot_svd() to choose the modes - DF list - 2 values delimiting a frequency interval (in Hz) from which to extract signal using a fft and rfft - Harm bool - Flag, if True all the available higher harmonics of FreqIn will also be included in the physical signal - DFEx list - 2 values delimiting a frequency interval (in Hz) that shall be avoided in the physical signal (relevant if some high harmonics of DF intersect DFEx) - HarmEx bool - Flag, if True all the available higher harmonics of Freqout will also be avoided in the physical signal - Deg int - Degree to be used for the polynomial noise model - Nbin int - Number of bins to be used for evaluating the noise (std) at various signal values - LimRatio float - Ratio ... to be finished... - Plot bool - Flag, if True the histogram of the estimated noise is plotted - - Examples - -------- - >> obj.set_PhysNoise(Mode='svd', Phys=[0,1,2,3,4,5], Deg=0) - Will take the first 6 modes of the signal svd and consider as physical, the rest is used to compute a constant (Deg=0) noise estimate on each channel - - """ - if Mode=='svd': - Physic, Noise = _tft_c.SVDExtractPhysNoise(self.data, ModesPhys=Phys) - Param = {'Phys':Phys} - elif Mode=='FFT': - Physic, Noise = _tft_c.FourierExtract(self.t, self.data, DF=DF, DFEx=DFEx, Harm=Harm, HarmEx=HarmEx, Test=True) - Param = {'DF':DF, 'DFEx':DFEx, 'Harm':Harm, 'HarmEx':HarmEx} - self._PhysNoise = {'Mode':Mode, 'Param':Param, 'Physic':Physic, 'Noise':Noise} - self._set_NoiseModel(Deg=Deg, Nbin=Nbin, LimRatio=LimRatio, Plot=Plot)
- - - def _set_NoiseModel(self, Deg=0, Nbin=3, LimRatio=0.05, Plot=False): - """ Fit the noise as a function of the physical part of the signal by a polynomial, using np.polyfit and the noise level estimated from self.set_PhysNoise() - - After the physical part of the data has been extracted with self.set_PhysNoise(), this function provides tools for estimating how the noise level varies with the signal value (i.e. fixed noise vs signal-dependent noise). - It fits the noise vs data plot to give a least-square noise model. - If you want a constant noise model, just use Deg=0. - - Parameters - ---------- - Deg : int - Degree to be used for the polynomial noise model - Nbin : int - Number of bins to be used for evaluating the noise (std) at various signal values - LimRatio : float - Ratio ... - Plot : bool - Flag, if True the histogram of the estimated noise is plotted - - """ - self._NoiseModel, self._Noise, self._NoiseCoefs = _tft_c._PreData_set_NoiseModel() - - -
[docs] def plot(self, a4=False): - """ Plot the signal in an interactive window, no arguments needed - - Plot an interactive matplotlib window to explore the data - - Parameters - ---------- - a4 : bool - Flag indicating whether the figure should be the size of a a4 sheet of paper (to facilitate printing) - - Returns - ------- - Lax : list - List of plt.Axes on which the plots are made - - """ - Lax = _tft_p.Plot_Signal(self.data, self.t, self.Chans, nMax=4, shot=self.shot, a4=a4) - return Lax
- - -
[docs] def plot_svd(self, Modes=10, NRef=None, a4=False, Test=True): - """ Plot the chosen modes (topos and chronos) of the svd of the data, and the associated spectrum on a separate figure - - Performs a svd of the data and plots the singular values, the temporal and spacial modes - - Paramaters - ---------- - Modes : int / iterable - Index of the modes to be plotted, the modes and sorted in decreasing order of singular value - - int : plots all modes in range(0,Modes) - - iterable : plots all modes whose index is contained in Modes - NRef : None - Number of columns in the plot, if None set to len(Modes)/2 (i.e.: 2 modes plotted per axes) - a4 : bool - Flag indicating whether the figure should be the size of a a4 sheet of paper (to facilitate printing) - Test : bool - Flag indicating whether the inputs should be tested for conformity - - Returns - ------- - Lax : list - List of plt.Axes on which the plots were made - - """ - Lax = _tft_p.SVDNoisePlot(self.data, t=self.t, Modes=Modes, NRef=NRef, a4=a4, Test=Test) - return Lax
- - -
[docs] def plot_fft(self, Val=None, Crit='Name', V='simple', tselect=None, Fselect=None, PreExp=None, PostExp=None, Log='or', InOut='In', SpectNorm=True, DTF=None, RatDef=100., Inst=True, MainF=True, - ylim=(None,None), cmap=plt.cm.gray_r, a4=False): - """ Plot the power spectrum (fft) of the chosen signals - - Computes the fft of the data and plots the power spectrum, normalized or not, for the chosen channels - - Parameters Val, Crit, PreExp, PostExp, Log and InOut are for channel selection and are fed to :meth:`~tofu.treat.PreData.select()` - - Parameters - ---------- - V : str - Flag indicating whether the plot should be interactive, values in ['simple','inter'] - tselect : None / - - Fselect : None / - - SpectNorm : bool - Flag, if True the power spectrum is normalised to its maximum at each time step (default: True) - DTF : float - Size (in seconds) of the running time window to be used for the windowed fft - RatDef : float - Used if DTF not provided, the number by which the total signal duration is divided to get a time window - Inst : bool - Flag, if true, the average of the signal is substracted at each time step to emphasize high frequencies (higher than the one associated to the running time window, default: True) - MainF : bool - Flag - ylim : tuple - Each limit which is not None is fed to plt.Axes.set_ylim() - a4 : bool - Flag, if true the figure is sized so as to fill a a4 paper sheet - - Returns - ------- - Lax : list - List of plt.Axes on which the plots were made - - """ - ind = self.select(Val=Val, Crit=Crit, PreExp=PreExp, PostExp=PostExp, Log=Log, InOut=InOut, Out=int, ToIn=True) - Lax = _tft_p._PreData_plot_fft(self.Chans, V, ind, Inst, self.data, self.t, DTF, RatDef, SpectNorm, cmap, ylim, tselect, Fselect, a4=False) - return Lax
- - def _plot_NoiseVSPhys(self, Val=None, Crit='Name', PreExp=None, PostExp=None, Log='any', a4=False): - ind = self.select(Val=Val, Crit=Crit, PreExp=PreExp, PostExp=PostExp, Log=Log, Out=int, ToIn=True) - LNames = self.select(Val=Val, Crit=Crit, PreExp=PreExp, PostExp=PostExp, Log=Log, Out='Name', ToIn=True) - Coefs = self._NoiseCoefs[:,ind] if self._NoiseCoefs.ndim==2 else self._NoiseCoefs[ind] - return Plot_Noise(self._PhysNoise['Phys'][:,ind], self._PhysNoise['Noise'][:,ind], self._NoiseCoefs[:,ind], LNames, self._NoiseModel['Deg'], a4=a4) - -
[docs] def save(self, SaveName=None, Path=None, Mode='npz', compressed=False): - """ Save the object in folder Name, under file name SaveName, using specified mode - - Most tofu objects can be saved automatically as numpy arrays (.npz, recommended) at the default location (recommended) by simply calling self.save() - - Parameters - ---------- - SaveName : None / str - The name to be used for the saved file, if None (recommended) uses self.Id.SaveName - Path : None / str - Path specifying where to save the file, if None (recommended) uses self.Id.SavePath - Mode : str - Flag specifying whether to save the object as a numpy array file ('.npz', recommended) or an object using cPickle (not recommended, heavier and may cause retro-compatibility issues) - compressed : bool - Flag, used when Mode='npz', indicating whether to use np.savez or np.savez_compressed (slower saving and loading but smaller files) - - """ - tfpf.Save_Generic(self, SaveName=SaveName, Path=Path, Mode=Mode, compressed=compressed)
- - - - -
- -
-
-
- -
-
- - - - \ No newline at end of file diff --git a/doc/build/html/_sources/Auto_tofu.geom.txt b/doc/build/html/_sources/Auto_tofu.geom.txt deleted file mode 100644 index 39547abef..000000000 --- a/doc/build/html/_sources/Auto_tofu.geom.txt +++ /dev/null @@ -1,28 +0,0 @@ -.. role:: envvar(literal) -.. role:: command(literal) -.. role:: file(literal) -.. role:: ref(title-reference) -.. _overview: - -**tofu.geom** -============== - -.. automodule:: tofu.geom - :members: - - -Indices and tables ------------------- -* Homepage_ -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - -.. _Homepage: index.html - - - -.. Local Variables: -.. mode: rst -.. End: - diff --git a/doc/build/html/_sources/Auto_tofu.pathfile.txt b/doc/build/html/_sources/Auto_tofu.pathfile.txt deleted file mode 100644 index 08fb4fd31..000000000 --- a/doc/build/html/_sources/Auto_tofu.pathfile.txt +++ /dev/null @@ -1,28 +0,0 @@ -.. role:: envvar(literal) -.. role:: command(literal) -.. role:: file(literal) -.. role:: ref(title-reference) -.. _overview: - -**tofu.pathfile** -================= - -.. automodule:: tofu.pathfile - :members: - - -Indices and tables ------------------- -* Homepage_ -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - -.. _Homepage: index.html - - - -.. Local Variables: -.. mode: rst -.. End: - diff --git a/doc/build/html/_sources/Auto_tofu.plugins.AUG.SXR.geom.txt b/doc/build/html/_sources/Auto_tofu.plugins.AUG.SXR.geom.txt deleted file mode 100644 index fea9c8bf8..000000000 --- a/doc/build/html/_sources/Auto_tofu.plugins.AUG.SXR.geom.txt +++ /dev/null @@ -1,35 +0,0 @@ -.. role:: envvar(literal) -.. role:: command(literal) -.. role:: file(literal) -.. role:: ref(title-reference) -.. _overview: - -**AUG.SXR** -=========== - - -**AUG.SXR.geom** ----------------- - -.. automodule:: tofu.plugins.AUG.SXR.geom - :members: - -**AUG.SXR.data** ----------------- -.. automodule:: tofu.plugins.AUG.SXR.data - :members: - - -Indices and tables ------------------- -* Homepage_ -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - -.. _Homepage: index.html - - -.. Local Variables: -.. mode: rst -.. End: diff --git a/doc/build/html/_sources/Auto_tofu.plugins.AUG.txt b/doc/build/html/_sources/Auto_tofu.plugins.AUG.txt deleted file mode 100644 index fbbe47ba9..000000000 --- a/doc/build/html/_sources/Auto_tofu.plugins.AUG.txt +++ /dev/null @@ -1,43 +0,0 @@ -.. role:: envvar(literal) -.. role:: command(literal) -.. role:: file(literal) -.. role:: ref(title-reference) -.. _overview: - -**AUG** -======= - - -**AUG.Ves** ------------ - -.. automodule:: tofu.plugins.AUG.Ves - :members: - - -**AUG.SXR.geom** ----------------- - -.. automodule:: tofu.plugins.AUG.SXR.geom - :members: - - -**AUG.SXR.data** ----------------- -.. automodule:: tofu.plugins.AUG.SXR.data - :members: - - -Indices and tables ------------------- -* Homepage_ -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - -.. _Homepage: index.html - - -.. Local Variables: -.. mode: rst -.. End: diff --git a/doc/build/html/_sources/Auto_tofu.plugins.ITER.Bolo.geom.txt b/doc/build/html/_sources/Auto_tofu.plugins.ITER.Bolo.geom.txt deleted file mode 100644 index 38d879d9c..000000000 --- a/doc/build/html/_sources/Auto_tofu.plugins.ITER.Bolo.geom.txt +++ /dev/null @@ -1,27 +0,0 @@ -.. role:: envvar(literal) -.. role:: command(literal) -.. role:: file(literal) -.. role:: ref(title-reference) -.. _overview: - -**tofu.plugins.ITER.Bolo.geom** -=============================== - -.. automodule:: tofu.plugins.ITER.Bolo.geom - :members: - - - -Indices and tables ------------------- -* Homepage_ -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - -.. _Homepage: index.html - - -.. Local Variables: -.. mode: rst -.. End: diff --git a/doc/build/html/_sources/Auto_tofu.plugins.ITER.txt b/doc/build/html/_sources/Auto_tofu.plugins.ITER.txt deleted file mode 100644 index 2a3ce8669..000000000 --- a/doc/build/html/_sources/Auto_tofu.plugins.ITER.txt +++ /dev/null @@ -1,44 +0,0 @@ -.. role:: envvar(literal) -.. role:: command(literal) -.. role:: file(literal) -.. role:: ref(title-reference) -.. _overview: - -**ITER** -=============================== - - -**ITER.Ves** ------------- - -.. automodule:: tofu.plugins.ITER.Ves - :members: - -**ITER.Struct** ---------------- - -.. automodule:: tofu.plugins.ITER.Struct - :members: - - -**ITER.Bolo.geom** ------------------- - -.. automodule:: tofu.plugins.ITER.Bolo.geom - :members: - - - -Indices and tables ------------------- -* Homepage_ -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - -.. _Homepage: index.html - - -.. Local Variables: -.. mode: rst -.. End: diff --git a/doc/build/html/_sources/Auto_tofu.plugins.txt b/doc/build/html/_sources/Auto_tofu.plugins.txt deleted file mode 100644 index 3bca24afa..000000000 --- a/doc/build/html/_sources/Auto_tofu.plugins.txt +++ /dev/null @@ -1,48 +0,0 @@ -.. role:: envvar(literal) -.. role:: command(literal) -.. role:: file(literal) -.. role:: ref(title-reference) -.. _overview: - -**tofu.plugins** -================ - - -In an effort to adapt ToFu to several experiments and ensure a smooth use for non-specialists users, plugins can be developped to adapt ToFu to the local specificities of each laboratory or environment (local computer systems and networks, local geometry and nomenclature, local data storing systems...). - -While ToFu in itself is open-source, the plugins, which concentrate everything that is machine-specific, are writen on demand and customized for the local needs, they remain on the local servers and are not provided on the GitHub page of ToFu. It is via the laboratories that you may have access to them. - -The following plugins have been / are being developped: - -Machine-oriented plugins ------------------------- - -.. toctree:: - :maxdepth: 1 - - Auto_tofu.plugins.AUG - Auto_tofu.plugins.ITER - - -Code-oriented plugins ---------------------- - -1. CAID_ - -.. _CAID: https://www.qwant.com/web - - - -Indices and tables ------------------- -* Homepage_ -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - -.. _Homepage: index.html - - -.. Local Variables: -.. mode: rst -.. End: diff --git a/doc/build/html/_sources/Auto_tofu.treat.txt b/doc/build/html/_sources/Auto_tofu.treat.txt deleted file mode 100644 index d8536b49d..000000000 --- a/doc/build/html/_sources/Auto_tofu.treat.txt +++ /dev/null @@ -1,28 +0,0 @@ -.. role:: envvar(literal) -.. role:: command(literal) -.. role:: file(literal) -.. role:: ref(title-reference) -.. _overview: - -**tofu.treat** -============== - -.. automodule:: tofu.treat - :members: - - -Indices and tables ------------------- -* Homepage_ -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - -.. _Homepage: index.html - - - -.. Local Variables: -.. mode: rst -.. End: - diff --git a/doc/build/html/_sources/Autodoc.txt b/doc/build/html/_sources/Autodoc.txt deleted file mode 100644 index 4ac1542a2..000000000 --- a/doc/build/html/_sources/Autodoc.txt +++ /dev/null @@ -1,19 +0,0 @@ -.. role:: envvar(literal) -.. role:: command(literal) -.. role:: file(literal) -.. role:: ref(title-reference) -.. _overview: - -**tofu.geom** -============== - -.. automodule:: tofu.geom - :members: - -.. automodule:: tofu.plugins.AUG.SXR.geom - :members: - - -.. Local Variables: -.. mode: rst -.. End: diff --git a/doc/build/html/_sources/Citation.txt b/doc/build/html/_sources/Citation.txt deleted file mode 100644 index 7cf988cb7..000000000 --- a/doc/build/html/_sources/Citation.txt +++ /dev/null @@ -1,41 +0,0 @@ -.. role:: envvar(literal) -.. role:: command(literal) -.. role:: file(literal) -.. role:: ref(title-reference) - -Citing ToFu: -============ - -An article dedicated to describing ToFu and its capacities is in preparation, in the meantime please cite this one_ [#]_, which briefly describes it and uses it to present physics results. Since this paper may not present enough details for the interested reader, please also include a url pointing to this web-based documentation. - -.. _one: http://iopscience.iop.org/article/10.1088/0029-5515/56/8/086001/meta - -.. [#] D. Vezinet et al., 'Non-monotonic growth rates of sawtooth precursors evidenced with a new method on ASDEX Upgrade', Nuclear Fusion **56**, 086001, 2016 - -**Bibtex:** - -:: - - @article{0029-5515-56-8-086001, - author={D. Vezinet and V. Igochine and M. Weiland and Q. Yu and A. Gude and D. Meshcheriakov and M. Sertoli and the Asdex Upgrade - Team and the EUROfusion MST1 Team}, - title={Non-monotonic growth rates of sawtooth precursors evidenced with a new method on ASDEX Upgrade}, - journal={Nuclear Fusion}, - volume={56}, - number={8}, - pages={086001}, - url={http://stacks.iop.org/0029-5515/56/i=8/a=086001}, - year={2016}, - } - - - -Indices and tables ------------------- -* Homepage_ -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - -.. _Homepage: index.html - diff --git a/doc/build/html/_sources/Dependencies.txt b/doc/build/html/_sources/Dependencies.txt deleted file mode 100644 index ac56ee71c..000000000 --- a/doc/build/html/_sources/Dependencies.txt +++ /dev/null @@ -1,63 +0,0 @@ -.. role:: envvar(literal) -.. role:: command(literal) -.. role:: file(literal) -.. role:: ref(title-reference) - -Dependencies -============ - -ToFu uses the following generic packages: - -- python/2.7.3 -- ipython/1.1.0 -- dateutil/2.4.0 -- docutils/0.12.0 -- distribute/0.6.34 - - -Scientific computing and plotting: - -- numpy/1.9.1 -- scipy/0.15.1 -- matplotlib/1.2.1 -- polygon2 -- datetime - - -Some part of ToFu are coded using Cython, which requires Cython and a compiler: - -- cython/0.19.1 -- gcc or intel - - -Testing: - -- nose/1.3.4 - - -Documentation: - -- pygments/1.5 - - -To be determined: - -- pyzmq/13.0.2 -- tornado/2.4.1 -- setuptools -- mdsplus/5.0_11 -- pip -- git/1.8.4 - - - - -Indices and tables ------------------- -* Homepage_ -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - -.. _Homepage: index.html - diff --git a/doc/build/html/_sources/Todos.txt b/doc/build/html/_sources/Todos.txt deleted file mode 100644 index 98696dbc4..000000000 --- a/doc/build/html/_sources/Todos.txt +++ /dev/null @@ -1,34 +0,0 @@ -.. role:: envvar(literal) -.. role:: command(literal) -.. role:: file(literal) -.. role:: ref(title-reference) -.. _overview: - -**To do for contributors** -========================== - -This to do list includes aspects that require a few hours up to a few months of work. -Whenever possible, a link to a document describing the problem in details is provided. - - -Math and geometry: ------------------- -* Write a C routine for (very) fast computation of solid angle in non-trival cases using spherical geometry and write a python / cython wrapper (weeks) - - -Coding: -------- -* Parallelize (frist CPU then GPU) the key functions of the geometry module (months) -* Branch the meshing module to allow compatibility with CAID/Pigasus (months) -* Branch the matrix computation module for the same reason (months) -* Branch the inversion module for the same reason (months) - -Long term: ----------- -* Create a parallel library called ToFuG, which provides all ToFu functionalities through a GUI for each ToFu module (year) - - - -.. Local Variables: -.. mode: rst -.. End: diff --git a/doc/build/html/_sources/Tutorial_AUG.txt b/doc/build/html/_sources/Tutorial_AUG.txt deleted file mode 100644 index eee76d8cb..000000000 --- a/doc/build/html/_sources/Tutorial_AUG.txt +++ /dev/null @@ -1,63 +0,0 @@ -.. role:: envvar(literal) -.. role:: command(literal) -.. role:: file(literal) -.. role:: ref(title-reference) - -AUG-specific tutorial -===================== - -How to access the ToFu library ------------------------------- - -The plugin for ASDEX Upgrade (AUG) is hosted on the theory (Tok) clusters of the Max-Planck Institute for Plasma Physics (IPP) in Garching. -If you have an account in IPP, you can then connect to one of the tok clusters where the library is hosted, via the command: - ->>> ssh toki01 - -Enter your password and then you need to load the module in the terminal - ->>> module load tofu - -You may need to load other modules on which ToFu depends (see the dependencies_). - -.. _dependencies : Dependencies.html - -You can then start a ipython console and load the AUG plugin for ToFu: - ->>> import tofu.plugins.AUG as tfAUG - - -How to load existing geometry ------------------------------- - -You can now load the geometry that was already computed and stored for some diagnostics (only the Soft X-Ray diagnostic at this date). -In general loading the geometry means using a method of the plugin that will load and return a list of :class:`tofu.geom.GDetect` instances. -On AUG, each :class:`tofu.geom.GDetect` instance corresponds to a camera head. -Since the geometry (position, aperture size...) of each camera head may change in time (changes are sometimes implemented between experimental campaigns), you can specify a shot number and the plugin will return the latest geometry that was computed before that shot number (only a few have been computed so far, but more will come). - ->>> LGD = tfAUG.SXR.geom.load(shot=31801) - -This command returns a list of :class:`tofu.geom.GDetect` instances with the latest geometry computed before shot 31801. - - -How to load SXR data --------------------- - -the ToFu plugin for AUG also comes with a data loading and formatting routine. -In addition to a shot number and a time window, you can choose whether the data is returned as numpy arrays or as a ToFu-compatible object for data pre-treatment via the Tofu keyword argument. - ->>> pre = tfAUG.SXR.data.load(shot=30801, Dt=[2.,2.01], Method='SX', Tofu=True) - -This command will return the SXR data for shot 30801 in the [2.,2.01] s time window using diagnostic 'SX.' (instead of SSX), in the form of a ToFu-compatible object. -See the documentation of the method for more details. - - -Indices and tables ------------------- -* Homepage_ -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - -.. _Homepage: index.html - diff --git a/doc/build/html/_sources/Tutorial_Geom_Advanced.txt b/doc/build/html/_sources/Tutorial_Geom_Advanced.txt deleted file mode 100644 index 7b4ba7d6d..000000000 --- a/doc/build/html/_sources/Tutorial_Geom_Advanced.txt +++ /dev/null @@ -1,102 +0,0 @@ -.. role:: envvar(literal) -.. role:: command(literal) -.. role:: file(literal) -.. role:: ref(title-reference) - -How to create a diagnostic geometry -==================================== - -It is the geometry module that provides all the necessary tools for creating a new diagnostic. -A diagnostic comprises a set of detectors (ToFu creates one object for each detector and you can then group them into a larger object to represent cameras). -Each detector is basically defined by its active surface, which should be a planar polygon, and by a set of optics through which it 'sees' the plasma. -The optics can be a converging spherical lens or an arbitrary number of apertures (of arbitrary shape). -Each detector is also assigned to a vessel, which defines the linear or toroidal volume in which the plasma can exist. - -The following guides you through the creation of these objects in the famous 'hello-world' example: - -To find out more about what you can do with the geometry module check out the advanced_ tutorial. - -.. _advanced: - -Creating a vessel ------------------ - -If a vessel object does not exist yet, you have to create one (otherwise you can just load it an existing one). -A vessel object is basically defined by a 2D simple polygon (i.e.: non self-intersecting), - - - - - - - - - - - - -**Open-source:** - ToFu is distributed under the very permissive MIT_ license, thus allowing free use, keeping in mind that neither the author nor any of the laboratories in which he worked can be held responsible for unwanted behaviour or results. - It is instead transparency that is considered for as a warranty of quality on the long-term. - - ToFu is hosted on github_. - -.. _MIT: https://opensource.org/licenses/MIT -.. _github: https://github.com/ - -**Versions:** - A list of the successive versions of ToFu, with a brief description can be found here_. - -.. _here: Versions.html - -**Dependences:** - ToFu uses the following python packages_. - -.. _packages: Dependencies.html - - -**Citing ToFu:** - If you decide to use ToFu for research and published results please acknowledge this work by citing_ the project. - -.. _citing: Citation.html - - -Contents: ---------- - -**Description of the library modules:** - -.. toctree:: - :maxdepth: 1 - - overview - -**Code documentation:** - -.. toctree:: - :maxdepth: 1 - - Auto_tofu.geom - Auto_tofu.plugins.AUG.SXR.geom - Auto_tofu.plugins.ITER.Bolo.geom - - -**Tutorials and how to's:** - * How to build a diagnostic geometry - Create apertures and detectors to test a new configuration, to apply ToFu to your own problems, to design a prospetive diagnostic... - * How to compute integrated signal from 2D or 3D synthetic emissivity - Use an already-existing diagnostic geometry in a synthetic diagnostic approach to solve the direct problem and compute the line Of Sight and / or Volume of Sight integrated signals from a simulated emissivity field that you provide as an input. - * How to compute tomographic inversions - Use existing diagnostic geometry and signals to solve the inverse problem and compute tomographic inversions using a choice of discretization basis functions and regularisation functionals. - * How to contribute (to do's) - - -Indices and tables -================== -* Homepage_ -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - -.. _Homepage: index.html - diff --git a/doc/build/html/_sources/Tutorial_Geom_HowToCreateGeometry.txt b/doc/build/html/_sources/Tutorial_Geom_HowToCreateGeometry.txt deleted file mode 100644 index 83ecd2355..000000000 --- a/doc/build/html/_sources/Tutorial_Geom_HowToCreateGeometry.txt +++ /dev/null @@ -1,247 +0,0 @@ -.. role:: envvar(literal) -.. role:: command(literal) -.. role:: file(literal) -.. role:: ref(title-reference) - -How to create a diagnostic geometry -==================================== - -It is the geometry module that provides all the necessary tools for creating a new diagnostic. -A diagnostic comprises a set of detectors (ToFu creates one object for each detector and you can then group them into a larger object to represent cameras). -Each detector is basically defined by its active surface, which should be a planar polygon, and by a set of optics through which it 'sees' the plasma. -The optics can be a converging spherical lens or an arbitrary number of apertures (of arbitrary shape). -Each detector is also assigned to a vessel, which defines the linear or toroidal volume in which the plasma can exist. - -The following guides you through the creation of these objects in the famous 'hello-world' example: - -To find out more about what you can do with the geometry module check out the advanced_ tutorial. - -.. _advanced: Tutorial_Geom_Advanced.html - - -As a pre-requisite, let's load some basic useful libraries in a ipython session, as well as the geometry module of ToFu: - ->>> import numpy as np ->>> import matplotlib.pyplot as plt ->>> plt.ion() ->>> # tofu-specific ->>> import tofu.geom as tfg - - -Creating, plotting and saving a vessel --------------------------------------- - -If a vessel object does not exist yet, you have to create one (otherwise you can just load it an existing one). -A vessel object is basically defined by a 2D simple polygon (i.e.: non self-intersecting), that is then expanded linearly or toroidally depending on the desired configuration. -This polygon limits the volume available for the plasma, where the emissivity can be non-zero. It is typically defined by the inner wall in a tokamak. - -Let's define the polygon limiting the vessel as a circle with a divertor-like shape at the bottom: - ->>> # Define the center, radius and lower limit ->>> R0, Z0, rad, ZL = 2., 0., 1., -0.85 ->>> # Define the key points in the divertor region below ZL ->>> Div_R, Div_Z = [R0-0.2, R0, R0+0.2], [-1.2, -0.9, -1.2] ->>> # Find the angles corresponding to ZL and span the rest ->>> thet1 = np.arcsin((ZL-Z0)/rad) ->>> thet2 = np.pi - thet1 ->>> thet = np.linspace(thet1,thet2,100) ->>> # Assemble the polygon ->>> poly_R = np.append(R0+rad*np.cos(thet), Div_R) ->>> poly_Z = np.append(Z0+rad*np.sin(thet), Div_Z) ->>> # Plot for checking ->>> f, l, a = plt.figure(facecolor='w', figsize=(6,6)), plt.plot(poly_R, poly_Z), plt.axis('equal') - -.. figure:: figures_doc/Fig_Tutor_Geom_Basic_01.png - :height: 300px - :width: 300 px - :scale: 100 % - :alt: Polygon used for defining the vaccum vessel where the plasma may live - :align: center - - Polygon used for defining the vaccum vessel where the plasma may live - -Notice that the polygon does not have to be closed, ToFu will anyway check that and close it automatically if necessary - -Now let's feed this 2D polygon to the appropriate ToFu class and specify that it should be a toroidal type (if linear type is chosen, the length should be specified by the 'DLong' keyword argument). -ToFu also asks for a name to be associated to this instance, and an experiment ('Exp') and a shot number (useful when the same experiment changes geometry in time). - ->>> # Create a toroidal Ves instance with name 'World', associated to experiment 'Misc' (for 'Miscellaneous') and shot number 0 ->>> ves = tfg.Ves('HelloWorld', [poly_R,poly_Z], Type='Tor', Exp='Misc', shot=0) - -Now the vessel instance is created. I provides you with several key attributes and methods (see :class:`~tofu.geom.Ves` for details). -Among them the Id attribute is itself a class instance that contains all useful information about this vessel instance for identification, saving... In particular, that's where the name, the default saving path, the Type, the experiment, the shot number... are all stored. -A default name for saving was also created that automatically includes not only the name you gave but also the module from which this instance was created (tofu.geom or tfg), the type of object, the experiment, the shot number... -This recommended default pattern is useful for quick identification of saved object, it is advised not to modify it. - ->>> print ves.Id.SaveName -TFG_VesTor_Misc_World_sh0 - -Now, we can simply visualise the created vessel by using the dedicated method (keyword argument 'Elt' specifies the elements of the instance we want to plot, typically one letter corresponds to one element, here we just want the polygon): - ->>> # Plot the polygon, by default in two projections (cross-section and horizontal) and return the list of axes ->>> Lax = ves.plot(Elt='P') - -.. figure:: figures_doc/Fig_Tutor_Geom_Basic_02.png - :height: 300px - :width: 600 px - :scale: 100 % - :alt: The created vessel instance, plotted in cross-section and horizontal projections - :align: center - - The created vessel instance, plotted in cross-section and horizontal projections - - -Since the vessel is an important object (it defines where the plasma can live), all the other ToFu objects rely on it. It is thus important that you save it so that it can be used by other ToFu objects when necessary. - ->>> ves.save(Path='./') - -This method will save the instance as a numpy compressed file (.npz), using the path and file name found in ves.Id.SavePath and ves.Id.SaveName. -While it is highly recommended to stick to the default value for the SaveName, but you can easily modify the saving path if you want by specifying it using keyword argument Path. - - - -Creating, plotting and saving structural elements -------------------------------------------------- - -Unlike the vessel, which is important for physics reasons, the structural elements that ToFu allows to create are purely for illustrative purposes. They are entirely passive and have no effect whatsoever on the computation of the volume of sight of the detectors or on the plasma volume and are just made available for illustrations. - -Like for a vessel, a structural element is mostly defined by a 2D polygon. If a vessel instance is provided, the type of the structural element (toroidal or linear) is automatically the same as the type of the vessel, otherwise the type must be specified. -For plotting, structural elements that enclose the entirety of a vessel are automatically transparent, and gray if they don't. - ->>> # Define two polygons, one that does not enclose the vessel and one that does ->>> thet = np.linspace(0.,2.*np.pi,100) ->>> poly1 = [[2.5,3.5,3.5,2.5],[0.,0.,0.5,0.5]] ->>> poly2 = [R0+1.5*np.cos(thet),1.5*np.sin(thet)] ->>> # Create the structural elements with the appropriate ToFu class, specifying the experiment and a shot number for keeping track of changes ->>> s1 = tfg.Struct('S1', poly1, Ves=ves, Exp='Misc', shot=0) ->>> s2 = tfg.Struct('S2', poly2, Ves=ves, Exp='Misc', shot=0) ->>> # Plot them on top of the vessel ->>> Lax = ves.plot(Elt='P') ->>> # Re-use the same list of axes to overlay the plots ->>> Lax = s1.plot(Lax=Lax) ->>> Lax = s2.plot(Lax=Lax) - -.. figure:: figures_doc/Fig_Tutor_Geom_Basic_03.png - :height: 300px - :width: 600 px - :scale: 100 % - :alt: The created structural elements, plotted over the structural elements on both projections - :align: center - - The created structural elements, plotted over the structural elements on both projections - - -It is not necessary for ToFu (since structural elements are used by no other objects) but for convenience you can save a structral element using the same save() method as for any other object. - - - -Creating apertures ------------------- - -An aperture is also mosly defined by a planar polygon, except that the polygon coordinates should be provided in 3D cartesian coordinates (even though the polygon is planar, it mey not live in the same plane as other apertures or as the detector). - -We can easily define two different polygons for two different apertures - ->>> # Define the planes in which they will live by a point (O) and a vector (n) ->>> O1, n1 = (3.0,0.00,0.52), (-1.,0.1,-0.9) ->>> O2, n2 = (2.9,0.01,0.48), (-1.,0.0,-1.0) ->>> # Compute local orthogonal basis vectors in the planes ->>> e11, e21 = np.cross(n1,(0.,0.,1.)), np.cross(n2,(0.,0.,1.)) ->>> e12, e22 = np.cross(e11,n1), np.cross(e21,n2) ->>> # Normalize ->>> e11, e12 = e11/np.linalg.norm(e11), e12/np.linalg.norm(e12) ->>> e21, e22 = e21/np.linalg.norm(e21), e22/np.linalg.norm(e22) ->>> # Implement the planar polygons 2D coordinates ->>> p1_2D = 0.005*np.array([[-1.,1.,1.,-1],[-1.,-1.,1.,1.]]) ->>> p2_2D = 0.01*np.array([[-1.,1.,1.,-1],[-1.,-1.,1.,1.]]) ->>> # Compute the 3D coordinates ->>> p1 = [O1[0] + e11[0]*p1_2D[0,:] + e12[0]*p1_2D[1,:], O1[1] + e11[1]*p1_2D[0,:] + e12[1]*p1_2D[1,:], O1[2] + e11[2]*p1_2D[0,:] + e12[2]*p1_2D[1,:]] ->>> p2 = [O2[0] + e21[0]*p2_2D[0,:] + e22[0]*p2_2D[1,:], O2[1] + e21[1]*p2_2D[0,:] + e22[1]*p2_2D[1,:], O2[2] + e21[2]*p2_2D[0,:] + e22[2]*p2_2D[1,:]] ->>> # Create the apertures, specifying also the diagnostic the apertures belong to ->>> a1 = tfg.Apert('A1', p1, Ves=ves, Exp='Misc', shot=0, Diag='misc') ->>> a2 = tfg.Apert('A2', p2, Ves=ves, Exp='Misc', shot=0, Diag='misc') ->>> # Plot them, both the polygon and the vector, with the associated vessel (using EltVes), in 3D ->>> Lax = a1.plot(Elt='PV', EltVes='P') ->>> Lax = a2.plot(Lax=Lax, Elt='PV') - -.. figure:: figures_doc/Fig_Tutor_Geom_Basic_04.png - :height: 300px - :width: 600 px - :scale: 100 % - :alt: The created apertures, plotted over the vessel on both projections - :align: center - - The created apertures, plotted over the vessel on both projections - -ToFu allows you to save the apertures, if you wish, but if you created then only to pass tem on to detectors, you can also skip saving them. Indeed, once the detector associated to these apertures is created, you will save the detector object instead, and ToFu will automatically store all information about the apertures (everything necessary to re-create them when loading the detector object). - - - -Creating, plotting and saving detectors objects ------------------------------------------------ - -A detector object is defined in the same way as an aperture, except that it needs to know which optics it is associated to. The optics can be either a converging spherical lens or, as in this case, a list of apertures. -In the folloing we will thus create two detectors (re-using the same planes as for the apertures for simplicity, but they could lie in any plane). - ->>> # Choose different reference points for the 2 planes ->>> Od1, Od2 = (3.05,0.00,0.54), (3.05,0.00,0.50) ->>> # Implement the planar polygons 2D coordinates ->>> pd1_2D = 0.005*np.array([[-1.,1.,1.,-1],[-1.,-1.,1.,1.]]) ->>> pd2_2D = 0.005*np.array([[-1.,1.,1.,-1],[-1.,-1.,1.,1.]]) ->>> # Compute the 3D coordinates ->>> pd1 = [Od1[0] + e11[0]*pd1_2D[0,:] + e12[0]*pd1_2D[1,:], Od1[1] + e11[1]*pd1_2D[0,:] + e12[1]*pd1_2D[1,:], Od1[2] + e11[2]*pd1_2D[0,:] + e12[2]*pd1_2D[1,:]] ->>> pd2 = [Od2[0] + e21[0]*pd2_2D[0,:] + e22[0]*pd2_2D[1,:], Od2[1] + e21[1]*pd2_2D[0,:] + e22[1]*pd2_2D[1,:], Od2[2] + e21[2]*pd2_2D[0,:] + e22[2]*pd2_2D[1,:]] ->>> # Create the detectors, specifying also the diagnostic and the Optics ->>> d1 = tfg.Detect('D1', pd1, Optics=[a1,a2], Ves=ves, Exp='Misc', shot=0, Diag='misc') ->>> d2 = tfg.Detect('D2', pd2, Optics=[a2], Ves=ves, Exp='Misc', shot=0, Diag='misc') - -The computation of the detectors may take a while (~3 min) because ToFu automatically computes the natural Line Of Sight (LOS) and its etendue, the Volume Of Sight (VOS), a pre-computed 3D grid of the VOS for faster computation of synthetic signal... -Some of these automatic computations can be de-activacted using the proper keyword arguments, or the resolution of the discretization can downgraded for faster computation (see :class:`~tofu.geom.Detect` for details). - -A Detect object is at the core of the added value of ToFu: all relevant quantities are automatically computed, and can be obtained and plotted via attributes and methods. - ->>> # Plot the detectors, specifying we want not only the polygon but also the perpendicular vector and the viewing cone ('C'), as well as elements of the LOS, Optics and vessel ->>> Lax = d1.plot(Elt='PVC', EltOptics='P', EltLOS='L', EltVes='P') ->>> Lax = d2.plot(Lax=Lax, Elt='PVC', EltOptics='P', EltLOS='L') - -.. figure:: figures_doc/Fig_Tutor_Geom_Basic_05.png - :height: 300px - :width: 600 px - :scale: 100 % - :alt: The created detectors, with associated apertures and vessel, on both projections - :align: center - - The created detectors, with associated apertures and vessel, on both projections - -Using d1.save() would save detector 1 and all necessary info about its associated optics (i.e.:apertures) will also be included in the file so it is not necessary to save the apertures separately (unless you need to for something else). -Usually, tomography diagnostics do not have a few but many different detectors, grouped in cameras (often a group of detectors sharing a common aperture). -ToFu provides an GDetect object that allows you to group a list of detectors and treat them like a single object (each method is automatically applied to all the detectors included in the GDetect object). - - - -Creating, plotting and saving GDetect objects ---------------------------------------------- - -Once several Detect objects are created, they can be fed to a GDetect object to be handle as a single object. - ->>> # Create the group of detectors by feeding a list of detectors ->>> gd = tfg.GDetect('GD', [d1,d2], Exp='Misc', shot=0) ->>> # Plot the group of detectors as a single set ->>> Lax = gd.plot(Elt='PVC', EltOptics='P', EltLOS='L', EltVes='P') - -The last command yields the same result as the previous figure. - - -Congratulations ! You completed the basic tutorial for getting started and creating your own geometry, take you time now to explore all the methods and attributes of the classes introduced in :mod:`tofu.geom`. - - - -Indices and tables ------------------- -* Homepage_ -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - -.. _Homepage: index.html - diff --git a/doc/build/html/_sources/Tutorial_Geom_SynthDiag_Basic.txt b/doc/build/html/_sources/Tutorial_Geom_SynthDiag_Basic.txt deleted file mode 100644 index f3e4c6ceb..000000000 --- a/doc/build/html/_sources/Tutorial_Geom_SynthDiag_Basic.txt +++ /dev/null @@ -1,94 +0,0 @@ -.. role:: envvar(literal) -.. role:: command(literal) -.. role:: file(literal) -.. role:: ref(title-reference) - -How to compute integrated signal from synthetic emissivity -========================================================== - - -We are assuming here that you have access to an existing geometry (i.e. to :class:`~tofu.geom.Detect` or :class:`~tofu.geom.GDetect` objects that you or someone else created or that you can load). -It if is not the case you should first create the geometry you need, by following the basic_ geometry tutorial. - -.. _basic: Tutorial_Geom_HowToCreateGeometry.html - -We are also assuming that you have a code that can produce as output a simulated isotropic emissivity. Either directly or by spacial interpolation, you should be able to write a python function that computes an emissivity value in any arbitrary point inside the vessel volume. - - -As a prerequisite load the necessary modules: - ->>> import numpy as np ->>> import matplotlib.pyplot as plt ->>> plt.ion() ->>> # tofu-specific ->>> import tofu.pathfile as tfpf - - -Writing the input function --------------------------- - -In the following, all is done assuming **gd** is a :class:`~tofu.geom.GDetect` object, but the same would apply if it is just a :class:`~tofu.geom.Detect` object. -If the :class:`~tofu.geom.GDetect` object you want to use is not already existing in your session, you can load it (with its absolute path and file name) using the :meth:`tofu.pathfile.Open()` function or a dedicated plugin function. - -Instances of :class:`~tofu.geom.GDetect` have a method called :meth:`~tofu.geom.GDetect.calc_Sig()`, which takes as input **ff** a python function able to evaluate the emissivity value in any number of points provided in 3D cartesian coordinates. - -This function should obey the following constraints: - * It is a callable with one input argument and optionally keyword arguments - * The input argument is a (3,N) numpy.ndarray, where N is the number of points at which one wants to evaluate the emissivity, provided in 3D cartesian coordinates (X,Y,Z) - -Hence, suppose that we simulate a 2D (i.e.: invariant along the 3rd dimension) gaussian emissivity centered on point (2.,0.), we can define ff as - ->>> def ff(Pts, A=1., DR=1., DZ=1.): ->>> R = np.hypot(Pts[0,:],Pts[1,:]) ->>> Z = Pts[2,:] ->>> Emiss = A*np.exp(-(R-2.)**2/DR**2 - (Z-0.)**2/DZ**2) ->>> return Emiss - -What will happen when we feed ff to :meth:`~tofu.geom.GDetect.calc_Sig()` depends on the choice of method for the integration: - * If we want a volumic integration, the VOS of each detector will be discretized and ff will be called to evaluate the emissivity at each point before perfoming the integration - * If a Line Of Sight integration is desired, only the LOS is discretized for integration and the result is multiplied by the etendue - -By default, the method uses a pre-computed discretization of the VOS (because re-computing the solid angle for each point every time is costly), but this feature can be suppressed by setting PreComp=False if you want to use customized integration parameters. -For example, in both cases, the numerical integration can be done by choosing the resolution of the discretization, or by using an iterative algorithm that only stops when the required relative error on the integral value is reached. -In our case: - ->>> # Compute synthetic signal using a volume approach with resolution-fixed numerical integration method ->>> sigVOS, ldet = gd.calc_Sig(ff, extargs={'A':1.,'DR':1.,'DZ':1.}, Method='Vol', Mode='simps', PreComp=False) ->>> sigLOS, ldet = gd.calc_Sig(ff, extargs={'A':1.}, Method='LOS', Mode='quad', PreComp=False) ->>> print sigVOS, sigLOS -[[ 1.31675917e-06 1.40620027e-06]] [[ 1.31408026e-06 1.39941326e-06]] - -Notice that when using the 'quad' numerical integration method, only one extra argument can be passed on to ff. -Notice the small differences in the volume and LOS approaches, due to the small non-zero second derivative of the emissivity field and to boundary effects (where there is small partial obstruction of the VOS). - - -If your code gives a tabulated emissivity field ------------------------------------------------ - -Then you simply have to include an intermediate function that interpolates your emissivity field to compute it at any point. Like in the following example: - ->>> def ff(Pts): ->>> R = np.hypot(Pts[0,:],Pts[1,:]) ->>> Z = Pts[2,:] ->>> Emiss = ff_interp(R,Z) ->>> return Emiss - -Where ff_interp() is an interpolating function using tabulated output from your code. - -Plotting the result -------------------- - -The :meth:`~tofu.geom.GDetect.plot_Sig()` method provides a way of plotting the result, either by feeding it the output signal of :meth:`~tofu.geom.GDetect.calc_Sig()` or directly **ff** (in which case it simply calls :meth:`~tofu.geom.GDetect.plot_Sig()` for you). -This feature is only available for :class:`~tofu.geom.GDetect` objects since the signal of a single detector is just a single value that does not really require plotting... - - - -Indices and tables ------------------- -* Homepage_ -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - -.. _Homepage: index.html - diff --git a/doc/build/html/_sources/Tutorial_ITER.txt b/doc/build/html/_sources/Tutorial_ITER.txt deleted file mode 100644 index 35807a420..000000000 --- a/doc/build/html/_sources/Tutorial_ITER.txt +++ /dev/null @@ -1,53 +0,0 @@ -.. role:: envvar(literal) -.. role:: command(literal) -.. role:: file(literal) -.. role:: ref(title-reference) - -ITER-specific tutorial -====================== - -How to access the ToFu library ------------------------------- - -The plugin for ITER is hosted on the theory (Tok) clusters of the Max-Planck Institute for Plasma Physics (IPP) in Garching. -If you have an account in IPP, you can then connect to one of the tok clusters where the library is hosted, via the command: - ->>> ssh toki01 - -Enter your password and then you need to load the module in the terminal - ->>> module load tofu - -You may need to load other modules on which ToFu depends (see the dependencies_). - -.. _dependencies : Dependencies.html - -You can then start a ipython console and load the AUG plugin for ToFu: - ->>> import tofu.plugins.ITER as tfITER - - -How to load existing geometry ------------------------------- - -You can now load the geometry that was already computed and stored for some diagnostics (only the Soft X-Ray diagnostic at this date). -In general loading the geometry means using a method of the plugin that will load and return a list of :class:`tofu.geom.GDetect` instances. -On AUG, each :class:`tofu.geom.GDetect` instance corresponds to a camera head. -Since the geometry (position, aperture size...) of each camera head may change in time (changes are sometimes implemented between experimental campaigns), you can specify a shot number and the plugin will return the latest geometry that was computed before that shot number (only a few have been computed so far, but more will come). - ->>> LGD = tfAUG.SXR.geom.load(shot=31801) - -This command returns a list of :class:`tofu.geom.GDetect` instances with the latest geometry computed before shot 31801. - - - - -Indices and tables ------------------- -* Homepage_ -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - -.. _Homepage: index.html - diff --git a/doc/build/html/_sources/Versions.txt b/doc/build/html/_sources/Versions.txt deleted file mode 100644 index 65b56bd46..000000000 --- a/doc/build/html/_sources/Versions.txt +++ /dev/null @@ -1,36 +0,0 @@ -.. role:: envvar(literal) -.. role:: command(literal) -.. role:: file(literal) -.. role:: ref(title-reference) - -Versions of ToFu: -================= - -Many versions of ToFu have been developped before reaching a stable and somewhat satisfactory state. Several versions were already used for producing physcis results and tomographic inversions before the open-source release, which requires documentation and a certain degree of user-friendlyness, thus more work. - -The versioning convention used by ToFu is semantic_ versioning and the module metadata is implemented according to PEP426_. - -.. _semantic: http://semver.org/ -.. _PEP426: https://www.python.org/dev/peps/pep-0426/ - - -The following only lists the versions advanced enough for release: - -* **1.1.0** (default) - This is the first version released in open-source, it only includes the geometry module (for diagnostic designing and synthetic diagnostic) and the pre-treatment module (for data handling) - - - - - - - -Indices and tables ------------------- -* Homepage_ -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - -.. _Homepage: index.html - diff --git a/doc/build/html/_sources/index.txt b/doc/build/html/_sources/index.txt deleted file mode 100644 index bfe6d8fc3..000000000 --- a/doc/build/html/_sources/index.txt +++ /dev/null @@ -1,113 +0,0 @@ -.. tofu_doc documentation master file, created by - sphinx-quickstart on Tue Jul 26 17:00:43 2016. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Welcome to tofu's documentation! -================================ - -**ToFu** (TOmography for FUsion) is an open-source python library first created at the Max-Planck Institute for Plasma Physics (IPP) in Garching (Germany) by Didier Vezinet (as a postdoc) through the years 2014-2016. -It is continuously maintained, debugged and upgraded to this day. - -It aims at providing the fusion and plasma community with an object-oriented, transparent and documented tool for designing tomography diagnostics, computing synthetic signal (direct problem) as well as tomographic inversions (inverse problem). -It gives access to a full 3D description of the diagnostic geometry, thus reducing the impact of geometrical approximations on the direct and, most importantly, on the inverse problem. - -It is modular and generic in the sense that it was developed with the objective of being machine-independent, thus guaranteeing that it can be used for arbitrary geometries and with an arbitrary number of apertures for each detector. - - -**Open-source:** - ToFu is distributed under the very permissive MIT_ license, thus allowing free use, keeping in mind that neither the author nor any of the laboratories in which he worked can be held responsible for unwanted behaviour or results. - It is instead transparency, reproducibility and incremental improvements that guarantee quality on the long-term. - - ToFu is hosted on github_. - -.. _MIT: https://opensource.org/licenses/MIT -.. _github: https://github.com/ - -**Versions:** - A list of the successive versions of ToFu, with a brief description can be found here_. - -.. _here: Versions.html - -**Dependences:** - ToFu uses the following python packages_. - -.. _packages: Dependencies.html - - -**Citing ToFu:** - If you decide to use ToFu for research and published results please acknowledge this work by citing_ the project. - -.. _citing: Citation.html - -**Feedback - bug report - wish list** - To provide feedback on ToFu itself please use the github_ page. -.. _github: https://github.com/ - -To provide feedback on a specific plugin, please refer to that plugin's webpage where a contact will be indicated. - - -**Miscellaneous** - ToFu is tested with the nose_/1.3.4 library (not all methods are tested yet, in process...) - ToFu can be installed using the distutils_ library. -.. _nose: https://pypi.python.org/pypi/nose -.. _distutils: https://docs.python.org/2/distutils/ - - -Contents: ---------- - -**Description of the library structure:** - -.. toctree:: - :maxdepth: 1 - - overview - -**Code documentation:** - -Notice that the main ToFu classes and methods have docstrings so you can access contextual help with the usual python syntax from a iython console (print .__doc__, or ?). - -.. toctree:: - :maxdepth: 2 - :numbered: - :titlesonly: - - Auto_tofu.geom - Auto_tofu.treat - Auto_tofu.pathfile - Auto_tofu.plugins - -**Tutorials and how to's:** - * How to create / handle a diagnostic geometry - - Visit the basic_ tutorial for getting started: create, plot and save a vessel, apertures and detectors and group them - - Check out the complete set of detailed_ tutorials for more info on each of these aspects and on others. - * How to compute integrated signal from 2D or 3D synthetic emissivity - - Visit the tutorial_ for getting started: load an already-existing diagnostic geometry in a synthetic diagnostic approach to solve the direct problem and compute the line Of Sight and / or Volume of Sight integrated signals from a simulated emissivity field that you provide as an input. - * How to compute tomographic inversions (to do) - Use existing diagnostic geometry and signals to solve the inverse problem and compute tomographic inversions using a choice of discretization basis functions and regularisation functionals. - * How to contribute (todos_) - -.. _basic: Tutorial_Geom_HowToCreateGeometry.html -.. _detailed: Tutorial_Geom_Advanced.html -.. _tutorial: Tutorial_Geom_SynthDiag_Basic.html -.. _todos: Todos.html - - -**Plugin-specific tutorials:** - * AUG_ : load the existing geometry, load data - * ITER_ : load existing geometry... - -.. _AUG : Tutorial_AUG.html -.. _ITER : Tutorial_ITER.html - - -Indices and tables -================== -* Homepage_ -* :ref:`genindex` -* :ref:`modindex` -* :ref:`search` - -.. _Homepage: index.html - diff --git a/doc/build/html/_sources/overview.txt b/doc/build/html/_sources/overview.txt deleted file mode 100644 index 9b56cb6e4..000000000 --- a/doc/build/html/_sources/overview.txt +++ /dev/null @@ -1,86 +0,0 @@ -.. role:: envvar(literal) -.. role:: command(literal) -.. role:: file(literal) -.. role:: ref(title-reference) -.. _overview: - -**Overview** -============ - -(This project is not finalised yet, work in progress...) - - -**ToFu**, which stands for "TOmography for FUsion" is a python package (with parts in C/C++) providing all necessary tools for tomography diagnostics for the Fusion community, it is particularly relevant for X-ray and bolometer diagnostics on Tokamaks. On of the objectoves is to provide a common tool for tomographic inversions, with both accurate methods and enough flexibility to be easily adapted to any Tokamak and to the specific requirements of each user. The main language (Python) has been chosen for its open-source philosophy, for its object-oriented capacities, and for the good performance / flexibility ratio that it offers. The architecture of the **ToFu** package is intended to be modular to allow again for maximum flexibility and to facilitate customisation and evolutivity from the users. - -**ToFu**: provides in particular, but not only, the main following functionnalities : - - Using the 3D geometry of the diagnostic (positions of detectors and apertures are provided as inputs) to compute quantities of interest (e.g.: the optimal line of sight, the exact etendue..). This is done by the module ToFu_Geom. - - Building of a variable grid size mesh for spatial discretisation of the solution (i.e. emissivity field) on which B-splines of any degree can be added to serve as Local Basis Functions. This is done by the module ToFu_Mesh. - - Computing of the geometry matrix associated to a set of detectors and a set of basis functions, both with a full 3D approach or with a Line Of Sight (LOS) approximation. This is done by the module ToFu_MatComp, which uses both ToFu_Geom and ToFu_Mesh. - - Computing tomographic inversions based on the constructed geometry matrix and Phillips-Tikhonov inversion with a choice of objective functionals (among which first order and second order derivatives or Fisher information, and more to come). This is done by the module ToFu_Inv, which uses the matrix computed by ToFu_MatComp. - - Visualizing, exploring and interpreting the resulting inversions using a built-in Graphic User Interface. - -The joint use of a full 3D approach and of regular basis functions (B-splines) allows for advanced functionalities and flexibility, like in particular : - - Accurate computation of etendue and geometry matrix. - - Exact differential operators (provided sufficient degree of the basis function) instead of discretised operators (this feature and the previous one aim at improving the accuracy of tomographic inversions). - - Accurate description of toroidal-viewing detectors with potentially large viewing cones and for which the LOS approximation cannot be used. - - Making possible 3D inversions (provided the geometrical coverage of the plasma volume is sufficient, for example thanks to toroidal-viewing detectors). - - Enabling proper taking into acccount of anisotropic radiation (for example due to fast electrons due to disruptions). - -The **ToFu** package has built-in mesh and B-spline definitions, however, if used alone, it can only create and handle rectangular mesh (with variable grid size though). In order to allow for more optimised mesh and basis functions, the **ToFu** package is fully compatible with **Pigasus** (and **CAID**), which is a another Python package (with a Fortran core), which uses cutting-edge technologies from Computer-Assisted Design (CAD) to create optimised mesh (using Non-Unifrom - Rational B-Splines, or NURBS, curves) on which it can also add several different types of regular basis functions. It is a next-gen solution for optimisation of plasma-physics simulation codes. Hence, the final idea is that the same mesh and tools can be used for running CPU-expensive plasma physics simulations and, from their output, to compute the associated simulated measurements on any radiation diagnostics. This synthetic diagnostic approach is aimed at facilitating direct - comparisons between simulations and experimental measurements and at providing the community with flexible and cross-compatible tools to fit their needs. Plasma physics codes that are planning on using **Pigasus** in a near future include in particuler **JOREK** (in its **Django** version) and **GYSELA** (**SELALIB** in its next version). More information about **Pigasus** (lien), **JOREK** (lien) and **GYSELA** can be found on their respective pages. - -In order to avoid too much dependency issues, the **ToFu** package resorts to widely used Python libraries like scipy, numpy and matplotlib. Whenever it was possible, the idea was either to use a very common and accessible library or to have built-in methods doing the job. It can be run as a stand-alone on an offline computer (i.e.: on a laptop while travelling), in an online mode (using a central database on the internet) and with or without **Pigasus** (keeping in mind that only rectangular mesh can be created without it). - -For faster computation, some modules and/or methods are coded with Cython or Boost.Pyton. It is also intended to be MPI and OpenMP parallelized. - -The general architecture is briefly represented in the following figure: - -.. figure:: /figures_doc/Fig_Tutor_BigPicture_General.png - :height: 700px - :width: 1000px - :scale: 100 % - :alt: ToFu big picture - :align: center - - Modular architecture of ToFu, with its main modules. - -This general overview shows all the **ToFu** modules and their main functionnalities and dependancies. Particularly important are the modules **ToFu_Geom**, **ToFu_Mesh** and **ToFu_MatComp** which provide all necessary tools to pre-calculate the geometry matrix which is a key feature of the two main uses of **ToFu**. - -On the one hand, **ToFu** can be used as a synthetic diagnostic since from a simulated emissivity field it can compute the corresponding synthetic measurements for comparison with experimental measurements. This, as illustrated below, can be done in different ways depending on whether the simualted is used directly as a function, projected on a predefined mesh of the plasma volume, or if the simulated emissivity itself was computed on a mesh using the **Pigasus/CAID** code suite which is directly compatible with **ToFu**. These three possibilities are illustrated in the following figure: - -.. figure:: /figures_doc/Fig_Tutor_BigPicture_SynthDiag.png - :height: 700px - :width: 1000px - :scale: 100 % - :alt: ToFu big picture for synthetic diagnostics - :align: center - - Modular architecture of ToFu, with its main modules for synthetic diagnostics. - -On the other hand, **ToFu** can be used the other way around : use the experimental measurements to compute a reconstructed experimental emissivity field via a tomographic inversion, for comparisopn with a simulated emissivity field or simply for getting an idea of what the emissivity field looks like, which is illustrated in the following figure: - -.. figure:: /figures_doc/Fig_Tutor_BigPicture_Tomo.png - :height: 700px - :width: 1000px - :scale: 100 % - :alt: ToFu big picture for tomography - :align: center - - Modular architecture of ToFu, with its main modules for tomography. - -The following will go into further details regarding each module. - - -ToDo list: - - Rest of documentation, with relevant references (like :cite:Ingesson08FST) and figures - - Tutorial - - ToFu_Inv - - GUI (one for each module) - - Accelerate existing modules with Cython, Boost.Python + Parallelization - - Use it to do some physics at last !!! - - -.. Local Variables: -.. mode: rst -.. End: diff --git a/doc/build/html/_static/ajax-loader.gif b/doc/build/html/_static/ajax-loader.gif deleted file mode 100644 index 61faf8cab..000000000 Binary files a/doc/build/html/_static/ajax-loader.gif and /dev/null differ diff --git a/doc/build/html/_static/basic.css b/doc/build/html/_static/basic.css deleted file mode 100644 index 2b513f0c9..000000000 --- a/doc/build/html/_static/basic.css +++ /dev/null @@ -1,604 +0,0 @@ -/* - * basic.css - * ~~~~~~~~~ - * - * Sphinx stylesheet -- basic theme. - * - * :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -/* -- main layout ----------------------------------------------------------- */ - -div.clearer { - clear: both; -} - -/* -- relbar ---------------------------------------------------------------- */ - -div.related { - width: 100%; - font-size: 90%; -} - -div.related h3 { - display: none; -} - -div.related ul { - margin: 0; - padding: 0 0 0 10px; - list-style: none; -} - -div.related li { - display: inline; -} - -div.related li.right { - float: right; - margin-right: 5px; -} - -/* -- sidebar --------------------------------------------------------------- */ - -div.sphinxsidebarwrapper { - padding: 10px 5px 0 10px; -} - -div.sphinxsidebar { - float: left; - width: 230px; - margin-left: -100%; - font-size: 90%; - word-wrap: break-word; - overflow-wrap : break-word; -} - -div.sphinxsidebar ul { - list-style: none; -} - -div.sphinxsidebar ul ul, -div.sphinxsidebar ul.want-points { - margin-left: 20px; - list-style: square; -} - -div.sphinxsidebar ul ul { - margin-top: 0; - margin-bottom: 0; -} - -div.sphinxsidebar form { - margin-top: 10px; -} - -div.sphinxsidebar input { - border: 1px solid #98dbcc; - font-family: sans-serif; - font-size: 1em; -} - -div.sphinxsidebar #searchbox input[type="text"] { - width: 170px; -} - -img { - border: 0; - max-width: 100%; -} - -/* -- search page ----------------------------------------------------------- */ - -ul.search { - margin: 10px 0 0 20px; - padding: 0; -} - -ul.search li { - padding: 5px 0 5px 20px; - background-image: url(file.png); - background-repeat: no-repeat; - background-position: 0 7px; -} - -ul.search li a { - font-weight: bold; -} - -ul.search li div.context { - color: #888; - margin: 2px 0 0 30px; - text-align: left; -} - -ul.keywordmatches li.goodmatch a { - font-weight: bold; -} - -/* -- index page ------------------------------------------------------------ */ - -table.contentstable { - width: 90%; -} - -table.contentstable p.biglink { - line-height: 150%; -} - -a.biglink { - font-size: 1.3em; -} - -span.linkdescr { - font-style: italic; - padding-top: 5px; - font-size: 90%; -} - -/* -- general index --------------------------------------------------------- */ - -table.indextable { - width: 100%; -} - -table.indextable td { - text-align: left; - vertical-align: top; -} - -table.indextable dl, table.indextable dd { - margin-top: 0; - margin-bottom: 0; -} - -table.indextable tr.pcap { - height: 10px; -} - -table.indextable tr.cap { - margin-top: 10px; - background-color: #f2f2f2; -} - -img.toggler { - margin-right: 3px; - margin-top: 3px; - cursor: pointer; -} - -div.modindex-jumpbox { - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - margin: 1em 0 1em 0; - padding: 0.4em; -} - -div.genindex-jumpbox { - border-top: 1px solid #ddd; - border-bottom: 1px solid #ddd; - margin: 1em 0 1em 0; - padding: 0.4em; -} - -/* -- general body styles --------------------------------------------------- */ - -div.body p, div.body dd, div.body li, div.body blockquote { - -moz-hyphens: auto; - -ms-hyphens: auto; - -webkit-hyphens: auto; - hyphens: auto; -} - -a.headerlink { - visibility: hidden; -} - -h1:hover > a.headerlink, -h2:hover > a.headerlink, -h3:hover > a.headerlink, -h4:hover > a.headerlink, -h5:hover > a.headerlink, -h6:hover > a.headerlink, -dt:hover > a.headerlink, -caption:hover > a.headerlink, -p.caption:hover > a.headerlink, -div.code-block-caption:hover > a.headerlink { - visibility: visible; -} - -div.body p.caption { - text-align: inherit; -} - -div.body td { - text-align: left; -} - -.field-list ul { - padding-left: 1em; -} - -.first { - margin-top: 0 !important; -} - -p.rubric { - margin-top: 30px; - font-weight: bold; -} - -img.align-left, .figure.align-left, object.align-left { - clear: left; - float: left; - margin-right: 1em; -} - -img.align-right, .figure.align-right, object.align-right { - clear: right; - float: right; - margin-left: 1em; -} - -img.align-center, .figure.align-center, object.align-center { - display: block; - margin-left: auto; - margin-right: auto; -} - -.align-left { - text-align: left; -} - -.align-center { - text-align: center; -} - -.align-right { - text-align: right; -} - -/* -- sidebars -------------------------------------------------------------- */ - -div.sidebar { - margin: 0 0 0.5em 1em; - border: 1px solid #ddb; - padding: 7px 7px 0 7px; - background-color: #ffe; - width: 40%; - float: right; -} - -p.sidebar-title { - font-weight: bold; -} - -/* -- topics ---------------------------------------------------------------- */ - -div.topic { - border: 1px solid #ccc; - padding: 7px 7px 0 7px; - margin: 10px 0 10px 0; -} - -p.topic-title { - font-size: 1.1em; - font-weight: bold; - margin-top: 10px; -} - -/* -- admonitions ----------------------------------------------------------- */ - -div.admonition { - margin-top: 10px; - margin-bottom: 10px; - padding: 7px; -} - -div.admonition dt { - font-weight: bold; -} - -div.admonition dl { - margin-bottom: 0; -} - -p.admonition-title { - margin: 0px 10px 5px 0px; - font-weight: bold; -} - -div.body p.centered { - text-align: center; - margin-top: 25px; -} - -/* -- tables ---------------------------------------------------------------- */ - -table.docutils { - border: 0; - border-collapse: collapse; -} - -table caption span.caption-number { - font-style: italic; -} - -table caption span.caption-text { -} - -table.docutils td, table.docutils th { - padding: 1px 8px 1px 5px; - border-top: 0; - border-left: 0; - border-right: 0; - border-bottom: 1px solid #aaa; -} - -table.field-list td, table.field-list th { - border: 0 !important; -} - -table.footnote td, table.footnote th { - border: 0 !important; -} - -th { - text-align: left; - padding-right: 5px; -} - -table.citation { - border-left: solid 1px gray; - margin-left: 1px; -} - -table.citation td { - border-bottom: none; -} - -/* -- figures --------------------------------------------------------------- */ - -div.figure { - margin: 0.5em; - padding: 0.5em; -} - -div.figure p.caption { - padding: 0.3em; -} - -div.figure p.caption span.caption-number { - font-style: italic; -} - -div.figure p.caption span.caption-text { -} - - -/* -- other body styles ----------------------------------------------------- */ - -ol.arabic { - list-style: decimal; -} - -ol.loweralpha { - list-style: lower-alpha; -} - -ol.upperalpha { - list-style: upper-alpha; -} - -ol.lowerroman { - list-style: lower-roman; -} - -ol.upperroman { - list-style: upper-roman; -} - -dl { - margin-bottom: 15px; -} - -dd p { - margin-top: 0px; -} - -dd ul, dd table { - margin-bottom: 10px; -} - -dd { - margin-top: 3px; - margin-bottom: 10px; - margin-left: 30px; -} - -dt:target, .highlighted { - background-color: #fbe54e; -} - -dl.glossary dt { - font-weight: bold; - font-size: 1.1em; -} - -.field-list ul { - margin: 0; - padding-left: 1em; -} - -.field-list p { - margin: 0; -} - -.optional { - font-size: 1.3em; -} - -.sig-paren { - font-size: larger; -} - -.versionmodified { - font-style: italic; -} - -.system-message { - background-color: #fda; - padding: 5px; - border: 3px solid red; -} - -.footnote:target { - background-color: #ffa; -} - -.line-block { - display: block; - margin-top: 1em; - margin-bottom: 1em; -} - -.line-block .line-block { - margin-top: 0; - margin-bottom: 0; - margin-left: 1.5em; -} - -.guilabel, .menuselection { - font-family: sans-serif; -} - -.accelerator { - text-decoration: underline; -} - -.classifier { - font-style: oblique; -} - -abbr, acronym { - border-bottom: dotted 1px; - cursor: help; -} - -/* -- code displays --------------------------------------------------------- */ - -pre { - overflow: auto; - overflow-y: hidden; /* fixes display issues on Chrome browsers */ -} - -td.linenos pre { - padding: 5px 0px; - border: 0; - background-color: transparent; - color: #aaa; -} - -table.highlighttable { - margin-left: 0.5em; -} - -table.highlighttable td { - padding: 0 0.5em 0 0.5em; -} - -div.code-block-caption { - padding: 2px 5px; - font-size: small; -} - -div.code-block-caption code { - background-color: transparent; -} - -div.code-block-caption + div > div.highlight > pre { - margin-top: 0; -} - -div.code-block-caption span.caption-number { - padding: 0.1em 0.3em; - font-style: italic; -} - -div.code-block-caption span.caption-text { -} - -div.literal-block-wrapper { - padding: 1em 1em 0; -} - -div.literal-block-wrapper div.highlight { - margin: 0; -} - -code.descname { - background-color: transparent; - font-weight: bold; - font-size: 1.2em; -} - -code.descclassname { - background-color: transparent; -} - -code.xref, a code { - background-color: transparent; - font-weight: bold; -} - -h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { - background-color: transparent; -} - -.viewcode-link { - float: right; -} - -.viewcode-back { - float: right; - font-family: sans-serif; -} - -div.viewcode-block:target { - margin: -1px -10px; - padding: 0 10px; -} - -/* -- math display ---------------------------------------------------------- */ - -img.math { - vertical-align: middle; -} - -div.body div.math p { - text-align: center; -} - -span.eqno { - float: right; -} - -/* -- printout stylesheet --------------------------------------------------- */ - -@media print { - div.document, - div.documentwrapper, - div.bodywrapper { - margin: 0 !important; - width: 100%; - } - - div.sphinxsidebar, - div.related, - div.footer, - #top-link { - display: none; - } -} \ No newline at end of file diff --git a/doc/build/html/_static/classic.css b/doc/build/html/_static/classic.css deleted file mode 100644 index d98894b3f..000000000 --- a/doc/build/html/_static/classic.css +++ /dev/null @@ -1,261 +0,0 @@ -/* - * default.css_t - * ~~~~~~~~~~~~~ - * - * Sphinx stylesheet -- default theme. - * - * :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -@import url("basic.css"); - -/* -- page layout ----------------------------------------------------------- */ - -body { - font-family: sans-serif; - font-size: 100%; - background-color: #11303d; - color: #000; - margin: 0; - padding: 0; -} - -div.document { - background-color: #1c4e63; -} - -div.documentwrapper { - float: left; - width: 100%; -} - -div.bodywrapper { - margin: 0 0 0 230px; -} - -div.body { - background-color: #ffffff; - color: #000000; - padding: 0 20px 30px 20px; -} - -div.footer { - color: #ffffff; - width: 100%; - padding: 9px 0 9px 0; - text-align: center; - font-size: 75%; -} - -div.footer a { - color: #ffffff; - text-decoration: underline; -} - -div.related { - background-color: #133f52; - line-height: 30px; - color: #ffffff; -} - -div.related a { - color: #ffffff; -} - -div.sphinxsidebar { -} - -div.sphinxsidebar h3 { - font-family: 'Trebuchet MS', sans-serif; - color: #ffffff; - font-size: 1.4em; - font-weight: normal; - margin: 0; - padding: 0; -} - -div.sphinxsidebar h3 a { - color: #ffffff; -} - -div.sphinxsidebar h4 { - font-family: 'Trebuchet MS', sans-serif; - color: #ffffff; - font-size: 1.3em; - font-weight: normal; - margin: 5px 0 0 0; - padding: 0; -} - -div.sphinxsidebar p { - color: #ffffff; -} - -div.sphinxsidebar p.topless { - margin: 5px 10px 10px 10px; -} - -div.sphinxsidebar ul { - margin: 10px; - padding: 0; - color: #ffffff; -} - -div.sphinxsidebar a { - color: #98dbcc; -} - -div.sphinxsidebar input { - border: 1px solid #98dbcc; - font-family: sans-serif; - font-size: 1em; -} - - - -/* -- hyperlink styles ------------------------------------------------------ */ - -a { - color: #355f7c; - text-decoration: none; -} - -a:visited { - color: #355f7c; - text-decoration: none; -} - -a:hover { - text-decoration: underline; -} - - - -/* -- body styles ----------------------------------------------------------- */ - -div.body h1, -div.body h2, -div.body h3, -div.body h4, -div.body h5, -div.body h6 { - font-family: 'Trebuchet MS', sans-serif; - background-color: #f2f2f2; - font-weight: normal; - color: #20435c; - border-bottom: 1px solid #ccc; - margin: 20px -20px 10px -20px; - padding: 3px 0 3px 10px; -} - -div.body h1 { margin-top: 0; font-size: 200%; } -div.body h2 { font-size: 160%; } -div.body h3 { font-size: 140%; } -div.body h4 { font-size: 120%; } -div.body h5 { font-size: 110%; } -div.body h6 { font-size: 100%; } - -a.headerlink { - color: #c60f0f; - font-size: 0.8em; - padding: 0 4px 0 4px; - text-decoration: none; -} - -a.headerlink:hover { - background-color: #c60f0f; - color: white; -} - -div.body p, div.body dd, div.body li, div.body blockquote { - text-align: justify; - line-height: 130%; -} - -div.admonition p.admonition-title + p { - display: inline; -} - -div.admonition p { - margin-bottom: 5px; -} - -div.admonition pre { - margin-bottom: 5px; -} - -div.admonition ul, div.admonition ol { - margin-bottom: 5px; -} - -div.note { - background-color: #eee; - border: 1px solid #ccc; -} - -div.seealso { - background-color: #ffc; - border: 1px solid #ff6; -} - -div.topic { - background-color: #eee; -} - -div.warning { - background-color: #ffe4e4; - border: 1px solid #f66; -} - -p.admonition-title { - display: inline; -} - -p.admonition-title:after { - content: ":"; -} - -pre { - padding: 5px; - background-color: #eeffcc; - color: #333333; - line-height: 120%; - border: 1px solid #ac9; - border-left: none; - border-right: none; -} - -code { - background-color: #ecf0f3; - padding: 0 1px 0 1px; - font-size: 0.95em; -} - -th { - background-color: #ede; -} - -.warning code { - background: #efc2c2; -} - -.note code { - background: #d6d6d6; -} - -.viewcode-back { - font-family: sans-serif; -} - -div.viewcode-block:target { - background-color: #f4debf; - border-top: 1px solid #ac9; - border-bottom: 1px solid #ac9; -} - -div.code-block-caption { - color: #efefef; - background-color: #1c4e63; -} \ No newline at end of file diff --git a/doc/build/html/_static/comment-bright.png b/doc/build/html/_static/comment-bright.png deleted file mode 100644 index 551517b8c..000000000 Binary files a/doc/build/html/_static/comment-bright.png and /dev/null differ diff --git a/doc/build/html/_static/comment-close.png b/doc/build/html/_static/comment-close.png deleted file mode 100644 index 09b54be46..000000000 Binary files a/doc/build/html/_static/comment-close.png and /dev/null differ diff --git a/doc/build/html/_static/comment.png b/doc/build/html/_static/comment.png deleted file mode 100644 index 92feb52b8..000000000 Binary files a/doc/build/html/_static/comment.png and /dev/null differ diff --git a/doc/build/html/_static/default.css b/doc/build/html/_static/default.css deleted file mode 100644 index 81b936363..000000000 --- a/doc/build/html/_static/default.css +++ /dev/null @@ -1 +0,0 @@ -@import url("classic.css"); diff --git a/doc/build/html/_static/doctools.js b/doc/build/html/_static/doctools.js deleted file mode 100644 index 816349563..000000000 --- a/doc/build/html/_static/doctools.js +++ /dev/null @@ -1,287 +0,0 @@ -/* - * doctools.js - * ~~~~~~~~~~~ - * - * Sphinx JavaScript utilities for all documentation. - * - * :copyright: Copyright 2007-2016 by the Sphinx team, see AUTHORS. - * :license: BSD, see LICENSE for details. - * - */ - -/** - * select a different prefix for underscore - */ -$u = _.noConflict(); - -/** - * make the code below compatible with browsers without - * an installed firebug like debugger -if (!window.console || !console.firebug) { - var names = ["log", "debug", "info", "warn", "error", "assert", "dir", - "dirxml", "group", "groupEnd", "time", "timeEnd", "count", "trace", - "profile", "profileEnd"]; - window.console = {}; - for (var i = 0; i < names.length; ++i) - window.console[names[i]] = function() {}; -} - */ - -/** - * small helper function to urldecode strings - */ -jQuery.urldecode = function(x) { - return decodeURIComponent(x).replace(/\+/g, ' '); -}; - -/** - * small helper function to urlencode strings - */ -jQuery.urlencode = encodeURIComponent; - -/** - * This function returns the parsed url parameters of the - * current request. Multiple values per key are supported, - * it will always return arrays of strings for the value parts. - */ -jQuery.getQueryParameters = function(s) { - if (typeof s == 'undefined') - s = document.location.search; - var parts = s.substr(s.indexOf('?') + 1).split('&'); - var result = {}; - for (var i = 0; i < parts.length; i++) { - var tmp = parts[i].split('=', 2); - var key = jQuery.urldecode(tmp[0]); - var value = jQuery.urldecode(tmp[1]); - if (key in result) - result[key].push(value); - else - result[key] = [value]; - } - return result; -}; - -/** - * highlight a given string on a jquery object by wrapping it in - * span elements with the given class name. - */ -jQuery.fn.highlightText = function(text, className) { - function highlight(node) { - if (node.nodeType == 3) { - var val = node.nodeValue; - var pos = val.toLowerCase().indexOf(text); - if (pos >= 0 && !jQuery(node.parentNode).hasClass(className)) { - var span = document.createElement("span"); - span.className = className; - span.appendChild(document.createTextNode(val.substr(pos, text.length))); - node.parentNode.insertBefore(span, node.parentNode.insertBefore( - document.createTextNode(val.substr(pos + text.length)), - node.nextSibling)); - node.nodeValue = val.substr(0, pos); - } - } - else if (!jQuery(node).is("button, select, textarea")) { - jQuery.each(node.childNodes, function() { - highlight(this); - }); - } - } - return this.each(function() { - highlight(this); - }); -}; - -/* - * backward compatibility for jQuery.browser - * This will be supported until firefox bug is fixed. - */ -if (!jQuery.browser) { - jQuery.uaMatch = function(ua) { - ua = ua.toLowerCase(); - - var match = /(chrome)[ \/]([\w.]+)/.exec(ua) || - /(webkit)[ \/]([\w.]+)/.exec(ua) || - /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) || - /(msie) ([\w.]+)/.exec(ua) || - ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || - []; - - return { - browser: match[ 1 ] || "", - version: match[ 2 ] || "0" - }; - }; - jQuery.browser = {}; - jQuery.browser[jQuery.uaMatch(navigator.userAgent).browser] = true; -} - -/** - * Small JavaScript module for the documentation. - */ -var Documentation = { - - init : function() { - this.fixFirefoxAnchorBug(); - this.highlightSearchWords(); - this.initIndexTable(); - - }, - - /** - * i18n support - */ - TRANSLATIONS : {}, - PLURAL_EXPR : function(n) { return n == 1 ? 0 : 1; }, - LOCALE : 'unknown', - - // gettext and ngettext don't access this so that the functions - // can safely bound to a different name (_ = Documentation.gettext) - gettext : function(string) { - var translated = Documentation.TRANSLATIONS[string]; - if (typeof translated == 'undefined') - return string; - return (typeof translated == 'string') ? translated : translated[0]; - }, - - ngettext : function(singular, plural, n) { - var translated = Documentation.TRANSLATIONS[singular]; - if (typeof translated == 'undefined') - return (n == 1) ? singular : plural; - return translated[Documentation.PLURALEXPR(n)]; - }, - - addTranslations : function(catalog) { - for (var key in catalog.messages) - this.TRANSLATIONS[key] = catalog.messages[key]; - this.PLURAL_EXPR = new Function('n', 'return +(' + catalog.plural_expr + ')'); - this.LOCALE = catalog.locale; - }, - - /** - * add context elements like header anchor links - */ - addContextElements : function() { - $('div[id] > :header:first').each(function() { - $('\u00B6'). - attr('href', '#' + this.id). - attr('title', _('Permalink to this headline')). - appendTo(this); - }); - $('dt[id]').each(function() { - $('\u00B6'). - attr('href', '#' + this.id). - attr('title', _('Permalink to this definition')). - appendTo(this); - }); - }, - - /** - * workaround a firefox stupidity - * see: https://bugzilla.mozilla.org/show_bug.cgi?id=645075 - */ - fixFirefoxAnchorBug : function() { - if (document.location.hash) - window.setTimeout(function() { - document.location.href += ''; - }, 10); - }, - - /** - * highlight the search words provided in the url in the text - */ - highlightSearchWords : function() { - var params = $.getQueryParameters(); - var terms = (params.highlight) ? params.highlight[0].split(/\s+/) : []; - if (terms.length) { - var body = $('div.body'); - if (!body.length) { - body = $('body'); - } - window.setTimeout(function() { - $.each(terms, function() { - body.highlightText(this.toLowerCase(), 'highlighted'); - }); - }, 10); - $('') - .appendTo($('#searchbox')); - } - }, - - /** - * init the domain index toggle buttons - */ - initIndexTable : function() { - var togglers = $('img.toggler').click(function() { - var src = $(this).attr('src'); - var idnum = $(this).attr('id').substr(7); - $('tr.cg-' + idnum).toggle(); - if (src.substr(-9) == 'minus.png') - $(this).attr('src', src.substr(0, src.length-9) + 'plus.png'); - else - $(this).attr('src', src.substr(0, src.length-8) + 'minus.png'); - }).css('display', ''); - if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) { - togglers.click(); - } - }, - - /** - * helper function to hide the search marks again - */ - hideSearchWords : function() { - $('#searchbox .highlight-link').fadeOut(300); - $('span.highlighted').removeClass('highlighted'); - }, - - /** - * make the url absolute - */ - makeURL : function(relativeURL) { - return DOCUMENTATION_OPTIONS.URL_ROOT + '/' + relativeURL; - }, - - /** - * get the current relative url - */ - getCurrentURL : function() { - var path = document.location.pathname; - var parts = path.split(/\//); - $.each(DOCUMENTATION_OPTIONS.URL_ROOT.split(/\//), function() { - if (this == '..') - parts.pop(); - }); - var url = parts.join('/'); - return path.substring(url.lastIndexOf('/') + 1, path.length - 1); - }, - - initOnKeyListeners: function() { - $(document).keyup(function(event) { - var activeElementType = document.activeElement.tagName; - // don't navigate when in search box or textarea - if (activeElementType !== 'TEXTAREA' && activeElementType !== 'INPUT' && activeElementType !== 'SELECT') { - switch (event.keyCode) { - case 37: // left - var prevHref = $('link[rel="prev"]').prop('href'); - if (prevHref) { - window.location.href = prevHref; - return false; - } - case 39: // right - var nextHref = $('link[rel="next"]').prop('href'); - if (nextHref) { - window.location.href = nextHref; - return false; - } - } - } - }); - } -}; - -// quick alias for translations -_ = Documentation.gettext; - -$(document).ready(function() { - Documentation.init(); -}); \ No newline at end of file diff --git a/doc/build/html/_static/down-pressed.png b/doc/build/html/_static/down-pressed.png deleted file mode 100644 index 7c30d004b..000000000 Binary files a/doc/build/html/_static/down-pressed.png and /dev/null differ diff --git a/doc/build/html/_static/down.png b/doc/build/html/_static/down.png deleted file mode 100644 index f48098a43..000000000 Binary files a/doc/build/html/_static/down.png and /dev/null differ diff --git a/doc/build/html/_static/file.png b/doc/build/html/_static/file.png deleted file mode 100644 index 254c60bfb..000000000 Binary files a/doc/build/html/_static/file.png and /dev/null differ diff --git a/doc/build/html/_static/jquery-1.11.1.js b/doc/build/html/_static/jquery-1.11.1.js deleted file mode 100644 index d4b67f7e6..000000000 --- a/doc/build/html/_static/jquery-1.11.1.js +++ /dev/null @@ -1,10308 +0,0 @@ -/*! - * jQuery JavaScript Library v1.11.1 - * http://jquery.com/ - * - * Includes Sizzle.js - * http://sizzlejs.com/ - * - * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2014-05-01T17:42Z - */ - -(function( global, factory ) { - - if ( typeof module === "object" && typeof module.exports === "object" ) { - // For CommonJS and CommonJS-like environments where a proper window is present, - // execute the factory and get jQuery - // For environments that do not inherently posses a window with a document - // (such as Node.js), expose a jQuery-making factory as module.exports - // This accentuates the need for the creation of a real window - // e.g. var jQuery = require("jquery")(window); - // See ticket #14549 for more info - module.exports = global.document ? - factory( global, true ) : - function( w ) { - if ( !w.document ) { - throw new Error( "jQuery requires a window with a document" ); - } - return factory( w ); - }; - } else { - factory( global ); - } - -// Pass this if window is not defined yet -}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { - -// Can't do this because several apps including ASP.NET trace -// the stack via arguments.caller.callee and Firefox dies if -// you try to trace through "use strict" call chains. (#13335) -// Support: Firefox 18+ -// - -var deletedIds = []; - -var slice = deletedIds.slice; - -var concat = deletedIds.concat; - -var push = deletedIds.push; - -var indexOf = deletedIds.indexOf; - -var class2type = {}; - -var toString = class2type.toString; - -var hasOwn = class2type.hasOwnProperty; - -var support = {}; - - - -var - version = "1.11.1", - - // Define a local copy of jQuery - jQuery = function( selector, context ) { - // The jQuery object is actually just the init constructor 'enhanced' - // Need init if jQuery is called (just allow error to be thrown if not included) - return new jQuery.fn.init( selector, context ); - }, - - // Support: Android<4.1, IE<9 - // Make sure we trim BOM and NBSP - rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, - - // Matches dashed string for camelizing - rmsPrefix = /^-ms-/, - rdashAlpha = /-([\da-z])/gi, - - // Used by jQuery.camelCase as callback to replace() - fcamelCase = function( all, letter ) { - return letter.toUpperCase(); - }; - -jQuery.fn = jQuery.prototype = { - // The current version of jQuery being used - jquery: version, - - constructor: jQuery, - - // Start with an empty selector - selector: "", - - // The default length of a jQuery object is 0 - length: 0, - - toArray: function() { - return slice.call( this ); - }, - - // Get the Nth element in the matched element set OR - // Get the whole matched element set as a clean array - get: function( num ) { - return num != null ? - - // Return just the one element from the set - ( num < 0 ? this[ num + this.length ] : this[ num ] ) : - - // Return all the elements in a clean array - slice.call( this ); - }, - - // Take an array of elements and push it onto the stack - // (returning the new matched element set) - pushStack: function( elems ) { - - // Build a new jQuery matched element set - var ret = jQuery.merge( this.constructor(), elems ); - - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - ret.context = this.context; - - // Return the newly-formed element set - return ret; - }, - - // Execute a callback for every element in the matched set. - // (You can seed the arguments with an array of args, but this is - // only used internally.) - each: function( callback, args ) { - return jQuery.each( this, callback, args ); - }, - - map: function( callback ) { - return this.pushStack( jQuery.map(this, function( elem, i ) { - return callback.call( elem, i, elem ); - })); - }, - - slice: function() { - return this.pushStack( slice.apply( this, arguments ) ); - }, - - first: function() { - return this.eq( 0 ); - }, - - last: function() { - return this.eq( -1 ); - }, - - eq: function( i ) { - var len = this.length, - j = +i + ( i < 0 ? len : 0 ); - return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); - }, - - end: function() { - return this.prevObject || this.constructor(null); - }, - - // For internal use only. - // Behaves like an Array's method, not like a jQuery method. - push: push, - sort: deletedIds.sort, - splice: deletedIds.splice -}; - -jQuery.extend = jQuery.fn.extend = function() { - var src, copyIsArray, copy, name, options, clone, - target = arguments[0] || {}, - i = 1, - length = arguments.length, - deep = false; - - // Handle a deep copy situation - if ( typeof target === "boolean" ) { - deep = target; - - // skip the boolean and the target - target = arguments[ i ] || {}; - i++; - } - - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !jQuery.isFunction(target) ) { - target = {}; - } - - // extend jQuery itself if only one argument is passed - if ( i === length ) { - target = this; - i--; - } - - for ( ; i < length; i++ ) { - // Only deal with non-null/undefined values - if ( (options = arguments[ i ]) != null ) { - // Extend the base object - for ( name in options ) { - src = target[ name ]; - copy = options[ name ]; - - // Prevent never-ending loop - if ( target === copy ) { - continue; - } - - // Recurse if we're merging plain objects or arrays - if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { - if ( copyIsArray ) { - copyIsArray = false; - clone = src && jQuery.isArray(src) ? src : []; - - } else { - clone = src && jQuery.isPlainObject(src) ? src : {}; - } - - // Never move original objects, clone them - target[ name ] = jQuery.extend( deep, clone, copy ); - - // Don't bring in undefined values - } else if ( copy !== undefined ) { - target[ name ] = copy; - } - } - } - } - - // Return the modified object - return target; -}; - -jQuery.extend({ - // Unique for each copy of jQuery on the page - expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), - - // Assume jQuery is ready without the ready module - isReady: true, - - error: function( msg ) { - throw new Error( msg ); - }, - - noop: function() {}, - - // See test/unit/core.js for details concerning isFunction. - // Since version 1.3, DOM methods and functions like alert - // aren't supported. They return false on IE (#2968). - isFunction: function( obj ) { - return jQuery.type(obj) === "function"; - }, - - isArray: Array.isArray || function( obj ) { - return jQuery.type(obj) === "array"; - }, - - isWindow: function( obj ) { - /* jshint eqeqeq: false */ - return obj != null && obj == obj.window; - }, - - isNumeric: function( obj ) { - // parseFloat NaNs numeric-cast false positives (null|true|false|"") - // ...but misinterprets leading-number strings, particularly hex literals ("0x...") - // subtraction forces infinities to NaN - return !jQuery.isArray( obj ) && obj - parseFloat( obj ) >= 0; - }, - - isEmptyObject: function( obj ) { - var name; - for ( name in obj ) { - return false; - } - return true; - }, - - isPlainObject: function( obj ) { - var key; - - // Must be an Object. - // Because of IE, we also have to check the presence of the constructor property. - // Make sure that DOM nodes and window objects don't pass through, as well - if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { - return false; - } - - try { - // Not own constructor property must be Object - if ( obj.constructor && - !hasOwn.call(obj, "constructor") && - !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { - return false; - } - } catch ( e ) { - // IE8,9 Will throw exceptions on certain host objects #9897 - return false; - } - - // Support: IE<9 - // Handle iteration over inherited properties before own properties. - if ( support.ownLast ) { - for ( key in obj ) { - return hasOwn.call( obj, key ); - } - } - - // Own properties are enumerated firstly, so to speed up, - // if last one is own, then all properties are own. - for ( key in obj ) {} - - return key === undefined || hasOwn.call( obj, key ); - }, - - type: function( obj ) { - if ( obj == null ) { - return obj + ""; - } - return typeof obj === "object" || typeof obj === "function" ? - class2type[ toString.call(obj) ] || "object" : - typeof obj; - }, - - // Evaluates a script in a global context - // Workarounds based on findings by Jim Driscoll - // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context - globalEval: function( data ) { - if ( data && jQuery.trim( data ) ) { - // We use execScript on Internet Explorer - // We use an anonymous function so that context is window - // rather than jQuery in Firefox - ( window.execScript || function( data ) { - window[ "eval" ].call( window, data ); - } )( data ); - } - }, - - // Convert dashed to camelCase; used by the css and data modules - // Microsoft forgot to hump their vendor prefix (#9572) - camelCase: function( string ) { - return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); - }, - - nodeName: function( elem, name ) { - return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); - }, - - // args is for internal usage only - each: function( obj, callback, args ) { - var value, - i = 0, - length = obj.length, - isArray = isArraylike( obj ); - - if ( args ) { - if ( isArray ) { - for ( ; i < length; i++ ) { - value = callback.apply( obj[ i ], args ); - - if ( value === false ) { - break; - } - } - } else { - for ( i in obj ) { - value = callback.apply( obj[ i ], args ); - - if ( value === false ) { - break; - } - } - } - - // A special, fast, case for the most common use of each - } else { - if ( isArray ) { - for ( ; i < length; i++ ) { - value = callback.call( obj[ i ], i, obj[ i ] ); - - if ( value === false ) { - break; - } - } - } else { - for ( i in obj ) { - value = callback.call( obj[ i ], i, obj[ i ] ); - - if ( value === false ) { - break; - } - } - } - } - - return obj; - }, - - // Support: Android<4.1, IE<9 - trim: function( text ) { - return text == null ? - "" : - ( text + "" ).replace( rtrim, "" ); - }, - - // results is for internal usage only - makeArray: function( arr, results ) { - var ret = results || []; - - if ( arr != null ) { - if ( isArraylike( Object(arr) ) ) { - jQuery.merge( ret, - typeof arr === "string" ? - [ arr ] : arr - ); - } else { - push.call( ret, arr ); - } - } - - return ret; - }, - - inArray: function( elem, arr, i ) { - var len; - - if ( arr ) { - if ( indexOf ) { - return indexOf.call( arr, elem, i ); - } - - len = arr.length; - i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; - - for ( ; i < len; i++ ) { - // Skip accessing in sparse arrays - if ( i in arr && arr[ i ] === elem ) { - return i; - } - } - } - - return -1; - }, - - merge: function( first, second ) { - var len = +second.length, - j = 0, - i = first.length; - - while ( j < len ) { - first[ i++ ] = second[ j++ ]; - } - - // Support: IE<9 - // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists) - if ( len !== len ) { - while ( second[j] !== undefined ) { - first[ i++ ] = second[ j++ ]; - } - } - - first.length = i; - - return first; - }, - - grep: function( elems, callback, invert ) { - var callbackInverse, - matches = [], - i = 0, - length = elems.length, - callbackExpect = !invert; - - // Go through the array, only saving the items - // that pass the validator function - for ( ; i < length; i++ ) { - callbackInverse = !callback( elems[ i ], i ); - if ( callbackInverse !== callbackExpect ) { - matches.push( elems[ i ] ); - } - } - - return matches; - }, - - // arg is for internal usage only - map: function( elems, callback, arg ) { - var value, - i = 0, - length = elems.length, - isArray = isArraylike( elems ), - ret = []; - - // Go through the array, translating each of the items to their new values - if ( isArray ) { - for ( ; i < length; i++ ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret.push( value ); - } - } - - // Go through every key on the object, - } else { - for ( i in elems ) { - value = callback( elems[ i ], i, arg ); - - if ( value != null ) { - ret.push( value ); - } - } - } - - // Flatten any nested arrays - return concat.apply( [], ret ); - }, - - // A global GUID counter for objects - guid: 1, - - // Bind a function to a context, optionally partially applying any - // arguments. - proxy: function( fn, context ) { - var args, proxy, tmp; - - if ( typeof context === "string" ) { - tmp = fn[ context ]; - context = fn; - fn = tmp; - } - - // Quick check to determine if target is callable, in the spec - // this throws a TypeError, but we will just return undefined. - if ( !jQuery.isFunction( fn ) ) { - return undefined; - } - - // Simulated bind - args = slice.call( arguments, 2 ); - proxy = function() { - return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); - }; - - // Set the guid of unique handler to the same of original handler, so it can be removed - proxy.guid = fn.guid = fn.guid || jQuery.guid++; - - return proxy; - }, - - now: function() { - return +( new Date() ); - }, - - // jQuery.support is not used in Core but other projects attach their - // properties to it so it needs to exist. - support: support -}); - -// Populate the class2type map -jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { - class2type[ "[object " + name + "]" ] = name.toLowerCase(); -}); - -function isArraylike( obj ) { - var length = obj.length, - type = jQuery.type( obj ); - - if ( type === "function" || jQuery.isWindow( obj ) ) { - return false; - } - - if ( obj.nodeType === 1 && length ) { - return true; - } - - return type === "array" || length === 0 || - typeof length === "number" && length > 0 && ( length - 1 ) in obj; -} -var Sizzle = -/*! - * Sizzle CSS Selector Engine v1.10.19 - * http://sizzlejs.com/ - * - * Copyright 2013 jQuery Foundation, Inc. and other contributors - * Released under the MIT license - * http://jquery.org/license - * - * Date: 2014-04-18 - */ -(function( window ) { - -var i, - support, - Expr, - getText, - isXML, - tokenize, - compile, - select, - outermostContext, - sortInput, - hasDuplicate, - - // Local document vars - setDocument, - document, - docElem, - documentIsHTML, - rbuggyQSA, - rbuggyMatches, - matches, - contains, - - // Instance-specific data - expando = "sizzle" + -(new Date()), - preferredDoc = window.document, - dirruns = 0, - done = 0, - classCache = createCache(), - tokenCache = createCache(), - compilerCache = createCache(), - sortOrder = function( a, b ) { - if ( a === b ) { - hasDuplicate = true; - } - return 0; - }, - - // General-purpose constants - strundefined = typeof undefined, - MAX_NEGATIVE = 1 << 31, - - // Instance methods - hasOwn = ({}).hasOwnProperty, - arr = [], - pop = arr.pop, - push_native = arr.push, - push = arr.push, - slice = arr.slice, - // Use a stripped-down indexOf if we can't use a native one - indexOf = arr.indexOf || function( elem ) { - var i = 0, - len = this.length; - for ( ; i < len; i++ ) { - if ( this[i] === elem ) { - return i; - } - } - return -1; - }, - - booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", - - // Regular expressions - - // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace - whitespace = "[\\x20\\t\\r\\n\\f]", - // http://www.w3.org/TR/css3-syntax/#characters - characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", - - // Loosely modeled on CSS identifier characters - // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors - // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier - identifier = characterEncoding.replace( "w", "w#" ), - - // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors - attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace + - // Operator (capture 2) - "*([*^$|!~]?=)" + whitespace + - // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" - "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + - "*\\]", - - pseudos = ":(" + characterEncoding + ")(?:\\((" + - // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: - // 1. quoted (capture 3; capture 4 or capture 5) - "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + - // 2. simple (capture 6) - "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + - // 3. anything else (capture 2) - ".*" + - ")\\)|)", - - // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter - rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), - - rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), - rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), - - rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), - - rpseudo = new RegExp( pseudos ), - ridentifier = new RegExp( "^" + identifier + "$" ), - - matchExpr = { - "ID": new RegExp( "^#(" + characterEncoding + ")" ), - "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), - "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), - "ATTR": new RegExp( "^" + attributes ), - "PSEUDO": new RegExp( "^" + pseudos ), - "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + - "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + - "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), - "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), - // For use in libraries implementing .is() - // We use this for POS matching in `select` - "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + - whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) - }, - - rinputs = /^(?:input|select|textarea|button)$/i, - rheader = /^h\d$/i, - - rnative = /^[^{]+\{\s*\[native \w/, - - // Easily-parseable/retrievable ID or TAG or CLASS selectors - rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, - - rsibling = /[+~]/, - rescape = /'|\\/g, - - // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters - runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), - funescape = function( _, escaped, escapedWhitespace ) { - var high = "0x" + escaped - 0x10000; - // NaN means non-codepoint - // Support: Firefox<24 - // Workaround erroneous numeric interpretation of +"0x" - return high !== high || escapedWhitespace ? - escaped : - high < 0 ? - // BMP codepoint - String.fromCharCode( high + 0x10000 ) : - // Supplemental Plane codepoint (surrogate pair) - String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); - }; - -// Optimize for push.apply( _, NodeList ) -try { - push.apply( - (arr = slice.call( preferredDoc.childNodes )), - preferredDoc.childNodes - ); - // Support: Android<4.0 - // Detect silently failing push.apply - arr[ preferredDoc.childNodes.length ].nodeType; -} catch ( e ) { - push = { apply: arr.length ? - - // Leverage slice if possible - function( target, els ) { - push_native.apply( target, slice.call(els) ); - } : - - // Support: IE<9 - // Otherwise append directly - function( target, els ) { - var j = target.length, - i = 0; - // Can't trust NodeList.length - while ( (target[j++] = els[i++]) ) {} - target.length = j - 1; - } - }; -} - -function Sizzle( selector, context, results, seed ) { - var match, elem, m, nodeType, - // QSA vars - i, groups, old, nid, newContext, newSelector; - - if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { - setDocument( context ); - } - - context = context || document; - results = results || []; - - if ( !selector || typeof selector !== "string" ) { - return results; - } - - if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) { - return []; - } - - if ( documentIsHTML && !seed ) { - - // Shortcuts - if ( (match = rquickExpr.exec( selector )) ) { - // Speed-up: Sizzle("#ID") - if ( (m = match[1]) ) { - if ( nodeType === 9 ) { - elem = context.getElementById( m ); - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document (jQuery #6963) - if ( elem && elem.parentNode ) { - // Handle the case where IE, Opera, and Webkit return items - // by name instead of ID - if ( elem.id === m ) { - results.push( elem ); - return results; - } - } else { - return results; - } - } else { - // Context is not a document - if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && - contains( context, elem ) && elem.id === m ) { - results.push( elem ); - return results; - } - } - - // Speed-up: Sizzle("TAG") - } else if ( match[2] ) { - push.apply( results, context.getElementsByTagName( selector ) ); - return results; - - // Speed-up: Sizzle(".CLASS") - } else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) { - push.apply( results, context.getElementsByClassName( m ) ); - return results; - } - } - - // QSA path - if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { - nid = old = expando; - newContext = context; - newSelector = nodeType === 9 && selector; - - // qSA works strangely on Element-rooted queries - // We can work around this by specifying an extra ID on the root - // and working up from there (Thanks to Andrew Dupont for the technique) - // IE 8 doesn't work on object elements - if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { - groups = tokenize( selector ); - - if ( (old = context.getAttribute("id")) ) { - nid = old.replace( rescape, "\\$&" ); - } else { - context.setAttribute( "id", nid ); - } - nid = "[id='" + nid + "'] "; - - i = groups.length; - while ( i-- ) { - groups[i] = nid + toSelector( groups[i] ); - } - newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; - newSelector = groups.join(","); - } - - if ( newSelector ) { - try { - push.apply( results, - newContext.querySelectorAll( newSelector ) - ); - return results; - } catch(qsaError) { - } finally { - if ( !old ) { - context.removeAttribute("id"); - } - } - } - } - } - - // All others - return select( selector.replace( rtrim, "$1" ), context, results, seed ); -} - -/** - * Create key-value caches of limited size - * @returns {Function(string, Object)} Returns the Object data after storing it on itself with - * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) - * deleting the oldest entry - */ -function createCache() { - var keys = []; - - function cache( key, value ) { - // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) - if ( keys.push( key + " " ) > Expr.cacheLength ) { - // Only keep the most recent entries - delete cache[ keys.shift() ]; - } - return (cache[ key + " " ] = value); - } - return cache; -} - -/** - * Mark a function for special use by Sizzle - * @param {Function} fn The function to mark - */ -function markFunction( fn ) { - fn[ expando ] = true; - return fn; -} - -/** - * Support testing using an element - * @param {Function} fn Passed the created div and expects a boolean result - */ -function assert( fn ) { - var div = document.createElement("div"); - - try { - return !!fn( div ); - } catch (e) { - return false; - } finally { - // Remove from its parent by default - if ( div.parentNode ) { - div.parentNode.removeChild( div ); - } - // release memory in IE - div = null; - } -} - -/** - * Adds the same handler for all of the specified attrs - * @param {String} attrs Pipe-separated list of attributes - * @param {Function} handler The method that will be applied - */ -function addHandle( attrs, handler ) { - var arr = attrs.split("|"), - i = attrs.length; - - while ( i-- ) { - Expr.attrHandle[ arr[i] ] = handler; - } -} - -/** - * Checks document order of two siblings - * @param {Element} a - * @param {Element} b - * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b - */ -function siblingCheck( a, b ) { - var cur = b && a, - diff = cur && a.nodeType === 1 && b.nodeType === 1 && - ( ~b.sourceIndex || MAX_NEGATIVE ) - - ( ~a.sourceIndex || MAX_NEGATIVE ); - - // Use IE sourceIndex if available on both nodes - if ( diff ) { - return diff; - } - - // Check if b follows a - if ( cur ) { - while ( (cur = cur.nextSibling) ) { - if ( cur === b ) { - return -1; - } - } - } - - return a ? 1 : -1; -} - -/** - * Returns a function to use in pseudos for input types - * @param {String} type - */ -function createInputPseudo( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === type; - }; -} - -/** - * Returns a function to use in pseudos for buttons - * @param {String} type - */ -function createButtonPseudo( type ) { - return function( elem ) { - var name = elem.nodeName.toLowerCase(); - return (name === "input" || name === "button") && elem.type === type; - }; -} - -/** - * Returns a function to use in pseudos for positionals - * @param {Function} fn - */ -function createPositionalPseudo( fn ) { - return markFunction(function( argument ) { - argument = +argument; - return markFunction(function( seed, matches ) { - var j, - matchIndexes = fn( [], seed.length, argument ), - i = matchIndexes.length; - - // Match elements found at the specified indexes - while ( i-- ) { - if ( seed[ (j = matchIndexes[i]) ] ) { - seed[j] = !(matches[j] = seed[j]); - } - } - }); - }); -} - -/** - * Checks a node for validity as a Sizzle context - * @param {Element|Object=} context - * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value - */ -function testContext( context ) { - return context && typeof context.getElementsByTagName !== strundefined && context; -} - -// Expose support vars for convenience -support = Sizzle.support = {}; - -/** - * Detects XML nodes - * @param {Element|Object} elem An element or a document - * @returns {Boolean} True iff elem is a non-HTML XML node - */ -isXML = Sizzle.isXML = function( elem ) { - // documentElement is verified for cases where it doesn't yet exist - // (such as loading iframes in IE - #4833) - var documentElement = elem && (elem.ownerDocument || elem).documentElement; - return documentElement ? documentElement.nodeName !== "HTML" : false; -}; - -/** - * Sets document-related variables once based on the current document - * @param {Element|Object} [doc] An element or document object to use to set the document - * @returns {Object} Returns the current document - */ -setDocument = Sizzle.setDocument = function( node ) { - var hasCompare, - doc = node ? node.ownerDocument || node : preferredDoc, - parent = doc.defaultView; - - // If no document and documentElement is available, return - if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { - return document; - } - - // Set our document - document = doc; - docElem = doc.documentElement; - - // Support tests - documentIsHTML = !isXML( doc ); - - // Support: IE>8 - // If iframe document is assigned to "document" variable and if iframe has been reloaded, - // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 - // IE6-8 do not support the defaultView property so parent will be undefined - if ( parent && parent !== parent.top ) { - // IE11 does not have attachEvent, so all must suffer - if ( parent.addEventListener ) { - parent.addEventListener( "unload", function() { - setDocument(); - }, false ); - } else if ( parent.attachEvent ) { - parent.attachEvent( "onunload", function() { - setDocument(); - }); - } - } - - /* Attributes - ---------------------------------------------------------------------- */ - - // Support: IE<8 - // Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans) - support.attributes = assert(function( div ) { - div.className = "i"; - return !div.getAttribute("className"); - }); - - /* getElement(s)By* - ---------------------------------------------------------------------- */ - - // Check if getElementsByTagName("*") returns only elements - support.getElementsByTagName = assert(function( div ) { - div.appendChild( doc.createComment("") ); - return !div.getElementsByTagName("*").length; - }); - - // Check if getElementsByClassName can be trusted - support.getElementsByClassName = rnative.test( doc.getElementsByClassName ) && assert(function( div ) { - div.innerHTML = "
"; - - // Support: Safari<4 - // Catch class over-caching - div.firstChild.className = "i"; - // Support: Opera<10 - // Catch gEBCN failure to find non-leading classes - return div.getElementsByClassName("i").length === 2; - }); - - // Support: IE<10 - // Check if getElementById returns elements by name - // The broken getElementById methods don't pick up programatically-set names, - // so use a roundabout getElementsByName test - support.getById = assert(function( div ) { - docElem.appendChild( div ).id = expando; - return !doc.getElementsByName || !doc.getElementsByName( expando ).length; - }); - - // ID find and filter - if ( support.getById ) { - Expr.find["ID"] = function( id, context ) { - if ( typeof context.getElementById !== strundefined && documentIsHTML ) { - var m = context.getElementById( id ); - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - return m && m.parentNode ? [ m ] : []; - } - }; - Expr.filter["ID"] = function( id ) { - var attrId = id.replace( runescape, funescape ); - return function( elem ) { - return elem.getAttribute("id") === attrId; - }; - }; - } else { - // Support: IE6/7 - // getElementById is not reliable as a find shortcut - delete Expr.find["ID"]; - - Expr.filter["ID"] = function( id ) { - var attrId = id.replace( runescape, funescape ); - return function( elem ) { - var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); - return node && node.value === attrId; - }; - }; - } - - // Tag - Expr.find["TAG"] = support.getElementsByTagName ? - function( tag, context ) { - if ( typeof context.getElementsByTagName !== strundefined ) { - return context.getElementsByTagName( tag ); - } - } : - function( tag, context ) { - var elem, - tmp = [], - i = 0, - results = context.getElementsByTagName( tag ); - - // Filter out possible comments - if ( tag === "*" ) { - while ( (elem = results[i++]) ) { - if ( elem.nodeType === 1 ) { - tmp.push( elem ); - } - } - - return tmp; - } - return results; - }; - - // Class - Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { - if ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) { - return context.getElementsByClassName( className ); - } - }; - - /* QSA/matchesSelector - ---------------------------------------------------------------------- */ - - // QSA and matchesSelector support - - // matchesSelector(:active) reports false when true (IE9/Opera 11.5) - rbuggyMatches = []; - - // qSa(:focus) reports false when true (Chrome 21) - // We allow this because of a bug in IE8/9 that throws an error - // whenever `document.activeElement` is accessed on an iframe - // So, we allow :focus to pass through QSA all the time to avoid the IE error - // See http://bugs.jquery.com/ticket/13378 - rbuggyQSA = []; - - if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { - // Build QSA regex - // Regex strategy adopted from Diego Perini - assert(function( div ) { - // Select is set to empty string on purpose - // This is to test IE's treatment of not explicitly - // setting a boolean content attribute, - // since its presence should be enough - // http://bugs.jquery.com/ticket/12359 - div.innerHTML = ""; - - // Support: IE8, Opera 11-12.16 - // Nothing should be selected when empty strings follow ^= or $= or *= - // The test attribute must be unknown in Opera but "safe" for WinRT - // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section - if ( div.querySelectorAll("[msallowclip^='']").length ) { - rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); - } - - // Support: IE8 - // Boolean attributes and "value" are not treated correctly - if ( !div.querySelectorAll("[selected]").length ) { - rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); - } - - // Webkit/Opera - :checked should return selected option elements - // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked - // IE8 throws error here and will not see later tests - if ( !div.querySelectorAll(":checked").length ) { - rbuggyQSA.push(":checked"); - } - }); - - assert(function( div ) { - // Support: Windows 8 Native Apps - // The type and name attributes are restricted during .innerHTML assignment - var input = doc.createElement("input"); - input.setAttribute( "type", "hidden" ); - div.appendChild( input ).setAttribute( "name", "D" ); - - // Support: IE8 - // Enforce case-sensitivity of name attribute - if ( div.querySelectorAll("[name=d]").length ) { - rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); - } - - // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) - // IE8 throws error here and will not see later tests - if ( !div.querySelectorAll(":enabled").length ) { - rbuggyQSA.push( ":enabled", ":disabled" ); - } - - // Opera 10-11 does not throw on post-comma invalid pseudos - div.querySelectorAll("*,:x"); - rbuggyQSA.push(",.*:"); - }); - } - - if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || - docElem.webkitMatchesSelector || - docElem.mozMatchesSelector || - docElem.oMatchesSelector || - docElem.msMatchesSelector) )) ) { - - assert(function( div ) { - // Check to see if it's possible to do matchesSelector - // on a disconnected node (IE 9) - support.disconnectedMatch = matches.call( div, "div" ); - - // This should fail with an exception - // Gecko does not error, returns false instead - matches.call( div, "[s!='']:x" ); - rbuggyMatches.push( "!=", pseudos ); - }); - } - - rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); - rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); - - /* Contains - ---------------------------------------------------------------------- */ - hasCompare = rnative.test( docElem.compareDocumentPosition ); - - // Element contains another - // Purposefully does not implement inclusive descendent - // As in, an element does not contain itself - contains = hasCompare || rnative.test( docElem.contains ) ? - function( a, b ) { - var adown = a.nodeType === 9 ? a.documentElement : a, - bup = b && b.parentNode; - return a === bup || !!( bup && bup.nodeType === 1 && ( - adown.contains ? - adown.contains( bup ) : - a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 - )); - } : - function( a, b ) { - if ( b ) { - while ( (b = b.parentNode) ) { - if ( b === a ) { - return true; - } - } - } - return false; - }; - - /* Sorting - ---------------------------------------------------------------------- */ - - // Document order sorting - sortOrder = hasCompare ? - function( a, b ) { - - // Flag for duplicate removal - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - // Sort on method existence if only one input has compareDocumentPosition - var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; - if ( compare ) { - return compare; - } - - // Calculate position if both inputs belong to the same document - compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? - a.compareDocumentPosition( b ) : - - // Otherwise we know they are disconnected - 1; - - // Disconnected nodes - if ( compare & 1 || - (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { - - // Choose the first element that is related to our preferred document - if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { - return -1; - } - if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { - return 1; - } - - // Maintain original order - return sortInput ? - ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : - 0; - } - - return compare & 4 ? -1 : 1; - } : - function( a, b ) { - // Exit early if the nodes are identical - if ( a === b ) { - hasDuplicate = true; - return 0; - } - - var cur, - i = 0, - aup = a.parentNode, - bup = b.parentNode, - ap = [ a ], - bp = [ b ]; - - // Parentless nodes are either documents or disconnected - if ( !aup || !bup ) { - return a === doc ? -1 : - b === doc ? 1 : - aup ? -1 : - bup ? 1 : - sortInput ? - ( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) : - 0; - - // If the nodes are siblings, we can do a quick check - } else if ( aup === bup ) { - return siblingCheck( a, b ); - } - - // Otherwise we need full lists of their ancestors for comparison - cur = a; - while ( (cur = cur.parentNode) ) { - ap.unshift( cur ); - } - cur = b; - while ( (cur = cur.parentNode) ) { - bp.unshift( cur ); - } - - // Walk down the tree looking for a discrepancy - while ( ap[i] === bp[i] ) { - i++; - } - - return i ? - // Do a sibling check if the nodes have a common ancestor - siblingCheck( ap[i], bp[i] ) : - - // Otherwise nodes in our document sort first - ap[i] === preferredDoc ? -1 : - bp[i] === preferredDoc ? 1 : - 0; - }; - - return doc; -}; - -Sizzle.matches = function( expr, elements ) { - return Sizzle( expr, null, null, elements ); -}; - -Sizzle.matchesSelector = function( elem, expr ) { - // Set document vars if needed - if ( ( elem.ownerDocument || elem ) !== document ) { - setDocument( elem ); - } - - // Make sure that attribute selectors are quoted - expr = expr.replace( rattributeQuotes, "='$1']" ); - - if ( support.matchesSelector && documentIsHTML && - ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && - ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { - - try { - var ret = matches.call( elem, expr ); - - // IE 9's matchesSelector returns false on disconnected nodes - if ( ret || support.disconnectedMatch || - // As well, disconnected nodes are said to be in a document - // fragment in IE 9 - elem.document && elem.document.nodeType !== 11 ) { - return ret; - } - } catch(e) {} - } - - return Sizzle( expr, document, null, [ elem ] ).length > 0; -}; - -Sizzle.contains = function( context, elem ) { - // Set document vars if needed - if ( ( context.ownerDocument || context ) !== document ) { - setDocument( context ); - } - return contains( context, elem ); -}; - -Sizzle.attr = function( elem, name ) { - // Set document vars if needed - if ( ( elem.ownerDocument || elem ) !== document ) { - setDocument( elem ); - } - - var fn = Expr.attrHandle[ name.toLowerCase() ], - // Don't get fooled by Object.prototype properties (jQuery #13807) - val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? - fn( elem, name, !documentIsHTML ) : - undefined; - - return val !== undefined ? - val : - support.attributes || !documentIsHTML ? - elem.getAttribute( name ) : - (val = elem.getAttributeNode(name)) && val.specified ? - val.value : - null; -}; - -Sizzle.error = function( msg ) { - throw new Error( "Syntax error, unrecognized expression: " + msg ); -}; - -/** - * Document sorting and removing duplicates - * @param {ArrayLike} results - */ -Sizzle.uniqueSort = function( results ) { - var elem, - duplicates = [], - j = 0, - i = 0; - - // Unless we *know* we can detect duplicates, assume their presence - hasDuplicate = !support.detectDuplicates; - sortInput = !support.sortStable && results.slice( 0 ); - results.sort( sortOrder ); - - if ( hasDuplicate ) { - while ( (elem = results[i++]) ) { - if ( elem === results[ i ] ) { - j = duplicates.push( i ); - } - } - while ( j-- ) { - results.splice( duplicates[ j ], 1 ); - } - } - - // Clear input after sorting to release objects - // See https://github.com/jquery/sizzle/pull/225 - sortInput = null; - - return results; -}; - -/** - * Utility function for retrieving the text value of an array of DOM nodes - * @param {Array|Element} elem - */ -getText = Sizzle.getText = function( elem ) { - var node, - ret = "", - i = 0, - nodeType = elem.nodeType; - - if ( !nodeType ) { - // If no nodeType, this is expected to be an array - while ( (node = elem[i++]) ) { - // Do not traverse comment nodes - ret += getText( node ); - } - } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { - // Use textContent for elements - // innerText usage removed for consistency of new lines (jQuery #11153) - if ( typeof elem.textContent === "string" ) { - return elem.textContent; - } else { - // Traverse its children - for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { - ret += getText( elem ); - } - } - } else if ( nodeType === 3 || nodeType === 4 ) { - return elem.nodeValue; - } - // Do not include comment or processing instruction nodes - - return ret; -}; - -Expr = Sizzle.selectors = { - - // Can be adjusted by the user - cacheLength: 50, - - createPseudo: markFunction, - - match: matchExpr, - - attrHandle: {}, - - find: {}, - - relative: { - ">": { dir: "parentNode", first: true }, - " ": { dir: "parentNode" }, - "+": { dir: "previousSibling", first: true }, - "~": { dir: "previousSibling" } - }, - - preFilter: { - "ATTR": function( match ) { - match[1] = match[1].replace( runescape, funescape ); - - // Move the given value to match[3] whether quoted or unquoted - match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); - - if ( match[2] === "~=" ) { - match[3] = " " + match[3] + " "; - } - - return match.slice( 0, 4 ); - }, - - "CHILD": function( match ) { - /* matches from matchExpr["CHILD"] - 1 type (only|nth|...) - 2 what (child|of-type) - 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) - 4 xn-component of xn+y argument ([+-]?\d*n|) - 5 sign of xn-component - 6 x of xn-component - 7 sign of y-component - 8 y of y-component - */ - match[1] = match[1].toLowerCase(); - - if ( match[1].slice( 0, 3 ) === "nth" ) { - // nth-* requires argument - if ( !match[3] ) { - Sizzle.error( match[0] ); - } - - // numeric x and y parameters for Expr.filter.CHILD - // remember that false/true cast respectively to 0/1 - match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); - match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); - - // other types prohibit arguments - } else if ( match[3] ) { - Sizzle.error( match[0] ); - } - - return match; - }, - - "PSEUDO": function( match ) { - var excess, - unquoted = !match[6] && match[2]; - - if ( matchExpr["CHILD"].test( match[0] ) ) { - return null; - } - - // Accept quoted arguments as-is - if ( match[3] ) { - match[2] = match[4] || match[5] || ""; - - // Strip excess characters from unquoted arguments - } else if ( unquoted && rpseudo.test( unquoted ) && - // Get excess from tokenize (recursively) - (excess = tokenize( unquoted, true )) && - // advance to the next closing parenthesis - (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { - - // excess is a negative index - match[0] = match[0].slice( 0, excess ); - match[2] = unquoted.slice( 0, excess ); - } - - // Return only captures needed by the pseudo filter method (type and argument) - return match.slice( 0, 3 ); - } - }, - - filter: { - - "TAG": function( nodeNameSelector ) { - var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); - return nodeNameSelector === "*" ? - function() { return true; } : - function( elem ) { - return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; - }; - }, - - "CLASS": function( className ) { - var pattern = classCache[ className + " " ]; - - return pattern || - (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && - classCache( className, function( elem ) { - return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute("class") || "" ); - }); - }, - - "ATTR": function( name, operator, check ) { - return function( elem ) { - var result = Sizzle.attr( elem, name ); - - if ( result == null ) { - return operator === "!="; - } - if ( !operator ) { - return true; - } - - result += ""; - - return operator === "=" ? result === check : - operator === "!=" ? result !== check : - operator === "^=" ? check && result.indexOf( check ) === 0 : - operator === "*=" ? check && result.indexOf( check ) > -1 : - operator === "$=" ? check && result.slice( -check.length ) === check : - operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : - operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : - false; - }; - }, - - "CHILD": function( type, what, argument, first, last ) { - var simple = type.slice( 0, 3 ) !== "nth", - forward = type.slice( -4 ) !== "last", - ofType = what === "of-type"; - - return first === 1 && last === 0 ? - - // Shortcut for :nth-*(n) - function( elem ) { - return !!elem.parentNode; - } : - - function( elem, context, xml ) { - var cache, outerCache, node, diff, nodeIndex, start, - dir = simple !== forward ? "nextSibling" : "previousSibling", - parent = elem.parentNode, - name = ofType && elem.nodeName.toLowerCase(), - useCache = !xml && !ofType; - - if ( parent ) { - - // :(first|last|only)-(child|of-type) - if ( simple ) { - while ( dir ) { - node = elem; - while ( (node = node[ dir ]) ) { - if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { - return false; - } - } - // Reverse direction for :only-* (if we haven't yet done so) - start = dir = type === "only" && !start && "nextSibling"; - } - return true; - } - - start = [ forward ? parent.firstChild : parent.lastChild ]; - - // non-xml :nth-child(...) stores cache data on `parent` - if ( forward && useCache ) { - // Seek `elem` from a previously-cached index - outerCache = parent[ expando ] || (parent[ expando ] = {}); - cache = outerCache[ type ] || []; - nodeIndex = cache[0] === dirruns && cache[1]; - diff = cache[0] === dirruns && cache[2]; - node = nodeIndex && parent.childNodes[ nodeIndex ]; - - while ( (node = ++nodeIndex && node && node[ dir ] || - - // Fallback to seeking `elem` from the start - (diff = nodeIndex = 0) || start.pop()) ) { - - // When found, cache indexes on `parent` and break - if ( node.nodeType === 1 && ++diff && node === elem ) { - outerCache[ type ] = [ dirruns, nodeIndex, diff ]; - break; - } - } - - // Use previously-cached element index if available - } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { - diff = cache[1]; - - // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) - } else { - // Use the same loop as above to seek `elem` from the start - while ( (node = ++nodeIndex && node && node[ dir ] || - (diff = nodeIndex = 0) || start.pop()) ) { - - if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { - // Cache the index of each encountered element - if ( useCache ) { - (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; - } - - if ( node === elem ) { - break; - } - } - } - } - - // Incorporate the offset, then check against cycle size - diff -= last; - return diff === first || ( diff % first === 0 && diff / first >= 0 ); - } - }; - }, - - "PSEUDO": function( pseudo, argument ) { - // pseudo-class names are case-insensitive - // http://www.w3.org/TR/selectors/#pseudo-classes - // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters - // Remember that setFilters inherits from pseudos - var args, - fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || - Sizzle.error( "unsupported pseudo: " + pseudo ); - - // The user may use createPseudo to indicate that - // arguments are needed to create the filter function - // just as Sizzle does - if ( fn[ expando ] ) { - return fn( argument ); - } - - // But maintain support for old signatures - if ( fn.length > 1 ) { - args = [ pseudo, pseudo, "", argument ]; - return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? - markFunction(function( seed, matches ) { - var idx, - matched = fn( seed, argument ), - i = matched.length; - while ( i-- ) { - idx = indexOf.call( seed, matched[i] ); - seed[ idx ] = !( matches[ idx ] = matched[i] ); - } - }) : - function( elem ) { - return fn( elem, 0, args ); - }; - } - - return fn; - } - }, - - pseudos: { - // Potentially complex pseudos - "not": markFunction(function( selector ) { - // Trim the selector passed to compile - // to avoid treating leading and trailing - // spaces as combinators - var input = [], - results = [], - matcher = compile( selector.replace( rtrim, "$1" ) ); - - return matcher[ expando ] ? - markFunction(function( seed, matches, context, xml ) { - var elem, - unmatched = matcher( seed, null, xml, [] ), - i = seed.length; - - // Match elements unmatched by `matcher` - while ( i-- ) { - if ( (elem = unmatched[i]) ) { - seed[i] = !(matches[i] = elem); - } - } - }) : - function( elem, context, xml ) { - input[0] = elem; - matcher( input, null, xml, results ); - return !results.pop(); - }; - }), - - "has": markFunction(function( selector ) { - return function( elem ) { - return Sizzle( selector, elem ).length > 0; - }; - }), - - "contains": markFunction(function( text ) { - return function( elem ) { - return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; - }; - }), - - // "Whether an element is represented by a :lang() selector - // is based solely on the element's language value - // being equal to the identifier C, - // or beginning with the identifier C immediately followed by "-". - // The matching of C against the element's language value is performed case-insensitively. - // The identifier C does not have to be a valid language name." - // http://www.w3.org/TR/selectors/#lang-pseudo - "lang": markFunction( function( lang ) { - // lang value must be a valid identifier - if ( !ridentifier.test(lang || "") ) { - Sizzle.error( "unsupported lang: " + lang ); - } - lang = lang.replace( runescape, funescape ).toLowerCase(); - return function( elem ) { - var elemLang; - do { - if ( (elemLang = documentIsHTML ? - elem.lang : - elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { - - elemLang = elemLang.toLowerCase(); - return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; - } - } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); - return false; - }; - }), - - // Miscellaneous - "target": function( elem ) { - var hash = window.location && window.location.hash; - return hash && hash.slice( 1 ) === elem.id; - }, - - "root": function( elem ) { - return elem === docElem; - }, - - "focus": function( elem ) { - return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); - }, - - // Boolean properties - "enabled": function( elem ) { - return elem.disabled === false; - }, - - "disabled": function( elem ) { - return elem.disabled === true; - }, - - "checked": function( elem ) { - // In CSS3, :checked should return both checked and selected elements - // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked - var nodeName = elem.nodeName.toLowerCase(); - return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); - }, - - "selected": function( elem ) { - // Accessing this property makes selected-by-default - // options in Safari work properly - if ( elem.parentNode ) { - elem.parentNode.selectedIndex; - } - - return elem.selected === true; - }, - - // Contents - "empty": function( elem ) { - // http://www.w3.org/TR/selectors/#empty-pseudo - // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), - // but not by others (comment: 8; processing instruction: 7; etc.) - // nodeType < 6 works because attributes (2) do not appear as children - for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { - if ( elem.nodeType < 6 ) { - return false; - } - } - return true; - }, - - "parent": function( elem ) { - return !Expr.pseudos["empty"]( elem ); - }, - - // Element/input types - "header": function( elem ) { - return rheader.test( elem.nodeName ); - }, - - "input": function( elem ) { - return rinputs.test( elem.nodeName ); - }, - - "button": function( elem ) { - var name = elem.nodeName.toLowerCase(); - return name === "input" && elem.type === "button" || name === "button"; - }, - - "text": function( elem ) { - var attr; - return elem.nodeName.toLowerCase() === "input" && - elem.type === "text" && - - // Support: IE<8 - // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" - ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); - }, - - // Position-in-collection - "first": createPositionalPseudo(function() { - return [ 0 ]; - }), - - "last": createPositionalPseudo(function( matchIndexes, length ) { - return [ length - 1 ]; - }), - - "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { - return [ argument < 0 ? argument + length : argument ]; - }), - - "even": createPositionalPseudo(function( matchIndexes, length ) { - var i = 0; - for ( ; i < length; i += 2 ) { - matchIndexes.push( i ); - } - return matchIndexes; - }), - - "odd": createPositionalPseudo(function( matchIndexes, length ) { - var i = 1; - for ( ; i < length; i += 2 ) { - matchIndexes.push( i ); - } - return matchIndexes; - }), - - "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { - var i = argument < 0 ? argument + length : argument; - for ( ; --i >= 0; ) { - matchIndexes.push( i ); - } - return matchIndexes; - }), - - "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { - var i = argument < 0 ? argument + length : argument; - for ( ; ++i < length; ) { - matchIndexes.push( i ); - } - return matchIndexes; - }) - } -}; - -Expr.pseudos["nth"] = Expr.pseudos["eq"]; - -// Add button/input type pseudos -for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { - Expr.pseudos[ i ] = createInputPseudo( i ); -} -for ( i in { submit: true, reset: true } ) { - Expr.pseudos[ i ] = createButtonPseudo( i ); -} - -// Easy API for creating new setFilters -function setFilters() {} -setFilters.prototype = Expr.filters = Expr.pseudos; -Expr.setFilters = new setFilters(); - -tokenize = Sizzle.tokenize = function( selector, parseOnly ) { - var matched, match, tokens, type, - soFar, groups, preFilters, - cached = tokenCache[ selector + " " ]; - - if ( cached ) { - return parseOnly ? 0 : cached.slice( 0 ); - } - - soFar = selector; - groups = []; - preFilters = Expr.preFilter; - - while ( soFar ) { - - // Comma and first run - if ( !matched || (match = rcomma.exec( soFar )) ) { - if ( match ) { - // Don't consume trailing commas as valid - soFar = soFar.slice( match[0].length ) || soFar; - } - groups.push( (tokens = []) ); - } - - matched = false; - - // Combinators - if ( (match = rcombinators.exec( soFar )) ) { - matched = match.shift(); - tokens.push({ - value: matched, - // Cast descendant combinators to space - type: match[0].replace( rtrim, " " ) - }); - soFar = soFar.slice( matched.length ); - } - - // Filters - for ( type in Expr.filter ) { - if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || - (match = preFilters[ type ]( match ))) ) { - matched = match.shift(); - tokens.push({ - value: matched, - type: type, - matches: match - }); - soFar = soFar.slice( matched.length ); - } - } - - if ( !matched ) { - break; - } - } - - // Return the length of the invalid excess - // if we're just parsing - // Otherwise, throw an error or return tokens - return parseOnly ? - soFar.length : - soFar ? - Sizzle.error( selector ) : - // Cache the tokens - tokenCache( selector, groups ).slice( 0 ); -}; - -function toSelector( tokens ) { - var i = 0, - len = tokens.length, - selector = ""; - for ( ; i < len; i++ ) { - selector += tokens[i].value; - } - return selector; -} - -function addCombinator( matcher, combinator, base ) { - var dir = combinator.dir, - checkNonElements = base && dir === "parentNode", - doneName = done++; - - return combinator.first ? - // Check against closest ancestor/preceding element - function( elem, context, xml ) { - while ( (elem = elem[ dir ]) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - return matcher( elem, context, xml ); - } - } - } : - - // Check against all ancestor/preceding elements - function( elem, context, xml ) { - var oldCache, outerCache, - newCache = [ dirruns, doneName ]; - - // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching - if ( xml ) { - while ( (elem = elem[ dir ]) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - if ( matcher( elem, context, xml ) ) { - return true; - } - } - } - } else { - while ( (elem = elem[ dir ]) ) { - if ( elem.nodeType === 1 || checkNonElements ) { - outerCache = elem[ expando ] || (elem[ expando ] = {}); - if ( (oldCache = outerCache[ dir ]) && - oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { - - // Assign to newCache so results back-propagate to previous elements - return (newCache[ 2 ] = oldCache[ 2 ]); - } else { - // Reuse newcache so results back-propagate to previous elements - outerCache[ dir ] = newCache; - - // A match means we're done; a fail means we have to keep checking - if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { - return true; - } - } - } - } - } - }; -} - -function elementMatcher( matchers ) { - return matchers.length > 1 ? - function( elem, context, xml ) { - var i = matchers.length; - while ( i-- ) { - if ( !matchers[i]( elem, context, xml ) ) { - return false; - } - } - return true; - } : - matchers[0]; -} - -function multipleContexts( selector, contexts, results ) { - var i = 0, - len = contexts.length; - for ( ; i < len; i++ ) { - Sizzle( selector, contexts[i], results ); - } - return results; -} - -function condense( unmatched, map, filter, context, xml ) { - var elem, - newUnmatched = [], - i = 0, - len = unmatched.length, - mapped = map != null; - - for ( ; i < len; i++ ) { - if ( (elem = unmatched[i]) ) { - if ( !filter || filter( elem, context, xml ) ) { - newUnmatched.push( elem ); - if ( mapped ) { - map.push( i ); - } - } - } - } - - return newUnmatched; -} - -function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { - if ( postFilter && !postFilter[ expando ] ) { - postFilter = setMatcher( postFilter ); - } - if ( postFinder && !postFinder[ expando ] ) { - postFinder = setMatcher( postFinder, postSelector ); - } - return markFunction(function( seed, results, context, xml ) { - var temp, i, elem, - preMap = [], - postMap = [], - preexisting = results.length, - - // Get initial elements from seed or context - elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), - - // Prefilter to get matcher input, preserving a map for seed-results synchronization - matcherIn = preFilter && ( seed || !selector ) ? - condense( elems, preMap, preFilter, context, xml ) : - elems, - - matcherOut = matcher ? - // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, - postFinder || ( seed ? preFilter : preexisting || postFilter ) ? - - // ...intermediate processing is necessary - [] : - - // ...otherwise use results directly - results : - matcherIn; - - // Find primary matches - if ( matcher ) { - matcher( matcherIn, matcherOut, context, xml ); - } - - // Apply postFilter - if ( postFilter ) { - temp = condense( matcherOut, postMap ); - postFilter( temp, [], context, xml ); - - // Un-match failing elements by moving them back to matcherIn - i = temp.length; - while ( i-- ) { - if ( (elem = temp[i]) ) { - matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); - } - } - } - - if ( seed ) { - if ( postFinder || preFilter ) { - if ( postFinder ) { - // Get the final matcherOut by condensing this intermediate into postFinder contexts - temp = []; - i = matcherOut.length; - while ( i-- ) { - if ( (elem = matcherOut[i]) ) { - // Restore matcherIn since elem is not yet a final match - temp.push( (matcherIn[i] = elem) ); - } - } - postFinder( null, (matcherOut = []), temp, xml ); - } - - // Move matched elements from seed to results to keep them synchronized - i = matcherOut.length; - while ( i-- ) { - if ( (elem = matcherOut[i]) && - (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { - - seed[temp] = !(results[temp] = elem); - } - } - } - - // Add elements to results, through postFinder if defined - } else { - matcherOut = condense( - matcherOut === results ? - matcherOut.splice( preexisting, matcherOut.length ) : - matcherOut - ); - if ( postFinder ) { - postFinder( null, results, matcherOut, xml ); - } else { - push.apply( results, matcherOut ); - } - } - }); -} - -function matcherFromTokens( tokens ) { - var checkContext, matcher, j, - len = tokens.length, - leadingRelative = Expr.relative[ tokens[0].type ], - implicitRelative = leadingRelative || Expr.relative[" "], - i = leadingRelative ? 1 : 0, - - // The foundational matcher ensures that elements are reachable from top-level context(s) - matchContext = addCombinator( function( elem ) { - return elem === checkContext; - }, implicitRelative, true ), - matchAnyContext = addCombinator( function( elem ) { - return indexOf.call( checkContext, elem ) > -1; - }, implicitRelative, true ), - matchers = [ function( elem, context, xml ) { - return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( - (checkContext = context).nodeType ? - matchContext( elem, context, xml ) : - matchAnyContext( elem, context, xml ) ); - } ]; - - for ( ; i < len; i++ ) { - if ( (matcher = Expr.relative[ tokens[i].type ]) ) { - matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; - } else { - matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); - - // Return special upon seeing a positional matcher - if ( matcher[ expando ] ) { - // Find the next relative operator (if any) for proper handling - j = ++i; - for ( ; j < len; j++ ) { - if ( Expr.relative[ tokens[j].type ] ) { - break; - } - } - return setMatcher( - i > 1 && elementMatcher( matchers ), - i > 1 && toSelector( - // If the preceding token was a descendant combinator, insert an implicit any-element `*` - tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) - ).replace( rtrim, "$1" ), - matcher, - i < j && matcherFromTokens( tokens.slice( i, j ) ), - j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), - j < len && toSelector( tokens ) - ); - } - matchers.push( matcher ); - } - } - - return elementMatcher( matchers ); -} - -function matcherFromGroupMatchers( elementMatchers, setMatchers ) { - var bySet = setMatchers.length > 0, - byElement = elementMatchers.length > 0, - superMatcher = function( seed, context, xml, results, outermost ) { - var elem, j, matcher, - matchedCount = 0, - i = "0", - unmatched = seed && [], - setMatched = [], - contextBackup = outermostContext, - // We must always have either seed elements or outermost context - elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), - // Use integer dirruns iff this is the outermost matcher - dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), - len = elems.length; - - if ( outermost ) { - outermostContext = context !== document && context; - } - - // Add elements passing elementMatchers directly to results - // Keep `i` a string if there are no elements so `matchedCount` will be "00" below - // Support: IE<9, Safari - // Tolerate NodeList properties (IE: "length"; Safari: ) matching elements by id - for ( ; i !== len && (elem = elems[i]) != null; i++ ) { - if ( byElement && elem ) { - j = 0; - while ( (matcher = elementMatchers[j++]) ) { - if ( matcher( elem, context, xml ) ) { - results.push( elem ); - break; - } - } - if ( outermost ) { - dirruns = dirrunsUnique; - } - } - - // Track unmatched elements for set filters - if ( bySet ) { - // They will have gone through all possible matchers - if ( (elem = !matcher && elem) ) { - matchedCount--; - } - - // Lengthen the array for every element, matched or not - if ( seed ) { - unmatched.push( elem ); - } - } - } - - // Apply set filters to unmatched elements - matchedCount += i; - if ( bySet && i !== matchedCount ) { - j = 0; - while ( (matcher = setMatchers[j++]) ) { - matcher( unmatched, setMatched, context, xml ); - } - - if ( seed ) { - // Reintegrate element matches to eliminate the need for sorting - if ( matchedCount > 0 ) { - while ( i-- ) { - if ( !(unmatched[i] || setMatched[i]) ) { - setMatched[i] = pop.call( results ); - } - } - } - - // Discard index placeholder values to get only actual matches - setMatched = condense( setMatched ); - } - - // Add matches to results - push.apply( results, setMatched ); - - // Seedless set matches succeeding multiple successful matchers stipulate sorting - if ( outermost && !seed && setMatched.length > 0 && - ( matchedCount + setMatchers.length ) > 1 ) { - - Sizzle.uniqueSort( results ); - } - } - - // Override manipulation of globals by nested matchers - if ( outermost ) { - dirruns = dirrunsUnique; - outermostContext = contextBackup; - } - - return unmatched; - }; - - return bySet ? - markFunction( superMatcher ) : - superMatcher; -} - -compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { - var i, - setMatchers = [], - elementMatchers = [], - cached = compilerCache[ selector + " " ]; - - if ( !cached ) { - // Generate a function of recursive functions that can be used to check each element - if ( !match ) { - match = tokenize( selector ); - } - i = match.length; - while ( i-- ) { - cached = matcherFromTokens( match[i] ); - if ( cached[ expando ] ) { - setMatchers.push( cached ); - } else { - elementMatchers.push( cached ); - } - } - - // Cache the compiled function - cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); - - // Save selector and tokenization - cached.selector = selector; - } - return cached; -}; - -/** - * A low-level selection function that works with Sizzle's compiled - * selector functions - * @param {String|Function} selector A selector or a pre-compiled - * selector function built with Sizzle.compile - * @param {Element} context - * @param {Array} [results] - * @param {Array} [seed] A set of elements to match against - */ -select = Sizzle.select = function( selector, context, results, seed ) { - var i, tokens, token, type, find, - compiled = typeof selector === "function" && selector, - match = !seed && tokenize( (selector = compiled.selector || selector) ); - - results = results || []; - - // Try to minimize operations if there is no seed and only one group - if ( match.length === 1 ) { - - // Take a shortcut and set the context if the root selector is an ID - tokens = match[0] = match[0].slice( 0 ); - if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && - support.getById && context.nodeType === 9 && documentIsHTML && - Expr.relative[ tokens[1].type ] ) { - - context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; - if ( !context ) { - return results; - - // Precompiled matchers will still verify ancestry, so step up a level - } else if ( compiled ) { - context = context.parentNode; - } - - selector = selector.slice( tokens.shift().value.length ); - } - - // Fetch a seed set for right-to-left matching - i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; - while ( i-- ) { - token = tokens[i]; - - // Abort if we hit a combinator - if ( Expr.relative[ (type = token.type) ] ) { - break; - } - if ( (find = Expr.find[ type ]) ) { - // Search, expanding context for leading sibling combinators - if ( (seed = find( - token.matches[0].replace( runescape, funescape ), - rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context - )) ) { - - // If seed is empty or no tokens remain, we can return early - tokens.splice( i, 1 ); - selector = seed.length && toSelector( tokens ); - if ( !selector ) { - push.apply( results, seed ); - return results; - } - - break; - } - } - } - } - - // Compile and execute a filtering function if one is not provided - // Provide `match` to avoid retokenization if we modified the selector above - ( compiled || compile( selector, match ) )( - seed, - context, - !documentIsHTML, - results, - rsibling.test( selector ) && testContext( context.parentNode ) || context - ); - return results; -}; - -// One-time assignments - -// Sort stability -support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; - -// Support: Chrome<14 -// Always assume duplicates if they aren't passed to the comparison function -support.detectDuplicates = !!hasDuplicate; - -// Initialize against the default document -setDocument(); - -// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) -// Detached nodes confoundingly follow *each other* -support.sortDetached = assert(function( div1 ) { - // Should return 1, but returns 4 (following) - return div1.compareDocumentPosition( document.createElement("div") ) & 1; -}); - -// Support: IE<8 -// Prevent attribute/property "interpolation" -// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx -if ( !assert(function( div ) { - div.innerHTML = ""; - return div.firstChild.getAttribute("href") === "#" ; -}) ) { - addHandle( "type|href|height|width", function( elem, name, isXML ) { - if ( !isXML ) { - return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); - } - }); -} - -// Support: IE<9 -// Use defaultValue in place of getAttribute("value") -if ( !support.attributes || !assert(function( div ) { - div.innerHTML = ""; - div.firstChild.setAttribute( "value", "" ); - return div.firstChild.getAttribute( "value" ) === ""; -}) ) { - addHandle( "value", function( elem, name, isXML ) { - if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { - return elem.defaultValue; - } - }); -} - -// Support: IE<9 -// Use getAttributeNode to fetch booleans when getAttribute lies -if ( !assert(function( div ) { - return div.getAttribute("disabled") == null; -}) ) { - addHandle( booleans, function( elem, name, isXML ) { - var val; - if ( !isXML ) { - return elem[ name ] === true ? name.toLowerCase() : - (val = elem.getAttributeNode( name )) && val.specified ? - val.value : - null; - } - }); -} - -return Sizzle; - -})( window ); - - - -jQuery.find = Sizzle; -jQuery.expr = Sizzle.selectors; -jQuery.expr[":"] = jQuery.expr.pseudos; -jQuery.unique = Sizzle.uniqueSort; -jQuery.text = Sizzle.getText; -jQuery.isXMLDoc = Sizzle.isXML; -jQuery.contains = Sizzle.contains; - - - -var rneedsContext = jQuery.expr.match.needsContext; - -var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/); - - - -var risSimple = /^.[^:#\[\.,]*$/; - -// Implement the identical functionality for filter and not -function winnow( elements, qualifier, not ) { - if ( jQuery.isFunction( qualifier ) ) { - return jQuery.grep( elements, function( elem, i ) { - /* jshint -W018 */ - return !!qualifier.call( elem, i, elem ) !== not; - }); - - } - - if ( qualifier.nodeType ) { - return jQuery.grep( elements, function( elem ) { - return ( elem === qualifier ) !== not; - }); - - } - - if ( typeof qualifier === "string" ) { - if ( risSimple.test( qualifier ) ) { - return jQuery.filter( qualifier, elements, not ); - } - - qualifier = jQuery.filter( qualifier, elements ); - } - - return jQuery.grep( elements, function( elem ) { - return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not; - }); -} - -jQuery.filter = function( expr, elems, not ) { - var elem = elems[ 0 ]; - - if ( not ) { - expr = ":not(" + expr + ")"; - } - - return elems.length === 1 && elem.nodeType === 1 ? - jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : - jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { - return elem.nodeType === 1; - })); -}; - -jQuery.fn.extend({ - find: function( selector ) { - var i, - ret = [], - self = this, - len = self.length; - - if ( typeof selector !== "string" ) { - return this.pushStack( jQuery( selector ).filter(function() { - for ( i = 0; i < len; i++ ) { - if ( jQuery.contains( self[ i ], this ) ) { - return true; - } - } - }) ); - } - - for ( i = 0; i < len; i++ ) { - jQuery.find( selector, self[ i ], ret ); - } - - // Needed because $( selector, context ) becomes $( context ).find( selector ) - ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); - ret.selector = this.selector ? this.selector + " " + selector : selector; - return ret; - }, - filter: function( selector ) { - return this.pushStack( winnow(this, selector || [], false) ); - }, - not: function( selector ) { - return this.pushStack( winnow(this, selector || [], true) ); - }, - is: function( selector ) { - return !!winnow( - this, - - // If this is a positional/relative selector, check membership in the returned set - // so $("p:first").is("p:last") won't return true for a doc with two "p". - typeof selector === "string" && rneedsContext.test( selector ) ? - jQuery( selector ) : - selector || [], - false - ).length; - } -}); - - -// Initialize a jQuery object - - -// A central reference to the root jQuery(document) -var rootjQuery, - - // Use the correct document accordingly with window argument (sandbox) - document = window.document, - - // A simple way to check for HTML strings - // Prioritize #id over to avoid XSS via location.hash (#9521) - // Strict HTML recognition (#11290: must start with <) - rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, - - init = jQuery.fn.init = function( selector, context ) { - var match, elem; - - // HANDLE: $(""), $(null), $(undefined), $(false) - if ( !selector ) { - return this; - } - - // Handle HTML strings - if ( typeof selector === "string" ) { - if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { - // Assume that strings that start and end with <> are HTML and skip the regex check - match = [ null, selector, null ]; - - } else { - match = rquickExpr.exec( selector ); - } - - // Match html or make sure no context is specified for #id - if ( match && (match[1] || !context) ) { - - // HANDLE: $(html) -> $(array) - if ( match[1] ) { - context = context instanceof jQuery ? context[0] : context; - - // scripts is true for back-compat - // Intentionally let the error be thrown if parseHTML is not present - jQuery.merge( this, jQuery.parseHTML( - match[1], - context && context.nodeType ? context.ownerDocument || context : document, - true - ) ); - - // HANDLE: $(html, props) - if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { - for ( match in context ) { - // Properties of context are called as methods if possible - if ( jQuery.isFunction( this[ match ] ) ) { - this[ match ]( context[ match ] ); - - // ...and otherwise set as attributes - } else { - this.attr( match, context[ match ] ); - } - } - } - - return this; - - // HANDLE: $(#id) - } else { - elem = document.getElementById( match[2] ); - - // Check parentNode to catch when Blackberry 4.6 returns - // nodes that are no longer in the document #6963 - if ( elem && elem.parentNode ) { - // Handle the case where IE and Opera return items - // by name instead of ID - if ( elem.id !== match[2] ) { - return rootjQuery.find( selector ); - } - - // Otherwise, we inject the element directly into the jQuery object - this.length = 1; - this[0] = elem; - } - - this.context = document; - this.selector = selector; - return this; - } - - // HANDLE: $(expr, $(...)) - } else if ( !context || context.jquery ) { - return ( context || rootjQuery ).find( selector ); - - // HANDLE: $(expr, context) - // (which is just equivalent to: $(context).find(expr) - } else { - return this.constructor( context ).find( selector ); - } - - // HANDLE: $(DOMElement) - } else if ( selector.nodeType ) { - this.context = this[0] = selector; - this.length = 1; - return this; - - // HANDLE: $(function) - // Shortcut for document ready - } else if ( jQuery.isFunction( selector ) ) { - return typeof rootjQuery.ready !== "undefined" ? - rootjQuery.ready( selector ) : - // Execute immediately if ready is not present - selector( jQuery ); - } - - if ( selector.selector !== undefined ) { - this.selector = selector.selector; - this.context = selector.context; - } - - return jQuery.makeArray( selector, this ); - }; - -// Give the init function the jQuery prototype for later instantiation -init.prototype = jQuery.fn; - -// Initialize central reference -rootjQuery = jQuery( document ); - - -var rparentsprev = /^(?:parents|prev(?:Until|All))/, - // methods guaranteed to produce a unique set when starting from a unique set - guaranteedUnique = { - children: true, - contents: true, - next: true, - prev: true - }; - -jQuery.extend({ - dir: function( elem, dir, until ) { - var matched = [], - cur = elem[ dir ]; - - while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { - if ( cur.nodeType === 1 ) { - matched.push( cur ); - } - cur = cur[dir]; - } - return matched; - }, - - sibling: function( n, elem ) { - var r = []; - - for ( ; n; n = n.nextSibling ) { - if ( n.nodeType === 1 && n !== elem ) { - r.push( n ); - } - } - - return r; - } -}); - -jQuery.fn.extend({ - has: function( target ) { - var i, - targets = jQuery( target, this ), - len = targets.length; - - return this.filter(function() { - for ( i = 0; i < len; i++ ) { - if ( jQuery.contains( this, targets[i] ) ) { - return true; - } - } - }); - }, - - closest: function( selectors, context ) { - var cur, - i = 0, - l = this.length, - matched = [], - pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? - jQuery( selectors, context || this.context ) : - 0; - - for ( ; i < l; i++ ) { - for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { - // Always skip document fragments - if ( cur.nodeType < 11 && (pos ? - pos.index(cur) > -1 : - - // Don't pass non-elements to Sizzle - cur.nodeType === 1 && - jQuery.find.matchesSelector(cur, selectors)) ) { - - matched.push( cur ); - break; - } - } - } - - return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched ); - }, - - // Determine the position of an element within - // the matched set of elements - index: function( elem ) { - - // No argument, return index in parent - if ( !elem ) { - return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1; - } - - // index in selector - if ( typeof elem === "string" ) { - return jQuery.inArray( this[0], jQuery( elem ) ); - } - - // Locate the position of the desired element - return jQuery.inArray( - // If it receives a jQuery object, the first element is used - elem.jquery ? elem[0] : elem, this ); - }, - - add: function( selector, context ) { - return this.pushStack( - jQuery.unique( - jQuery.merge( this.get(), jQuery( selector, context ) ) - ) - ); - }, - - addBack: function( selector ) { - return this.add( selector == null ? - this.prevObject : this.prevObject.filter(selector) - ); - } -}); - -function sibling( cur, dir ) { - do { - cur = cur[ dir ]; - } while ( cur && cur.nodeType !== 1 ); - - return cur; -} - -jQuery.each({ - parent: function( elem ) { - var parent = elem.parentNode; - return parent && parent.nodeType !== 11 ? parent : null; - }, - parents: function( elem ) { - return jQuery.dir( elem, "parentNode" ); - }, - parentsUntil: function( elem, i, until ) { - return jQuery.dir( elem, "parentNode", until ); - }, - next: function( elem ) { - return sibling( elem, "nextSibling" ); - }, - prev: function( elem ) { - return sibling( elem, "previousSibling" ); - }, - nextAll: function( elem ) { - return jQuery.dir( elem, "nextSibling" ); - }, - prevAll: function( elem ) { - return jQuery.dir( elem, "previousSibling" ); - }, - nextUntil: function( elem, i, until ) { - return jQuery.dir( elem, "nextSibling", until ); - }, - prevUntil: function( elem, i, until ) { - return jQuery.dir( elem, "previousSibling", until ); - }, - siblings: function( elem ) { - return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); - }, - children: function( elem ) { - return jQuery.sibling( elem.firstChild ); - }, - contents: function( elem ) { - return jQuery.nodeName( elem, "iframe" ) ? - elem.contentDocument || elem.contentWindow.document : - jQuery.merge( [], elem.childNodes ); - } -}, function( name, fn ) { - jQuery.fn[ name ] = function( until, selector ) { - var ret = jQuery.map( this, fn, until ); - - if ( name.slice( -5 ) !== "Until" ) { - selector = until; - } - - if ( selector && typeof selector === "string" ) { - ret = jQuery.filter( selector, ret ); - } - - if ( this.length > 1 ) { - // Remove duplicates - if ( !guaranteedUnique[ name ] ) { - ret = jQuery.unique( ret ); - } - - // Reverse order for parents* and prev-derivatives - if ( rparentsprev.test( name ) ) { - ret = ret.reverse(); - } - } - - return this.pushStack( ret ); - }; -}); -var rnotwhite = (/\S+/g); - - - -// String to Object options format cache -var optionsCache = {}; - -// Convert String-formatted options into Object-formatted ones and store in cache -function createOptions( options ) { - var object = optionsCache[ options ] = {}; - jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { - object[ flag ] = true; - }); - return object; -} - -/* - * Create a callback list using the following parameters: - * - * options: an optional list of space-separated options that will change how - * the callback list behaves or a more traditional option object - * - * By default a callback list will act like an event callback list and can be - * "fired" multiple times. - * - * Possible options: - * - * once: will ensure the callback list can only be fired once (like a Deferred) - * - * memory: will keep track of previous values and will call any callback added - * after the list has been fired right away with the latest "memorized" - * values (like a Deferred) - * - * unique: will ensure a callback can only be added once (no duplicate in the list) - * - * stopOnFalse: interrupt callings when a callback returns false - * - */ -jQuery.Callbacks = function( options ) { - - // Convert options from String-formatted to Object-formatted if needed - // (we check in cache first) - options = typeof options === "string" ? - ( optionsCache[ options ] || createOptions( options ) ) : - jQuery.extend( {}, options ); - - var // Flag to know if list is currently firing - firing, - // Last fire value (for non-forgettable lists) - memory, - // Flag to know if list was already fired - fired, - // End of the loop when firing - firingLength, - // Index of currently firing callback (modified by remove if needed) - firingIndex, - // First callback to fire (used internally by add and fireWith) - firingStart, - // Actual callback list - list = [], - // Stack of fire calls for repeatable lists - stack = !options.once && [], - // Fire callbacks - fire = function( data ) { - memory = options.memory && data; - fired = true; - firingIndex = firingStart || 0; - firingStart = 0; - firingLength = list.length; - firing = true; - for ( ; list && firingIndex < firingLength; firingIndex++ ) { - if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { - memory = false; // To prevent further calls using add - break; - } - } - firing = false; - if ( list ) { - if ( stack ) { - if ( stack.length ) { - fire( stack.shift() ); - } - } else if ( memory ) { - list = []; - } else { - self.disable(); - } - } - }, - // Actual Callbacks object - self = { - // Add a callback or a collection of callbacks to the list - add: function() { - if ( list ) { - // First, we save the current length - var start = list.length; - (function add( args ) { - jQuery.each( args, function( _, arg ) { - var type = jQuery.type( arg ); - if ( type === "function" ) { - if ( !options.unique || !self.has( arg ) ) { - list.push( arg ); - } - } else if ( arg && arg.length && type !== "string" ) { - // Inspect recursively - add( arg ); - } - }); - })( arguments ); - // Do we need to add the callbacks to the - // current firing batch? - if ( firing ) { - firingLength = list.length; - // With memory, if we're not firing then - // we should call right away - } else if ( memory ) { - firingStart = start; - fire( memory ); - } - } - return this; - }, - // Remove a callback from the list - remove: function() { - if ( list ) { - jQuery.each( arguments, function( _, arg ) { - var index; - while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { - list.splice( index, 1 ); - // Handle firing indexes - if ( firing ) { - if ( index <= firingLength ) { - firingLength--; - } - if ( index <= firingIndex ) { - firingIndex--; - } - } - } - }); - } - return this; - }, - // Check if a given callback is in the list. - // If no argument is given, return whether or not list has callbacks attached. - has: function( fn ) { - return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); - }, - // Remove all callbacks from the list - empty: function() { - list = []; - firingLength = 0; - return this; - }, - // Have the list do nothing anymore - disable: function() { - list = stack = memory = undefined; - return this; - }, - // Is it disabled? - disabled: function() { - return !list; - }, - // Lock the list in its current state - lock: function() { - stack = undefined; - if ( !memory ) { - self.disable(); - } - return this; - }, - // Is it locked? - locked: function() { - return !stack; - }, - // Call all callbacks with the given context and arguments - fireWith: function( context, args ) { - if ( list && ( !fired || stack ) ) { - args = args || []; - args = [ context, args.slice ? args.slice() : args ]; - if ( firing ) { - stack.push( args ); - } else { - fire( args ); - } - } - return this; - }, - // Call all the callbacks with the given arguments - fire: function() { - self.fireWith( this, arguments ); - return this; - }, - // To know if the callbacks have already been called at least once - fired: function() { - return !!fired; - } - }; - - return self; -}; - - -jQuery.extend({ - - Deferred: function( func ) { - var tuples = [ - // action, add listener, listener list, final state - [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], - [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], - [ "notify", "progress", jQuery.Callbacks("memory") ] - ], - state = "pending", - promise = { - state: function() { - return state; - }, - always: function() { - deferred.done( arguments ).fail( arguments ); - return this; - }, - then: function( /* fnDone, fnFail, fnProgress */ ) { - var fns = arguments; - return jQuery.Deferred(function( newDefer ) { - jQuery.each( tuples, function( i, tuple ) { - var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; - // deferred[ done | fail | progress ] for forwarding actions to newDefer - deferred[ tuple[1] ](function() { - var returned = fn && fn.apply( this, arguments ); - if ( returned && jQuery.isFunction( returned.promise ) ) { - returned.promise() - .done( newDefer.resolve ) - .fail( newDefer.reject ) - .progress( newDefer.notify ); - } else { - newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); - } - }); - }); - fns = null; - }).promise(); - }, - // Get a promise for this deferred - // If obj is provided, the promise aspect is added to the object - promise: function( obj ) { - return obj != null ? jQuery.extend( obj, promise ) : promise; - } - }, - deferred = {}; - - // Keep pipe for back-compat - promise.pipe = promise.then; - - // Add list-specific methods - jQuery.each( tuples, function( i, tuple ) { - var list = tuple[ 2 ], - stateString = tuple[ 3 ]; - - // promise[ done | fail | progress ] = list.add - promise[ tuple[1] ] = list.add; - - // Handle state - if ( stateString ) { - list.add(function() { - // state = [ resolved | rejected ] - state = stateString; - - // [ reject_list | resolve_list ].disable; progress_list.lock - }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); - } - - // deferred[ resolve | reject | notify ] - deferred[ tuple[0] ] = function() { - deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); - return this; - }; - deferred[ tuple[0] + "With" ] = list.fireWith; - }); - - // Make the deferred a promise - promise.promise( deferred ); - - // Call given func if any - if ( func ) { - func.call( deferred, deferred ); - } - - // All done! - return deferred; - }, - - // Deferred helper - when: function( subordinate /* , ..., subordinateN */ ) { - var i = 0, - resolveValues = slice.call( arguments ), - length = resolveValues.length, - - // the count of uncompleted subordinates - remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, - - // the master Deferred. If resolveValues consist of only a single Deferred, just use that. - deferred = remaining === 1 ? subordinate : jQuery.Deferred(), - - // Update function for both resolve and progress values - updateFunc = function( i, contexts, values ) { - return function( value ) { - contexts[ i ] = this; - values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; - if ( values === progressValues ) { - deferred.notifyWith( contexts, values ); - - } else if ( !(--remaining) ) { - deferred.resolveWith( contexts, values ); - } - }; - }, - - progressValues, progressContexts, resolveContexts; - - // add listeners to Deferred subordinates; treat others as resolved - if ( length > 1 ) { - progressValues = new Array( length ); - progressContexts = new Array( length ); - resolveContexts = new Array( length ); - for ( ; i < length; i++ ) { - if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { - resolveValues[ i ].promise() - .done( updateFunc( i, resolveContexts, resolveValues ) ) - .fail( deferred.reject ) - .progress( updateFunc( i, progressContexts, progressValues ) ); - } else { - --remaining; - } - } - } - - // if we're not waiting on anything, resolve the master - if ( !remaining ) { - deferred.resolveWith( resolveContexts, resolveValues ); - } - - return deferred.promise(); - } -}); - - -// The deferred used on DOM ready -var readyList; - -jQuery.fn.ready = function( fn ) { - // Add the callback - jQuery.ready.promise().done( fn ); - - return this; -}; - -jQuery.extend({ - // Is the DOM ready to be used? Set to true once it occurs. - isReady: false, - - // A counter to track how many items to wait for before - // the ready event fires. See #6781 - readyWait: 1, - - // Hold (or release) the ready event - holdReady: function( hold ) { - if ( hold ) { - jQuery.readyWait++; - } else { - jQuery.ready( true ); - } - }, - - // Handle when the DOM is ready - ready: function( wait ) { - - // Abort if there are pending holds or we're already ready - if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { - return; - } - - // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). - if ( !document.body ) { - return setTimeout( jQuery.ready ); - } - - // Remember that the DOM is ready - jQuery.isReady = true; - - // If a normal DOM Ready event fired, decrement, and wait if need be - if ( wait !== true && --jQuery.readyWait > 0 ) { - return; - } - - // If there are functions bound, to execute - readyList.resolveWith( document, [ jQuery ] ); - - // Trigger any bound ready events - if ( jQuery.fn.triggerHandler ) { - jQuery( document ).triggerHandler( "ready" ); - jQuery( document ).off( "ready" ); - } - } -}); - -/** - * Clean-up method for dom ready events - */ -function detach() { - if ( document.addEventListener ) { - document.removeEventListener( "DOMContentLoaded", completed, false ); - window.removeEventListener( "load", completed, false ); - - } else { - document.detachEvent( "onreadystatechange", completed ); - window.detachEvent( "onload", completed ); - } -} - -/** - * The ready event handler and self cleanup method - */ -function completed() { - // readyState === "complete" is good enough for us to call the dom ready in oldIE - if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) { - detach(); - jQuery.ready(); - } -} - -jQuery.ready.promise = function( obj ) { - if ( !readyList ) { - - readyList = jQuery.Deferred(); - - // Catch cases where $(document).ready() is called after the browser event has already occurred. - // we once tried to use readyState "interactive" here, but it caused issues like the one - // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 - if ( document.readyState === "complete" ) { - // Handle it asynchronously to allow scripts the opportunity to delay ready - setTimeout( jQuery.ready ); - - // Standards-based browsers support DOMContentLoaded - } else if ( document.addEventListener ) { - // Use the handy event callback - document.addEventListener( "DOMContentLoaded", completed, false ); - - // A fallback to window.onload, that will always work - window.addEventListener( "load", completed, false ); - - // If IE event model is used - } else { - // Ensure firing before onload, maybe late but safe also for iframes - document.attachEvent( "onreadystatechange", completed ); - - // A fallback to window.onload, that will always work - window.attachEvent( "onload", completed ); - - // If IE and not a frame - // continually check to see if the document is ready - var top = false; - - try { - top = window.frameElement == null && document.documentElement; - } catch(e) {} - - if ( top && top.doScroll ) { - (function doScrollCheck() { - if ( !jQuery.isReady ) { - - try { - // Use the trick by Diego Perini - // http://javascript.nwbox.com/IEContentLoaded/ - top.doScroll("left"); - } catch(e) { - return setTimeout( doScrollCheck, 50 ); - } - - // detach all dom ready events - detach(); - - // and execute any waiting functions - jQuery.ready(); - } - })(); - } - } - } - return readyList.promise( obj ); -}; - - -var strundefined = typeof undefined; - - - -// Support: IE<9 -// Iteration over object's inherited properties before its own -var i; -for ( i in jQuery( support ) ) { - break; -} -support.ownLast = i !== "0"; - -// Note: most support tests are defined in their respective modules. -// false until the test is run -support.inlineBlockNeedsLayout = false; - -// Execute ASAP in case we need to set body.style.zoom -jQuery(function() { - // Minified: var a,b,c,d - var val, div, body, container; - - body = document.getElementsByTagName( "body" )[ 0 ]; - if ( !body || !body.style ) { - // Return for frameset docs that don't have a body - return; - } - - // Setup - div = document.createElement( "div" ); - container = document.createElement( "div" ); - container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px"; - body.appendChild( container ).appendChild( div ); - - if ( typeof div.style.zoom !== strundefined ) { - // Support: IE<8 - // Check if natively block-level elements act like inline-block - // elements when setting their display to 'inline' and giving - // them layout - div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1"; - - support.inlineBlockNeedsLayout = val = div.offsetWidth === 3; - if ( val ) { - // Prevent IE 6 from affecting layout for positioned elements #11048 - // Prevent IE from shrinking the body in IE 7 mode #12869 - // Support: IE<8 - body.style.zoom = 1; - } - } - - body.removeChild( container ); -}); - - - - -(function() { - var div = document.createElement( "div" ); - - // Execute the test only if not already executed in another module. - if (support.deleteExpando == null) { - // Support: IE<9 - support.deleteExpando = true; - try { - delete div.test; - } catch( e ) { - support.deleteExpando = false; - } - } - - // Null elements to avoid leaks in IE. - div = null; -})(); - - -/** - * Determines whether an object can have data - */ -jQuery.acceptData = function( elem ) { - var noData = jQuery.noData[ (elem.nodeName + " ").toLowerCase() ], - nodeType = +elem.nodeType || 1; - - // Do not set data on non-element DOM nodes because it will not be cleared (#8335). - return nodeType !== 1 && nodeType !== 9 ? - false : - - // Nodes accept data unless otherwise specified; rejection can be conditional - !noData || noData !== true && elem.getAttribute("classid") === noData; -}; - - -var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, - rmultiDash = /([A-Z])/g; - -function dataAttr( elem, key, data ) { - // If nothing was found internally, try to fetch any - // data from the HTML5 data-* attribute - if ( data === undefined && elem.nodeType === 1 ) { - - var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); - - data = elem.getAttribute( name ); - - if ( typeof data === "string" ) { - try { - data = data === "true" ? true : - data === "false" ? false : - data === "null" ? null : - // Only convert to a number if it doesn't change the string - +data + "" === data ? +data : - rbrace.test( data ) ? jQuery.parseJSON( data ) : - data; - } catch( e ) {} - - // Make sure we set the data so it isn't changed later - jQuery.data( elem, key, data ); - - } else { - data = undefined; - } - } - - return data; -} - -// checks a cache object for emptiness -function isEmptyDataObject( obj ) { - var name; - for ( name in obj ) { - - // if the public data object is empty, the private is still empty - if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { - continue; - } - if ( name !== "toJSON" ) { - return false; - } - } - - return true; -} - -function internalData( elem, name, data, pvt /* Internal Use Only */ ) { - if ( !jQuery.acceptData( elem ) ) { - return; - } - - var ret, thisCache, - internalKey = jQuery.expando, - - // We have to handle DOM nodes and JS objects differently because IE6-7 - // can't GC object references properly across the DOM-JS boundary - isNode = elem.nodeType, - - // Only DOM nodes need the global jQuery cache; JS object data is - // attached directly to the object so GC can occur automatically - cache = isNode ? jQuery.cache : elem, - - // Only defining an ID for JS objects if its cache already exists allows - // the code to shortcut on the same path as a DOM node with no cache - id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; - - // Avoid doing any more work than we need to when trying to get data on an - // object that has no data at all - if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string" ) { - return; - } - - if ( !id ) { - // Only DOM nodes need a new unique ID for each element since their data - // ends up in the global cache - if ( isNode ) { - id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++; - } else { - id = internalKey; - } - } - - if ( !cache[ id ] ) { - // Avoid exposing jQuery metadata on plain JS objects when the object - // is serialized using JSON.stringify - cache[ id ] = isNode ? {} : { toJSON: jQuery.noop }; - } - - // An object can be passed to jQuery.data instead of a key/value pair; this gets - // shallow copied over onto the existing cache - if ( typeof name === "object" || typeof name === "function" ) { - if ( pvt ) { - cache[ id ] = jQuery.extend( cache[ id ], name ); - } else { - cache[ id ].data = jQuery.extend( cache[ id ].data, name ); - } - } - - thisCache = cache[ id ]; - - // jQuery data() is stored in a separate object inside the object's internal data - // cache in order to avoid key collisions between internal data and user-defined - // data. - if ( !pvt ) { - if ( !thisCache.data ) { - thisCache.data = {}; - } - - thisCache = thisCache.data; - } - - if ( data !== undefined ) { - thisCache[ jQuery.camelCase( name ) ] = data; - } - - // Check for both converted-to-camel and non-converted data property names - // If a data property was specified - if ( typeof name === "string" ) { - - // First Try to find as-is property data - ret = thisCache[ name ]; - - // Test for null|undefined property data - if ( ret == null ) { - - // Try to find the camelCased property - ret = thisCache[ jQuery.camelCase( name ) ]; - } - } else { - ret = thisCache; - } - - return ret; -} - -function internalRemoveData( elem, name, pvt ) { - if ( !jQuery.acceptData( elem ) ) { - return; - } - - var thisCache, i, - isNode = elem.nodeType, - - // See jQuery.data for more information - cache = isNode ? jQuery.cache : elem, - id = isNode ? elem[ jQuery.expando ] : jQuery.expando; - - // If there is already no cache entry for this object, there is no - // purpose in continuing - if ( !cache[ id ] ) { - return; - } - - if ( name ) { - - thisCache = pvt ? cache[ id ] : cache[ id ].data; - - if ( thisCache ) { - - // Support array or space separated string names for data keys - if ( !jQuery.isArray( name ) ) { - - // try the string as a key before any manipulation - if ( name in thisCache ) { - name = [ name ]; - } else { - - // split the camel cased version by spaces unless a key with the spaces exists - name = jQuery.camelCase( name ); - if ( name in thisCache ) { - name = [ name ]; - } else { - name = name.split(" "); - } - } - } else { - // If "name" is an array of keys... - // When data is initially created, via ("key", "val") signature, - // keys will be converted to camelCase. - // Since there is no way to tell _how_ a key was added, remove - // both plain key and camelCase key. #12786 - // This will only penalize the array argument path. - name = name.concat( jQuery.map( name, jQuery.camelCase ) ); - } - - i = name.length; - while ( i-- ) { - delete thisCache[ name[i] ]; - } - - // If there is no data left in the cache, we want to continue - // and let the cache object itself get destroyed - if ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) { - return; - } - } - } - - // See jQuery.data for more information - if ( !pvt ) { - delete cache[ id ].data; - - // Don't destroy the parent cache unless the internal data object - // had been the only thing left in it - if ( !isEmptyDataObject( cache[ id ] ) ) { - return; - } - } - - // Destroy the cache - if ( isNode ) { - jQuery.cleanData( [ elem ], true ); - - // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) - /* jshint eqeqeq: false */ - } else if ( support.deleteExpando || cache != cache.window ) { - /* jshint eqeqeq: true */ - delete cache[ id ]; - - // When all else fails, null - } else { - cache[ id ] = null; - } -} - -jQuery.extend({ - cache: {}, - - // The following elements (space-suffixed to avoid Object.prototype collisions) - // throw uncatchable exceptions if you attempt to set expando properties - noData: { - "applet ": true, - "embed ": true, - // ...but Flash objects (which have this classid) *can* handle expandos - "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" - }, - - hasData: function( elem ) { - elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; - return !!elem && !isEmptyDataObject( elem ); - }, - - data: function( elem, name, data ) { - return internalData( elem, name, data ); - }, - - removeData: function( elem, name ) { - return internalRemoveData( elem, name ); - }, - - // For internal use only. - _data: function( elem, name, data ) { - return internalData( elem, name, data, true ); - }, - - _removeData: function( elem, name ) { - return internalRemoveData( elem, name, true ); - } -}); - -jQuery.fn.extend({ - data: function( key, value ) { - var i, name, data, - elem = this[0], - attrs = elem && elem.attributes; - - // Special expections of .data basically thwart jQuery.access, - // so implement the relevant behavior ourselves - - // Gets all values - if ( key === undefined ) { - if ( this.length ) { - data = jQuery.data( elem ); - - if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { - i = attrs.length; - while ( i-- ) { - - // Support: IE11+ - // The attrs elements can be null (#14894) - if ( attrs[ i ] ) { - name = attrs[ i ].name; - if ( name.indexOf( "data-" ) === 0 ) { - name = jQuery.camelCase( name.slice(5) ); - dataAttr( elem, name, data[ name ] ); - } - } - } - jQuery._data( elem, "parsedAttrs", true ); - } - } - - return data; - } - - // Sets multiple values - if ( typeof key === "object" ) { - return this.each(function() { - jQuery.data( this, key ); - }); - } - - return arguments.length > 1 ? - - // Sets one value - this.each(function() { - jQuery.data( this, key, value ); - }) : - - // Gets one value - // Try to fetch any internally stored data first - elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined; - }, - - removeData: function( key ) { - return this.each(function() { - jQuery.removeData( this, key ); - }); - } -}); - - -jQuery.extend({ - queue: function( elem, type, data ) { - var queue; - - if ( elem ) { - type = ( type || "fx" ) + "queue"; - queue = jQuery._data( elem, type ); - - // Speed up dequeue by getting out quickly if this is just a lookup - if ( data ) { - if ( !queue || jQuery.isArray(data) ) { - queue = jQuery._data( elem, type, jQuery.makeArray(data) ); - } else { - queue.push( data ); - } - } - return queue || []; - } - }, - - dequeue: function( elem, type ) { - type = type || "fx"; - - var queue = jQuery.queue( elem, type ), - startLength = queue.length, - fn = queue.shift(), - hooks = jQuery._queueHooks( elem, type ), - next = function() { - jQuery.dequeue( elem, type ); - }; - - // If the fx queue is dequeued, always remove the progress sentinel - if ( fn === "inprogress" ) { - fn = queue.shift(); - startLength--; - } - - if ( fn ) { - - // Add a progress sentinel to prevent the fx queue from being - // automatically dequeued - if ( type === "fx" ) { - queue.unshift( "inprogress" ); - } - - // clear up the last queue stop function - delete hooks.stop; - fn.call( elem, next, hooks ); - } - - if ( !startLength && hooks ) { - hooks.empty.fire(); - } - }, - - // not intended for public consumption - generates a queueHooks object, or returns the current one - _queueHooks: function( elem, type ) { - var key = type + "queueHooks"; - return jQuery._data( elem, key ) || jQuery._data( elem, key, { - empty: jQuery.Callbacks("once memory").add(function() { - jQuery._removeData( elem, type + "queue" ); - jQuery._removeData( elem, key ); - }) - }); - } -}); - -jQuery.fn.extend({ - queue: function( type, data ) { - var setter = 2; - - if ( typeof type !== "string" ) { - data = type; - type = "fx"; - setter--; - } - - if ( arguments.length < setter ) { - return jQuery.queue( this[0], type ); - } - - return data === undefined ? - this : - this.each(function() { - var queue = jQuery.queue( this, type, data ); - - // ensure a hooks for this queue - jQuery._queueHooks( this, type ); - - if ( type === "fx" && queue[0] !== "inprogress" ) { - jQuery.dequeue( this, type ); - } - }); - }, - dequeue: function( type ) { - return this.each(function() { - jQuery.dequeue( this, type ); - }); - }, - clearQueue: function( type ) { - return this.queue( type || "fx", [] ); - }, - // Get a promise resolved when queues of a certain type - // are emptied (fx is the type by default) - promise: function( type, obj ) { - var tmp, - count = 1, - defer = jQuery.Deferred(), - elements = this, - i = this.length, - resolve = function() { - if ( !( --count ) ) { - defer.resolveWith( elements, [ elements ] ); - } - }; - - if ( typeof type !== "string" ) { - obj = type; - type = undefined; - } - type = type || "fx"; - - while ( i-- ) { - tmp = jQuery._data( elements[ i ], type + "queueHooks" ); - if ( tmp && tmp.empty ) { - count++; - tmp.empty.add( resolve ); - } - } - resolve(); - return defer.promise( obj ); - } -}); -var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source; - -var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; - -var isHidden = function( elem, el ) { - // isHidden might be called from jQuery#filter function; - // in that case, element will be second argument - elem = el || elem; - return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); - }; - - - -// Multifunctional method to get and set values of a collection -// The value/s can optionally be executed if it's a function -var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) { - var i = 0, - length = elems.length, - bulk = key == null; - - // Sets many values - if ( jQuery.type( key ) === "object" ) { - chainable = true; - for ( i in key ) { - jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); - } - - // Sets one value - } else if ( value !== undefined ) { - chainable = true; - - if ( !jQuery.isFunction( value ) ) { - raw = true; - } - - if ( bulk ) { - // Bulk operations run against the entire set - if ( raw ) { - fn.call( elems, value ); - fn = null; - - // ...except when executing function values - } else { - bulk = fn; - fn = function( elem, key, value ) { - return bulk.call( jQuery( elem ), value ); - }; - } - } - - if ( fn ) { - for ( ; i < length; i++ ) { - fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); - } - } - } - - return chainable ? - elems : - - // Gets - bulk ? - fn.call( elems ) : - length ? fn( elems[0], key ) : emptyGet; -}; -var rcheckableType = (/^(?:checkbox|radio)$/i); - - - -(function() { - // Minified: var a,b,c - var input = document.createElement( "input" ), - div = document.createElement( "div" ), - fragment = document.createDocumentFragment(); - - // Setup - div.innerHTML = "
a"; - - // IE strips leading whitespace when .innerHTML is used - support.leadingWhitespace = div.firstChild.nodeType === 3; - - // Make sure that tbody elements aren't automatically inserted - // IE will insert them into empty tables - support.tbody = !div.getElementsByTagName( "tbody" ).length; - - // Make sure that link elements get serialized correctly by innerHTML - // This requires a wrapper element in IE - support.htmlSerialize = !!div.getElementsByTagName( "link" ).length; - - // Makes sure cloning an html5 element does not cause problems - // Where outerHTML is undefined, this still works - support.html5Clone = - document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav>"; - - // Check if a disconnected checkbox will retain its checked - // value of true after appended to the DOM (IE6/7) - input.type = "checkbox"; - input.checked = true; - fragment.appendChild( input ); - support.appendChecked = input.checked; - - // Make sure textarea (and checkbox) defaultValue is properly cloned - // Support: IE6-IE11+ - div.innerHTML = ""; - support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; - - // #11217 - WebKit loses check when the name is after the checked attribute - fragment.appendChild( div ); - div.innerHTML = ""; - - // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3 - // old WebKit doesn't clone checked state correctly in fragments - support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; - - // Support: IE<9 - // Opera does not clone events (and typeof div.attachEvent === undefined). - // IE9-10 clones events bound via attachEvent, but they don't trigger with .click() - support.noCloneEvent = true; - if ( div.attachEvent ) { - div.attachEvent( "onclick", function() { - support.noCloneEvent = false; - }); - - div.cloneNode( true ).click(); - } - - // Execute the test only if not already executed in another module. - if (support.deleteExpando == null) { - // Support: IE<9 - support.deleteExpando = true; - try { - delete div.test; - } catch( e ) { - support.deleteExpando = false; - } - } -})(); - - -(function() { - var i, eventName, - div = document.createElement( "div" ); - - // Support: IE<9 (lack submit/change bubble), Firefox 23+ (lack focusin event) - for ( i in { submit: true, change: true, focusin: true }) { - eventName = "on" + i; - - if ( !(support[ i + "Bubbles" ] = eventName in window) ) { - // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP) - div.setAttribute( eventName, "t" ); - support[ i + "Bubbles" ] = div.attributes[ eventName ].expando === false; - } - } - - // Null elements to avoid leaks in IE. - div = null; -})(); - - -var rformElems = /^(?:input|select|textarea)$/i, - rkeyEvent = /^key/, - rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/, - rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, - rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; - -function returnTrue() { - return true; -} - -function returnFalse() { - return false; -} - -function safeActiveElement() { - try { - return document.activeElement; - } catch ( err ) { } -} - -/* - * Helper functions for managing events -- not part of the public interface. - * Props to Dean Edwards' addEvent library for many of the ideas. - */ -jQuery.event = { - - global: {}, - - add: function( elem, types, handler, data, selector ) { - var tmp, events, t, handleObjIn, - special, eventHandle, handleObj, - handlers, type, namespaces, origType, - elemData = jQuery._data( elem ); - - // Don't attach events to noData or text/comment nodes (but allow plain objects) - if ( !elemData ) { - return; - } - - // Caller can pass in an object of custom data in lieu of the handler - if ( handler.handler ) { - handleObjIn = handler; - handler = handleObjIn.handler; - selector = handleObjIn.selector; - } - - // Make sure that the handler has a unique ID, used to find/remove it later - if ( !handler.guid ) { - handler.guid = jQuery.guid++; - } - - // Init the element's event structure and main handler, if this is the first - if ( !(events = elemData.events) ) { - events = elemData.events = {}; - } - if ( !(eventHandle = elemData.handle) ) { - eventHandle = elemData.handle = function( e ) { - // Discard the second event of a jQuery.event.trigger() and - // when an event is called after a page has unloaded - return typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ? - jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : - undefined; - }; - // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events - eventHandle.elem = elem; - } - - // Handle multiple events separated by a space - types = ( types || "" ).match( rnotwhite ) || [ "" ]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[t] ) || []; - type = origType = tmp[1]; - namespaces = ( tmp[2] || "" ).split( "." ).sort(); - - // There *must* be a type, no attaching namespace-only handlers - if ( !type ) { - continue; - } - - // If event changes its type, use the special event handlers for the changed type - special = jQuery.event.special[ type ] || {}; - - // If selector defined, determine special event api type, otherwise given type - type = ( selector ? special.delegateType : special.bindType ) || type; - - // Update special based on newly reset type - special = jQuery.event.special[ type ] || {}; - - // handleObj is passed to all event handlers - handleObj = jQuery.extend({ - type: type, - origType: origType, - data: data, - handler: handler, - guid: handler.guid, - selector: selector, - needsContext: selector && jQuery.expr.match.needsContext.test( selector ), - namespace: namespaces.join(".") - }, handleObjIn ); - - // Init the event handler queue if we're the first - if ( !(handlers = events[ type ]) ) { - handlers = events[ type ] = []; - handlers.delegateCount = 0; - - // Only use addEventListener/attachEvent if the special events handler returns false - if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { - // Bind the global event handler to the element - if ( elem.addEventListener ) { - elem.addEventListener( type, eventHandle, false ); - - } else if ( elem.attachEvent ) { - elem.attachEvent( "on" + type, eventHandle ); - } - } - } - - if ( special.add ) { - special.add.call( elem, handleObj ); - - if ( !handleObj.handler.guid ) { - handleObj.handler.guid = handler.guid; - } - } - - // Add to the element's handler list, delegates in front - if ( selector ) { - handlers.splice( handlers.delegateCount++, 0, handleObj ); - } else { - handlers.push( handleObj ); - } - - // Keep track of which events have ever been used, for event optimization - jQuery.event.global[ type ] = true; - } - - // Nullify elem to prevent memory leaks in IE - elem = null; - }, - - // Detach an event or set of events from an element - remove: function( elem, types, handler, selector, mappedTypes ) { - var j, handleObj, tmp, - origCount, t, events, - special, handlers, type, - namespaces, origType, - elemData = jQuery.hasData( elem ) && jQuery._data( elem ); - - if ( !elemData || !(events = elemData.events) ) { - return; - } - - // Once for each type.namespace in types; type may be omitted - types = ( types || "" ).match( rnotwhite ) || [ "" ]; - t = types.length; - while ( t-- ) { - tmp = rtypenamespace.exec( types[t] ) || []; - type = origType = tmp[1]; - namespaces = ( tmp[2] || "" ).split( "." ).sort(); - - // Unbind all events (on this namespace, if provided) for the element - if ( !type ) { - for ( type in events ) { - jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); - } - continue; - } - - special = jQuery.event.special[ type ] || {}; - type = ( selector ? special.delegateType : special.bindType ) || type; - handlers = events[ type ] || []; - tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); - - // Remove matching events - origCount = j = handlers.length; - while ( j-- ) { - handleObj = handlers[ j ]; - - if ( ( mappedTypes || origType === handleObj.origType ) && - ( !handler || handler.guid === handleObj.guid ) && - ( !tmp || tmp.test( handleObj.namespace ) ) && - ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { - handlers.splice( j, 1 ); - - if ( handleObj.selector ) { - handlers.delegateCount--; - } - if ( special.remove ) { - special.remove.call( elem, handleObj ); - } - } - } - - // Remove generic event handler if we removed something and no more handlers exist - // (avoids potential for endless recursion during removal of special event handlers) - if ( origCount && !handlers.length ) { - if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { - jQuery.removeEvent( elem, type, elemData.handle ); - } - - delete events[ type ]; - } - } - - // Remove the expando if it's no longer used - if ( jQuery.isEmptyObject( events ) ) { - delete elemData.handle; - - // removeData also checks for emptiness and clears the expando if empty - // so use it instead of delete - jQuery._removeData( elem, "events" ); - } - }, - - trigger: function( event, data, elem, onlyHandlers ) { - var handle, ontype, cur, - bubbleType, special, tmp, i, - eventPath = [ elem || document ], - type = hasOwn.call( event, "type" ) ? event.type : event, - namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; - - cur = tmp = elem = elem || document; - - // Don't do events on text and comment nodes - if ( elem.nodeType === 3 || elem.nodeType === 8 ) { - return; - } - - // focus/blur morphs to focusin/out; ensure we're not firing them right now - if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { - return; - } - - if ( type.indexOf(".") >= 0 ) { - // Namespaced trigger; create a regexp to match event type in handle() - namespaces = type.split("."); - type = namespaces.shift(); - namespaces.sort(); - } - ontype = type.indexOf(":") < 0 && "on" + type; - - // Caller can pass in a jQuery.Event object, Object, or just an event type string - event = event[ jQuery.expando ] ? - event : - new jQuery.Event( type, typeof event === "object" && event ); - - // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) - event.isTrigger = onlyHandlers ? 2 : 3; - event.namespace = namespaces.join("."); - event.namespace_re = event.namespace ? - new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : - null; - - // Clean up the event in case it is being reused - event.result = undefined; - if ( !event.target ) { - event.target = elem; - } - - // Clone any incoming data and prepend the event, creating the handler arg list - data = data == null ? - [ event ] : - jQuery.makeArray( data, [ event ] ); - - // Allow special events to draw outside the lines - special = jQuery.event.special[ type ] || {}; - if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { - return; - } - - // Determine event propagation path in advance, per W3C events spec (#9951) - // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) - if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { - - bubbleType = special.delegateType || type; - if ( !rfocusMorph.test( bubbleType + type ) ) { - cur = cur.parentNode; - } - for ( ; cur; cur = cur.parentNode ) { - eventPath.push( cur ); - tmp = cur; - } - - // Only add window if we got to document (e.g., not plain obj or detached DOM) - if ( tmp === (elem.ownerDocument || document) ) { - eventPath.push( tmp.defaultView || tmp.parentWindow || window ); - } - } - - // Fire handlers on the event path - i = 0; - while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { - - event.type = i > 1 ? - bubbleType : - special.bindType || type; - - // jQuery handler - handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); - if ( handle ) { - handle.apply( cur, data ); - } - - // Native handler - handle = ontype && cur[ ontype ]; - if ( handle && handle.apply && jQuery.acceptData( cur ) ) { - event.result = handle.apply( cur, data ); - if ( event.result === false ) { - event.preventDefault(); - } - } - } - event.type = type; - - // If nobody prevented the default action, do it now - if ( !onlyHandlers && !event.isDefaultPrevented() ) { - - if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && - jQuery.acceptData( elem ) ) { - - // Call a native DOM method on the target with the same name name as the event. - // Can't use an .isFunction() check here because IE6/7 fails that test. - // Don't do default actions on window, that's where global variables be (#6170) - if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) { - - // Don't re-trigger an onFOO event when we call its FOO() method - tmp = elem[ ontype ]; - - if ( tmp ) { - elem[ ontype ] = null; - } - - // Prevent re-triggering of the same event, since we already bubbled it above - jQuery.event.triggered = type; - try { - elem[ type ](); - } catch ( e ) { - // IE<9 dies on focus/blur to hidden element (#1486,#12518) - // only reproducible on winXP IE8 native, not IE9 in IE8 mode - } - jQuery.event.triggered = undefined; - - if ( tmp ) { - elem[ ontype ] = tmp; - } - } - } - } - - return event.result; - }, - - dispatch: function( event ) { - - // Make a writable jQuery.Event from the native event object - event = jQuery.event.fix( event ); - - var i, ret, handleObj, matched, j, - handlerQueue = [], - args = slice.call( arguments ), - handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], - special = jQuery.event.special[ event.type ] || {}; - - // Use the fix-ed jQuery.Event rather than the (read-only) native event - args[0] = event; - event.delegateTarget = this; - - // Call the preDispatch hook for the mapped type, and let it bail if desired - if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { - return; - } - - // Determine handlers - handlerQueue = jQuery.event.handlers.call( this, event, handlers ); - - // Run delegates first; they may want to stop propagation beneath us - i = 0; - while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { - event.currentTarget = matched.elem; - - j = 0; - while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { - - // Triggered event must either 1) have no namespace, or - // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). - if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { - - event.handleObj = handleObj; - event.data = handleObj.data; - - ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) - .apply( matched.elem, args ); - - if ( ret !== undefined ) { - if ( (event.result = ret) === false ) { - event.preventDefault(); - event.stopPropagation(); - } - } - } - } - } - - // Call the postDispatch hook for the mapped type - if ( special.postDispatch ) { - special.postDispatch.call( this, event ); - } - - return event.result; - }, - - handlers: function( event, handlers ) { - var sel, handleObj, matches, i, - handlerQueue = [], - delegateCount = handlers.delegateCount, - cur = event.target; - - // Find delegate handlers - // Black-hole SVG instance trees (#13180) - // Avoid non-left-click bubbling in Firefox (#3861) - if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { - - /* jshint eqeqeq: false */ - for ( ; cur != this; cur = cur.parentNode || this ) { - /* jshint eqeqeq: true */ - - // Don't check non-elements (#13208) - // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) - if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) { - matches = []; - for ( i = 0; i < delegateCount; i++ ) { - handleObj = handlers[ i ]; - - // Don't conflict with Object.prototype properties (#13203) - sel = handleObj.selector + " "; - - if ( matches[ sel ] === undefined ) { - matches[ sel ] = handleObj.needsContext ? - jQuery( sel, this ).index( cur ) >= 0 : - jQuery.find( sel, this, null, [ cur ] ).length; - } - if ( matches[ sel ] ) { - matches.push( handleObj ); - } - } - if ( matches.length ) { - handlerQueue.push({ elem: cur, handlers: matches }); - } - } - } - } - - // Add the remaining (directly-bound) handlers - if ( delegateCount < handlers.length ) { - handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); - } - - return handlerQueue; - }, - - fix: function( event ) { - if ( event[ jQuery.expando ] ) { - return event; - } - - // Create a writable copy of the event object and normalize some properties - var i, prop, copy, - type = event.type, - originalEvent = event, - fixHook = this.fixHooks[ type ]; - - if ( !fixHook ) { - this.fixHooks[ type ] = fixHook = - rmouseEvent.test( type ) ? this.mouseHooks : - rkeyEvent.test( type ) ? this.keyHooks : - {}; - } - copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; - - event = new jQuery.Event( originalEvent ); - - i = copy.length; - while ( i-- ) { - prop = copy[ i ]; - event[ prop ] = originalEvent[ prop ]; - } - - // Support: IE<9 - // Fix target property (#1925) - if ( !event.target ) { - event.target = originalEvent.srcElement || document; - } - - // Support: Chrome 23+, Safari? - // Target should not be a text node (#504, #13143) - if ( event.target.nodeType === 3 ) { - event.target = event.target.parentNode; - } - - // Support: IE<9 - // For mouse/key events, metaKey==false if it's undefined (#3368, #11328) - event.metaKey = !!event.metaKey; - - return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; - }, - - // Includes some event props shared by KeyEvent and MouseEvent - props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), - - fixHooks: {}, - - keyHooks: { - props: "char charCode key keyCode".split(" "), - filter: function( event, original ) { - - // Add which for key events - if ( event.which == null ) { - event.which = original.charCode != null ? original.charCode : original.keyCode; - } - - return event; - } - }, - - mouseHooks: { - props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), - filter: function( event, original ) { - var body, eventDoc, doc, - button = original.button, - fromElement = original.fromElement; - - // Calculate pageX/Y if missing and clientX/Y available - if ( event.pageX == null && original.clientX != null ) { - eventDoc = event.target.ownerDocument || document; - doc = eventDoc.documentElement; - body = eventDoc.body; - - event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); - event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); - } - - // Add relatedTarget, if necessary - if ( !event.relatedTarget && fromElement ) { - event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; - } - - // Add which for click: 1 === left; 2 === middle; 3 === right - // Note: button is not normalized, so don't use it - if ( !event.which && button !== undefined ) { - event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); - } - - return event; - } - }, - - special: { - load: { - // Prevent triggered image.load events from bubbling to window.load - noBubble: true - }, - focus: { - // Fire native event if possible so blur/focus sequence is correct - trigger: function() { - if ( this !== safeActiveElement() && this.focus ) { - try { - this.focus(); - return false; - } catch ( e ) { - // Support: IE<9 - // If we error on focus to hidden element (#1486, #12518), - // let .trigger() run the handlers - } - } - }, - delegateType: "focusin" - }, - blur: { - trigger: function() { - if ( this === safeActiveElement() && this.blur ) { - this.blur(); - return false; - } - }, - delegateType: "focusout" - }, - click: { - // For checkbox, fire native event so checked state will be right - trigger: function() { - if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) { - this.click(); - return false; - } - }, - - // For cross-browser consistency, don't fire native .click() on links - _default: function( event ) { - return jQuery.nodeName( event.target, "a" ); - } - }, - - beforeunload: { - postDispatch: function( event ) { - - // Support: Firefox 20+ - // Firefox doesn't alert if the returnValue field is not set. - if ( event.result !== undefined && event.originalEvent ) { - event.originalEvent.returnValue = event.result; - } - } - } - }, - - simulate: function( type, elem, event, bubble ) { - // Piggyback on a donor event to simulate a different one. - // Fake originalEvent to avoid donor's stopPropagation, but if the - // simulated event prevents default then we do the same on the donor. - var e = jQuery.extend( - new jQuery.Event(), - event, - { - type: type, - isSimulated: true, - originalEvent: {} - } - ); - if ( bubble ) { - jQuery.event.trigger( e, null, elem ); - } else { - jQuery.event.dispatch.call( elem, e ); - } - if ( e.isDefaultPrevented() ) { - event.preventDefault(); - } - } -}; - -jQuery.removeEvent = document.removeEventListener ? - function( elem, type, handle ) { - if ( elem.removeEventListener ) { - elem.removeEventListener( type, handle, false ); - } - } : - function( elem, type, handle ) { - var name = "on" + type; - - if ( elem.detachEvent ) { - - // #8545, #7054, preventing memory leaks for custom events in IE6-8 - // detachEvent needed property on element, by name of that event, to properly expose it to GC - if ( typeof elem[ name ] === strundefined ) { - elem[ name ] = null; - } - - elem.detachEvent( name, handle ); - } - }; - -jQuery.Event = function( src, props ) { - // Allow instantiation without the 'new' keyword - if ( !(this instanceof jQuery.Event) ) { - return new jQuery.Event( src, props ); - } - - // Event object - if ( src && src.type ) { - this.originalEvent = src; - this.type = src.type; - - // Events bubbling up the document may have been marked as prevented - // by a handler lower down the tree; reflect the correct value. - this.isDefaultPrevented = src.defaultPrevented || - src.defaultPrevented === undefined && - // Support: IE < 9, Android < 4.0 - src.returnValue === false ? - returnTrue : - returnFalse; - - // Event type - } else { - this.type = src; - } - - // Put explicitly provided properties onto the event object - if ( props ) { - jQuery.extend( this, props ); - } - - // Create a timestamp if incoming event doesn't have one - this.timeStamp = src && src.timeStamp || jQuery.now(); - - // Mark it as fixed - this[ jQuery.expando ] = true; -}; - -// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding -// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html -jQuery.Event.prototype = { - isDefaultPrevented: returnFalse, - isPropagationStopped: returnFalse, - isImmediatePropagationStopped: returnFalse, - - preventDefault: function() { - var e = this.originalEvent; - - this.isDefaultPrevented = returnTrue; - if ( !e ) { - return; - } - - // If preventDefault exists, run it on the original event - if ( e.preventDefault ) { - e.preventDefault(); - - // Support: IE - // Otherwise set the returnValue property of the original event to false - } else { - e.returnValue = false; - } - }, - stopPropagation: function() { - var e = this.originalEvent; - - this.isPropagationStopped = returnTrue; - if ( !e ) { - return; - } - // If stopPropagation exists, run it on the original event - if ( e.stopPropagation ) { - e.stopPropagation(); - } - - // Support: IE - // Set the cancelBubble property of the original event to true - e.cancelBubble = true; - }, - stopImmediatePropagation: function() { - var e = this.originalEvent; - - this.isImmediatePropagationStopped = returnTrue; - - if ( e && e.stopImmediatePropagation ) { - e.stopImmediatePropagation(); - } - - this.stopPropagation(); - } -}; - -// Create mouseenter/leave events using mouseover/out and event-time checks -jQuery.each({ - mouseenter: "mouseover", - mouseleave: "mouseout", - pointerenter: "pointerover", - pointerleave: "pointerout" -}, function( orig, fix ) { - jQuery.event.special[ orig ] = { - delegateType: fix, - bindType: fix, - - handle: function( event ) { - var ret, - target = this, - related = event.relatedTarget, - handleObj = event.handleObj; - - // For mousenter/leave call the handler if related is outside the target. - // NB: No relatedTarget if the mouse left/entered the browser window - if ( !related || (related !== target && !jQuery.contains( target, related )) ) { - event.type = handleObj.origType; - ret = handleObj.handler.apply( this, arguments ); - event.type = fix; - } - return ret; - } - }; -}); - -// IE submit delegation -if ( !support.submitBubbles ) { - - jQuery.event.special.submit = { - setup: function() { - // Only need this for delegated form submit events - if ( jQuery.nodeName( this, "form" ) ) { - return false; - } - - // Lazy-add a submit handler when a descendant form may potentially be submitted - jQuery.event.add( this, "click._submit keypress._submit", function( e ) { - // Node name check avoids a VML-related crash in IE (#9807) - var elem = e.target, - form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; - if ( form && !jQuery._data( form, "submitBubbles" ) ) { - jQuery.event.add( form, "submit._submit", function( event ) { - event._submit_bubble = true; - }); - jQuery._data( form, "submitBubbles", true ); - } - }); - // return undefined since we don't need an event listener - }, - - postDispatch: function( event ) { - // If form was submitted by the user, bubble the event up the tree - if ( event._submit_bubble ) { - delete event._submit_bubble; - if ( this.parentNode && !event.isTrigger ) { - jQuery.event.simulate( "submit", this.parentNode, event, true ); - } - } - }, - - teardown: function() { - // Only need this for delegated form submit events - if ( jQuery.nodeName( this, "form" ) ) { - return false; - } - - // Remove delegated handlers; cleanData eventually reaps submit handlers attached above - jQuery.event.remove( this, "._submit" ); - } - }; -} - -// IE change delegation and checkbox/radio fix -if ( !support.changeBubbles ) { - - jQuery.event.special.change = { - - setup: function() { - - if ( rformElems.test( this.nodeName ) ) { - // IE doesn't fire change on a check/radio until blur; trigger it on click - // after a propertychange. Eat the blur-change in special.change.handle. - // This still fires onchange a second time for check/radio after blur. - if ( this.type === "checkbox" || this.type === "radio" ) { - jQuery.event.add( this, "propertychange._change", function( event ) { - if ( event.originalEvent.propertyName === "checked" ) { - this._just_changed = true; - } - }); - jQuery.event.add( this, "click._change", function( event ) { - if ( this._just_changed && !event.isTrigger ) { - this._just_changed = false; - } - // Allow triggered, simulated change events (#11500) - jQuery.event.simulate( "change", this, event, true ); - }); - } - return false; - } - // Delegated event; lazy-add a change handler on descendant inputs - jQuery.event.add( this, "beforeactivate._change", function( e ) { - var elem = e.target; - - if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) { - jQuery.event.add( elem, "change._change", function( event ) { - if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { - jQuery.event.simulate( "change", this.parentNode, event, true ); - } - }); - jQuery._data( elem, "changeBubbles", true ); - } - }); - }, - - handle: function( event ) { - var elem = event.target; - - // Swallow native change events from checkbox/radio, we already triggered them above - if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { - return event.handleObj.handler.apply( this, arguments ); - } - }, - - teardown: function() { - jQuery.event.remove( this, "._change" ); - - return !rformElems.test( this.nodeName ); - } - }; -} - -// Create "bubbling" focus and blur events -if ( !support.focusinBubbles ) { - jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { - - // Attach a single capturing handler on the document while someone wants focusin/focusout - var handler = function( event ) { - jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); - }; - - jQuery.event.special[ fix ] = { - setup: function() { - var doc = this.ownerDocument || this, - attaches = jQuery._data( doc, fix ); - - if ( !attaches ) { - doc.addEventListener( orig, handler, true ); - } - jQuery._data( doc, fix, ( attaches || 0 ) + 1 ); - }, - teardown: function() { - var doc = this.ownerDocument || this, - attaches = jQuery._data( doc, fix ) - 1; - - if ( !attaches ) { - doc.removeEventListener( orig, handler, true ); - jQuery._removeData( doc, fix ); - } else { - jQuery._data( doc, fix, attaches ); - } - } - }; - }); -} - -jQuery.fn.extend({ - - on: function( types, selector, data, fn, /*INTERNAL*/ one ) { - var type, origFn; - - // Types can be a map of types/handlers - if ( typeof types === "object" ) { - // ( types-Object, selector, data ) - if ( typeof selector !== "string" ) { - // ( types-Object, data ) - data = data || selector; - selector = undefined; - } - for ( type in types ) { - this.on( type, selector, data, types[ type ], one ); - } - return this; - } - - if ( data == null && fn == null ) { - // ( types, fn ) - fn = selector; - data = selector = undefined; - } else if ( fn == null ) { - if ( typeof selector === "string" ) { - // ( types, selector, fn ) - fn = data; - data = undefined; - } else { - // ( types, data, fn ) - fn = data; - data = selector; - selector = undefined; - } - } - if ( fn === false ) { - fn = returnFalse; - } else if ( !fn ) { - return this; - } - - if ( one === 1 ) { - origFn = fn; - fn = function( event ) { - // Can use an empty set, since event contains the info - jQuery().off( event ); - return origFn.apply( this, arguments ); - }; - // Use same guid so caller can remove using origFn - fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); - } - return this.each( function() { - jQuery.event.add( this, types, fn, data, selector ); - }); - }, - one: function( types, selector, data, fn ) { - return this.on( types, selector, data, fn, 1 ); - }, - off: function( types, selector, fn ) { - var handleObj, type; - if ( types && types.preventDefault && types.handleObj ) { - // ( event ) dispatched jQuery.Event - handleObj = types.handleObj; - jQuery( types.delegateTarget ).off( - handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, - handleObj.selector, - handleObj.handler - ); - return this; - } - if ( typeof types === "object" ) { - // ( types-object [, selector] ) - for ( type in types ) { - this.off( type, selector, types[ type ] ); - } - return this; - } - if ( selector === false || typeof selector === "function" ) { - // ( types [, fn] ) - fn = selector; - selector = undefined; - } - if ( fn === false ) { - fn = returnFalse; - } - return this.each(function() { - jQuery.event.remove( this, types, fn, selector ); - }); - }, - - trigger: function( type, data ) { - return this.each(function() { - jQuery.event.trigger( type, data, this ); - }); - }, - triggerHandler: function( type, data ) { - var elem = this[0]; - if ( elem ) { - return jQuery.event.trigger( type, data, elem, true ); - } - } -}); - - -function createSafeFragment( document ) { - var list = nodeNames.split( "|" ), - safeFrag = document.createDocumentFragment(); - - if ( safeFrag.createElement ) { - while ( list.length ) { - safeFrag.createElement( - list.pop() - ); - } - } - return safeFrag; -} - -var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + - "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", - rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, - rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"), - rleadingWhitespace = /^\s+/, - rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, - rtagName = /<([\w:]+)/, - rtbody = /\s*$/g, - - // We have to close these tags to support XHTML (#13200) - wrapMap = { - option: [ 1, "" ], - legend: [ 1, "
", "
" ], - area: [ 1, "", "" ], - param: [ 1, "", "" ], - thead: [ 1, "", "
" ], - tr: [ 2, "", "
" ], - col: [ 2, "", "
" ], - td: [ 3, "", "
" ], - - // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, - // unless wrapped in a div with non-breaking characters in front of it. - _default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X
", "
" ] - }, - safeFragment = createSafeFragment( document ), - fragmentDiv = safeFragment.appendChild( document.createElement("div") ); - -wrapMap.optgroup = wrapMap.option; -wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; -wrapMap.th = wrapMap.td; - -function getAll( context, tag ) { - var elems, elem, - i = 0, - found = typeof context.getElementsByTagName !== strundefined ? context.getElementsByTagName( tag || "*" ) : - typeof context.querySelectorAll !== strundefined ? context.querySelectorAll( tag || "*" ) : - undefined; - - if ( !found ) { - for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) { - if ( !tag || jQuery.nodeName( elem, tag ) ) { - found.push( elem ); - } else { - jQuery.merge( found, getAll( elem, tag ) ); - } - } - } - - return tag === undefined || tag && jQuery.nodeName( context, tag ) ? - jQuery.merge( [ context ], found ) : - found; -} - -// Used in buildFragment, fixes the defaultChecked property -function fixDefaultChecked( elem ) { - if ( rcheckableType.test( elem.type ) ) { - elem.defaultChecked = elem.checked; - } -} - -// Support: IE<8 -// Manipulating tables requires a tbody -function manipulationTarget( elem, content ) { - return jQuery.nodeName( elem, "table" ) && - jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ? - - elem.getElementsByTagName("tbody")[0] || - elem.appendChild( elem.ownerDocument.createElement("tbody") ) : - elem; -} - -// Replace/restore the type attribute of script elements for safe DOM manipulation -function disableScript( elem ) { - elem.type = (jQuery.find.attr( elem, "type" ) !== null) + "/" + elem.type; - return elem; -} -function restoreScript( elem ) { - var match = rscriptTypeMasked.exec( elem.type ); - if ( match ) { - elem.type = match[1]; - } else { - elem.removeAttribute("type"); - } - return elem; -} - -// Mark scripts as having already been evaluated -function setGlobalEval( elems, refElements ) { - var elem, - i = 0; - for ( ; (elem = elems[i]) != null; i++ ) { - jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) ); - } -} - -function cloneCopyEvent( src, dest ) { - - if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { - return; - } - - var type, i, l, - oldData = jQuery._data( src ), - curData = jQuery._data( dest, oldData ), - events = oldData.events; - - if ( events ) { - delete curData.handle; - curData.events = {}; - - for ( type in events ) { - for ( i = 0, l = events[ type ].length; i < l; i++ ) { - jQuery.event.add( dest, type, events[ type ][ i ] ); - } - } - } - - // make the cloned public data object a copy from the original - if ( curData.data ) { - curData.data = jQuery.extend( {}, curData.data ); - } -} - -function fixCloneNodeIssues( src, dest ) { - var nodeName, e, data; - - // We do not need to do anything for non-Elements - if ( dest.nodeType !== 1 ) { - return; - } - - nodeName = dest.nodeName.toLowerCase(); - - // IE6-8 copies events bound via attachEvent when using cloneNode. - if ( !support.noCloneEvent && dest[ jQuery.expando ] ) { - data = jQuery._data( dest ); - - for ( e in data.events ) { - jQuery.removeEvent( dest, e, data.handle ); - } - - // Event data gets referenced instead of copied if the expando gets copied too - dest.removeAttribute( jQuery.expando ); - } - - // IE blanks contents when cloning scripts, and tries to evaluate newly-set text - if ( nodeName === "script" && dest.text !== src.text ) { - disableScript( dest ).text = src.text; - restoreScript( dest ); - - // IE6-10 improperly clones children of object elements using classid. - // IE10 throws NoModificationAllowedError if parent is null, #12132. - } else if ( nodeName === "object" ) { - if ( dest.parentNode ) { - dest.outerHTML = src.outerHTML; - } - - // This path appears unavoidable for IE9. When cloning an object - // element in IE9, the outerHTML strategy above is not sufficient. - // If the src has innerHTML and the destination does not, - // copy the src.innerHTML into the dest.innerHTML. #10324 - if ( support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) { - dest.innerHTML = src.innerHTML; - } - - } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) { - // IE6-8 fails to persist the checked state of a cloned checkbox - // or radio button. Worse, IE6-7 fail to give the cloned element - // a checked appearance if the defaultChecked value isn't also set - - dest.defaultChecked = dest.checked = src.checked; - - // IE6-7 get confused and end up setting the value of a cloned - // checkbox/radio button to an empty string instead of "on" - if ( dest.value !== src.value ) { - dest.value = src.value; - } - - // IE6-8 fails to return the selected option to the default selected - // state when cloning options - } else if ( nodeName === "option" ) { - dest.defaultSelected = dest.selected = src.defaultSelected; - - // IE6-8 fails to set the defaultValue to the correct value when - // cloning other types of input fields - } else if ( nodeName === "input" || nodeName === "textarea" ) { - dest.defaultValue = src.defaultValue; - } -} - -jQuery.extend({ - clone: function( elem, dataAndEvents, deepDataAndEvents ) { - var destElements, node, clone, i, srcElements, - inPage = jQuery.contains( elem.ownerDocument, elem ); - - if ( support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { - clone = elem.cloneNode( true ); - - // IE<=8 does not properly clone detached, unknown element nodes - } else { - fragmentDiv.innerHTML = elem.outerHTML; - fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); - } - - if ( (!support.noCloneEvent || !support.noCloneChecked) && - (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { - - // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 - destElements = getAll( clone ); - srcElements = getAll( elem ); - - // Fix all IE cloning issues - for ( i = 0; (node = srcElements[i]) != null; ++i ) { - // Ensure that the destination node is not null; Fixes #9587 - if ( destElements[i] ) { - fixCloneNodeIssues( node, destElements[i] ); - } - } - } - - // Copy the events from the original to the clone - if ( dataAndEvents ) { - if ( deepDataAndEvents ) { - srcElements = srcElements || getAll( elem ); - destElements = destElements || getAll( clone ); - - for ( i = 0; (node = srcElements[i]) != null; i++ ) { - cloneCopyEvent( node, destElements[i] ); - } - } else { - cloneCopyEvent( elem, clone ); - } - } - - // Preserve script evaluation history - destElements = getAll( clone, "script" ); - if ( destElements.length > 0 ) { - setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); - } - - destElements = srcElements = node = null; - - // Return the cloned set - return clone; - }, - - buildFragment: function( elems, context, scripts, selection ) { - var j, elem, contains, - tmp, tag, tbody, wrap, - l = elems.length, - - // Ensure a safe fragment - safe = createSafeFragment( context ), - - nodes = [], - i = 0; - - for ( ; i < l; i++ ) { - elem = elems[ i ]; - - if ( elem || elem === 0 ) { - - // Add nodes directly - if ( jQuery.type( elem ) === "object" ) { - jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); - - // Convert non-html into a text node - } else if ( !rhtml.test( elem ) ) { - nodes.push( context.createTextNode( elem ) ); - - // Convert html into DOM nodes - } else { - tmp = tmp || safe.appendChild( context.createElement("div") ); - - // Deserialize a standard representation - tag = (rtagName.exec( elem ) || [ "", "" ])[ 1 ].toLowerCase(); - wrap = wrapMap[ tag ] || wrapMap._default; - - tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1>" ) + wrap[2]; - - // Descend through wrappers to the right content - j = wrap[0]; - while ( j-- ) { - tmp = tmp.lastChild; - } - - // Manually add leading whitespace removed by IE - if ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { - nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) ); - } - - // Remove IE's autoinserted from table fragments - if ( !support.tbody ) { - - // String was a , *may* have spurious - elem = tag === "table" && !rtbody.test( elem ) ? - tmp.firstChild : - - // String was a bare or - wrap[1] === "
" && !rtbody.test( elem ) ? - tmp : - 0; - - j = elem && elem.childNodes.length; - while ( j-- ) { - if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) { - elem.removeChild( tbody ); - } - } - } - - jQuery.merge( nodes, tmp.childNodes ); - - // Fix #12392 for WebKit and IE > 9 - tmp.textContent = ""; - - // Fix #12392 for oldIE - while ( tmp.firstChild ) { - tmp.removeChild( tmp.firstChild ); - } - - // Remember the top-level container for proper cleanup - tmp = safe.lastChild; - } - } - } - - // Fix #11356: Clear elements from fragment - if ( tmp ) { - safe.removeChild( tmp ); - } - - // Reset defaultChecked for any radios and checkboxes - // about to be appended to the DOM in IE 6/7 (#8060) - if ( !support.appendChecked ) { - jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); - } - - i = 0; - while ( (elem = nodes[ i++ ]) ) { - - // #4087 - If origin and destination elements are the same, and this is - // that element, do not do anything - if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { - continue; - } - - contains = jQuery.contains( elem.ownerDocument, elem ); - - // Append to fragment - tmp = getAll( safe.appendChild( elem ), "script" ); - - // Preserve script evaluation history - if ( contains ) { - setGlobalEval( tmp ); - } - - // Capture executables - if ( scripts ) { - j = 0; - while ( (elem = tmp[ j++ ]) ) { - if ( rscriptType.test( elem.type || "" ) ) { - scripts.push( elem ); - } - } - } - } - - tmp = null; - - return safe; - }, - - cleanData: function( elems, /* internal */ acceptData ) { - var elem, type, id, data, - i = 0, - internalKey = jQuery.expando, - cache = jQuery.cache, - deleteExpando = support.deleteExpando, - special = jQuery.event.special; - - for ( ; (elem = elems[i]) != null; i++ ) { - if ( acceptData || jQuery.acceptData( elem ) ) { - - id = elem[ internalKey ]; - data = id && cache[ id ]; - - if ( data ) { - if ( data.events ) { - for ( type in data.events ) { - if ( special[ type ] ) { - jQuery.event.remove( elem, type ); - - // This is a shortcut to avoid jQuery.event.remove's overhead - } else { - jQuery.removeEvent( elem, type, data.handle ); - } - } - } - - // Remove cache only if it was not already removed by jQuery.event.remove - if ( cache[ id ] ) { - - delete cache[ id ]; - - // IE does not allow us to delete expando properties from nodes, - // nor does it have a removeAttribute function on Document nodes; - // we must handle all of these cases - if ( deleteExpando ) { - delete elem[ internalKey ]; - - } else if ( typeof elem.removeAttribute !== strundefined ) { - elem.removeAttribute( internalKey ); - - } else { - elem[ internalKey ] = null; - } - - deletedIds.push( id ); - } - } - } - } - } -}); - -jQuery.fn.extend({ - text: function( value ) { - return access( this, function( value ) { - return value === undefined ? - jQuery.text( this ) : - this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); - }, null, value, arguments.length ); - }, - - append: function() { - return this.domManip( arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.appendChild( elem ); - } - }); - }, - - prepend: function() { - return this.domManip( arguments, function( elem ) { - if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { - var target = manipulationTarget( this, elem ); - target.insertBefore( elem, target.firstChild ); - } - }); - }, - - before: function() { - return this.domManip( arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this ); - } - }); - }, - - after: function() { - return this.domManip( arguments, function( elem ) { - if ( this.parentNode ) { - this.parentNode.insertBefore( elem, this.nextSibling ); - } - }); - }, - - remove: function( selector, keepData /* Internal Use Only */ ) { - var elem, - elems = selector ? jQuery.filter( selector, this ) : this, - i = 0; - - for ( ; (elem = elems[i]) != null; i++ ) { - - if ( !keepData && elem.nodeType === 1 ) { - jQuery.cleanData( getAll( elem ) ); - } - - if ( elem.parentNode ) { - if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { - setGlobalEval( getAll( elem, "script" ) ); - } - elem.parentNode.removeChild( elem ); - } - } - - return this; - }, - - empty: function() { - var elem, - i = 0; - - for ( ; (elem = this[i]) != null; i++ ) { - // Remove element nodes and prevent memory leaks - if ( elem.nodeType === 1 ) { - jQuery.cleanData( getAll( elem, false ) ); - } - - // Remove any remaining nodes - while ( elem.firstChild ) { - elem.removeChild( elem.firstChild ); - } - - // If this is a select, ensure that it displays empty (#12336) - // Support: IE<9 - if ( elem.options && jQuery.nodeName( elem, "select" ) ) { - elem.options.length = 0; - } - } - - return this; - }, - - clone: function( dataAndEvents, deepDataAndEvents ) { - dataAndEvents = dataAndEvents == null ? false : dataAndEvents; - deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; - - return this.map(function() { - return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); - }); - }, - - html: function( value ) { - return access( this, function( value ) { - var elem = this[ 0 ] || {}, - i = 0, - l = this.length; - - if ( value === undefined ) { - return elem.nodeType === 1 ? - elem.innerHTML.replace( rinlinejQuery, "" ) : - undefined; - } - - // See if we can take a shortcut and just use innerHTML - if ( typeof value === "string" && !rnoInnerhtml.test( value ) && - ( support.htmlSerialize || !rnoshimcache.test( value ) ) && - ( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && - !wrapMap[ (rtagName.exec( value ) || [ "", "" ])[ 1 ].toLowerCase() ] ) { - - value = value.replace( rxhtmlTag, "<$1>" ); - - try { - for (; i < l; i++ ) { - // Remove element nodes and prevent memory leaks - elem = this[i] || {}; - if ( elem.nodeType === 1 ) { - jQuery.cleanData( getAll( elem, false ) ); - elem.innerHTML = value; - } - } - - elem = 0; - - // If using innerHTML throws an exception, use the fallback method - } catch(e) {} - } - - if ( elem ) { - this.empty().append( value ); - } - }, null, value, arguments.length ); - }, - - replaceWith: function() { - var arg = arguments[ 0 ]; - - // Make the changes, replacing each context element with the new content - this.domManip( arguments, function( elem ) { - arg = this.parentNode; - - jQuery.cleanData( getAll( this ) ); - - if ( arg ) { - arg.replaceChild( elem, this ); - } - }); - - // Force removal if there was no new content (e.g., from empty arguments) - return arg && (arg.length || arg.nodeType) ? this : this.remove(); - }, - - detach: function( selector ) { - return this.remove( selector, true ); - }, - - domManip: function( args, callback ) { - - // Flatten any nested arrays - args = concat.apply( [], args ); - - var first, node, hasScripts, - scripts, doc, fragment, - i = 0, - l = this.length, - set = this, - iNoClone = l - 1, - value = args[0], - isFunction = jQuery.isFunction( value ); - - // We can't cloneNode fragments that contain checked, in WebKit - if ( isFunction || - ( l > 1 && typeof value === "string" && - !support.checkClone && rchecked.test( value ) ) ) { - return this.each(function( index ) { - var self = set.eq( index ); - if ( isFunction ) { - args[0] = value.call( this, index, self.html() ); - } - self.domManip( args, callback ); - }); - } - - if ( l ) { - fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); - first = fragment.firstChild; - - if ( fragment.childNodes.length === 1 ) { - fragment = first; - } - - if ( first ) { - scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); - hasScripts = scripts.length; - - // Use the original fragment for the last item instead of the first because it can end up - // being emptied incorrectly in certain situations (#8070). - for ( ; i < l; i++ ) { - node = fragment; - - if ( i !== iNoClone ) { - node = jQuery.clone( node, true, true ); - - // Keep references to cloned scripts for later restoration - if ( hasScripts ) { - jQuery.merge( scripts, getAll( node, "script" ) ); - } - } - - callback.call( this[i], node, i ); - } - - if ( hasScripts ) { - doc = scripts[ scripts.length - 1 ].ownerDocument; - - // Reenable scripts - jQuery.map( scripts, restoreScript ); - - // Evaluate executable scripts on first document insertion - for ( i = 0; i < hasScripts; i++ ) { - node = scripts[ i ]; - if ( rscriptType.test( node.type || "" ) && - !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) { - - if ( node.src ) { - // Optional AJAX dependency, but won't run scripts if not present - if ( jQuery._evalUrl ) { - jQuery._evalUrl( node.src ); - } - } else { - jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) ); - } - } - } - } - - // Fix #11809: Avoid leaking memory - fragment = first = null; - } - } - - return this; - } -}); - -jQuery.each({ - appendTo: "append", - prependTo: "prepend", - insertBefore: "before", - insertAfter: "after", - replaceAll: "replaceWith" -}, function( name, original ) { - jQuery.fn[ name ] = function( selector ) { - var elems, - i = 0, - ret = [], - insert = jQuery( selector ), - last = insert.length - 1; - - for ( ; i <= last; i++ ) { - elems = i === last ? this : this.clone(true); - jQuery( insert[i] )[ original ]( elems ); - - // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() - push.apply( ret, elems.get() ); - } - - return this.pushStack( ret ); - }; -}); - - -var iframe, - elemdisplay = {}; - -/** - * Retrieve the actual display of a element - * @param {String} name nodeName of the element - * @param {Object} doc Document object - */ -// Called only from within defaultDisplay -function actualDisplay( name, doc ) { - var style, - elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), - - // getDefaultComputedStyle might be reliably used only on attached element - display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ? - - // Use of this method is a temporary fix (more like optmization) until something better comes along, - // since it was removed from specification and supported only in FF - style.display : jQuery.css( elem[ 0 ], "display" ); - - // We don't have any data stored on the element, - // so use "detach" method as fast way to get rid of the element - elem.detach(); - - return display; -} - -/** - * Try to determine the default display value of an element - * @param {String} nodeName - */ -function defaultDisplay( nodeName ) { - var doc = document, - display = elemdisplay[ nodeName ]; - - if ( !display ) { - display = actualDisplay( nodeName, doc ); - - // If the simple way fails, read from inside an iframe - if ( display === "none" || !display ) { - - // Use the already-created iframe if possible - iframe = (iframe || jQuery( "